change PTE PG_* bit define to support SH4 PCMCIA space attribute fully.
for detail, see pte.h.
This commit is contained in:
parent
32f2c6e61f
commit
9487e1d731
|
@ -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_ */
|
||||
|
|
|
@ -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 <uvm/uvm_extern.h>
|
||||
|
||||
#include <sh3/mmureg.h>
|
||||
#include <sh3/trapreg.h>
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/cpufunc.h>
|
||||
|
@ -80,26 +81,54 @@
|
|||
#include <sys/kgdb.h>
|
||||
#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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue