diff options
author | kmacy <kmacy@FreeBSD.org> | 2006-11-03 23:41:53 +0000 |
---|---|---|
committer | kmacy <kmacy@FreeBSD.org> | 2006-11-03 23:41:53 +0000 |
commit | 78fce1a4a66554d3f9032c176e3fd9d071385816 (patch) | |
tree | c046deade7d13b18c6315a5b117cfe205b418c96 | |
parent | 744ac9e5e7811ba6d2189cec3b6731c1e6332e92 (diff) | |
download | FreeBSD-src-78fce1a4a66554d3f9032c176e3fd9d071385816.zip FreeBSD-src-78fce1a4a66554d3f9032c176e3fd9d071385816.tar.gz |
- map hardware trap numbers to those used by by sparc64 for inter-compatibility
and to make user-level trap handlers work
- add new trap entry to trap table to enable fast fetching of floating point trap
context
- remove unused debug code
- map unimplemented floating point trap to SIGFPE
Approved by: scottl (standing in for mentor rwatson)
-rw-r--r-- | sys/sun4v/include/trap.h | 169 | ||||
-rw-r--r-- | sys/sun4v/include/utrap.h | 1 | ||||
-rw-r--r-- | sys/sun4v/sun4v/exception.S | 126 | ||||
-rw-r--r-- | sys/sun4v/sun4v/trap.c | 27 | ||||
-rw-r--r-- | sys/sun4v/sun4v/wbuf.S | 14 |
5 files changed, 203 insertions, 134 deletions
diff --git a/sys/sun4v/include/trap.h b/sys/sun4v/include/trap.h index 16457e0..03dfa29 100644 --- a/sys/sun4v/include/trap.h +++ b/sys/sun4v/include/trap.h @@ -31,12 +31,6 @@ #ifdef _KERNEL - -#define T_DATA_MISS 0x31 -#define T_ALIGNMENT 0x34 -#define T_DATA_PROTECTION 0x6c -#define T_MEM_ADDRESS_NOT_ALIGNED T_ALIGNMENT - #define T_RESERVED 0 #define T_INSTRUCTION_EXCEPTION 1 #define T_INSTRUCTION_ERROR 2 @@ -46,99 +40,108 @@ #define T_PRIVILEGED_OPCODE 6 #define T_FP_DISABLED 7 #define T_FP_EXCEPTION_IEEE_754 8 - -#define T_INSTRUCTION_MISS 0x09 -#define T_TAG_OVERFLOW 0x0a -#define T_DIVISION_BY_ZERO 0x0b -#define T_DATA_EXCEPTION 0x0c -#define T_DATA_ERROR 0x0d - - -#define T_PRIVILEGED_ACTION 0x10 -#define T_ASYNC_DATA_ERROR 0x11 -#define T_TRAP_INSTRUCTION_16 0x12 -#define T_TRAP_INSTRUCTION_17 0x13 -#define T_TRAP_INSTRUCTION_18 0x14 -#define T_TRAP_INSTRUCTION_19 0x15 -#define T_TRAP_INSTRUCTION_20 0x16 -#define T_TRAP_INSTRUCTION_21 0x17 -#define T_TRAP_INSTRUCTION_22 0x18 -#define T_TRAP_INSTRUCTION_23 0x19 -#define T_TRAP_INSTRUCTION_24 0x1a -#define T_TRAP_INSTRUCTION_25 0x1b -#define T_TRAP_INSTRUCTION_26 0x1c -#define T_TRAP_INSTRUCTION_27 0x1d -#define T_TRAP_INSTRUCTION_28 0x1e -#define T_TRAP_INSTRUCTION_29 0x1f -#define T_TRAP_INSTRUCTION_30 0x20 -#define T_TRAP_INSTRUCTION_31 0x21 -#define T_FP_EXCEPTION_OTHER 0x22 - - - -#define T_INTERRUPT 0x24 -#define T_PA_WATCHPOINT 0x25 -#define T_VA_WATCHPOINT 0x26 -#define T_CORRECTED_ECC_ERROR 0x27 -#define T_SPILL 0x28 -#define T_FILL 0x29 -#define T_FILL_RET 0x2a -#define T_BREAKPOINT 0x2b -#define T_CLEAN_WINDOW 0x2c -#define T_RANGE_CHECK 0x2d -#define T_FIX_ALIGNMENT 0x2e -#define T_INTEGER_OVERFLOW 0x2f -#define T_SYSCALL 0x30 -#define T_RSTRWP_PHYS -#define T_RSTRWP_VIRT +#define T_FP_EXCEPTION_OTHER 9 +#define T_TAG_OVERFLOW 10 +#define T_DIVISION_BY_ZERO 11 +#define T_DATA_EXCEPTION 12 +#define T_DATA_ERROR 13 +#define T_DATA_PROTECTION 14 +#define T_MEM_ADDRESS_NOT_ALIGNED 15 +#define T_ALIGNMENT 15 +#define T_PRIVILEGED_ACTION 16 +#define T_ASYNC_DATA_ERROR 17 +#define T_TRAP_INSTRUCTION_16 18 +#define T_TRAP_INSTRUCTION_17 19 +#define T_TRAP_INSTRUCTION_18 20 +#define T_TRAP_INSTRUCTION_19 21 +#define T_TRAP_INSTRUCTION_20 22 +#define T_TRAP_INSTRUCTION_21 23 +#define T_TRAP_INSTRUCTION_22 24 +#define T_TRAP_INSTRUCTION_23 25 +#define T_TRAP_INSTRUCTION_24 26 +#define T_TRAP_INSTRUCTION_25 27 +#define T_TRAP_INSTRUCTION_26 28 +#define T_TRAP_INSTRUCTION_27 29 +#define T_TRAP_INSTRUCTION_28 30 +#define T_TRAP_INSTRUCTION_29 31 +#define T_TRAP_INSTRUCTION_30 32 +#define T_TRAP_INSTRUCTION_31 33 +#define T_INSTRUCTION_MISS 34 +#define T_DATA_MISS 35 + +#define T_INTERRUPT 36 +#define T_PA_WATCHPOINT 37 +#define T_VA_WATCHPOINT 38 +#define T_CORRECTED_ECC_ERROR 39 +#define T_SPILL 40 +#define T_FILL 41 +#define T_FILL_RET 42 +#define T_BREAKPOINT 43 +#define T_CLEAN_WINDOW 44 +#define T_RANGE_CHECK 45 +#define T_FIX_ALIGNMENT 46 +#define T_INTEGER_OVERFLOW 47 +#define T_SYSCALL 48 +#define T_RSTRWP_PHYS 49 +#define T_RSTRWP_VIRT 50 #define T_KSTACK_FAULT 51 #define T_RESUMABLE_ERROR 52 #define T_NONRESUMABLE_ERROR 53 #define T_MAX (T_NONRESUMABLE_ERROR + 1) -#define T_KERNEL 0x100 -#define TRAP_MASK ((1<<8)-1) -#define TRAP_CTX_SHIFT 10 - -#define PTL1_BAD_DEBUG 0 -#define PTL1_BAD_WTRAP 1 -#define PTL1_BAD_KMISS 2 -#define PTL1_BAD_KPROT_FAULT 3 -#define PTL1_BAD_ISM 4 -#define PTL1_BAD_MMUTRAP 5 -#define PTL1_BAD_TRAP 6 -#define PTL1_BAD_FPTRAP 7 -#define PTL1_BAD_INTR_REQ 8 -#define PTL1_BAD_TRACE_PTR 9 -#define PTL1_BAD_STACK 10 -#define PTL1_BAD_DTRACE_FLAGS 11 -#define PTL1_BAD_CTX_STEAL 12 -#define PTL1_BAD_ECC 13 -#define PTL1_BAD_HCALL 14 -#define PTL1_BAD_GL 15 - - -#define TL_CPU_MONDO 0x1 -#define TL_DEV_MONDO 0x2 -#define TL_TSB_MISS 0x3 -#define TL_TL0_TRAP 0x4 -#define TL_SET_ACKMASK 0x5 +#define T_KERNEL 64 +#define TRAP_MASK ((1<<6)-1) +#define TRAP_CTX_SHIFT 8 /* * These defines are used by the TL1 tlb miss handlers to calculate * the pc to jump to in the case the entry was not found in the TSB. */ -#define WTRAP_ALIGN 0x7f /* window handlers are 128 byte align */ -#define WTRAP_FAULTOFF 124 /* last instruction in handler */ +#define WTRAP_ALIGN 0x7f /* window handlers are 128 byte align */ +#define WTRAP_FAULTOFF 124 /* last instruction in handler */ + /* use the following defines to determine if trap was a fill or a spill */ -#define WTRAP_TTMASK 0x180 -#define WTRAP_TYPE 0x080 +#define WTRAP_TTMASK 0x180 +#define WTRAP_TYPE 0x080 + +#define TT_INSTRUCTION_EXCEPTION 0x8 +#define TT_INSTRUCTION_MISS 0x9 +#define TT_ILLEGAL_INSTRUCTION 0x10 +#define TT_PRIVILEGED_OPCODE 0x11 +#define TT_FP_EXCEPTION_IEEE_754 0x21 +#define TT_FP_EXCEPTION_OTHER 0x22 +#define TT_TAG_OVERFLOW 0x23 +#define TT_DIVISION_BY_ZERO 0x28 +#define TT_DATA_EXCEPTION 0x30 +#define TT_DATA_MISS 0x31 +#define TT_ALIGNNMENT 0x34 +#define TT_DATA_PROTECTION 0x6c +#define TT_ALIGNMENT 0x6c +#define TT_BREAKPOINT 0x76 + +#define PTL1_BAD_DEBUG 0 +#define PTL1_BAD_WTRAP 1 +#define PTL1_BAD_KMISS 2 +#define PTL1_BAD_KPROT_FAULT 3 +#define PTL1_BAD_ISM 4 +#define PTL1_BAD_MMUTRAP 5 +#define PTL1_BAD_TRAP 6 +#define PTL1_BAD_FPTRAP 7 +#define PTL1_BAD_INTR_REQ 8 +#define PTL1_BAD_TRACE_PTR 9 +#define PTL1_BAD_STACK 10 +#define PTL1_BAD_DTRACE_FLAGS 11 +#define PTL1_BAD_CTX_STEAL 12 +#define PTL1_BAD_ECC 13 +#define PTL1_BAD_HCALL 14 +#define PTL1_BAD_GL 15 + #ifndef LOCORE extern const char *trap_msg[]; -void trap_init(void); +extern void trap_init(void); #endif #endif diff --git a/sys/sun4v/include/utrap.h b/sys/sun4v/include/utrap.h index c8fa743..cea6933 100644 --- a/sys/sun4v/include/utrap.h +++ b/sys/sun4v/include/utrap.h @@ -77,6 +77,7 @@ /* 8 is 32-bit ABI syscall (old solaris syscall?) */ #define ST_BSD_SYSCALL 9 #define ST_FP_RESTORE 10 +#define ST_FPEMU_CONTEXT 11 /* 11-15 are available */ /* 16 is linux 32 bit syscall (but supposed to be reserved, grr) */ /* 17 is old linux 64 bit syscall (but supposed to be reserved, grr) */ diff --git a/sys/sun4v/sun4v/exception.S b/sys/sun4v/sun4v/exception.S index 71b7210..e3b3179 100644 --- a/sys/sun4v/sun4v/exception.S +++ b/sys/sun4v/sun4v/exception.S @@ -57,6 +57,7 @@ __FBSDID("$FreeBSD$") .register %g6,#ignore .register %g7,#ignore + .globl trap_conversion #define PCB_REG %g6 @@ -314,7 +315,7 @@ __FBSDID("$FreeBSD$") ldxa [%g1 + %g2]ASI_REAL, %g3 sub %g0, 1, %g4 set trap, %g1 - ba %xcc, tl0_trap + ba,pt %xcc, tl0_trap mov T_INSTRUCTION_EXCEPTION, %g2 .align 32 @@ -327,8 +328,7 @@ __FBSDID("$FreeBSD$") mov MMFSA_I_CTX, %g7 ldxa [%g1 + %g2]ASI_REAL, %g4 ldxa [%g1 + %g3]ASI_REAL, %g5 - ba,pt %xcc, tsb_miss_handler - mov T_INSTRUCTION_MISS, %g3 + ba,a,pt %xcc, tsb_miss_handler .align 32 .endm @@ -357,8 +357,7 @@ END(data_excptn_fault) mov MMFSA_D_CTX, %g7 ldxa [%g1 + %g2]ASI_REAL, %g4 ldxa [%g1 + %g3]ASI_REAL, %g5 - ba,pt %xcc, tsb_miss_handler - mov T_DATA_MISS, %g3 + ba,a,pt %xcc, tsb_miss_handler .align 32 .endm @@ -367,8 +366,7 @@ END(data_excptn_fault) mov MMFSA_D_ADDR, %g3 mov MMFSA_D_CTX, %g7 ldxa [%g1 + %g3]ASI_REAL, %g5 - ba,pt %xcc, tsb_miss_handler - mov T_DATA_PROTECTION, %g3 + ba,a,pt %xcc, tsb_miss_handler .align 32 .endm @@ -406,7 +404,7 @@ END(align_fault) clr %g3 sub %g0, 1, %g4 set trap, %g1 - ba %xcc, tl0_trap + ba,pt %xcc, tl0_trap mov T_RESUMABLE_ERROR, %g2 .align 32 .endm @@ -415,7 +413,7 @@ END(align_fault) clr %g3 sub %g0, 1, %g4 set trap, %g1 - ba %xcc, tl0_trap + ba,pt %xcc, tl0_trap mov T_NONRESUMABLE_ERROR, %g2 .align 32 .endm @@ -732,6 +730,33 @@ tick_ ## tl ## _entry: \ .align 32 .endm #endif + + ! fetch FP context into local registers + .macro tl0_fpemu_context + GET_PCB(PCB_REG) ! 3 instructions + ldx [PCB_REG + PCB_PAD], %l5 ! %tstate + ldx [PCB_REG + PCB_PAD + 8], %l6 ! %tpc + ldx [PCB_REG + PCB_PAD + 16], %l7 ! %tncp + ldx [PCB_REG + PCB_PAD + 24], %g2 ! %tt + ba,a,pt %xcc, tl0_fpemu_context + .align 32 + .endm + +ENTRY(tl0_fpemu_context) + mov %g2, %o0 + clr %o1 + + rd %fprs, %l1 + or %l1, FPRS_FEF, %l2 + wr %l2, 0, %fprs + stx %fsr, [PCB_REG + PCB_PAD] + ldx [PCB_REG + PCB_PAD], %l4 + wr %l1, 0, %fprs + + sub %fp, CCFSZ, %sp + done +END(tl0_fpemu_context) + .macro tl0_fp_restore GET_PCB(PCB_REG) ! 3 instructions ldx [%g6 + PCB_FLAGS], %g1 @@ -898,7 +923,8 @@ tl0_soft_100: tl0_gen T_SYSCALL ! 0x108 tl0_gen T_SYSCALL ! 0x109 tl0_fp_restore ! 0x10a - tl0_reserved 5 ! 0x10b-0x10f + tl0_fpemu_context ! 0x10b + tl0_reserved 4 ! 0x10c-0x10f tl0_gen T_TRAP_INSTRUCTION_16 ! 0x110 tl0_gen T_TRAP_INSTRUCTION_17 ! 0x111 tl0_gen T_TRAP_INSTRUCTION_18 ! 0x112 @@ -1355,6 +1381,8 @@ ENTRY(tl0_intr) ! %g1 pc of trap handler ! %g2, %g3 args of trap handler + ! %g2 software trap type + ! %g3 additional argument to trap ! %g4 desired pil ! %g5, %g6 temps ! %g7 saved @@ -1380,6 +1408,37 @@ ENTRY(tl0_trap) bnz,pn %xcc, tl0_ktrap nop ENTRY(tl0_utrap) + GET_PCPU_SCRATCH + + cmp %g2, UT_MAX + bge,a,pn %xcc, skip_utrap + nop + + ldx [PCPU(CURTHREAD)], %g5 + ldx [%g5 + TD_PROC], %g5 + ldx [%g5 + P_MD + MD_UTRAP], %g5 + brz,pn %g5, skip_utrap + sllx %g2, PTR_SHIFT, %g6 + ldx [%g5 + %g6], %g5 + brz,pn %g5, skip_utrap + nop + + mov %g5, %g4 + + ! 0) save trap state to memory + ldx [PCPU_REG + PC_CURPCB], %g6 + rdpr %tstate, %g5 + stx %g5, [%g6 + PCB_PAD] + rdpr %tpc, %g5 + stx %g5, [%g6 + PCB_PAD + 8] + rdpr %tnpc, %g5 + stx %g5, [%g6 + PCB_PAD + 16] + stx %g2, [%g6 + PCB_PAD + 24] + + wrpr %g4, %tnpc + done +skip_utrap: + #ifdef notyet /* we need to determine from the hardware the number of register windows */ sethi %hi(nwin_minus_one), %g5 @@ -1387,29 +1446,12 @@ ENTRY(tl0_utrap) #else mov nwin_minus_one, %g5 #endif - GET_PCB(%g6) + ldx [PCPU_REG + PC_CURPCB], %g6 wrpr %g0, %g5, %cleanwin ldx [%g6 + PCB_KSTACK], %g6 sub %g6, TF_SIZEOF, %g6 -#ifdef DEBUG_KSTACK - mov %o0, %g5 - mov %o3, %l0 - mov %o4, %l1 - mov %o5, %l2 - mov %o6, %l3 - mov %o7, %l4 - mov 0x10, %o0 - mov %g6, %o1 - ta TTRACE_ADDENTRY - mov %g5, %o0 - mov %l0, %o3 - mov %l1, %o4 - mov %l2, %o5 - mov %l3, %o6 - mov %l4, %o7 -#endif - save %g6, 0, %sp + save %g6, 0, %sp rdpr %canrestore, %l0 rdpr %wstate, %l1 wrpr %g0, 0, %canrestore @@ -1456,21 +1498,25 @@ win_saved: ! brlz,pt %g4, 1f nop +#if 0 #ifdef PMAP_DEBUG rdpr %pil, %l0 cmp %g4, %l0 - bge,pt %xcc, 0f + bge,pt %xcc, 10f nop call panic -0: +10: +#endif #endif - wrpr %g0, %g4, %pil 1: wrpr %g0, %g6, %tnpc + + ! save g7 before it can be overwritten by PCPU when returning from an interrupt wrpr %g0, 0, %gl - stx %g7, [%l7 + TF_G7] ! save g7 before it can be overwritten by PCPU when returning from an interrupt + stx %g7, [%l7 + TF_G7] wrpr %g0, 1, %gl + rdpr %cwp, %l0 set TSTATE_KERNEL, %l1 wrpr %l1, %l0, %tstate @@ -1722,7 +1768,11 @@ tsb_miss_not_found: RESTORE_TRAPWIN(PCPU_REG, %g1, 14, 15) - mov %g3, %g2 ! trap type + ! convert hardware trap type to kernel trap type + set trap_conversion, %g2 + sllx %g3, INT_SHIFT, %g3 + ld [%g2 + %g3], %g2 + sethi %hi(trap), %g1 or %g6, %g5, %g3 ! trap data sub %g0, 1, %g4 ! pil info @@ -1732,13 +1782,13 @@ tsb_miss_not_found: tsb_miss_found: wr %g0, %l3, %asi - cmp %g3, T_DATA_MISS ! TSB data miss + cmp %g3, TT_DATA_MISS ! TSB data miss be,pt %xcc, 9f or %l7, VTD_REF, %l7 ! set referenced unconditionally - cmp %g3, T_INSTRUCTION_MISS ! TSB instruction miss + cmp %g3, TT_INSTRUCTION_MISS ! TSB instruction miss be,pt %xcc, 9f nop - cmp %g3, T_DATA_PROTECTION ! protection fault + cmp %g3, TT_DATA_PROTECTION ! protection fault bne,pn %xcc, unsupported_fault_trap ! we don't handle any other fault types currently nop andcc %l7, VTD_SW_W, %g0 ! write enabled? @@ -1798,7 +1848,7 @@ tsb_miss_found: RESTORE_TRAPWIN(PCPU_REG, %g1, 13, 16) upgrade_demap: rdpr %tt, %g3 - cmp %g3, T_DATA_PROTECTION + cmp %g3, TT_DATA_PROTECTION beq,pn %xcc, demap_begin nop retry diff --git a/sys/sun4v/sun4v/trap.c b/sys/sun4v/sun4v/trap.c index a7a6f68..a5cd103 100644 --- a/sys/sun4v/sun4v/trap.c +++ b/sys/sun4v/sun4v/trap.c @@ -115,7 +115,7 @@ extern char fas_nofault_end[]; extern char *syscallnames[]; -static int trap_conversion[256]; +int trap_conversion[256]; const char *trap_msg[] = { "reserved", @@ -209,8 +209,7 @@ const int trap_sig[] = { SIGILL, /* trap instruction 29 */ SIGILL, /* trap instruction 30 */ SIGILL, /* trap instruction 31 */ - SIGSEGV, /* floating point not implemented */ - /* should be SIGFPE but other signals currently cause problems */ + SIGFPE, /* floating point error */ SIGSEGV, /* fast data access mmu miss */ -1, /* interrupt */ -1, /* physical address watchpoint */ @@ -238,6 +237,7 @@ SYSCTL_INT(_debug, OID_AUTO, debugger_on_signal, CTLFLAG_RW, &debugger_on_signal, 0, ""); #endif + void trap_init(void) { @@ -250,15 +250,20 @@ trap_init(void) init_mondo_queue(); OF_set_mmfsa_traptable(&tl0_base, mmfsa); - for (i = 0; i < 128; i++) - trap_conversion[i] = i; - for (i = 128; i < 256; i++) + for (i = 0; i < 256; i++) trap_conversion[i] = 0; - trap_conversion[0x31] = 35; - trap_conversion[0x34] = 15; - trap_conversion[0x9] = 34; - trap_conversion[0x6c] = 14; - + trap_conversion[TT_INSTRUCTION_EXCEPTION] = T_INSTRUCTION_EXCEPTION; + trap_conversion[TT_INSTRUCTION_MISS] = T_INSTRUCTION_MISS; + trap_conversion[TT_ILLEGAL_INSTRUCTION] = T_ILLEGAL_INSTRUCTION; + trap_conversion[TT_PRIVILEGED_OPCODE] = T_PRIVILEGED_OPCODE; + trap_conversion[TT_FP_EXCEPTION_IEEE_754] = T_FP_EXCEPTION_IEEE_754; + trap_conversion[TT_TAG_OVERFLOW] = T_TAG_OVERFLOW; + trap_conversion[TT_DIVISION_BY_ZERO] = T_DIVISION_BY_ZERO; + trap_conversion[TT_DATA_EXCEPTION] = T_DATA_EXCEPTION; + trap_conversion[TT_DATA_MISS] = T_DATA_MISS; + trap_conversion[TT_ALIGNMENT] = T_ALIGNMENT; + trap_conversion[TT_DATA_PROTECTION] = T_DATA_PROTECTION; + trap_conversion[TT_BREAKPOINT] = T_BREAKPOINT; } void diff --git a/sys/sun4v/sun4v/wbuf.S b/sys/sun4v/sun4v/wbuf.S index 1e4c1bb..5db16c3 100644 --- a/sys/sun4v/sun4v/wbuf.S +++ b/sys/sun4v/sun4v/wbuf.S @@ -36,8 +36,13 @@ ENTRY(fault_64bit_sn0) SAVE_WINDOW(%g3) mov 1, %g3 stx %g3, [%g4 + PCB_NSAVED] + + ! convert hardware trap type to kernel trap type + set trap_conversion, %g1 + sllx %g5, INT_SHIFT, %g5 + ld [%g1 + %g5], %g2 + set trap, %g1 - mov %g5, %g2 mov %g6, %g3 sub %g0, 1, %g4 @@ -146,7 +151,12 @@ fault_fn1_common: wrpr %g0, %g1, %tpc add %g1, 4, %g1 wrpr %g0, %g1, %tnpc - + + ! convert hardware trap type to kernel trap type + set trap_conversion, %g1 + sllx %g5, INT_SHIFT, %g5 + ld [%g1 + %g5], %g5 + set trap, %g1 mov 1, %g2 sllx %g2, CTX_OTHER_SHIFT, %g2 |