Rev 227 | Rev 317 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 227 | Rev 313 | ||
---|---|---|---|
Line 37... | Line 37... | ||
37 | void exception(void) |
37 | void exception(void) |
38 | { |
38 | { |
39 | int excno; |
39 | int excno; |
40 | __u32 epc; |
40 | __u32 epc; |
41 | __u32 epc_shift = 0; |
41 | __u32 epc_shift = 0; |
42 | pri_t pri; |
- | |
43 | 42 | ||
44 | ASSERT(CPU != NULL); |
43 | ASSERT(CPU != NULL); |
45 | 44 | ||
46 | /* |
45 | /* |
47 | * NOTE ON OPERATION ORDERING |
46 | * NOTE ON OPERATION ORDERING |
48 | * |
47 | * |
49 | * On entry, cpu_priority_high() must be called before exception bit is cleared. |
48 | * On entry, cpu_priority_high() must be called before exception bit is cleared. |
50 | * On exit, exception bit must be set before cpu_priority_restore() is called. |
49 | * On exit, exception bit must be set before cpu_priority_restore() is called. |
51 | */ |
50 | */ |
52 | 51 | ||
53 | pri = cpu_priority_high(); |
52 | cpu_priority_high(); |
54 | epc = cp0_epc_read(); |
53 | epc = cp0_epc_read(); |
55 | cp0_status_write(cp0_status_read() & ~ cp0_status_exl_exception_bit); |
54 | cp0_status_write(cp0_status_read() & ~ (cp0_status_exl_exception_bit | |
- | 55 | cp0_status_um_bit)); |
|
56 | 56 | ||
57 | if (THREAD) { |
57 | if (THREAD) { |
58 | THREAD->saved_pri = pri; |
- | |
59 | THREAD->saved_epc = epc; |
58 | THREAD->saved_epc = epc; |
60 | } |
59 | } |
61 | /* decode exception number and process the exception */ |
60 | /* decode exception number and process the exception */ |
62 | switch (excno = (cp0_cause_read() >> 2) & 0x1f) { |
61 | switch (excno = (cp0_cause_read() >> 2) & 0x1f) { |
63 | case EXC_Int: |
62 | case EXC_Int: |
Line 113... | Line 112... | ||
113 | break; |
112 | break; |
114 | default: |
113 | default: |
115 | panic("unhandled exception %d\n", excno); |
114 | panic("unhandled exception %d\n", excno); |
116 | } |
115 | } |
117 | 116 | ||
118 | if (THREAD) { |
117 | if (THREAD) |
119 | pri = THREAD->saved_pri; |
- | |
120 | epc = THREAD->saved_epc; |
118 | epc = THREAD->saved_epc; |
121 | } |
119 | |
122 | - | ||
- | 120 | /* Raise EXL bit before epc_write, so that we support |
|
123 | cp0_epc_write(epc + epc_shift); |
121 | * properly nested exceptions |
- | 122 | */ |
|
124 | cp0_status_write(cp0_status_read() | cp0_status_exl_exception_bit); |
123 | cp0_status_write(cp0_status_read() | cp0_status_exl_exception_bit); |
125 | cpu_priority_restore(pri); |
124 | cp0_epc_write(epc + epc_shift); |
126 | } |
125 | } |