Subversion Repositories HelenOS-historic

Compare Revisions

Ignore whitespace Rev 666 → Rev 667

/kernel/trunk/arch/sparc64/src/trap/trap_table.S
48,6 → 48,8
#include <arch/trap/trap_table.h>
#include <arch/trap/regwin.h>
#include <arch/trap/interrupt.h>
#include <arch/trap/exception.h>
#include <arch/stack.h>
 
#define TABLE_SIZE TRAP_TABLE_SIZE
#define ENTRY_SIZE TRAP_TABLE_ENTRY_SIZE
59,6 → 61,12
.global trap_table
trap_table:
 
/* TT = 0x08, TL = 0, instruction_access_exception */
.org trap_table + TT_INSTRUCTION_ACCESS_EXCEPTION*ENTRY_SIZE
.global instruction_access_exception
instruction_access_exception:
SIMPLE_HANDLER do_instruction_access_exc
 
/* TT = 0x24, TL = 0, clean_window handler */
.org trap_table + TT_CLEAN_WINDOW*ENTRY_SIZE
.global clean_window_handler
65,6 → 73,12
clean_window_handler:
CLEAN_WINDOW_HANDLER
 
/* TT = 0x34, TL = 0, mem_address_not_aligned */
.org trap_table + TT_MEM_ADDRESS_NOT_ALIGNED*ENTRY_SIZE
.global mem_address_not_aligned
mem_address_not_aligned:
SIMPLE_HANDLER do_mem_address_not_aligned
 
/* TT = 0x41, TL = 0, interrupt_level_1 handler */
.org trap_table + TT_INTERRUPT_LEVEL_1*ENTRY_SIZE
.global interrupt_level_1_handler
177,6 → 191,12
* Handlers for TL>0.
*/
 
/* TT = 0x08, TL > 0, instruction_access_exception */
.org trap_table + (TT_INSTRUCTION_ACCESS_EXCEPTION+512)*ENTRY_SIZE
.global instruction_access_exception_high
instruction_access_exception_high:
SIMPLE_HANDLER do_instruction_access_exc
 
/* TT = 0x24, TL > 0, clean_window handler */
.org trap_table + (TT_CLEAN_WINDOW+512)*ENTRY_SIZE
.global clean_window_handler_high
183,15 → 203,18
clean_window_handler_high:
CLEAN_WINDOW_HANDLER
 
/* TT = 0x34, TL > 0, mem_address_not_aligned */
.org trap_table + (TT_MEM_ADDRESS_NOT_ALIGNED+512)*ENTRY_SIZE
.global mem_address_not_aligned_high
mem_address_not_aligned_high:
SIMPLE_HANDLER do_mem_address_not_aligned
 
/* TT = 0x80, TL > 0, spill_0_normal handler */
 
.org trap_table + (TT_SPILL_0_NORMAL+512)*ENTRY_SIZE
.global spill_0_normal_high
spill_0_normal_high:
SPILL_NORMAL_HANDLER
 
 
/* TT = 0xc0, TL > 0, fill_0_normal handler */
.org trap_table + (TT_FILL_0_NORMAL+512)*ENTRY_SIZE
.global fill_0_normal_high
209,18 → 232,105
.space TABLE_SIZE, 0
 
 
/* Trap handler that explicitly saves global registers.
/* Preemptible trap handler.
*
* This trap handler makes arrangements to
* make calling scheduler() possible.
*
* The caller is responsible for doing save
* and allocating PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE
* bytes on stack.
*
* Input registers:
* %l0 Address of function to call.
* Output registers:
* %l1 - %l7 Copy of %g1 - %g7
*/
.global saving_handler
saving_handler:
.global preemptible_handler
preemptible_handler:
/*
* Save TSTATE, TPC, TNPC and PSTATE aside.
*/
rdpr %tstate, %g1
rdpr %tpc, %g2
rdpr %tnpc, %g3
rdpr %pstate, %g4
 
stx %g1, [%fp + STACK_BIAS + SAVED_TSTATE]
stx %g2, [%fp + STACK_BIAS + SAVED_TPC]
stx %g3, [%fp + STACK_BIAS + SAVED_TNPC]
stx %g4, [%fp + STACK_BIAS + SAVED_PSTATE]
/*
* Write 0 to TL.
*/
wrpr %g0, 0, %tl
/*
* Alter PSTATE.
* - switch to normal globals.
*/
and %g4, ~1, %g4 ! mask alternate globals
wrpr %g4, 0, %pstate
/*
* Save the normal globals.
*/
SAVE_GLOBALS
/*
* Call the higher-level handler.
*/
call %l0
nop
/*
* Restore the normal global register set.
*/
RESTORE_GLOBALS
restore /* matches the save instruction from the top-level handler */
/*
* Restore PSTATE from saved copy.
* Alternate globals become active.
*/
ldx [%fp + STACK_BIAS + SAVED_PSTATE], %l4
wrpr %l4, 0, %pstate
/*
* Write 1 to TL.
*/
wrpr %g0, 1, %tl
/*
* Read TSTATE, TPC and TNPC from saved copy.
*/
ldx [%fp + STACK_BIAS + SAVED_TSTATE], %g1
ldx [%fp + STACK_BIAS + SAVED_TPC], %g2
ldx [%fp + STACK_BIAS + SAVED_TNPC], %g3
 
/*
* Do restore to match the save instruction from the top-level handler.
*/
restore
 
/*
* On execution of retry instruction, CWP will be restored from TSTATE register.
* However, because of scheduling, it is possible that CWP in saved TSTATE
* is different from current CWP. The following chunk of code fixes CWP
* in the saved copy of TSTATE.
*/
rdpr %cwp, %g4 ! read current CWP
and %g1, ~0x1f, %g1 ! clear CWP field in saved TSTATE
or %g1, %g4, %g1 ! write current CWP to TSTATE
/*
* Restore TSTATE, TPC and TNPC from saved copies.
*/
wrpr %g1, 0, %tstate
wrpr %g2, 0, %tpc
wrpr %g3, 0, %tnpc
/*
* Return from interrupt.
*/
retry