123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671 |
- MODULE Interrupts;
- IMPORT Platform, SYSTEM, Caches, Trace;
- CONST
- (* Interrupt Vector base *)
- InterruptVector = ADDRESS( 0H ); (* Check value *)
- MinIRQ = 0;
- MaxIRQ = 255;
- MaxIRQHandlers = 4;
-
- (** Period at which the CPU timer interrupts, in micro seconds *)
- TimerPeriod* = 1000;
-
- (** ID of the global timer IRQ *)
- TimerIRQ* = 27;
- PrivateTimerIRQ* = 29;
-
- PSUART0IRQ* = 59;
- PSUART1IRQ* = 82;
-
- I2C0* = 57;
- I2C1* = 80;
- QSPI* = 51;
-
- PLUARTIRQ* = 61; (* interrupt from the PL UART in the programming logic subsystem *)
-
- TYPE
- (** processor state *)
- State* = RECORD
- R*: ARRAY 12 OF ADDRESS; (** registers 0-11 *)
- BP*, SP*, LR*, PC*: ADDRESS; (** special registers *)
- PSR*: ADDRESS; (** processor state register *)
- irq*: ADDRESS; (** IRQ number *)
- END;
- (** NEON Coprocessor state *)
- NEONState* = ARRAY (16 * 16) OF CHAR; (* 16 Quadword = 16 bytes registers *)
- (** exception state *)
- ExceptionState* = RECORD
- halt*: LONGINT; (** halt code *)
- pf*: LONGINT; (** page fault address *)
- locks*: SET; (** active locks *)
- SP*: LONGINT; (** actual SP value at time of interrupt *)
- END;
- (* Interrupt Handler *)
- Handler* = PROCEDURE {DELEGATE} ( irq: LONGINT );
- TrapHandler* = PROCEDURE {DELEGATE} ( type, adr, fp: LONGINT; VAR resFP: LONGINT);
- VAR
- (** Interrupt Mask *)
- IRQMask: SET;
-
- irqHandler: ARRAY MaxIRQ + 1, MaxIRQHandlers OF Handler;
- irqCounter : LONGINT;
-
- trapHandler : TrapHandler;
-
- stateTag : LONGINT;
- globalLR : LONGINT;
-
-
- PROCEDURE RegisterTimerHandler*( proc : Handler );
- BEGIN
- InstallHandler( proc, PrivateTimerIRQ );
- END RegisterTimerHandler;
-
-
- (* Current processor's ID, between 0 and MaxProc - 1 *)
- PROCEDURE ID*(): LONGINT;
- CODE
- MRC p15, 0, R0, C0, C0, 5
- AND R0, R0, #3H; Get the last 2 bits of R0
- END ID;
- (*PROCEDURE InvalidateDCache*(dCacheBase: LONGINT);
- CODE
- LDR R1, [FP, #dCacheBase] ; R1 contains the virtual address of a region of cacheable memory
- LDR R1, [R1, #0]
- MOV R0, #1024 ; R0 is the loop count
- .loop1
- MCR p15, 0, R1, c7, c2, 5 ; allocate line in data cache
- ADD R1, R1, #32 ; increment the address in R1 to the next cache line
- SUBS R0, R0, #1
- BNE loop1
- ; clean the mini-data cache
- MOV R0, #64
- .loop2
- LDR R3, [R1], #32 ; load and increment to next cache line
- SUBS R0, R0, #1
- BNE loop2
- B invalidate
- DCD dCacheBase
-
- .invalidate
- ; invalidate data cache and mini-data cache
- MCR p15, 0, R0, c7, c6, 0
- ; cpwait
- MRC p15, 0, R0, c2, c0, 0
- MOV R0, R0
- SUB PC, PC, #4
- MOV R0, R0
- MOV R0, R0
- MOV R0, R0
- MOV R0, R0
- END InvalidateDCache;*)
- PROCEDURE EnableInterrupts*;
- VAR cpsr: LONGINT;
- BEGIN
- SYSTEM.STPSR(0, cpsr);
- cpsr := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, cpsr) - {7, 8});
- SYSTEM.LDPSR(0, cpsr);
- END EnableInterrupts;
- (* Taken from Minos/Kernel.Mos *)
- PROCEDURE DisableInterrupts*;
- VAR cpsr: LONGINT;
- BEGIN
- SYSTEM.STPSR(0, cpsr);
- cpsr := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, cpsr) + {7, 8});
- SYSTEM.LDPSR( 0, cpsr);
- END DisableInterrupts;
- PROCEDURE IsIRQEnabled(int: LONGINT): BOOLEAN;
- VAR
- enabled: BOOLEAN;
- reg: SET;
- BEGIN
- (*Acquire(Interrupts);*)
- SYSTEM.GET(Platform.ICDISER + 4 * (int DIV 32) , reg);
- enabled := (int MOD 32) IN reg;
- (*Release(Interrupts);*)
- RETURN enabled
- END IsIRQEnabled;
- (* DefaultUndef - default handler for undefined instruction exceptions *)
- PROCEDURE DefaultUndefined;
- VAR
- adr, fp: ADDRESS;
- udf, resFP: LONGINT;
- BEGIN
- CODE
- SUB R1, LR, #4 ; save address of undefined instruction
- STR R1, [FP, #adr]
- END;
- SYSTEM.GET(adr, udf);
- fp := GetFP();
- IF ( trapHandler # NIL ) THEN
- trapHandler( Platform.DataAbort, adr, fp, resFP );
- ELSE
- Trace.Ln;
- Trace.StringLn("Undefined Instruction Trap:");
- Trace.String(" pc: "); Trace.Hex(adr, -8); Trace.Ln;
- Trace.String(" instruction: "); Trace.Hex(udf, -8); Trace.Ln;
- Trace.String(" CPU: "); Trace.Address(ID()); Trace.Ln;
- Trace.String("Kernel Halted");
- END;
- LOOP END;
- END DefaultUndefined;
- (* DefaultSWI - default handler for software interrupts *)
- PROCEDURE DefaultSWI;
- VAR
- adr: ADDRESS;
- fp, resFP : LONGINT;
- swi: LONGINT;
- BEGIN
- CODE
- SUB R1, LR, #4
- STR R1, [FP, #adr] ; store address in adr
- END;
-
- fp := GetFP();
-
- SYSTEM.GET(adr, swi);
- swi := swi MOD 1000000H;
- IF ( trapHandler # NIL ) THEN
- trapHandler( Platform.SWI, adr, fp, resFP );
- ELSE
- Trace.Ln;
- Trace.StringLn("Software Interrupt:");
- Trace.String(" pc: "); Trace.Hex(adr, -8); Trace.Ln;
- Trace.String(" number: "); Trace.Hex(swi, -8); Trace.Ln;
- Trace.String(" CPU: "); Trace.Address(ID()); Trace.Ln;
- END;
- LOOP END;
- END DefaultSWI;
- (* Instruction Prefetch abort *)
- PROCEDURE {INTERRUPT, PCOFFSET=4} DefaultPrefetchAbort;
- VAR lnk, fp: LONGINT;
- BEGIN
- (* Store exception location. The location that trapped was lnk - 4 *)
- lnk := SYSTEM.LNK() - 4;
- fp := SYSTEM.FP();
- Trace.String("Prefetch abort at location: "); Trace.Hex(lnk,-8); Trace.Ln;
- Trace.String(" CPU: "); Trace.Address(ID()); Trace.Ln;
-
- SYSTEM.STPSR(1, lnk);
- Trace.String("SPSR: "); Trace.Address(lnk); Trace.Ln;
- (* Release(TraceOutput); *)
- LOOP END;
- END DefaultPrefetchAbort;
- (* DefaultDataAbort - default handler for data abort exceptions *)
- PROCEDURE {NOPAF} DefaultDataAbort;
- VAR
- pcAdr, faultAdr: ADDRESS;
- inst, stat: LONGINT;
- fp, resFP : LONGINT;
- BEGIN
- CODE
- SUB R1, LR, #8
- STR R1, [FP, #pcAdr]
- LDR R0, [R1, #0]
- STR R0, [FP, #inst]
- MRC p15, 0, R0, C5, C0 ; load fault status register (FSR)
- AND R0, R0, #0FFH ; only bits 7:0 are valid
- STR R0, [FP, #stat]
- MRC p15, 0, R0, C6, C0 ; load fault address (FAR)
- STR R0, [FP, #faultAdr]
- END;
-
- fp := GetFP();
-
- IF ( trapHandler # NIL ) THEN
- trapHandler( Platform.DataAbort, pcAdr, fp, resFP );
- ELSE
- Trace.Ln;
- Trace.StringLn("Data Abort Trap:");
- Trace.String(" pc: "); Trace.Hex(pcAdr, -8); Trace.Ln;
- Trace.String(" instruction: "); Trace.Hex(inst, -8); Trace.Ln;
- Trace.String(" fault status: "); Trace.Hex(stat, -8); Trace.Ln;
- Trace.String(" fault address: "); Trace.Hex(faultAdr, -8); Trace.Ln;
- Trace.String(" CPU: "); Trace.Address(ID()); Trace.Ln;
- Trace.String("Kernel halted.");
- END;
- LOOP END;
- END DefaultDataAbort;
- (* DefaultIRQ - default handler for IRQs *)
- PROCEDURE {INTERRUPT, PCOFFSET=4} DefaultIRQ;
- BEGIN
- (* Acquire(TraceOutput); *)
- Trace.StringLn("(IRQ)");
- Trace.String(" CPU: "); Trace.Address(ID()); Trace.Ln;
- (* Release(TraceOutput); *)
-
- SYSTEM.PUT32( Platform.PrivateTimerInterruptStatusRegister, 1);
- END DefaultIRQ;
- (*
- PROCEDURE {NOPAF} IRQGlue;
- CODE
- SUB SP, SP, #72 ; Room for the State record
- STMIA SP!, {R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, FP, SP, LR} ;^
- MOV R0, R0
- SUB R0, LR, #4 ; return address = LR-4
- STR R0, [SP], #4 ; push ('PC' in 'State'). SP points to offset 64
- MRS R0, SPSR ; get saved PSR
- STR R0, [SP], #4 ; push ('PSR' in 'State'). SP points to offset 68
- SUB SP, SP, #68
- MOV R11, SP
- LDR R5, [pc, #state-$-8] ; load address of stateTag constant
- STR R5, [SP, #-4]! ; push value (type tag)
- STR R11, [SP, #-4]! ; push parameter (address of 'State' parameter)
- BL IRQCaller
-
- LDR R11, [SP], #4
- ADD SP, SP, #4
- ADD SP, SP, #72 ; adjust SP & remove PAF
- LDR R0, [R11, #64] ; load 'State.PSR'
- MSR SPSR_cxsf, R0 ; and store it into SPSR
- LDR R0, [R11, #60] ; load 'State.PC'...
- MOV LR, R0 ; ...into LR (because we will return to LR, not PC)
- ADD R0, R11, #48 ; R0 points to 'State.SP'
- LDMIA R0, { FP, SP, LR }^ ; load 'State.SP' & 'State.LR' into user mode registers
- MOV R0, R0 ; nop, to not access banked registers after LDM ^
- LDMIA R11, { R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10 } ; restore unbanked regs
- LDR R11, [R11, #44]
-
- ;BX LR
- MOVS PC, LR ; SPSR -> CPSR & return
-
- ; Data section
- state: d32 stateTag ; address of stateTag
- END IRQGlue;
- *)
- (* Primary interrupt handler *)
- PROCEDURE {INTERRUPT, PCOFFSET=4} IRQTrap;
- VAR
- spsr, count : LONGINT;
- lr, ack, irq : LONGINT;
- state : State;
- handler: Handler;
- BEGIN
- SYSTEM.STPSR( 1, spsr ); (* store SPSR *)
- (*
- (* Context Switch to SVC mode *)
- SYSTEM.LDPSR( 0, Platform.SVCMode + Platform.IRQDisabled + Platform.FIQDisabled);
- globalLR := SYSTEM.LNK();
-
- SYSTEM.LDPSR( 0, Platform.IRQMode + Platform.IRQDisabled + Platform.FIQDisabled);
- lr := globalLR;
-
- (* Enable Interrupts *)
- SYSTEM.LDPSR( 0, Platform.SVCMode );
- *)
- (* call the irq handlers *)
- (* IrqCaller( state );*)
- ack := SYSTEM.GET32( Platform.ICCIAR );
-
- (* service this irq *)
- irq := ack MOD 1024;
-
- IF irq # 1023 THEN (* not a spurious IRQ *)
- state.irq := irq;
-
- IF ( state.irq = PrivateTimerIRQ ) THEN
- SYSTEM.PUT32( Platform.PrivateTimerInterruptStatusRegister, 1);
- END;
- IF (MinIRQ <= irq) & (irq<= MaxIRQ) THEN
- count := 0;
- handler := irqHandler[irq, count];
- WHILE (handler # NIL) & (count < MaxIRQHandlers - 1) DO
- handler(irq);
- DisableInterrupts; (* handler may have reactivated interrupts *)
- INC(count);
- handler := irqHandler[ irq, count ];
- END;
- END;
-
- SYSTEM.PUT32( Platform.ICCEOIR, ack );
-
- END;
-
- (*
- (* Context Switch to IRQ mode*)
- SYSTEM.LDPSR( 0, Platform.IRQMode + Platform.IRQDisabled + Platform.FIQDisabled);
- globalLR := lr;
- SYSTEM.LDPSR( 0, Platform.SVCMode + Platform.IRQDisabled + Platform.FIQDisabled);
- SYSTEM.SETLNK(globalLR);
- SYSTEM.LDPSR( 0, Platform.IRQMode + Platform.IRQDisabled + Platform.FIQDisabled);
- *)
- SYSTEM.LDPSR( 1, spsr ); (* SPSR := old *)
- END IRQTrap;
- (* DefaultFIQ - default handler for fast interrupts *)
- PROCEDURE DefaultFIQ;
- BEGIN
- Trace.StringLn("Fast IRQ Trap");
- Trace.String(" CPU: "); Trace.Address(ID()); Trace.Ln;
- Trace.String("Kernel halted.");
- LOOP END
- END DefaultFIQ;
- (* InstallDefaultInterrupts - installs default interrupt handlers *)
- PROCEDURE InstallDefaultInterrupts*;
- VAR p: PROCEDURE; base: ADDRESS; pi: PROCEDURE {INTERRUPT};
- i, int: LONGINT;
- BEGIN
-
- base := InterruptVector;
-
- p := DefaultUndefined; SYSTEM.PUT32(base + 024H, SYSTEM.VAL(LONGINT, p));
- p := DefaultSWI; SYSTEM.PUT32(base + 028H, SYSTEM.VAL(LONGINT, p));
- pi := DefaultPrefetchAbort; SYSTEM.PUT32(base + 02CH, SYSTEM.VAL(LONGINT, pi));
- p := DefaultDataAbort; SYSTEM.PUT32(base + 030H, SYSTEM.VAL(LONGINT, p));
- pi := IRQTrap; SYSTEM.PUT32(base + 038H, SYSTEM.VAL(LONGINT, pi));
- p := DefaultFIQ; SYSTEM.PUT32(base + 03CH, SYSTEM.VAL(LONGINT, p));
- FOR int := 0 TO MaxIRQ DO
- FOR i := 0 TO MaxIRQHandlers -1 DO
- irqHandler[int, i] := NIL
- END
- END;
- END InstallDefaultInterrupts;
- PROCEDURE GetPC*(): LONGINT;
- CODE
- MOV R0, SP
- END GetPC;
- PROCEDURE GetFP*(): LONGINT;
- CODE
- MOV R0, FP
- END GetFP;
- (** EnableIRQ - enables a hardware interrupt (also done automatically by InstallHandler) *)
- PROCEDURE EnableIrq*( num: LONGINT );
- VAR
- add : LONGINT;
- val : SET;
- loc : LONGINT;
- BEGIN
- IF num = PrivateTimerIRQ THEN Trace.StringLn("Enable PrivateTimer IRQ") END;
- IF num = PSUART0IRQ THEN Trace.StringLn("Enable PSUART0 IRQ.") END;
- IF num = PSUART1IRQ THEN Trace.StringLn("Enable PSUART1 IRQ."); END;
- add := Platform.ICDISER + ( 4 * (num DIV 32));
- SYSTEM.GET( add, val );
- val := val + {num MOD 32};
- SYSTEM.PUT32( add, val );
- END EnableIrq;
- (** InstallHandler - installs a interrupt handler & enable IRQ if necessary.
- On entry to h interrupts are disabled and may be enabled with XXXXX. After handling the interrupt
- the state of interrupts are restored. The acknowledgement of a hardware interrupt is done automatically.
- IRQs are mapped from MinIRQ to MaxIRQ. *)
- PROCEDURE InstallHandler*( h: Handler; int: LONGINT );
- VAR
- i: LONGINT;
- BEGIN
-
- DisableInterrupts();
-
- i := 0;
-
- WHILE irqHandler[int, i] # NIL DO
- INC(i)
- END;
- (* IRQGlue may traverse list while it is being modified. *)
- irqHandler[int, i] := h;
- IF (int >= MinIRQ) & (int <= MaxIRQ) THEN
-
- EnableIrq(int);
- IF Platform.TraceInterrupts THEN
- Trace.String("[Machine]InstallHandler: h = 0x"); Trace.Address(SYSTEM.VAL(LONGINT, h));
- Trace.String("; int = "); Trace.Address(int);
- Trace.String("; IRQMask = 0x"); Trace.Address(SYSTEM.VAL(LONGINT, IRQMask));
- Trace.Ln;
- END;
-
- ELSE
- Trace.String("[Machine]: Failed to enable interrupt, illegal number.");
- END;
-
- EnableInterrupts();
- END InstallHandler;
- PROCEDURE RegisterTraphandler*( proc : TrapHandler );
- BEGIN
- IF ( proc # NIL ) THEN
- trapHandler := proc;
- END;
- END RegisterTraphandler;
- (** Calls all handlers for all pending IRQs.
- Is called by IRQGlue.
- *)
- PROCEDURE IrqCaller( VAR state: State );
- VAR
- i, reg, irq, ack, count: LONGINT;
- handler: Handler;
- icip: SET;
- test: BOOLEAN;
- BEGIN
- (*
- IF ( state.PSR MOD 20H ) # 1FH THEN
- Trace.StringLn( "IRQCaller: Recursive IRQ" );
- END;
- *)
- ack := SYSTEM.GET32( Platform.ICCIAR );
-
- (* service this irq *)
- irq := ack MOD 1024;
-
- IF irq # 1023 THEN (* not a spurious IRQ *)
- state.irq := irq;
-
- IF ( state.irq = PrivateTimerIRQ ) THEN
- SYSTEM.PUT32( Platform.PrivateTimerInterruptStatusRegister, 1);
- END;
- IF (MinIRQ <= irq) & (irq<= MaxIRQ) THEN
- count := 0;
- handler := irqHandler[irq, count];
- WHILE (handler # NIL) & (count < MaxIRQHandlers - 1) DO
- handler(irq);
- DisableInterrupts; (* handler may have reactivated interrupts *)
- INC(count);
- handler := irqHandler[ irq, count ];
- END;
- END;
-
- SYSTEM.PUT32( Platform.ICCEOIR, ack );
-
- END;
- (*
- (* service pending IRQs *)
- FOR reg := 0 TO 2 DO
- SYSTEM.GET( Platform.ICDISPR+reg*4, icip );
- i := 0;
- WHILE (i <= 31) & (icip # {}) DO
- IF (i IN icip) & IsIRQEnabled(i) THEN
-
- icip := icip - {i};
- irq := i+reg*32;
- Trace.String("Pending IRQ "); Trace.Hex(irq,-8); Trace.String(" "); Trace.Address(reg); Trace.Ln;
-
- count := 0;
- state.irq := irq;
- handler := irqHandler[irq, count];
-
- WHILE (handler # NIL) & (count < MaxIRQHandlers - 1) DO
- handler(state);
- DisableInterrupts; (* handler may have reactivated interrupts *)
- INC(count);
- handler := irqHandler[irq, count]
- END;
- SYSTEM.PUT32(Platform.ICCEOIR, irq); (* end of interrupt *)
- SYSTEM.PUT32(Platform.ICDICPR+reg*4, {i}); (* clear pending bit *)
- END;
-
- INC( i )
-
- END
- END;
- *)
- IF test THEN Trace.StringLn("End IRQCaller") END;
- END IrqCaller;
- (** Initializes IRQ handling. *)
- PROCEDURE InitInterrupts*;
- CONST
- EnableSecure=0;
- EnableNonSecure=1;
- NumberIRQs = 96;
- VAR dummy: BOOLEAN; p: PROCEDURE; i, int: LONGINT;
- BEGIN
- (* Acquire(Interrupts); *)
- IRQMask := {};
- (*SYSTEM.PUT32(IC + Platform.ICMR, IRQMask); (* mask all interrupts *)
- SYSTEM.PUT32(IC + Platform.ICLR, {}); (* all interrupts to IRQ, no FIQ *)*)
- (*
- p := IRQGlue;
- SYSTEM.PUT32(InterruptVector + 038H, SYSTEM.VAL(LONGINT, p)); (* install new handler *)
- *)
-
- SYSTEM.PUT32(Platform.ICDDCR, 0);
- FOR i := 32 DIV 16 TO (NumberIRQs-1) DIV 16 (* 2 bits per IRQ *) DO
- SYSTEM.PUT32(Platform.ICDICFR+i*4, 0);
- END;
- FOR i := 0 TO (NumberIRQs-1) DIV 4 (* 8 bits per IRQ *) DO
- SYSTEM.PUT32(Platform.ICDIPR+i*4, LONGINT(0A0A0A0A0H)); (* set priority of each interrupt to 160 *)
- END;
- FOR i := (32 DIV 4) TO (NumberIRQs-1) DIV 4 (* 8 bits per IRQ *) DO
- SYSTEM.PUT32(Platform.ICDIPTR+i*4, 1010101H); (* reset interrupt targets to processor 0 *)
- END;
- (* disable all interrupt forwardings *)
- FOR i := 0 TO (NumberIRQs-1) DIV 32 (* 1 bit per IRQ *) DO
- SYSTEM.PUT32(Platform.ICDICER+i*4, LONGINT(0FFFFFFFFH));
- END;
- SYSTEM.PUT32(Platform.ICCPMR, 0F0H);
- SYSTEM.PUT32(Platform.ICCICR, {0,1,2});
- SYSTEM.PUT32(Platform.ICCBPR, 0);
- SYSTEM.PUT32(Platform.ICDDCR, {EnableSecure, EnableNonSecure});
- (*Release(Interrupts);*)
- (* InvalidateDCache(dCacheBase); *)
- (*Caches.CleanDCache();*)
-
-
- END InitInterrupts;
- PROCEDURE SetupInterruptLocation();
- CODE
- ; set IRQ vector base register to zero
- mov r0, #0
- mcr p15, 0, r0, c12, c0, 0
-
- END SetupInterruptLocation;
- (* Setup the primary interrupt handler vectors. This must be done AFTER the MMU Setup, otherwise there's ROM mapped to
- memory location 0(Interrupt vectors)*)
- PROCEDURE SetupInterruptVectors;
- CONST Code = LONGINT(0E59FF018H); (* Code that represents LDR pc, pc + 18 *)
- VAR i: LONGINT;
- BEGIN
- Trace.StringLn("Setup IRQ Location!");
- FOR i := 0 TO 7 DO
- SYSTEM.PUT32( InterruptVector+ 4*i, Code );
- END;
- END SetupInterruptVectors;
- (** Init private timer *)
- PROCEDURE InitSysTick*;
- CONST
-
- TimerEnable=0;
- AutoReload=1;
- IRQEnable=2;
- Delay = LONGINT( 375000 );
-
- BEGIN
- (* disable first *)
- SYSTEM.PUT32( Platform.PrivateTimerControlRegister, {} );
- SYSTEM.PUT32( Platform.PrivateTimerControlRegister, { TimerEnable, AutoReload, IRQEnable } );
- SYSTEM.PUT32( Platform.PrivateLoadValueRegister, Delay );
- EnableIrq( PrivateTimerIRQ );
-
- END InitSysTick;
- BEGIN
-
- irqCounter := 0;
- trapHandler := NIL;
-
- Trace.StringLn("Setup Interrupt handling.");
-
- SetupInterruptLocation();
- (*SetupInterruptVectors();*)
- InstallDefaultInterrupts();
- Trace.StringLn("Initializing interrupts");
- InitInterrupts();
- Trace.StringLn("Interrupts Initialized")
- END Interrupts.
|