From 8065f1dfa12d725742543fcd37db93e7ee5c00c5 Mon Sep 17 00:00:00 2001 From: kleink Date: Wed, 22 Jan 2003 21:44:54 +0000 Subject: [PATCH] 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 --- sys/arch/powerpc/include/db_machdep.h | 3 +- sys/arch/powerpc/include/frame.h | 4 +- sys/arch/powerpc/include/mpc6xx/pmap.h | 13 +- sys/arch/powerpc/include/mpc6xx/sr_601.h | 12 +- sys/arch/powerpc/mpc6xx/genassym.cf | 3 +- sys/arch/powerpc/mpc6xx/mpc6xx_machdep.c | 208 +++++++++++++++++++---- sys/arch/powerpc/mpc6xx/pmap.c | 37 ++-- sys/arch/powerpc/powerpc/db_interface.c | 4 +- sys/arch/powerpc/powerpc/db_trace.c | 5 +- sys/arch/powerpc/powerpc/kgdb_machdep.c | 73 +++++--- sys/arch/powerpc/powerpc/trap_subr.S | 24 ++- 11 files changed, 291 insertions(+), 95 deletions(-) diff --git a/sys/arch/powerpc/include/db_machdep.h b/sys/arch/powerpc/include/db_machdep.h index 07cbc064ff8c..2214a5bed982 100644 --- a/sys/arch/powerpc/include/db_machdep.h +++ b/sys/arch/powerpc/include/db_machdep.h @@ -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; diff --git a/sys/arch/powerpc/include/frame.h b/sys/arch/powerpc/include/frame.h index d89c58084d4d..ae0b2ac1c43f 100644 --- a/sys/arch/powerpc/include/frame.h +++ b/sys/arch/powerpc/include/frame.h @@ -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 */ diff --git a/sys/arch/powerpc/include/mpc6xx/pmap.h b/sys/arch/powerpc/include/mpc6xx/pmap.h index 332eccf7255d..ad2fa6a083d0 100644 --- a/sys/arch/powerpc/include/mpc6xx/pmap.h +++ b/sys/arch/powerpc/include/mpc6xx/pmap.h @@ -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); diff --git a/sys/arch/powerpc/include/mpc6xx/sr_601.h b/sys/arch/powerpc/include/mpc6xx/sr_601.h index 8f0b58efcbcc..ecbe72365b25 100644 --- a/sys/arch/powerpc/include/mpc6xx/sr_601.h +++ b/sys/arch/powerpc/include/mpc6xx/sr_601.h @@ -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_ */ diff --git a/sys/arch/powerpc/mpc6xx/genassym.cf b/sys/arch/powerpc/mpc6xx/genassym.cf index 67e0dec27f0b..acd143128b18 100644 --- a/sys/arch/powerpc/mpc6xx/genassym.cf +++ b/sys/arch/powerpc/mpc6xx/genassym.cf @@ -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) diff --git a/sys/arch/powerpc/mpc6xx/mpc6xx_machdep.c b/sys/arch/powerpc/mpc6xx/mpc6xx_machdep.c index 580469bf9685..eeb4631ab452 100644 --- a/sys/arch/powerpc/mpc6xx/mpc6xx_machdep.c +++ b/sys/arch/powerpc/mpc6xx/mpc6xx_machdep.c @@ -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 +#include #include #include #include +#include #include #include @@ -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); + } } } diff --git a/sys/arch/powerpc/mpc6xx/pmap.c b/sys/arch/powerpc/mpc6xx/pmap.c index 2eab591bbd0f..dd38f1b84d1b 100644 --- a/sys/arch/powerpc/mpc6xx/pmap.c +++ b/sys/arch/powerpc/mpc6xx/pmap.c @@ -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 #include #include +#include #if __NetBSD_Version__ > 105010000 #include #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(); diff --git a/sys/arch/powerpc/powerpc/db_interface.c b/sys/arch/powerpc/powerpc/db_interface.c index 9d16414009b9..50d300e4100f 100644 --- a/sys/arch/powerpc/powerpc/db_interface.c +++ b/sys/arch/powerpc/powerpc/db_interface.c @@ -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; diff --git a/sys/arch/powerpc/powerpc/db_trace.c b/sys/arch/powerpc/powerpc/db_trace.c index 7663461f17c3..a74c747ef506 100644 --- a/sys/arch/powerpc/powerpc/db_trace.c +++ b/sys/arch/powerpc/powerpc/db_trace.c @@ -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) diff --git a/sys/arch/powerpc/powerpc/kgdb_machdep.c b/sys/arch/powerpc/powerpc/kgdb_machdep.c index f5e2e0f0acc7..ba76c0345abc 100644 --- a/sys/arch/powerpc/powerpc/kgdb_machdep.c +++ b/sys/arch/powerpc/powerpc/kgdb_machdep.c @@ -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; diff --git a/sys/arch/powerpc/powerpc/trap_subr.S b/sys/arch/powerpc/powerpc/trap_subr.S index d5189a3cfabf..3f9821943972 100644 --- a/sys/arch/powerpc/powerpc/trap_subr.S +++ b/sys/arch/powerpc/powerpc/trap_subr.S @@ -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; \