MPC601 support bits:

* install 601-specific DSI and RUNMODETRC trap handlers
* save/restore MQ in trapframe, add MQ hooks to DDB
* extend battable to 512 entries to hold the 601's 8M translations
* instead of adding I/O to BAT starvation, set up segment registers
  for Memory-Forced I/O Controller Interface Access
* sync after tlbie
This commit is contained in:
kleink 2003-01-22 21:44:54 +00:00
parent c54aea6fb9
commit 8065f1dfa1
11 changed files with 291 additions and 95 deletions

View File

@ -1,5 +1,5 @@
/* $OpenBSD: db_machdep.h,v 1.2 1997/03/21 00:48:48 niklas Exp $ */
/* $NetBSD: db_machdep.h,v 1.14 2002/12/20 15:23:13 scw Exp $ */
/* $NetBSD: db_machdep.h,v 1.15 2003/01/22 21:44:54 kleink Exp $ */
/*
* Mach Operating System
@ -54,6 +54,7 @@ struct powerpc_saved_state {
u_int32_t ctr;
u_int32_t cr;
u_int32_t xer;
u_int32_t mq;
u_int32_t dear;
u_int32_t esr;
u_int32_t pid;

View File

@ -1,4 +1,4 @@
/* $NetBSD: frame.h,v 1.11 2003/01/19 02:39:47 matt Exp $ */
/* $NetBSD: frame.h,v 1.12 2003/01/22 21:44:54 kleink Exp $ */
/*
* Copyright (C) 1995, 1996 Wolfgang Solfrank.
@ -57,6 +57,7 @@ struct trapframe {
int dsisr;
int exc;
uint32_t vrsave;
uint32_t mq;
};
#if defined(_KERNEL) || defined(_LKM)
@ -73,6 +74,7 @@ struct trapframe32 {
int dsisr;
int exc;
uint32_t vrsave;
uint32_t mq;
};
#endif
#endif /* _KERNEL || _LKM */

View File

@ -1,4 +1,4 @@
/* $NetBSD: pmap.h,v 1.9 2002/10/10 22:37:50 matt Exp $ */
/* $NetBSD: pmap.h,v 1.10 2003/01/22 21:44:55 kleink Exp $ */
/*-
* Copyright (C) 1995, 1996 Wolfgang Solfrank.
@ -81,16 +81,7 @@ pmap_remove_all(struct pmap *pmap)
/* Nothing. */
}
/*
* pmap_bootstrap interface
*/
struct segtab {
sr_t st_sr[16]; /* SR contents */
int st_mask; /* st_sr allocation bitmask */
};
void pmap_bootstrap (vaddr_t kernelstart, vaddr_t kernelend,
const struct segtab *);
void pmap_bootstrap (vaddr_t kernelstart, vaddr_t kernelend);
boolean_t pmap_extract (struct pmap *, vaddr_t, paddr_t *);
boolean_t pmap_query_bit (struct vm_page *, int);
boolean_t pmap_clear_bit (struct vm_page *, int);

View File

@ -1,4 +1,4 @@
/* $NetBSD: sr_601.h,v 1.1 2002/02/09 17:44:40 kleink Exp $ */
/* $NetBSD: sr_601.h,v 1.2 2003/01/22 21:44:55 kleink Exp $ */
/*-
* Copyright (c) 2002 The NetBSD Foundation, Inc.
@ -59,4 +59,14 @@
#define SR601_BUID_MEMFORCED 0x07f /* Translate to memory access, taking
PA[0:3] from the PACKET1 field */
#define SR601(key, buid, csi, p1) \
(SR601_T | \
(key) | \
(buid) << SR601_BUID_SHFT | \
(csi) << SR601_CSI_SHFT | (p1))
#ifdef _KERNEL
void mpc601_ioseg_add(paddr_t, register_t);
#endif
#endif /* !_MPC6XX_SR_601_H_ */

View File

@ -1,4 +1,4 @@
# $NetBSD: genassym.cf,v 1.8 2003/01/19 02:43:12 matt Exp $
# $NetBSD: genassym.cf,v 1.9 2003/01/22 21:44:55 kleink Exp $
#
# Copyright (C) 1995, 1996 Wolfgang Solfrank.
@ -59,6 +59,7 @@ define FRAME_DAR offsetof(struct trapframe, dar)
define FRAME_DSISR offsetof(struct trapframe, dsisr)
define FRAME_EXC offsetof(struct trapframe, exc)
define FRAME_VRSAVE offsetof(struct trapframe, vrsave)
define FRAME_MQ offsetof(struct trapframe, mq)
define IFRAMELEN IFRAMELEN
define IFRAME_R1 offsetof(struct intrframe, r1)

View File

@ -1,4 +1,4 @@
/* $NetBSD: mpc6xx_machdep.c,v 1.11 2003/01/19 02:46:08 matt Exp $ */
/* $NetBSD: mpc6xx_machdep.c,v 1.12 2003/01/22 21:44:55 kleink Exp $ */
/*
* Copyright (C) 2002 Matt Thomas
@ -74,9 +74,11 @@
#endif
#include <powerpc/mpc6xx/bat.h>
#include <powerpc/mpc6xx/sr_601.h>
#include <powerpc/trap.h>
#include <powerpc/stdarg.h>
#include <powerpc/spr.h>
#include <powerpc/pte.h>
#include <powerpc/altivec.h>
#include <machine/powerpc.h>
@ -97,16 +99,19 @@ struct pmap *curpm;
extern struct user *proc0paddr;
struct bat battable[16];
struct bat battable[512];
sr_t iosrtable[16]; /* I/O segments, for kernel_pmap setup */
paddr_t msgbuf_paddr;
void
mpc6xx_init(void (*handler)(void))
{
extern int trapstart[], trapend[];
extern int trapcode, trapsize;
extern int sctrap, scsize;
extern int alitrap, alisize;
extern int dsitrap, dsisize;
extern int dsi601trap, dsi601size;
extern int decrint, decrsize;
extern int tlbimiss, tlbimsize;
extern int tlbdlmiss, tlbdlmsize;
@ -122,6 +127,7 @@ mpc6xx_init(void (*handler)(void))
#endif
uintptr_t exc;
register_t scratch;
unsigned int cpuvers;
size_t size;
#ifdef MULTIPROCESSOR
struct cpu_info * const ci = &cpu_info[0];
@ -130,6 +136,7 @@ mpc6xx_init(void (*handler)(void))
#endif
__asm __volatile ("mtsprg 0,%0" :: "r"(ci));
cpuvers = mfpvr() >> 16;
/*
@ -172,8 +179,13 @@ mpc6xx_init(void (*handler)(void))
memcpy((void *)EXC_ALI, &alitrap, size);
break;
case EXC_DSI:
size = (size_t)&dsisize;
memcpy((void *)EXC_DSI, &dsitrap, size);
if (cpuvers == MPC601) {
size = (size_t)&dsi601size;
memcpy((void *)EXC_DSI, &dsi601trap, size);
} else {
size = (size_t)&dsisize;
memcpy((void *)EXC_DSI, &dsitrap, size);
}
break;
case EXC_DECR:
size = (size_t)&decrsize;
@ -197,6 +209,13 @@ mpc6xx_init(void (*handler)(void))
memcpy((void *)EXC_VEC, &trapcode, size);
break;
#if defined(DDB) || defined(IPKDB) || defined(KGDB)
case EXC_RUNMODETRC:
if (cpuvers != MPC601) {
size = (size_t)&trapsize;
memcpy((void *)EXC_RUNMODETRC, &trapcode, size);
break;
}
/* FALLTHROUGH */
case EXC_PGM:
case EXC_TRC:
case EXC_BPT:
@ -223,11 +242,14 @@ mpc6xx_init(void (*handler)(void))
*/
cpu_probe_cache();
#define MxSPR_MASK 0x7c1fffff
#define MFSPR_MQ 0x7c0002a6
#define MTSPR_MQ 0x7c0003a6
#define NOP 0x60000000
#ifdef ALTIVEC
#define MFSPR_VRSAVE 0x7c0042a6
#define MTSPR_VRSAVE 0x7c0043a6
#define MxSPR_MASK 0x7c1fffff
#define NOP 0x60000000
/*
* Try to set the VEC bit in the MSR. If it doesn't get set, we are
@ -246,7 +268,6 @@ mpc6xx_init(void (*handler)(void))
if (scratch & PSL_VEC) {
cpu_altivec = 1;
} else {
extern int trapstart[], trapend[];
int *ip = trapstart;
for (; ip < trapend; ip++) {
@ -258,13 +279,34 @@ mpc6xx_init(void (*handler)(void))
ip[0] = NOP; /* mtspr */
}
}
}
#endif
/*
* If we aren't on a MPC601 processor, we to need zap any of
* sequences we save/restore the MQ SPR into NOPs.
*/
if (cpuvers != MPC601) {
int *ip = trapstart;
for (; ip < trapend; ip++) {
if ((ip[0] & MxSPR_MASK) == MFSPR_MQ) {
ip[0] = NOP; /* mfspr */
ip[1] = NOP; /* stw */
} else if ((ip[0] & MxSPR_MASK) == MTSPR_MQ) {
ip[-1] = NOP; /* lwz */
ip[0] = NOP; /* mtspr */
}
}
}
if (cpu_altivec == 1 || cpuvers != MPC601) {
/*
* Sync the changed instructions.
*/
__syncicache((void *) trapstart,
(uintptr_t) trapend - (uintptr_t) trapstart);
}
#endif
/*
* external interrupt handler install
@ -282,6 +324,24 @@ mpc6xx_init(void (*handler)(void))
: "K"(PSL_IR|PSL_DR|PSL_ME|PSL_RI));
}
void
mpc601_ioseg_add(paddr_t pa, register_t len)
{
const u_int i = pa >> ADDR_SR_SHFT;
if (len != BAT_BL_256M)
panic("mpc601_ioseg_add: len != 256M");
/*
* Translate into an I/O segment, load it, and stash away for use
* in pmap_bootstrap().
*/
iosrtable[i] = SR601(SR601_Ks, SR601_BUID_MEMFORCED, 0, i);
__asm __volatile ("mtsrin %0,%1"
:: "r"(iosrtable[i]),
"r"(pa));
}
void
mpc6xx_iobat_add(paddr_t pa, register_t len)
{
@ -321,30 +381,78 @@ void
mpc6xx_batinit(paddr_t pa, ...)
{
struct mem_region *allmem, *availmem, *mp;
int i;
unsigned int cpuvers;
va_list ap;
cpuvers = mfpvr() >> 16;
/*
* Initialize BAT registers to unmapped to not generate
* overlapping mappings below.
*
* The 601's implementation differs in the Valid bit being situated
* in the lower BAT register, and in being a unified BAT only whose
* four entries are accessed through the IBAT[0-3] SPRs.
*
* Also, while the 601 does distinguish between supervisor/user
* protection keys, it does _not_ distinguish distinguish between
* validity in supervisor/user mode.
*/
__asm __volatile ("mtibatu 0,%0" :: "r"(0));
__asm __volatile ("mtibatu 1,%0" :: "r"(0));
__asm __volatile ("mtibatu 2,%0" :: "r"(0));
__asm __volatile ("mtibatu 3,%0" :: "r"(0));
__asm __volatile ("mtdbatu 0,%0" :: "r"(0));
__asm __volatile ("mtdbatu 1,%0" :: "r"(0));
__asm __volatile ("mtdbatu 2,%0" :: "r"(0));
__asm __volatile ("mtdbatu 3,%0" :: "r"(0));
if (cpuvers == MPC601) {
__asm __volatile ("mtibatl 0,%0" :: "r"(0));
__asm __volatile ("mtibatl 1,%0" :: "r"(0));
__asm __volatile ("mtibatl 2,%0" :: "r"(0));
__asm __volatile ("mtibatl 3,%0" :: "r"(0));
} else {
__asm __volatile ("mtibatu 0,%0" :: "r"(0));
__asm __volatile ("mtibatu 1,%0" :: "r"(0));
__asm __volatile ("mtibatu 2,%0" :: "r"(0));
__asm __volatile ("mtibatu 3,%0" :: "r"(0));
__asm __volatile ("mtdbatu 0,%0" :: "r"(0));
__asm __volatile ("mtdbatu 1,%0" :: "r"(0));
__asm __volatile ("mtdbatu 2,%0" :: "r"(0));
__asm __volatile ("mtdbatu 3,%0" :: "r"(0));
}
/*
* Set up BAT0 to only map the lowest 256 MB area
* Set up BAT to map physical memory
*/
battable[0].batl = BATL(0x00000000, BAT_M, BAT_PP_RW);
battable[0].batu = BATU(0x00000000, BAT_BL_256M, BAT_Vs);
if (cpuvers == MPC601) {
/*
* Set up battable to map the lowest 256 MB area.
* Map the lowest 32 MB area via BAT[0-3];
* BAT[01] are fixed, BAT[23] are floating.
*/
for (i = 0; i < 32; i++) {
battable[i].batl = BATL601(i << 23,
BAT601_BSM_8M, BAT601_V);
battable[i].batu = BATU601(i << 23,
BAT601_M, BAT601_Ku, BAT601_PP_NONE);
}
__asm __volatile ("mtibatu 0,%1; mtibatl 0,%0"
:: "r"(battable[0x00000000 >> 23].batl),
"r"(battable[0x00000000 >> 23].batu));
__asm __volatile ("mtibatu 1,%1; mtibatl 1,%0"
:: "r"(battable[0x00800000 >> 23].batl),
"r"(battable[0x00800000 >> 23].batu));
__asm __volatile ("mtibatu 2,%1; mtibatl 2,%0"
:: "r"(battable[0x01000000 >> 23].batl),
"r"(battable[0x01000000 >> 23].batu));
__asm __volatile ("mtibatu 3,%1; mtibatl 3,%0"
:: "r"(battable[0x01800000 >> 23].batl),
"r"(battable[0x01800000 >> 23].batu));
} else {
/*
* Set up BAT0 to only map the lowest 256 MB area
*/
battable[0].batl = BATL(0x00000000, BAT_M, BAT_PP_RW);
battable[0].batu = BATU(0x00000000, BAT_BL_256M, BAT_Vs);
__asm __volatile ("mtibatl 0,%0; mtibatu 0,%1;"
"mtdbatl 0,%0; mtdbatu 0,%1;"
:: "r"(battable[0].batl), "r"(battable[0].batu));
__asm __volatile ("mtibatl 0,%0; mtibatu 0,%1;"
"mtdbatl 0,%0; mtdbatu 0,%1;"
:: "r"(battable[0].batl), "r"(battable[0].batu));
}
/*
* Now setup other fixed bat registers
@ -356,12 +464,21 @@ mpc6xx_batinit(paddr_t pa, ...)
va_start(ap, pa);
/*
* Add any I/O BATs specificed.
* Add any I/O BATs specificed;
* use I/O segments on the BAT-starved 601.
*/
while (pa != 0) {
register_t len = va_arg(ap, register_t);
mpc6xx_iobat_add(pa, len);
pa = va_arg(ap, paddr_t);
if (cpuvers == MPC601) {
while (pa != 0) {
register_t len = va_arg(ap, register_t);
mpc601_ioseg_add(pa, len);
pa = va_arg(ap, paddr_t);
}
} else {
while (pa != 0) {
register_t len = va_arg(ap, register_t);
mpc6xx_iobat_add(pa, len);
pa = va_arg(ap, paddr_t);
}
}
va_end(ap);
@ -371,17 +488,36 @@ mpc6xx_batinit(paddr_t pa, ...)
* This is here because mem_regions() call needs bat0 set up.
*/
mem_regions(&allmem, &availmem);
for (mp = allmem; mp->size; mp++) {
paddr_t pa = mp->start & 0xf0000000;
paddr_t end = mp->start + mp->size;
if (cpuvers == MPC601) {
for (mp = allmem; mp->size; mp++) {
paddr_t pa = mp->start & 0xff800000;
paddr_t end = mp->start + mp->size;
do {
u_int i = pa >> 28;
do {
u_int i = pa >> 23;
battable[i].batl = BATL(pa, BAT_M, BAT_PP_RW);
battable[i].batu = BATU(pa, BAT_BL_256M, BAT_Vs);
pa += SEGMENT_LENGTH;
} while (pa < end);
battable[i].batl =
BATL601(pa, BAT601_BSM_8M, BAT601_V);
battable[i].batu =
BATU601(pa, BAT601_M, BAT601_Ku, BAT601_PP_NONE);
pa += (1 << 23);
} while (pa < end);
}
} else {
for (mp = allmem; mp->size; mp++) {
paddr_t pa = mp->start & 0xf0000000;
paddr_t end = mp->start + mp->size;
do {
u_int i = pa >> 28;
battable[i].batl =
BATL(pa, BAT_M, BAT_PP_RW);
battable[i].batu =
BATU(pa, BAT_BL_256M, BAT_Vs);
pa += SEGMENT_LENGTH;
} while (pa < end);
}
}
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: pmap.c,v 1.63 2003/01/18 06:23:32 thorpej Exp $ */
/* $NetBSD: pmap.c,v 1.64 2003/01/22 21:44:55 kleink Exp $ */
/*-
* Copyright (c) 2001 The NetBSD Foundation, Inc.
* All rights reserved.
@ -88,6 +88,7 @@
#include <machine/pcb.h>
#include <machine/powerpc.h>
#include <powerpc/spr.h>
#include <powerpc/mpc6xx/sr_601.h>
#if __NetBSD_Version__ > 105010000
#include <powerpc/mpc6xx/bat.h>
#else
@ -130,6 +131,8 @@ extern paddr_t msgbuf_paddr;
static struct mem_region *mem, *avail;
static u_int mem_cnt, avail_cnt;
extern sr_t iosrtable[16];
#ifdef __HAVE_PMAP_PHYSSEG
/*
* This is a cache of referenced/modified bits.
@ -399,7 +402,7 @@ extern struct evcnt pmap_evcnt_idlezeroed_pages;
#define MTMSR(psl) mtmsr(psl)
#define MFPVR() mfpvr()
#define MFSRIN(va) mfsrin(va)
#define MFTB() mftbl()
#define MFTB() mfrtcltbl()
static __inline sr_t
mfsrin(vaddr_t va)
@ -425,6 +428,16 @@ pmap_interrupts_restore(u_int32_t msr)
MTMSR(msr);
}
static __inline u_int32_t
mfrtcltbl(void)
{
if ((MFPVR() >> 16) == MPC601)
return (mfrtcl() >> 7);
else
return (mftbl());
}
/*
* These small routines may have to be replaced,
* if/when we support processors other that the 604.
@ -445,6 +458,7 @@ tlbia(void)
for (i = 0; i < (caddr_t)0x00040000; i += 0x00001000) {
TLBIE(i);
EIEIO();
SYNC();
}
TLBSYNC();
SYNC();
@ -628,6 +642,7 @@ pmap_pte_clear(volatile pte_t *pt, vaddr_t va, int ptebit)
*/
pt->pte_lo &= ~ptebit;
TLBIE(va);
SYNC();
EIEIO();
TLBSYNC();
SYNC();
@ -674,6 +689,7 @@ pmap_pte_unset(volatile pte_t *pt, pte_t *pvo_pt, vaddr_t va)
pt->pte_hi &= ~PTE_VALID;
SYNC();
TLBIE(va);
SYNC();
EIEIO();
TLBSYNC();
SYNC();
@ -2709,8 +2725,7 @@ pmap_boot_find_memory(psize_t size, psize_t alignment, int at_end)
* is really initialized.
*/
void
pmap_bootstrap(paddr_t kernelstart, paddr_t kernelend,
const struct segtab *kernsegs)
pmap_bootstrap(paddr_t kernelstart, paddr_t kernelend)
{
struct mem_region *mp, tmp;
paddr_t s, e;
@ -2978,16 +2993,14 @@ pmap_bootstrap(paddr_t kernelstart, paddr_t kernelend,
__asm __volatile ("mtsr %0,%1"
:: "n"(KERNEL2_SR), "r"(KERNEL2_SEGMENT));
#endif
if (kernsegs != NULL) {
for (i = 0; i < 16; i++) {
if (kernsegs->st_mask & (1 << i)) {
pmap_kernel()->pm_sr[i] = kernsegs->st_sr[i];
__asm __volatile ("mtsrin %0,%1"
:: "r"(pmap_kernel()->pm_sr[i]),
"r"(i << ADDR_SR_SHFT));
}
for (i = 0; i < 16; i++) {
if (iosrtable[i] & SR601_T) {
pmap_kernel()->pm_sr[i] = iosrtable[i];
__asm __volatile ("mtsrin %0,%1"
:: "r"(iosrtable[i]), "r"(i << ADDR_SR_SHFT));
}
}
__asm __volatile ("sync; mtsdr1 %0; isync"
:: "r"((u_int)pmap_pteg_table | (pmap_pteg_mask >> 10)));
tlbia();

View File

@ -1,4 +1,4 @@
/* $NetBSD: db_interface.c,v 1.25 2003/01/04 23:46:11 thorpej Exp $ */
/* $NetBSD: db_interface.c,v 1.26 2003/01/22 21:44:56 kleink Exp $ */
/* $OpenBSD: db_interface.c,v 1.2 1996/12/28 06:21:50 rahnds Exp $ */
#define USERACC
@ -118,6 +118,7 @@ kdb_trap(type, v)
DDB_REGS->ctr = frame->ctr;
DDB_REGS->cr = frame->cr;
DDB_REGS->xer = frame->xer;
DDB_REGS->mq = frame->mq;
#ifdef PPC_IBM4XX
DDB_REGS->dear = frame->dear;
DDB_REGS->esr = frame->esr;
@ -154,6 +155,7 @@ kdb_trap(type, v)
frame->ctr = DDB_REGS->ctr;
frame->cr = DDB_REGS->cr;
frame->xer = DDB_REGS->xer;
frame->mq = DDB_REGS->mq;
#ifdef PPC_IBM4XX
frame->dear = DDB_REGS->dear;
frame->esr = DDB_REGS->esr;

View File

@ -1,4 +1,4 @@
/* $NetBSD: db_trace.c,v 1.23 2003/01/18 06:23:33 thorpej Exp $ */
/* $NetBSD: db_trace.c,v 1.24 2003/01/22 21:44:56 kleink Exp $ */
/* $OpenBSD: db_trace.c,v 1.3 1997/03/21 02:10:48 niklas Exp $ */
/*
@ -84,6 +84,7 @@ const struct db_variable db_regs[] = {
{ "ctr", (long *)&ddb_regs.ctr, FCN_NULL },
{ "cr", (long *)&ddb_regs.cr, FCN_NULL },
{ "xer", (long *)&ddb_regs.xer, FCN_NULL },
{ "mq", (long *)&ddb_regs.mq, FCN_NULL },
#ifdef PPC_IBM4XX
{ "dear", (long *)&ddb_regs.dear, FCN_NULL },
{ "esr", (long *)&ddb_regs.esr, FCN_NULL },
@ -252,6 +253,8 @@ db_stack_trace_print(addr, have_addr, count, modif, pr)
#ifdef PPC_MPC6XX
if (tf->exc == EXC_DSI)
(*pr)(" dsisr=%#x", tf->dsisr);
if ((mfpvr() >> 16) == MPC601)
(*pr)(" mq=%#x", tf->mq);
#endif
#ifdef PPC_IBM4XX
if (tf->exc == EXC_DSI)

View File

@ -1,4 +1,4 @@
/* $NetBSD: kgdb_machdep.c,v 1.4 2003/01/13 20:29:34 augustss Exp $ */
/* $NetBSD: kgdb_machdep.c,v 1.5 2003/01/22 21:44:56 kleink Exp $ */
/*
* Copyright 2001 Wasabi Systems, Inc.
@ -69,7 +69,7 @@ kgdb_acc(vaddr_t va, size_t len)
vaddr_t last_va;
paddr_t pa;
u_int msr;
u_int batu;
u_int batu, batl;
/* If translation is off, everything is fair game */
asm volatile ("mfmsr %0" : "=r"(msr));
@ -78,29 +78,52 @@ kgdb_acc(vaddr_t va, size_t len)
}
/* Now check battable registers */
asm volatile ("mfdbatu %0,0" : "=r"(batu));
if (BAT_VALID_P(batu,msr) &&
BAT_VA_MATCH_P(batu,va) &&
(batu & BAT_PP) != BAT_PP_NONE) {
return 1;
}
asm volatile ("mfdbatu %0,1" : "=r"(batu));
if (BAT_VALID_P(batu,msr) &&
BAT_VA_MATCH_P(batu,va) &&
(batu & BAT_PP) != BAT_PP_NONE) {
return 1;
}
asm volatile ("mfdbatu %0,2" : "=r"(batu));
if (BAT_VALID_P(batu,msr) &&
BAT_VA_MATCH_P(batu,va) &&
(batu & BAT_PP) != BAT_PP_NONE) {
return 1;
}
asm volatile ("mfdbatu %0,3" : "=r"(batu));
if (BAT_VALID_P(batu,msr) &&
BAT_VA_MATCH_P(batu,va) &&
(batu & BAT_PP) != BAT_PP_NONE) {
return 1;
if ((mfpvr() >> 16) == MPC601) {
asm volatile ("mfibatl %0,0" : "=r"(batl));
asm volatile ("mfibatu %0,0" : "=r"(batu));
if (BAT601_VALID_P(batl) &&
BAT601_VA_MATCH_P(batu,batl,va))
return 1;
asm volatile ("mfibatl %0,1" : "=r"(batl));
asm volatile ("mfibatu %0,1" : "=r"(batu));
if (BAT601_VALID_P(batl) &&
BAT601_VA_MATCH_P(batu,batl,va))
return 1;
asm volatile ("mfibatl %0,2" : "=r"(batl));
asm volatile ("mfibatu %0,2" : "=r"(batu));
if (BAT601_VALID_P(batl) &&
BAT601_VA_MATCH_P(batu,batl,va))
return 1;
asm volatile ("mfibatl %0,3" : "=r"(batl));
asm volatile ("mfibatu %0,3" : "=r"(batu));
if (BAT601_VALID_P(batl) &&
BAT601_VA_MATCH_P(batu,batl,va))
return 1;
} else {
asm volatile ("mfdbatu %0,0" : "=r"(batu));
if (BAT_VALID_P(batu,msr) &&
BAT_VA_MATCH_P(batu,va) &&
(batu & BAT_PP) != BAT_PP_NONE) {
return 1;
}
asm volatile ("mfdbatu %0,1" : "=r"(batu));
if (BAT_VALID_P(batu,msr) &&
BAT_VA_MATCH_P(batu,va) &&
(batu & BAT_PP) != BAT_PP_NONE) {
return 1;
}
asm volatile ("mfdbatu %0,2" : "=r"(batu));
if (BAT_VALID_P(batu,msr) &&
BAT_VA_MATCH_P(batu,va) &&
(batu & BAT_PP) != BAT_PP_NONE) {
return 1;
}
asm volatile ("mfdbatu %0,3" : "=r"(batu));
if (BAT_VALID_P(batu,msr) &&
BAT_VA_MATCH_P(batu,va) &&
(batu & BAT_PP) != BAT_PP_NONE) {
return 1;
}
}
last_va = va + len;

View File

@ -1,4 +1,4 @@
/* $NetBSD: trap_subr.S,v 1.30 2003/01/18 06:23:35 thorpej Exp $ */
/* $NetBSD: trap_subr.S,v 1.31 2003/01/22 21:44:56 kleink Exp $ */
/*
* Copyright (C) 1995, 1996 Wolfgang Solfrank.
@ -85,6 +85,18 @@
lwzu sr,_C_LABEL(kernel_pmap_)+PM_SR@l(pmap); \
RESTORE_SRS(pmap,sr)
/*
* Save/restore MPC601 MQ register.
* Note: mpc6xx_init() relies on this instruction sequence.
*/
#define SAVE_MQ(tf,b) \
mfspr b,SPR_MQ; \
stw b,FRAME_MQ+8(tf);
#define RESTORE_MQ(tf,b) \
lwz b,FRAME_MQ+8(tf); \
mtspr SPR_MQ,b;
/*
* Data used during primary/secondary traps/interrupts
*/
@ -192,8 +204,8 @@ _C_LABEL(dsisize) = .-_C_LABEL(dsitrap)
* Considers different BAT format and combined implementation
* (being addressed as I-BAT).
*/
.globl _C_LABEL(dsitrap601),_C_LABEL(dsi601size)
_C_LABEL(dsitrap601):
.globl _C_LABEL(dsi601trap),_C_LABEL(dsi601size)
_C_LABEL(dsi601trap):
stmw 28,disisave(0) /* free r28-r31 */
mfcr 29 /* save CR */
mfxer 30 /* save XER */
@ -233,7 +245,7 @@ _C_LABEL(dsitrap601):
mflr 28 /* save LR */
mtsprg 1,1
bla disitrap
_C_LABEL(dsi601size) = .-_C_LABEL(dsitrap601)
_C_LABEL(dsi601size) = .-_C_LABEL(dsi601trap)
/*
* This one for the external interrupt handler.
@ -588,6 +600,7 @@ _C_LABEL(ipkdbsize) = .-_C_LABEL(ipkdblow)
stw 4,FRAME_CTR+8(1); \
stw 5,FRAME_EXC+8(1); \
SAVE_VRSAVE(1,6); \
SAVE_MQ(1,7); \
stw 28,FRAME_DAR+8(1); \
stw 29,FRAME_DSISR+8(1); \
stw 30,FRAME_SRR0+8(1); \
@ -601,7 +614,8 @@ _C_LABEL(ipkdbsize) = .-_C_LABEL(ipkdblow)
lwz 5,FRAME_XER+8(1); \
lwz 6,FRAME_LR+8(1); \
lwz 7,FRAME_CR+8(1); \
RESTORE_VRSAVE(1,8); \
RESTORE_MQ(1,8); \
RESTORE_VRSAVE(1,9); \
stw 2,savearea(0); \
stw 3,savearea+4(0); \
mtctr 4; \