Rev 1787 | Rev 1852 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1787 | Rev 1851 | ||
---|---|---|---|
Line 41... | Line 41... | ||
41 | #include <arch/trap/regwin.h> |
41 | #include <arch/trap/regwin.h> |
42 | #include <arch/trap/interrupt.h> |
42 | #include <arch/trap/interrupt.h> |
43 | #include <arch/trap/exception.h> |
43 | #include <arch/trap/exception.h> |
44 | #include <arch/trap/mmu.h> |
44 | #include <arch/trap/mmu.h> |
45 | #include <arch/stack.h> |
45 | #include <arch/stack.h> |
- | 46 | #include <arch/regdef.h> |
|
46 | 47 | ||
47 | #define TABLE_SIZE TRAP_TABLE_SIZE |
48 | #define TABLE_SIZE TRAP_TABLE_SIZE |
48 | #define ENTRY_SIZE TRAP_TABLE_ENTRY_SIZE |
49 | #define ENTRY_SIZE TRAP_TABLE_ENTRY_SIZE |
49 | 50 | ||
50 | /* |
51 | /* |
Line 273... | Line 274... | ||
273 | .global fill_0_normal_high |
274 | .global fill_0_normal_high |
274 | fill_0_normal_high: |
275 | fill_0_normal_high: |
275 | FILL_NORMAL_HANDLER |
276 | FILL_NORMAL_HANDLER |
276 | 277 | ||
277 | 278 | ||
278 | /* Preemptible trap handler. |
279 | /* Preemptible trap handler for TL=1. |
279 | * |
280 | * |
280 | * This trap handler makes arrangements to |
281 | * This trap handler makes arrangements to make calling of scheduler() from |
- | 282 | * within a trap context possible. It is guaranteed to function only when traps |
|
281 | * make calling scheduler() possible. |
283 | * are not nested (i.e. for TL=1). |
282 | * |
284 | * |
- | 285 | * Every trap handler on TL=1 that makes a call to the scheduler needs to |
|
- | 286 | * be based on this function. The reason behind it is that the nested |
|
- | 287 | * trap levels and the automatic saving of the interrupted context by hardware |
|
- | 288 | * does not work well together with scheduling (i.e. a thread cannot be rescheduled |
|
- | 289 | * with TL>0). Therefore it is necessary to eliminate the effect of trap levels |
|
- | 290 | * by software and save the necessary state on the kernel stack. |
|
- | 291 | * |
|
- | 292 | * Note that for traps with TL>1, more state needs to be saved. This function |
|
- | 293 | * is therefore not going to work when TL>1. |
|
- | 294 | * |
|
283 | * The caller is responsible for doing save |
295 | * The caller is responsible for doing SAVE and allocating |
284 | * and allocating PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE |
296 | * PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE bytes on the stack. |
285 | * bytes on stack. |
- | |
286 | * |
297 | * |
287 | * Input registers: |
298 | * Input registers: |
288 | * %l0 Address of function to call. |
299 | * %l0 Address of function to call. |
289 | * Output registers: |
300 | * Output registers: |
290 | * %l1 - %l7 Copy of %g1 - %g7 |
301 | * %l1 - %l7 Copy of %g1 - %g7 |
Line 297... | Line 308... | ||
297 | rdpr %tstate, %g1 |
308 | rdpr %tstate, %g1 |
298 | rdpr %tpc, %g2 |
309 | rdpr %tpc, %g2 |
299 | rdpr %tnpc, %g3 |
310 | rdpr %tnpc, %g3 |
300 | rdpr %pstate, %g4 |
311 | rdpr %pstate, %g4 |
301 | 312 | ||
- | 313 | /* |
|
- | 314 | * The following memory accesses will not fault |
|
- | 315 | * because special provisions are made to have |
|
- | 316 | * the kernel stack of THREAD locked in DTLB. |
|
- | 317 | */ |
|
302 | stx %g1, [%fp + STACK_BIAS + SAVED_TSTATE] |
318 | stx %g1, [%fp + STACK_BIAS + SAVED_TSTATE] |
303 | stx %g2, [%fp + STACK_BIAS + SAVED_TPC] |
319 | stx %g2, [%fp + STACK_BIAS + SAVED_TPC] |
304 | stx %g3, [%fp + STACK_BIAS + SAVED_TNPC] |
320 | stx %g3, [%fp + STACK_BIAS + SAVED_TNPC] |
305 | stx %g4, [%fp + STACK_BIAS + SAVED_PSTATE] |
321 | stx %g4, [%fp + STACK_BIAS + SAVED_PSTATE] |
306 | 322 | ||
Line 311... | Line 327... | ||
311 | 327 | ||
312 | /* |
328 | /* |
313 | * Alter PSTATE. |
329 | * Alter PSTATE. |
314 | * - switch to normal globals. |
330 | * - switch to normal globals. |
315 | */ |
331 | */ |
316 | and %g4, ~1, %g4 ! mask alternate globals |
332 | and %g4, ~(PSTATE_AG_BIT|PSTATE_IG_BIT|PSTATE_MG_BIT), %g4 |
317 | wrpr %g4, 0, %pstate |
333 | wrpr %g4, 0, %pstate |
318 | 334 | ||
319 | /* |
335 | /* |
320 | * Save the normal globals. |
336 | * Save the normal globals. |
321 | */ |
337 | */ |
322 | SAVE_GLOBALS |
338 | SAVE_GLOBALS |
323 | 339 | ||
324 | /* |
340 | /* |
325 | * Call the higher-level handler. |
341 | * Call the higher-level handler. |
326 | */ |
342 | */ |
- | 343 | mov %fp, %o1 ! calculate istate address |
|
327 | call %l0 |
344 | call %l0 |
328 | nop |
- | |
- | 345 | add %o1, STACK_BIAS + SAVED_PSTATE, %o1 ! calculate istate address |
|
329 | 346 | ||
330 | /* |
347 | /* |
331 | * Restore the normal global register set. |
348 | * Restore the normal global register set. |
332 | */ |
349 | */ |
333 | RESTORE_GLOBALS |
350 | RESTORE_GLOBALS |
334 | 351 | ||
335 | /* |
352 | /* |
336 | * Restore PSTATE from saved copy. |
353 | * Restore PSTATE from saved copy. |
337 | * Alternate globals become active. |
354 | * Alternate/Interrupt/MM globals become active. |
338 | */ |
355 | */ |
339 | ldx [%fp + STACK_BIAS + SAVED_PSTATE], %l4 |
356 | ldx [%fp + STACK_BIAS + SAVED_PSTATE], %l4 |
340 | wrpr %l4, 0, %pstate |
357 | wrpr %l4, 0, %pstate |
341 | 358 | ||
342 | /* |
359 | /* |
Line 355... | Line 372... | ||
355 | * Do restore to match the save instruction from the top-level handler. |
372 | * Do restore to match the save instruction from the top-level handler. |
356 | */ |
373 | */ |
357 | restore |
374 | restore |
358 | 375 | ||
359 | /* |
376 | /* |
360 | * On execution of retry instruction, CWP will be restored from TSTATE register. |
377 | * On execution of the RETRY instruction, CWP will be restored from the TSTATE |
361 | * However, because of scheduling, it is possible that CWP in saved TSTATE |
378 | * register. However, because of scheduling, it is possible that CWP in the saved |
362 | * is different from current CWP. The following chunk of code fixes CWP |
379 | * TSTATE is different from the current CWP. The following chunk of code fixes |
363 | * in the saved copy of TSTATE. |
380 | * CWP in the saved copy of TSTATE. |
364 | */ |
381 | */ |
365 | rdpr %cwp, %g4 ! read current CWP |
382 | rdpr %cwp, %g4 ! read current CWP |
366 | and %g1, ~0x1f, %g1 ! clear CWP field in saved TSTATE |
383 | and %g1, ~0x1f, %g1 ! clear CWP field in saved TSTATE |
367 | or %g1, %g4, %g1 ! write current CWP to TSTATE |
384 | or %g1, %g4, %g1 ! write current CWP to TSTATE |
368 | 385 |