diff --git a/sys/arch/sh3/include/pte.h b/sys/arch/sh3/include/pte.h index edadb0ef407c..443767150ca5 100644 --- a/sys/arch/sh3/include/pte.h +++ b/sys/arch/sh3/include/pte.h @@ -1,4 +1,4 @@ -/* $NetBSD: pte.h,v 1.4 2000/02/24 23:32:27 msaitoh Exp $ */ +/* $NetBSD: pte.h,v 1.5 2002/02/11 18:06:06 uch Exp $ */ /*- * Copyright (c) 1990 The Regents of the University of California. @@ -62,39 +62,63 @@ typedef int pt_entry_t; /* Mach page table entry */ #define PT_MASK 0x003ff000 /* page table address bits */ #define PTES_PER_PTP (NBPD / NBPG) /* # of PTEs in a PTP */ -#define PG_AVAIL2 0x00000200 /* ignored by hardware */ -#define PG_V 0x00000100 /* present */ -#define PG_AVAIL1 0x00000080 /* ignored by hardware */ -#define PG_RO 0x00000000 /* read-only by user */ -#define PG_RW 0x00000020 /* read-write by user */ -#define PG_u 0x00000040 /* accessible by user */ -#define PG_PROT 0x00000060 /* all protection bits */ -#define PG_N 0x00000008 /* 0=non-cacheable */ -#define PG_M 0x00000004 /* has been modified */ -#define PG_FRAME 0xfffff000 /* page frame mask */ +/* + * + * NetBSD/sh3 PTE format. + * + * SH3 + * PPN V PR SZ C D SH + * [28:10][8][6:5][4][3][2][1] + * + * SH4 + * V SZ PR SZ C D SH WT + * [28:10][8][7][6:5][4][3][2][1][0] + * + * + NetBSD/sh3 page size is 4KB. [11:10] and [7] can be used as SW bit. + * + [31:29] should be available for SW bit... + * + SH4 WT bit is not stored in PTE. U0 is always write-back. and + * P3 is always write-thurogh. (see sh3/trap.c::__setup_pte_sh4()) + * We use WT bit as SW bit. + * + * Software bit assign + * [11:9] - SH4 PCMCIA Assistant bit. (space attribute bit only) + * [7] - Wired page bit. + * [0] - PVlist bit. + */ -#ifdef SH4_PCMCIA -#define PG_PCMCIA_16 0x00000000 /* 16bit width */ -#define PG_PCMCIA_8 0x00000080 /* 8 bit width */ -#define PG_PCMCIA_NONE 0x00000000 /* Non PCMCIA space */ -#define PG_PCMCIA 0x00000a00 /* PCMCIA space */ -#define PG_PCMCIA_IO 0x00000200 /* PCMCIA IO space */ -#define PG_PCMCIA_MEM 0x00000800 /* PCMCIA Memory space */ -#define PG_PCMCIA_ATT 0x00000a00 /* PCMCIA Attribute space */ -#endif +/* + * Hardware bits + */ +#define PG_FRAME 0xfffff000 /* page frame mask XXX */ +#define PG_V 0x00000100 /* present */ +#define PG_UW 0x00000060 /* kernel/user read/write */ +#define PG_URKR 0x00000040 /* kernel/user read only */ +#define PG_KW 0x00000020 /* kernel read/write */ +#define PG_KR 0x00000000 /* kernel read only */ +#define PG_4K 0x00000010 /* page size 4KB */ +#define PG_N 0x00000008 /* 0=non-cacheable */ +#define PG_M 0x00000004 /* has been modified */ +#define PG_G 0x00000002 /* share status */ +#define PG_WT 0x00000001 /* write through (SH4) */ -#define PG_KR 0x00000000 -#define PG_KW 0x00000020 -#define PG_URKR 0x00000040 -#define PG_UW 0x00000060 +#define PG_HW_BITS 0x1ffff17e /* [28:12][8][6:1] */ -#define PG_W 0x00000400 /* page is wired */ - -#define PG_4K 0x00000010 -#define PG_G 0x00000002 /* share status */ - -#ifdef SH4 -#define PG_WT 0x00000001 /* write through */ -#endif +/* + * Software bits + */ +#define PG_W 0x00000080 /* page is wired */ +#define PG_PVLIST 0x00000001 /* mapping has entry on pvlist */ +/* SH4 PCMCIA MMU support bits */ +/* PTEA SA (Space Attribute bit) */ +#define _PG_PCMCIA 0x00000e00 +#define _PG_PCMCIA_SHIFT 9 +#define _PG_PCMCIA_NONE 0x00000000 /* Non PCMCIA space */ +#define _PG_PCMCIA_IO 0x00000200 /* IOIS16 signal */ +#define _PG_PCMCIA_IO8 0x00000400 /* 8 bit I/O */ +#define _PG_PCMCIA_IO16 0x00000600 /* 16 bit I/O */ +#define _PG_PCMCIA_MEM8 0x00000800 /* 8 bit common memory */ +#define _PG_PCMCIA_MEM16 0x00000a00 /* 16 bit common memory */ +#define _PG_PCMCIA_ATTR8 0x00000c00 /* 8 bit attribute */ +#define _PG_PCMCIA_ATTR16 0x00000e00 /* 16 bit attribute */ #endif /* !_SH3_PTE_H_ */ diff --git a/sys/arch/sh3/sh3/trap.c b/sys/arch/sh3/sh3/trap.c index c4ae6f2b0384..ce5a55f13ab7 100644 --- a/sys/arch/sh3/sh3/trap.c +++ b/sys/arch/sh3/sh3/trap.c @@ -1,4 +1,4 @@ -/* $NetBSD: trap.c,v 1.28 2001/08/10 18:27:08 msaitoh Exp $ */ +/* $NetBSD: trap.c,v 1.29 2002/02/11 18:06:06 uch Exp $ */ /*- * Copyright (c) 1995 Charles M. Hannum. All rights reserved. @@ -66,6 +66,7 @@ #include +#include #include #include #include @@ -80,26 +81,54 @@ #include #endif -extern int cpu_debug_mode; +char *trap_type[] = { + "power-on", /* 0x000 T_POWERON */ + "manual reset", /* 0x020 T_RESET */ + "TLB miss/invalid (load)", /* 0x040 T_TLBMISSR */ + "TLB miss/invalid (store)", /* 0x060 T_TLBMISSW */ + "initial page write", /* 0x080 T_INITPAGEWR */ + "TLB protection violation (load)", /* 0x0a0 T_TLBPRIVR */ + "TLB protection violation (store)", /* 0x0c0 T_TLBPRIVW */ + "address error (load)", /* 0x0e0 T_ADDRESSERRR */ + "address error (store)", /* 0x100 T_ADDRESSERRW */ + "unknown trap (0x120)", /* 0x120 */ + "unknown trap (0x140)", /* 0x140 */ + "unconditional trap (TRAPA)", /* 0x160 T_TRAP */ + "reserved instruction code exception", /* 0x180 T_INVALIDISN */ + "illegal slot instruction exception", /* 0x1a0 T_INVALIDSLOT */ + "nonmaskable interrupt", /* 0x1c0 T_NMI */ + "user break point trap", /* 0x1e0 T_USERBREAK */ +}; +int trap_types = sizeof trap_type / sizeof trap_type[0]; -static __inline void userret __P((struct proc *, int, u_quad_t)); -void trap __P((int, int, int, int, struct trapframe)); -int trapwrite __P((unsigned)); -void syscall __P((struct trapframe *)); -void -tlb_handler __P(( - int p1, int p2, int p3, int p4, /* These four param is dummy */ - struct trapframe frame)); +extern int cpu_debug_mode; +int trapdebug = 1; + +static __inline void userret(struct proc *, int, u_quad_t); +void trap(int, int, int, int /* dummy 4 param*/, struct trapframe); +int trapwrite(unsigned); +void syscall(struct trapframe *); +void tlb_handler(int, int, int, int /* dummy 4 param */, struct trapframe); +void __setup_pte_sh3(vaddr_t, u_int32_t); +void __setup_pte_sh4(vaddr_t, u_int32_t); + +#ifdef SH4 +#define __SETUP_PTE(v, pte) __setup_pte_sh4((v), (pte)) +#define __PD_AREA(x) SH3_P1SEG_TO_P2SEG(x) +#else /* SH4 */ +#define __SETUP_PTE(v, pte) __setup_pte_sh3((v), (pte)) +#define __PD_AREA(x) (x) +#endif /* SH4 */ + +#define __PD_TOP() ((u_long *)__PD_AREA(SHREG_TTB)) +#define __PDE(pd, i) ((u_long *)__PD_AREA((pd)[(i)])) /* * Define the code needed before returning to user mode, for * trap and syscall. */ static __inline void -userret(p, pc, oticks) - register struct proc *p; - int pc; - u_quad_t oticks; +userret(struct proc *p, int pc, u_quad_t oticks) { int sig; @@ -128,30 +157,34 @@ userret(p, pc, oticks) curcpu()->ci_schedstate.spc_curpriority = p->p_priority; } -char *trap_type[] = { - "power-on", /* 0x000 T_POWERON */ - "manual reset", /* 0x020 T_RESET */ - "TLB miss/invalid (load)", /* 0x040 T_TLBMISSR */ - "TLB miss/invalid (store)", /* 0x060 T_TLBMISSW */ - "initial page write", /* 0x080 T_INITPAGEWR */ - "TLB protection violation (load)", /* 0x0a0 T_TLBPRIVR */ - "TLB protection violation (store)", /* 0x0c0 T_TLBPRIVW */ - "address error (load)", /* 0x0e0 T_ADDRESSERRR */ - "address error (store)", /* 0x100 T_ADDRESSERRW */ - "unknown trap (0x120)", /* 0x120 */ - "unknown trap (0x140)", /* 0x140 */ - "unconditional trap (TRAPA)", /* 0x160 T_TRAP */ - "reserved instruction code exception", /* 0x180 T_INVALIDISN */ - "illegal slot instruction exception", /* 0x1a0 T_INVALIDSLOT */ - "nonmaskable interrupt", /* 0x1c0 T_NMI */ - "user break point trap", /* 0x1e0 T_USERBREAK */ -}; -int trap_types = sizeof trap_type / sizeof trap_type[0]; +/* + * PTEL, PTEA + */ +void +__setup_pte_sh3(vaddr_t va, u_int32_t pte) +{ -#define DEBUG 1 -#ifdef DEBUG -int trapdebug = 1; -#endif + SHREG_PTEL = pte & PG_HW_BITS; +} + +void +__setup_pte_sh4(vaddr_t va, u_int32_t pte) +{ + u_int32_t ptel; + + ptel = pte & PG_HW_BITS; + + if (pte & _PG_PCMCIA) { + SHREG_PTEA = (pte >> _PG_PCMCIA_SHIFT) & SH4_PTEA_SA_MASK; + SHREG_PTEL = ptel & ~PG_N; + } else { + if (va >= SH3_P1SEG_BASE) + ptel |= PG_WT; /* P3SEG is always write-through */ + + SHREG_PTEL = ptel; + SHREG_PTEA = 0; + } +} /* * trap(frame): @@ -163,9 +196,7 @@ int trapdebug = 1; */ /*ARGSUSED*/ void -trap(p1, p2, p3, p4, frame) - int p1, p2, p3, p4; /* dummy param */ - struct trapframe frame; +trap(int p1, int p2, int p3, int p4,/* dummy param */ struct trapframe frame) { register struct proc *p = curproc; int type = frame.tf_trapno; @@ -409,8 +440,7 @@ trap(p1, p2, p3, p4, frame) */ /*ARGSUSED*/ void -syscall(frame) - struct trapframe *frame; +syscall(struct trapframe *frame) { register caddr_t params; register const struct sysent *callp; @@ -567,8 +597,7 @@ syscall(frame) } void -child_return(arg) - void *arg; +child_return(void *arg) { struct proc *p = arg; struct trapframe *tf = p->p_md.md_regs; @@ -588,9 +617,7 @@ child_return(arg) * This is called from tlb_miss exception handler. */ void -tlb_handler(p1, p2, p3, p4, frame) - int p1, p2, p3, p4; /* These four params are dummy */ - struct trapframe frame; +tlb_handler(int p1, int p2, int p3, int p4, struct trapframe frame) { vaddr_t va; int pde_index, sig; @@ -617,82 +644,17 @@ tlb_handler(p1, p2, p3, p4, frame) va = (vaddr_t)SHREG_TEA; va = trunc_page(va); pde_index = pdei(va); -#ifdef SH4 - pd_top = (u_long *)(SH3_P1SEG_TO_P2SEG(SHREG_TTB)); - pde = (u_long *)((u_long)SH3_P1SEG_TO_P2SEG(pd_top[pde_index])); -#else - pd_top = (u_long *)SHREG_TTB; - pde = (u_long *)pd_top[pde_index]; -#endif + pd_top = __PD_TOP(); + pde = __PDE(pd_top, pde_index); exptype = SHREG_EXPEVT; -#if 0 /* def SH4 */ - if (((u_long)pde & PG_V) != 0 && - (incpuswitch || exptype != T_TLBPRIVW)) { -#else if (((u_long)pde & PG_V) != 0 && exptype != T_TLBPRIVW) { -#endif (u_long)pde &= ~PGOFSET; pte_index = ptei(va); -#ifdef SH4 - pte = SH3_P1SEG_TO_P2SEG(pde[pte_index]); -#else - pte = pde[pte_index]; -#endif - + pte = (u_int32_t)__PDE(pde, pte_index); if ((pte & PG_V) != 0) { -#ifdef DEBUG_TLB - if (trapdebug) - printf("tlb_handler:va(0x%lx),pte(0x%lx)\n", - va, pte); -#endif - -#ifdef SH4_PCMCIA -#define PTEL_VALIDBITS 0x1ffff17e -#else -#define PTEL_VALIDBITS 0x1ffffd7e -#endif -#ifdef SH4 -#ifdef SH4_PCMCIA - if (pte & PG_PCMCIA) { - int pcmtype; - unsigned long ptea = 0; - - pcmtype = pte & PG_PCMCIA; - - /* printf("pcmtype = %lx,pte=%lx\n", - pcmtype,pte); */ - - if (pcmtype == PG_PCMCIA_IO) { - ptea = 0x03; - } else if (pcmtype == PG_PCMCIA_MEM) { - ptea = 0x05; - /* ptea = 0x03; */ - } else if (pcmtype == PG_PCMCIA_ATT) { - ptea = 0x07; - } - - SHREG_PTEL = (pte & PTEL_VALIDBITS) - & ~PG_N; - - SHREG_PTEA = ptea; - } else -#endif - { - if ( /*1 ||*/ (va >= SH3_P1SEG_BASE)) { - SHREG_PTEL = (pte & PTEL_VALIDBITS) - | PG_WT; - } else { - SHREG_PTEL = pte & PTEL_VALIDBITS; - } - - SHREG_PTEA = 0; - } -#else - SHREG_PTEL = pte & PTEL_VALIDBITS; -#endif + __SETUP_PTE(va, pte); __asm __volatile ("ldtlb; nop"); - return; } } @@ -780,67 +742,16 @@ tlb_handler(p1, p2, p3, p4, frame) va = va_save; SHREG_PTEH = pteh_save; pde_index = pdei(va); - pd_top = (u_long *)SHREG_TTB; -#ifdef SH4 - pde = (u_long *) - ((u_long)SH3_P1SEG_TO_P2SEG(pd_top[pde_index])); -#else - pde = (u_long *)pd_top[pde_index]; -#endif + pd_top = __PD_TOP(); + pde = __PDE(pd_top, pde_index); if (((u_long)pde & PG_V) != 0) { (u_long)pde &= ~PGOFSET; pte_index = ptei(va); pte = pde[pte_index]; - if ((pte & PG_V) != 0) { -#ifdef TRAP_DEBUG - if (trapdebug) - printf("tlb_handler#:va(0x%lx),pte(0x%lx)\n", va, pte); -#endif - -#ifdef SH4 -#ifdef SH4_PCMCIA - if (pte & PG_PCMCIA) { - int pcmtype; - unsigned long ptea = 0; - - pcmtype = pte & PG_PCMCIA; - - /* printf("pcmtype = %lx,pte=%lx\n", - pcmtype,pte); */ - - if (pcmtype == PG_PCMCIA_IO) { - ptea = 0x03; - } else if (pcmtype == PG_PCMCIA_MEM) { - ptea = 0x05; - /*ptea = 0x03; */ - } else if (pcmtype == PG_PCMCIA_ATT) { - ptea = 0x07; - } - - SHREG_PTEL = (pte & PTEL_VALIDBITS) - & ~PG_N; - - SHREG_PTEA = ptea; - } else -#endif - { - if ( /*1 ||*/ (va >= SH3_P1SEG_BASE)) { - SHREG_PTEL = - (pte & PTEL_VALIDBITS) - | PG_WT; - } else { - SHREG_PTEL = - (pte & PTEL_VALIDBITS); - } - SHREG_PTEA = 0; - } -#else - - SHREG_PTEL = pte & PTEL_VALIDBITS; -#endif - } + if ((pte & PG_V) != 0) + __SETUP_PTE(va, pte); } __asm __volatile("ldtlb; nop"); if (user) @@ -850,8 +761,7 @@ tlb_handler(p1, p2, p3, p4, frame) if (user == 0) { /* Check for copyin/copyout fault. */ - if (p != NULL && - p->p_addr->u_pcb.pcb_onfault != 0) { + if (p != NULL && p->p_addr->u_pcb.pcb_onfault != 0) { frame.tf_spc = (int) p->p_addr->u_pcb.pcb_onfault; return; }