- 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)
This commit is contained in:
Kip Macy 2006-11-03 23:41:53 +00:00
parent ef8f32e393
commit 45897edf72
5 changed files with 202 additions and 133 deletions

View File

@ -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_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_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_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

View File

@ -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) */

View File

@ -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

View File

@ -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

View File

@ -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