Zynq.Interrupts.Mos 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671
  1. MODULE Interrupts;
  2. IMPORT Platform, SYSTEM, Caches, Trace;
  3. CONST
  4. (* Interrupt Vector base *)
  5. InterruptVector = ADDRESS( 0H ); (* Check value *)
  6. MinIRQ = 0;
  7. MaxIRQ = 255;
  8. MaxIRQHandlers = 4;
  9. (** Period at which the CPU timer interrupts, in micro seconds *)
  10. TimerPeriod* = 1000;
  11. (** ID of the global timer IRQ *)
  12. TimerIRQ* = 27;
  13. PrivateTimerIRQ* = 29;
  14. PSUART0IRQ* = 59;
  15. PSUART1IRQ* = 82;
  16. I2C0* = 57;
  17. I2C1* = 80;
  18. QSPI* = 51;
  19. PLUARTIRQ* = 61; (* interrupt from the PL UART in the programming logic subsystem *)
  20. TYPE
  21. (** processor state *)
  22. State* = RECORD
  23. R*: ARRAY 12 OF ADDRESS; (** registers 0-11 *)
  24. BP*, SP*, LR*, PC*: ADDRESS; (** special registers *)
  25. PSR*: ADDRESS; (** processor state register *)
  26. irq*: ADDRESS; (** IRQ number *)
  27. END;
  28. (** NEON Coprocessor state *)
  29. NEONState* = ARRAY (16 * 16) OF CHAR; (* 16 Quadword = 16 bytes registers *)
  30. (** exception state *)
  31. ExceptionState* = RECORD
  32. halt*: LONGINT; (** halt code *)
  33. pf*: LONGINT; (** page fault address *)
  34. locks*: SET; (** active locks *)
  35. SP*: LONGINT; (** actual SP value at time of interrupt *)
  36. END;
  37. (* Interrupt Handler *)
  38. Handler* = PROCEDURE {DELEGATE} ( irq: LONGINT );
  39. TrapHandler* = PROCEDURE {DELEGATE} ( type, adr, fp: LONGINT; VAR resFP: LONGINT);
  40. VAR
  41. (** Interrupt Mask *)
  42. IRQMask: SET;
  43. irqHandler: ARRAY MaxIRQ + 1, MaxIRQHandlers OF Handler;
  44. irqCounter : LONGINT;
  45. trapHandler : TrapHandler;
  46. stateTag : LONGINT;
  47. globalLR : LONGINT;
  48. PROCEDURE RegisterTimerHandler*( proc : Handler );
  49. BEGIN
  50. InstallHandler( proc, PrivateTimerIRQ );
  51. END RegisterTimerHandler;
  52. (* Current processor's ID, between 0 and MaxProc - 1 *)
  53. PROCEDURE ID*(): LONGINT;
  54. CODE
  55. MRC p15, 0, R0, C0, C0, 5
  56. AND R0, R0, #3H; Get the last 2 bits of R0
  57. END ID;
  58. (*PROCEDURE InvalidateDCache*(dCacheBase: LONGINT);
  59. CODE
  60. LDR R1, [FP, #dCacheBase] ; R1 contains the virtual address of a region of cacheable memory
  61. LDR R1, [R1, #0]
  62. MOV R0, #1024 ; R0 is the loop count
  63. .loop1
  64. MCR p15, 0, R1, c7, c2, 5 ; allocate line in data cache
  65. ADD R1, R1, #32 ; increment the address in R1 to the next cache line
  66. SUBS R0, R0, #1
  67. BNE loop1
  68. ; clean the mini-data cache
  69. MOV R0, #64
  70. .loop2
  71. LDR R3, [R1], #32 ; load and increment to next cache line
  72. SUBS R0, R0, #1
  73. BNE loop2
  74. B invalidate
  75. DCD dCacheBase
  76. .invalidate
  77. ; invalidate data cache and mini-data cache
  78. MCR p15, 0, R0, c7, c6, 0
  79. ; cpwait
  80. MRC p15, 0, R0, c2, c0, 0
  81. MOV R0, R0
  82. SUB PC, PC, #4
  83. MOV R0, R0
  84. MOV R0, R0
  85. MOV R0, R0
  86. MOV R0, R0
  87. END InvalidateDCache;*)
  88. PROCEDURE EnableInterrupts*;
  89. VAR cpsr: LONGINT;
  90. BEGIN
  91. SYSTEM.STPSR(0, cpsr);
  92. cpsr := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, cpsr) - {7, 8});
  93. SYSTEM.LDPSR(0, cpsr);
  94. END EnableInterrupts;
  95. (* Taken from Minos/Kernel.Mos *)
  96. PROCEDURE DisableInterrupts*;
  97. VAR cpsr: LONGINT;
  98. BEGIN
  99. SYSTEM.STPSR(0, cpsr);
  100. cpsr := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, cpsr) + {7, 8});
  101. SYSTEM.LDPSR( 0, cpsr);
  102. END DisableInterrupts;
  103. PROCEDURE IsIRQEnabled(int: LONGINT): BOOLEAN;
  104. VAR
  105. enabled: BOOLEAN;
  106. reg: SET;
  107. BEGIN
  108. (*Acquire(Interrupts);*)
  109. SYSTEM.GET(Platform.ICDISER + 4 * (int DIV 32) , reg);
  110. enabled := (int MOD 32) IN reg;
  111. (*Release(Interrupts);*)
  112. RETURN enabled
  113. END IsIRQEnabled;
  114. (* DefaultUndef - default handler for undefined instruction exceptions *)
  115. PROCEDURE DefaultUndefined;
  116. VAR
  117. adr, fp: ADDRESS;
  118. udf, resFP: LONGINT;
  119. BEGIN
  120. CODE
  121. SUB R1, LR, #4 ; save address of undefined instruction
  122. STR R1, [FP, #adr]
  123. END;
  124. SYSTEM.GET(adr, udf);
  125. fp := GetFP();
  126. IF ( trapHandler # NIL ) THEN
  127. trapHandler( Platform.DataAbort, adr, fp, resFP );
  128. ELSE
  129. Trace.Ln;
  130. Trace.StringLn("Undefined Instruction Trap:");
  131. Trace.String(" pc: "); Trace.Hex(adr, -8); Trace.Ln;
  132. Trace.String(" instruction: "); Trace.Hex(udf, -8); Trace.Ln;
  133. Trace.String(" CPU: "); Trace.Address(ID()); Trace.Ln;
  134. Trace.String("Kernel Halted");
  135. END;
  136. LOOP END;
  137. END DefaultUndefined;
  138. (* DefaultSWI - default handler for software interrupts *)
  139. PROCEDURE DefaultSWI;
  140. VAR
  141. adr: ADDRESS;
  142. fp, resFP : LONGINT;
  143. swi: LONGINT;
  144. BEGIN
  145. CODE
  146. SUB R1, LR, #4
  147. STR R1, [FP, #adr] ; store address in adr
  148. END;
  149. fp := GetFP();
  150. SYSTEM.GET(adr, swi);
  151. swi := swi MOD 1000000H;
  152. IF ( trapHandler # NIL ) THEN
  153. trapHandler( Platform.SWI, adr, fp, resFP );
  154. ELSE
  155. Trace.Ln;
  156. Trace.StringLn("Software Interrupt:");
  157. Trace.String(" pc: "); Trace.Hex(adr, -8); Trace.Ln;
  158. Trace.String(" number: "); Trace.Hex(swi, -8); Trace.Ln;
  159. Trace.String(" CPU: "); Trace.Address(ID()); Trace.Ln;
  160. END;
  161. LOOP END;
  162. END DefaultSWI;
  163. (* Instruction Prefetch abort *)
  164. PROCEDURE {INTERRUPT, PCOFFSET=4} DefaultPrefetchAbort;
  165. VAR lnk, fp: LONGINT;
  166. BEGIN
  167. (* Store exception location. The location that trapped was lnk - 4 *)
  168. lnk := SYSTEM.LNK() - 4;
  169. fp := SYSTEM.FP();
  170. Trace.String("Prefetch abort at location: "); Trace.Hex(lnk,-8); Trace.Ln;
  171. Trace.String(" CPU: "); Trace.Address(ID()); Trace.Ln;
  172. SYSTEM.STPSR(1, lnk);
  173. Trace.String("SPSR: "); Trace.Address(lnk); Trace.Ln;
  174. (* Release(TraceOutput); *)
  175. LOOP END;
  176. END DefaultPrefetchAbort;
  177. (* DefaultDataAbort - default handler for data abort exceptions *)
  178. PROCEDURE {NOPAF} DefaultDataAbort;
  179. VAR
  180. pcAdr, faultAdr: ADDRESS;
  181. inst, stat: LONGINT;
  182. fp, resFP : LONGINT;
  183. BEGIN
  184. CODE
  185. SUB R1, LR, #8
  186. STR R1, [FP, #pcAdr]
  187. LDR R0, [R1, #0]
  188. STR R0, [FP, #inst]
  189. MRC p15, 0, R0, C5, C0 ; load fault status register (FSR)
  190. AND R0, R0, #0FFH ; only bits 7:0 are valid
  191. STR R0, [FP, #stat]
  192. MRC p15, 0, R0, C6, C0 ; load fault address (FAR)
  193. STR R0, [FP, #faultAdr]
  194. END;
  195. fp := GetFP();
  196. IF ( trapHandler # NIL ) THEN
  197. trapHandler( Platform.DataAbort, pcAdr, fp, resFP );
  198. ELSE
  199. Trace.Ln;
  200. Trace.StringLn("Data Abort Trap:");
  201. Trace.String(" pc: "); Trace.Hex(pcAdr, -8); Trace.Ln;
  202. Trace.String(" instruction: "); Trace.Hex(inst, -8); Trace.Ln;
  203. Trace.String(" fault status: "); Trace.Hex(stat, -8); Trace.Ln;
  204. Trace.String(" fault address: "); Trace.Hex(faultAdr, -8); Trace.Ln;
  205. Trace.String(" CPU: "); Trace.Address(ID()); Trace.Ln;
  206. Trace.String("Kernel halted.");
  207. END;
  208. LOOP END;
  209. END DefaultDataAbort;
  210. (* DefaultIRQ - default handler for IRQs *)
  211. PROCEDURE {INTERRUPT, PCOFFSET=4} DefaultIRQ;
  212. BEGIN
  213. (* Acquire(TraceOutput); *)
  214. Trace.StringLn("(IRQ)");
  215. Trace.String(" CPU: "); Trace.Address(ID()); Trace.Ln;
  216. (* Release(TraceOutput); *)
  217. SYSTEM.PUT32( Platform.PrivateTimerInterruptStatusRegister, 1);
  218. END DefaultIRQ;
  219. (*
  220. PROCEDURE {NOPAF} IRQGlue;
  221. CODE
  222. SUB SP, SP, #72 ; Room for the State record
  223. STMIA SP!, {R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, FP, SP, LR} ;^
  224. MOV R0, R0
  225. SUB R0, LR, #4 ; return address = LR-4
  226. STR R0, [SP], #4 ; push ('PC' in 'State'). SP points to offset 64
  227. MRS R0, SPSR ; get saved PSR
  228. STR R0, [SP], #4 ; push ('PSR' in 'State'). SP points to offset 68
  229. SUB SP, SP, #68
  230. MOV R11, SP
  231. LDR R5, [pc, #state-$-8] ; load address of stateTag constant
  232. STR R5, [SP, #-4]! ; push value (type tag)
  233. STR R11, [SP, #-4]! ; push parameter (address of 'State' parameter)
  234. BL IRQCaller
  235. LDR R11, [SP], #4
  236. ADD SP, SP, #4
  237. ADD SP, SP, #72 ; adjust SP & remove PAF
  238. LDR R0, [R11, #64] ; load 'State.PSR'
  239. MSR SPSR_cxsf, R0 ; and store it into SPSR
  240. LDR R0, [R11, #60] ; load 'State.PC'...
  241. MOV LR, R0 ; ...into LR (because we will return to LR, not PC)
  242. ADD R0, R11, #48 ; R0 points to 'State.SP'
  243. LDMIA R0, { FP, SP, LR }^ ; load 'State.SP' & 'State.LR' into user mode registers
  244. MOV R0, R0 ; nop, to not access banked registers after LDM ^
  245. LDMIA R11, { R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10 } ; restore unbanked regs
  246. LDR R11, [R11, #44]
  247. ;BX LR
  248. MOVS PC, LR ; SPSR -> CPSR & return
  249. ; Data section
  250. state: d32 stateTag ; address of stateTag
  251. END IRQGlue;
  252. *)
  253. (* Primary interrupt handler *)
  254. PROCEDURE {INTERRUPT, PCOFFSET=4} IRQTrap;
  255. VAR
  256. spsr, count : LONGINT;
  257. lr, ack, irq : LONGINT;
  258. state : State;
  259. handler: Handler;
  260. BEGIN
  261. SYSTEM.STPSR( 1, spsr ); (* store SPSR *)
  262. (*
  263. (* Context Switch to SVC mode *)
  264. SYSTEM.LDPSR( 0, Platform.SVCMode + Platform.IRQDisabled + Platform.FIQDisabled);
  265. globalLR := SYSTEM.LNK();
  266. SYSTEM.LDPSR( 0, Platform.IRQMode + Platform.IRQDisabled + Platform.FIQDisabled);
  267. lr := globalLR;
  268. (* Enable Interrupts *)
  269. SYSTEM.LDPSR( 0, Platform.SVCMode );
  270. *)
  271. (* call the irq handlers *)
  272. (* IrqCaller( state );*)
  273. ack := SYSTEM.GET32( Platform.ICCIAR );
  274. (* service this irq *)
  275. irq := ack MOD 1024;
  276. IF irq # 1023 THEN (* not a spurious IRQ *)
  277. state.irq := irq;
  278. IF ( state.irq = PrivateTimerIRQ ) THEN
  279. SYSTEM.PUT32( Platform.PrivateTimerInterruptStatusRegister, 1);
  280. END;
  281. IF (MinIRQ <= irq) & (irq<= MaxIRQ) THEN
  282. count := 0;
  283. handler := irqHandler[irq, count];
  284. WHILE (handler # NIL) & (count < MaxIRQHandlers - 1) DO
  285. handler(irq);
  286. DisableInterrupts; (* handler may have reactivated interrupts *)
  287. INC(count);
  288. handler := irqHandler[ irq, count ];
  289. END;
  290. END;
  291. SYSTEM.PUT32( Platform.ICCEOIR, ack );
  292. END;
  293. (*
  294. (* Context Switch to IRQ mode*)
  295. SYSTEM.LDPSR( 0, Platform.IRQMode + Platform.IRQDisabled + Platform.FIQDisabled);
  296. globalLR := lr;
  297. SYSTEM.LDPSR( 0, Platform.SVCMode + Platform.IRQDisabled + Platform.FIQDisabled);
  298. SYSTEM.SETLNK(globalLR);
  299. SYSTEM.LDPSR( 0, Platform.IRQMode + Platform.IRQDisabled + Platform.FIQDisabled);
  300. *)
  301. SYSTEM.LDPSR( 1, spsr ); (* SPSR := old *)
  302. END IRQTrap;
  303. (* DefaultFIQ - default handler for fast interrupts *)
  304. PROCEDURE DefaultFIQ;
  305. BEGIN
  306. Trace.StringLn("Fast IRQ Trap");
  307. Trace.String(" CPU: "); Trace.Address(ID()); Trace.Ln;
  308. Trace.String("Kernel halted.");
  309. LOOP END
  310. END DefaultFIQ;
  311. (* InstallDefaultInterrupts - installs default interrupt handlers *)
  312. PROCEDURE InstallDefaultInterrupts*;
  313. VAR p: PROCEDURE; base: ADDRESS; pi: PROCEDURE {INTERRUPT};
  314. i, int: LONGINT;
  315. BEGIN
  316. base := InterruptVector;
  317. p := DefaultUndefined; SYSTEM.PUT32(base + 024H, SYSTEM.VAL(LONGINT, p));
  318. p := DefaultSWI; SYSTEM.PUT32(base + 028H, SYSTEM.VAL(LONGINT, p));
  319. pi := DefaultPrefetchAbort; SYSTEM.PUT32(base + 02CH, SYSTEM.VAL(LONGINT, pi));
  320. p := DefaultDataAbort; SYSTEM.PUT32(base + 030H, SYSTEM.VAL(LONGINT, p));
  321. pi := IRQTrap; SYSTEM.PUT32(base + 038H, SYSTEM.VAL(LONGINT, pi));
  322. p := DefaultFIQ; SYSTEM.PUT32(base + 03CH, SYSTEM.VAL(LONGINT, p));
  323. FOR int := 0 TO MaxIRQ DO
  324. FOR i := 0 TO MaxIRQHandlers -1 DO
  325. irqHandler[int, i] := NIL
  326. END
  327. END;
  328. END InstallDefaultInterrupts;
  329. PROCEDURE GetPC*(): LONGINT;
  330. CODE
  331. MOV R0, SP
  332. END GetPC;
  333. PROCEDURE GetFP*(): LONGINT;
  334. CODE
  335. MOV R0, FP
  336. END GetFP;
  337. (** EnableIRQ - enables a hardware interrupt (also done automatically by InstallHandler) *)
  338. PROCEDURE EnableIrq*( num: LONGINT );
  339. VAR
  340. add : LONGINT;
  341. val : SET;
  342. loc : LONGINT;
  343. BEGIN
  344. IF num = PrivateTimerIRQ THEN Trace.StringLn("Enable PrivateTimer IRQ") END;
  345. IF num = PSUART0IRQ THEN Trace.StringLn("Enable PSUART0 IRQ.") END;
  346. IF num = PSUART1IRQ THEN Trace.StringLn("Enable PSUART1 IRQ."); END;
  347. add := Platform.ICDISER + ( 4 * (num DIV 32));
  348. SYSTEM.GET( add, val );
  349. val := val + {num MOD 32};
  350. SYSTEM.PUT32( add, val );
  351. END EnableIrq;
  352. (** InstallHandler - installs a interrupt handler & enable IRQ if necessary.
  353. On entry to h interrupts are disabled and may be enabled with XXXXX. After handling the interrupt
  354. the state of interrupts are restored. The acknowledgement of a hardware interrupt is done automatically.
  355. IRQs are mapped from MinIRQ to MaxIRQ. *)
  356. PROCEDURE InstallHandler*( h: Handler; int: LONGINT );
  357. VAR
  358. i: LONGINT;
  359. BEGIN
  360. DisableInterrupts();
  361. i := 0;
  362. WHILE irqHandler[int, i] # NIL DO
  363. INC(i)
  364. END;
  365. (* IRQGlue may traverse list while it is being modified. *)
  366. irqHandler[int, i] := h;
  367. IF (int >= MinIRQ) & (int <= MaxIRQ) THEN
  368. EnableIrq(int);
  369. IF Platform.TraceInterrupts THEN
  370. Trace.String("[Machine]InstallHandler: h = 0x"); Trace.Address(SYSTEM.VAL(LONGINT, h));
  371. Trace.String("; int = "); Trace.Address(int);
  372. Trace.String("; IRQMask = 0x"); Trace.Address(SYSTEM.VAL(LONGINT, IRQMask));
  373. Trace.Ln;
  374. END;
  375. ELSE
  376. Trace.String("[Machine]: Failed to enable interrupt, illegal number.");
  377. END;
  378. EnableInterrupts();
  379. END InstallHandler;
  380. PROCEDURE RegisterTraphandler*( proc : TrapHandler );
  381. BEGIN
  382. IF ( proc # NIL ) THEN
  383. trapHandler := proc;
  384. END;
  385. END RegisterTraphandler;
  386. (** Calls all handlers for all pending IRQs.
  387. Is called by IRQGlue.
  388. *)
  389. PROCEDURE IrqCaller( VAR state: State );
  390. VAR
  391. i, reg, irq, ack, count: LONGINT;
  392. handler: Handler;
  393. icip: SET;
  394. test: BOOLEAN;
  395. BEGIN
  396. (*
  397. IF ( state.PSR MOD 20H ) # 1FH THEN
  398. Trace.StringLn( "IRQCaller: Recursive IRQ" );
  399. END;
  400. *)
  401. ack := SYSTEM.GET32( Platform.ICCIAR );
  402. (* service this irq *)
  403. irq := ack MOD 1024;
  404. IF irq # 1023 THEN (* not a spurious IRQ *)
  405. state.irq := irq;
  406. IF ( state.irq = PrivateTimerIRQ ) THEN
  407. SYSTEM.PUT32( Platform.PrivateTimerInterruptStatusRegister, 1);
  408. END;
  409. IF (MinIRQ <= irq) & (irq<= MaxIRQ) THEN
  410. count := 0;
  411. handler := irqHandler[irq, count];
  412. WHILE (handler # NIL) & (count < MaxIRQHandlers - 1) DO
  413. handler(irq);
  414. DisableInterrupts; (* handler may have reactivated interrupts *)
  415. INC(count);
  416. handler := irqHandler[ irq, count ];
  417. END;
  418. END;
  419. SYSTEM.PUT32( Platform.ICCEOIR, ack );
  420. END;
  421. (*
  422. (* service pending IRQs *)
  423. FOR reg := 0 TO 2 DO
  424. SYSTEM.GET( Platform.ICDISPR+reg*4, icip );
  425. i := 0;
  426. WHILE (i <= 31) & (icip # {}) DO
  427. IF (i IN icip) & IsIRQEnabled(i) THEN
  428. icip := icip - {i};
  429. irq := i+reg*32;
  430. Trace.String("Pending IRQ "); Trace.Hex(irq,-8); Trace.String(" "); Trace.Address(reg); Trace.Ln;
  431. count := 0;
  432. state.irq := irq;
  433. handler := irqHandler[irq, count];
  434. WHILE (handler # NIL) & (count < MaxIRQHandlers - 1) DO
  435. handler(state);
  436. DisableInterrupts; (* handler may have reactivated interrupts *)
  437. INC(count);
  438. handler := irqHandler[irq, count]
  439. END;
  440. SYSTEM.PUT32(Platform.ICCEOIR, irq); (* end of interrupt *)
  441. SYSTEM.PUT32(Platform.ICDICPR+reg*4, {i}); (* clear pending bit *)
  442. END;
  443. INC( i )
  444. END
  445. END;
  446. *)
  447. IF test THEN Trace.StringLn("End IRQCaller") END;
  448. END IrqCaller;
  449. (** Initializes IRQ handling. *)
  450. PROCEDURE InitInterrupts*;
  451. CONST
  452. EnableSecure=0;
  453. EnableNonSecure=1;
  454. NumberIRQs = 96;
  455. VAR dummy: BOOLEAN; p: PROCEDURE; i, int: LONGINT;
  456. BEGIN
  457. (* Acquire(Interrupts); *)
  458. IRQMask := {};
  459. (*SYSTEM.PUT32(IC + Platform.ICMR, IRQMask); (* mask all interrupts *)
  460. SYSTEM.PUT32(IC + Platform.ICLR, {}); (* all interrupts to IRQ, no FIQ *)*)
  461. (*
  462. p := IRQGlue;
  463. SYSTEM.PUT32(InterruptVector + 038H, SYSTEM.VAL(LONGINT, p)); (* install new handler *)
  464. *)
  465. SYSTEM.PUT32(Platform.ICDDCR, 0);
  466. FOR i := 32 DIV 16 TO (NumberIRQs-1) DIV 16 (* 2 bits per IRQ *) DO
  467. SYSTEM.PUT32(Platform.ICDICFR+i*4, 0);
  468. END;
  469. FOR i := 0 TO (NumberIRQs-1) DIV 4 (* 8 bits per IRQ *) DO
  470. SYSTEM.PUT32(Platform.ICDIPR+i*4, LONGINT(0A0A0A0A0H)); (* set priority of each interrupt to 160 *)
  471. END;
  472. FOR i := (32 DIV 4) TO (NumberIRQs-1) DIV 4 (* 8 bits per IRQ *) DO
  473. SYSTEM.PUT32(Platform.ICDIPTR+i*4, 1010101H); (* reset interrupt targets to processor 0 *)
  474. END;
  475. (* disable all interrupt forwardings *)
  476. FOR i := 0 TO (NumberIRQs-1) DIV 32 (* 1 bit per IRQ *) DO
  477. SYSTEM.PUT32(Platform.ICDICER+i*4, LONGINT(0FFFFFFFFH));
  478. END;
  479. SYSTEM.PUT32(Platform.ICCPMR, 0F0H);
  480. SYSTEM.PUT32(Platform.ICCICR, {0,1,2});
  481. SYSTEM.PUT32(Platform.ICCBPR, 0);
  482. SYSTEM.PUT32(Platform.ICDDCR, {EnableSecure, EnableNonSecure});
  483. (*Release(Interrupts);*)
  484. (* InvalidateDCache(dCacheBase); *)
  485. (*Caches.CleanDCache();*)
  486. END InitInterrupts;
  487. PROCEDURE SetupInterruptLocation();
  488. CODE
  489. ; set IRQ vector base register to zero
  490. mov r0, #0
  491. mcr p15, 0, r0, c12, c0, 0
  492. END SetupInterruptLocation;
  493. (* Setup the primary interrupt handler vectors. This must be done AFTER the MMU Setup, otherwise there's ROM mapped to
  494. memory location 0(Interrupt vectors)*)
  495. PROCEDURE SetupInterruptVectors;
  496. CONST Code = LONGINT(0E59FF018H); (* Code that represents LDR pc, pc + 18 *)
  497. VAR i: LONGINT;
  498. BEGIN
  499. Trace.StringLn("Setup IRQ Location!");
  500. FOR i := 0 TO 7 DO
  501. SYSTEM.PUT32( InterruptVector+ 4*i, Code );
  502. END;
  503. END SetupInterruptVectors;
  504. (** Init private timer *)
  505. PROCEDURE InitSysTick*;
  506. CONST
  507. TimerEnable=0;
  508. AutoReload=1;
  509. IRQEnable=2;
  510. Delay = LONGINT( 375000 );
  511. BEGIN
  512. (* disable first *)
  513. SYSTEM.PUT32( Platform.PrivateTimerControlRegister, {} );
  514. SYSTEM.PUT32( Platform.PrivateTimerControlRegister, { TimerEnable, AutoReload, IRQEnable } );
  515. SYSTEM.PUT32( Platform.PrivateLoadValueRegister, Delay );
  516. EnableIrq( PrivateTimerIRQ );
  517. END InitSysTick;
  518. BEGIN
  519. irqCounter := 0;
  520. trapHandler := NIL;
  521. Trace.StringLn("Setup Interrupt handling.");
  522. SetupInterruptLocation();
  523. (*SetupInterruptVectors();*)
  524. InstallDefaultInterrupts();
  525. Trace.StringLn("Initializing interrupts");
  526. InitInterrupts();
  527. Trace.StringLn("Interrupts Initialized")
  528. END Interrupts.