@@ -21,6 +21,8 @@ struct handlerArgPair irq_handlers[64];
2121// if the highest bit on this addr is set, the cpu will switch into supervisor mode
2222irqType __attribute__ ((aligned (512 ))) vectorTable [144 ]; // might only need to be 128 entries
2323
24+ uint8_t irq_stack0 [4096 ];
25+
2426static const char * g_ExceptionNames [] = {
2527 "Zero" ,
2628 "Misaligned" ,
@@ -50,6 +52,10 @@ void set_interrupt(int intno, bool enable, int core) {
5052
5153
5254void intc_init (void ) {
55+ uint32_t r28 , sp ;
56+ __asm__ volatile ("mov %0, r28" : "=r" (r28 ));
57+ __asm__ volatile ("mov %0, sp" : "=r" (sp ));
58+ dprintf (INFO , "intc_init\nr28: 0x%x\nsp: 0x%x\n" , r28 , sp );
5359 // TODO
5460 for (int i = 0 ; i < 64 ; i ++ ) {
5561 irq_handlers [0 ].h = 0 ; // is this needed? maybe .bss already took care of it?
@@ -77,18 +83,23 @@ void intc_init(void) {
7783 }
7884 // swi opcode handler
7985 for (int i = 32 ; i <=63 ; i ++ ) {
80- vectorTable [i ] = fleh_irq ;
86+ vectorTable [i ] = ( uint32_t ) fleh_irq | 1 ;
8187 }
8288 // external interrupts
8389 for (int i = 64 ; i <=127 ; i ++ ) {
84- vectorTable [i ] = fleh_irq ;
90+ vectorTable [i ] = ( uint32_t ) fleh_irq | 1 ;
8591 }
8692
93+ uint32_t irq_sp = (irq_stack0 + sizeof (irq_stack0 )) - 4 ;
94+ dprintf (INFO , "r28 = 0x%x\nirq_stack0: %p\nsizeof(irq_stack0): %d\n" , irq_sp , irq_stack0 , sizeof (irq_stack0 ));
95+
96+ __asm__ volatile ("mov r28, 0xdeadbeef" : :"r" (irq_sp ));
97+
8798 * REG32 (IC0_VADDR ) = vectorTable ;
8899 * REG32 (IC1_VADDR ) = vectorTable ;
89100
90101 if (* REG32 (IC0_VADDR ) != vectorTable ) {
91- printf ("vector table now at 0x%08lx 0x%08lx \n" , * REG32 (IC0_VADDR ), (uint32_t )vectorTable );
102+ printf ("vector table now at 0x%08x 0x%08x \n" , * REG32 (IC0_VADDR ), (uint32_t )vectorTable );
92103 panic ("vector table failed to install" );
93104 }
94105}
@@ -182,11 +193,25 @@ void sleh_fatal(vc4_saved_state_t* pcb, uint32_t n) {
182193 while (true) __asm__ volatile ("nop" );
183194}
184195
196+ // upon entry to this function(before its prologue runs), sp and r0 point to a `struct vc4_saved_state_t`
197+ // r0 (which lands in pcb) contains a copy of that sp from before the prologue
198+ // some common values and offsets:
199+ // r0 + 0: r23
200+ // ...
201+ // r0 + 92: r0
202+ // r0 + 96: lr
203+ // r0 + 100: sr
204+ // r0 + 104: pc
185205void sleh_irq (vc4_saved_state_t * pcb , uint32_t tp ) {
186206 uint32_t status = * REG32 (IC0_S );
187207 uint32_t source = status & 0xFF ;
188- uint32_t cs ;
189- int ret ;
208+ enum handler_return ret = INT_NO_RESCHEDULE ;
209+
210+ uint32_t r28 , sp , sr ;
211+ __asm__ volatile ("mov %0, r28" : "=r" (r28 ));
212+ __asm__ volatile ("mov %0, sp" : "=r" (sp ));
213+ __asm__ volatile ("mov %0, sr" : "=r" (sr ));
214+ //dprintf(INFO, "sleh_irq\nr28: 0x%x\nsp: 0x%x\nsr: 0x%x\n", r28, sp, sr);
190215
191216 //dprintf(INFO, "VPU Received interrupt from source %d\n", source);
192217
@@ -195,7 +220,11 @@ void sleh_irq(vc4_saved_state_t* pcb, uint32_t tp) {
195220 case 121 : // uart
196221 assert (irq_handlers [source - 64 ].h );
197222 ret = irq_handlers [source - 64 ].h (irq_handlers [source - 64 ].arg );
198- if (ret == INT_RESCHEDULE ) thread_preempt ();
223+ if (ret == INT_RESCHEDULE ) {
224+ //dprintf(INFO, "pre-emptying\n");
225+ thread_preempt ();
226+ //dprintf(INFO, "done preempt\n");
227+ }
199228 break ;
200229 case INTERRUPT_ARM :
201230 // fired when the arm cpu writes to the arm->vpu mailbox
0 commit comments