exceptions mips style
play

Exceptions, MIPS-Style Reminder: MIPS CPU deals with exceptions. - PDF document

CPSC-410/611 Operating Systems Exceptions, MIPS-Style Reminder: MIPS CPU deals with exceptions. Interrupts are just a special case of exceptions. The MIPS Architecture has no interrupt-vector table! All exceptions trigger


  1. CPSC-410/611 Operating Systems Exceptions, MIPS-Style • Reminder: – MIPS CPU deals with exceptions. • Interrupts are just a special case of exceptions. – The MIPS Architecture has no interrupt-vector table! • All exceptions trigger a jump to the same location, and de- multiplexing happens in the exception handler, after looking up the reason for the exception in the CAUSE register. exception exception handler specific service routine Exception Handling MIPS-Style (I): Data Structures /*-----------------------------------------------------------------------*/ /* DATA STRUCTURES */ xcptlow_handler /*-----------------------------------------------------------------------*/ typedef enum {Int = 0, Mod = 1, TLBL = 2, TLBS = 3, AdEL = 4, AdES = 5, set up exception frame IBE = 6, DBE = 7, Syscall = 8, Bp = 9, RI = 10, CpU = 11, on stack Ov = 12, TRAP = 13, VCEI = 14, FPE = 15, C2E = 16, Watch = 23, VCED = 31} EXCEPTION_CODE; save enough registers to get by typedef unsigned int reg_t; typedef struct xcptcontext { save rest of registers /* This is the exception context frame that is passed to the exception handlers. It gets filled in by the low-level exception handler in "machine.S". An assembler version of this structure can be found at the call C exception handler bottom of "machine.H".*/ reg_t sr; /* Status Register */ reg_t cr; /* Cause Register */ restore registers reg_t epc; /* PC at time of exception. */ reg_t vaddr; reg_t regs[32]; /* Copy of all general purpose registers */ return from exception reg_t mdlo; /* HI/LO registers (used for memory management) */ reg_t mdhi; reg_t count; /* Timer registers */ reg_t compare; struct xcptcontext * prev; /* To link exceptions. (unused for now) */ unsigned xclass; /* Priority class of this exception. (unused for now). */ } EXCEPTION_CONTEXT; 1

  2. CPSC-410/611 Operating Systems Exception Handling MIPS-Style (II): Set-up Frame xcptlow_handler set up exception frame LEAF(xcptlow_handler) on stack .set noreorder .set noat /* Note: exceptions do not save and restore registers k0 and k1. save enough registers * on entry, k1 = exception class. to get by */ /* save exception class in memory */ save rest of registers la k0, class sw k1, 0(k0) # had better not trap! move k0, zero # now boot exception will abort. call C exception handler /* allocate exception stack frame (on 8-byte boundary) */ subu k1, sp, XCP_SIZE srl k1, 3 /* shift right/left -> alligned on boundary */ restore registers sll k1, 3 return from exception Exception Handling MIPS-Style (III): Save Registers /* save enough registers to get by */ sr AT, XCP_AT(k1) sr v0, XCP_V0(k1) sr v1, XCP_V1(k1) xcptlow_handler sr a0, XCP_A0(k1) sr a1, XCP_A1(k1) set up exception frame sr a2, XCP_A2(k1) sr a3, XCP_A3(k1) on stack sr sp, XCP_SP(k1) sr ra, XCP_RA(k1) save enough registers to get by /* get coprocessor 0 exception state */ mfc0 a0, CPU0_CR mfc0 a1, CPU0_SR save rest of registers mfc0 a2, CPU0_VADDR mfc0 a3, CPU0_EPC /* we can safely use AT now */ call C exception handler .set at /* switch to using sp to point at exception frame */ restore registers move sp, k1 /* we skip saving of watchpoint registers */ return from exception /* stash exception class */ lw v0, class /* nothing sensible to store for k0/k1, store zero */ sr zero, XCP_K0(sp) sr zero, XCP_K1(sp) 2

  3. CPSC-410/611 Operating Systems Exception Handling MIPS-Style (IV): Save More Registers /* we have finished with the uninterruptible code. * (using k0/k1, and saving exception state), so * we can permit nested exceptions ; however, we cannot * permit device interrupts until the interrupt handler * does its prioritization and sets SR_IMASK. xcptlow_handler */ la k0, xcptlow_handler # restore rom boot exception hook set up exception frame and v0, a1, ~(SR_IMASK|SR_EXL|SR_KSU_MASK) on stack mtc0 v0, CPU0_SR .set reorder save enough registers to get by /* we are now interruptible: dump all remaining state * into the exception stack frame. */ save rest of registers /* coprocessor exception state */ sr a0, XCP_CR(sp) call C exception handler sr a1, XCP_SR(sp) sr a2, XCP_VADDR(sp) sr a3, XCP_EPC(sp) restore registers /* timer data */ mfc0 a0, CPU0_COUNT mfc0 a1, CPU0_COMPARE return from exception sr a0, XCP_COUNT(sp) sr a1, XCP_COMPARE(sp) /* mdhi and mdlo */ mfhi v0 mflo v1 sr v0, XCP_MDHI(sp) sr v1, XCP_MDLO(sp) Exception Handling MIPS-Style (V) /* Save all the other general registers. * We save zero, s0-s7 and s8 as well, as instruction emulators (e.g. FP * operations) and debuggers rely on all registers stored together in xcptlow_handler * well-defined structure. */ set up exception frame sr zero, XCP_ZERO(sp) sr t0, XCP_T0(sp) on stack … sr t7, XCP_T7(sp) save enough registers sr s0, XCP_S0(sp) to get by … sr s7, XCP_S7(sp) sr t8, XCP_T8(sp) save rest of registers sr t9, XCP_T9(sp) sr gp, XCP_GP(sp) sr s8, XCP_S8(sp) call C exception handler /* I don't know what the following does. [rb] */ /* load our _gp pointer */ la gp, _gp restore registers return from exception 3

  4. CPSC-410/611 Operating Systems Exception Handling MIPS-Style (VI) /* and call the C exception handler */ move a0, sp # arg1 = &xcp subu sp, 16 # (arg save area) move ra, zero # fake return address b _xcptcall xcptlow_handler /* This strange call to _xcptcall with zero return address is to * help exception-aware debuggers to trace back over the exception event. set up exception frame * We are basically interposing a bogus stackframe (with a zero return on stack * address) between the C exception handler and the actual machine * exception. */ save enough registers to get by xcptrest: LEAF(_xcptcall) .set noat /* on entry: a0 == &xcp */ add AT, sp, 16 save rest of registers subu sp, 24 /* at points to exception frame */ sr ra, 16(sp) /* punt out to _xcpt_deliver */ call C exception handler jal _xcpt_deliver lr ra, 16(sp) restore registers addu sp, 24 beqz ra, xcptrest j ra END(_xcptcall) return from exception extern "C" int _xcpt_deliver(struct xcptcontext * _xcp) { /* This function gets called by the low-level exception handler. */ ExceptionDispatcher::dispatch(_xcp); return 0; } /* end of _xcpt_deliver */ Exception Handling MIPS-Style (VII): Restore Registers xcptrestother: /* restore all state */ /* restore most general registers */ lr t0, XCP_T0(AT) xcptlow_handler … lr t7, XCP_T7(AT) set up exception frame lr s0, XCP_S0(AT) on stack … lr s7, XCP_S7(AT) lr t8, XCP_T8(AT) save enough registers lr t9, XCP_T9(AT) to get by lr gp, XCP_GP(AT) lr s8, XCP_S8(AT) save rest of registers /* mdhi and mdlo */ lr v0, XCP_MDHI(AT) lr v1, XCP_MDLO(AT) call C exception handler mthi v0 mtlo v1 /* remaining general registers */ restore registers lr a0, XCP_A0(AT) lr a1, XCP_A1(AT) lr a2, XCP_A2(AT) return from exception lr a3, XCP_A3(AT) lr ra, XCP_RA(AT) /* restore the exception-time status register, which has the * side effect of disabling interrupts. */ .set noreorder lr v0, XCP_SR(AT) 4

  5. CPSC-410/611 Operating Systems Exception Handling MIPS-Style (VIII): Return /* in the following we do some magic address pipeline xcptlow_handler effects when updating the control register. */ #clear SR_IMASK before setting SR_EXL (nasty window) set up exception frame li v1, ~(SR_IMASK|SR_EXL) on stack and v1, v0 mtc0 v1, CPU0_SR or v0, SR_EXL save enough registers nop to get by lr v1, XCP_V1(AT) mtc0 v0, CPU0_SR save rest of registers lr v0, XCP_V0(AT) lr sp, XCP_SP(AT) call C exception handler /* we are not uninterruptible and can use k1 safely */ lr k1, XCP_EPC(AT) lr AT, XCP_AT(AT) restore registers mtc0 k1, CPU0_EPC nop nop return from exception eret nop .set reorder .set at END(xcptlow_handler) Initialize MIPS Low-Level Exception Handler /* Macro to copy exception handler to unchached low memory */ #define XCPTCOPY(offs, start, end) \ li t0, KSEG1_BASE+offs ; \ la t1, start ; \ la t2, end ; \ 1: lw t3, 0(t1) ; \ addu t1, 4 ; \ sw t3, 0(t0) ; \ addu t0, 4 ; \ .text bne t1, t2, 1b .set noat .set noreorder _xcptlowstart: la k1, xcptlow_handler LEAF(_xcptlow_init) j k1 /* disable all interrupts */ _xcptlowend: mfc0 t4, CPU0_SR and t4, ~SR_IE .set reorder mtc0 t4, CPU0_SR .set at XCPTCOPY(0x180, _xcptlowstart, _xcptlowend) lw t0, _ram_based beqz t0, 1f /* using RAM-based handlers, so switch off boot exceptions */ and t4, ~SR_BEV mtc0 t4, CPU0_SR 1: la k0, xcptlow_handler j ra END(_xcptlow_init) 5

Download Presentation
Download Policy: The content available on the website is offered to you 'AS IS' for your personal information and use only. It cannot be commercialized, licensed, or distributed on other websites without prior consent from the author. To download a presentation, simply click this link. If you encounter any difficulties during the download process, it's possible that the publisher has removed the file from their server.

Recommend


More recommend