Rev 959 | Rev 1100 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 959 | Rev 1096 | ||
|---|---|---|---|
| Line 127... | Line 127... | ||
| 127 | for (i = 0; i < 8; i++) |
127 | for (i = 0; i < 8; i++) |
| 128 | if (cause & (1 << i)) |
128 | if (cause & (1 << i)) |
| 129 | exc_dispatch(i+INT_OFFSET, istate); |
129 | exc_dispatch(i+INT_OFFSET, istate); |
| 130 | } |
130 | } |
| 131 | 131 | ||
| 132 | #include <debug.h> |
- | |
| 133 | /** Handle syscall userspace call */ |
132 | __native syscall_handler(__native a0, __native a1, __native a2, |
| 134 | static void syscall_exception(int n, istate_t *istate) |
133 | __native a3, __native sysnum) |
| 135 | { |
134 | { |
| 136 | interrupts_enable(); |
- | |
| 137 | if (istate->t0 < SYSCALL_END) |
135 | if (sysnum < SYSCALL_END) |
| 138 | istate->v0 = syscall_table[istate->t0](istate->a0, |
136 | return syscall_table[sysnum](a0,a1,a2,a3); |
| 139 | istate->a1, |
- | |
| 140 | istate->a2, |
- | |
| 141 | istate->a3); |
- | |
| 142 | else |
- | |
| 143 | panic("Undefined syscall %d", istate->a3); |
137 | panic("Undefined syscall %d", sysnum); |
| 144 | istate->epc += 4; |
- | |
| 145 | interrupts_disable(); |
- | |
| 146 | } |
138 | } |
| 147 | 139 | ||
| - | 140 | /** Handle syscall userspace call */ |
|
| 148 | void exception(istate_t *istate) |
141 | static void syscall_exception(int n, istate_t *istate) |
| 149 | { |
142 | { |
| 150 | int cause; |
- | |
| 151 | int excno; |
- | |
| 152 | - | ||
| 153 | ASSERT(CPU != NULL); |
- | |
| 154 | - | ||
| 155 | /* |
- | |
| 156 | * NOTE ON OPERATION ORDERING |
- | |
| 157 | * |
- | |
| 158 | * On entry, interrupts_disable() must be called before |
- | |
| 159 | * exception bit is cleared. |
- | |
| 160 | */ |
- | |
| 161 | - | ||
| 162 | interrupts_disable(); |
- | |
| 163 | cp0_status_write(cp0_status_read() & ~ (cp0_status_exl_exception_bit | |
- | |
| 164 | cp0_status_um_bit)); |
- | |
| 165 | - | ||
| 166 | /* Save istate so that the threads can access it */ |
143 | panic("Syscall is handled through shortcut"); |
| 167 | /* If THREAD->istate is set, this is nested exception, |
- | |
| 168 | * do not rewrite it |
- | |
| 169 | */ |
- | |
| 170 | if (THREAD && !THREAD->istate) |
- | |
| 171 | THREAD->istate = istate; |
- | |
| 172 | - | ||
| 173 | cause = cp0_cause_read(); |
- | |
| 174 | excno = cp0_cause_excno(cause); |
- | |
| 175 | /* Dispatch exception */ |
- | |
| 176 | exc_dispatch(excno, istate); |
- | |
| 177 | - | ||
| 178 | /* Set to NULL, so that we can still support nested |
- | |
| 179 | * exceptions |
- | |
| 180 | * TODO: We should probably set EXL bit before this command, |
- | |
| 181 | * nesting. On the other hand, if some exception occurs between |
- | |
| 182 | * here and ERET, it won't set anything on the istate anyway. |
- | |
| 183 | */ |
- | |
| 184 | if (THREAD) |
- | |
| 185 | THREAD->istate = NULL; |
- | |
| 186 | } |
144 | } |
| 187 | 145 | ||
| 188 | void exception_init(void) |
146 | void exception_init(void) |
| 189 | { |
147 | { |
| 190 | int i; |
148 | int i; |