Module Name: src Committed By: bouyer Date: Mon Nov 16 09:00:01 UTC 2015
Modified Files: src/sys/arch/powerpc/include [netbsd-6]: psl.h userret.h src/sys/arch/powerpc/oea [netbsd-6]: altivec.c oea_machdep.c src/sys/arch/powerpc/powerpc [netbsd-6]: fpu.c Log Message: Revert ticket 1310: > sys/arch/powerpc/include/psl.h 1.20 > sys/arch/powerpc/include/userret.h 1.29, 1.30 > sys/arch/powerpc/oea/altivec.c 1.30 > sys/arch/powerpc/oea/oea_machdep.c 1.72 > sys/arch/powerpc/powerpc/fpu.c 1.36 > > powerpc PCU fixes because it breaks the build: http://releng.netbsd.org/builds/netbsd-6/201511152000Z/ To generate a diff of this commit: cvs rdiff -u -r1.18.8.1 -r1.18.8.2 src/sys/arch/powerpc/include/psl.h cvs rdiff -u -r1.22.8.2 -r1.22.8.3 src/sys/arch/powerpc/include/userret.h cvs rdiff -u -r1.25.8.1 -r1.25.8.2 src/sys/arch/powerpc/oea/altivec.c cvs rdiff -u -r1.63.2.1 -r1.63.2.2 src/sys/arch/powerpc/oea/oea_machdep.c cvs rdiff -u -r1.31.8.1 -r1.31.8.2 src/sys/arch/powerpc/powerpc/fpu.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/powerpc/include/psl.h diff -u src/sys/arch/powerpc/include/psl.h:1.18.8.1 src/sys/arch/powerpc/include/psl.h:1.18.8.2 --- src/sys/arch/powerpc/include/psl.h:1.18.8.1 Sun Nov 15 16:36:57 2015 +++ src/sys/arch/powerpc/include/psl.h Mon Nov 16 09:00:01 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: psl.h,v 1.18.8.1 2015/11/15 16:36:57 bouyer Exp $ */ +/* $NetBSD: psl.h,v 1.18.8.2 2015/11/16 09:00:01 bouyer Exp $ */ /* * Copyright (C) 1995, 1996 Wolfgang Solfrank. @@ -102,7 +102,8 @@ #include "opt_ppcarch.h" #endif /* _KERNEL_OPT */ -#if defined(PPC_OEA) || defined (PPC_OEA64_BRIDGE) || defined(_MODULE) +#if defined(PPC_OEA) || defined (PPC_OEA64_BRIDGE) || defined (PPC_OEA64) \ + || defined(_MODULE) extern register_t cpu_psluserset, cpu_pslusermod, cpu_pslusermask; #define PSL_USERSET cpu_psluserset Index: src/sys/arch/powerpc/include/userret.h diff -u src/sys/arch/powerpc/include/userret.h:1.22.8.2 src/sys/arch/powerpc/include/userret.h:1.22.8.3 --- src/sys/arch/powerpc/include/userret.h:1.22.8.2 Sun Nov 15 16:36:57 2015 +++ src/sys/arch/powerpc/include/userret.h Mon Nov 16 09:00:01 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: userret.h,v 1.22.8.2 2015/11/15 16:36:57 bouyer Exp $ */ +/* $NetBSD: userret.h,v 1.22.8.3 2015/11/16 09:00:01 bouyer Exp $ */ /* * Copyright (C) 1995, 1996 Wolfgang Solfrank. @@ -58,6 +58,14 @@ userret(struct lwp *l, struct trapframe /* Invoke MI userret code */ mi_userret(l); + KASSERTMSG((tf->tf_srr1 & PSL_PR) != 0, + "tf=%p: srr1 (%#lx): PSL_PR isn't set!", + tf, tf->tf_srr1); + KASSERTMSG((tf->tf_srr1 & PSL_FP) == 0 + || l->l_cpu->ci_data.cpu_pcu_curlwp[PCU_FPU] == l, + "tf=%p: srr1 (%#lx): PSL_FP set but FPU curlwp %p is not curlwp %p!", + tf, tf->tf_srr1, l->l_cpu->ci_data.cpu_pcu_curlwp[PCU_FPU], l); + /* clear SRR1 status bits */ tf->tf_srr1 &= (PSL_USERSRR1|PSL_FP|PSL_VEC); @@ -71,12 +79,12 @@ userret(struct lwp *l, struct trapframe #endif #ifdef PPC_BOOKE /* - * BookE doesn't PSL_SE but it does have a debug instruction completion - * exception but it needs PSL_DE to fire. Since we don't want it to - * happen in the kernel, we must disable PSL_DE and let it get - * restored by rfi/rfci. + * BookE doesn't have PSL_SE but it does have a debug instruction + * completion exception but it needs PSL_DE to fire. Instead we + * use IAC1/IAC2 to match the next PC. */ if (__predict_false(tf->tf_srr1 & PSL_SE)) { + tf->tf_srr1 &= ~PSL_SE; extern void booke_sstep(struct trapframe *); /* ugly */ booke_sstep(tf); } Index: src/sys/arch/powerpc/oea/altivec.c diff -u src/sys/arch/powerpc/oea/altivec.c:1.25.8.1 src/sys/arch/powerpc/oea/altivec.c:1.25.8.2 --- src/sys/arch/powerpc/oea/altivec.c:1.25.8.1 Sun Nov 15 16:36:57 2015 +++ src/sys/arch/powerpc/oea/altivec.c Mon Nov 16 09:00:01 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: altivec.c,v 1.25.8.1 2015/11/15 16:36:57 bouyer Exp $ */ +/* $NetBSD: altivec.c,v 1.25.8.2 2015/11/16 09:00:01 bouyer Exp $ */ /* * Copyright (C) 1996 Wolfgang Solfrank. @@ -32,7 +32,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: altivec.c,v 1.25.8.1 2015/11/15 16:36:57 bouyer Exp $"); +__KERNEL_RCSID(0, "$NetBSD: altivec.c,v 1.25.8.2 2015/11/16 09:00:01 bouyer Exp $"); #include "opt_multiprocessor.h" @@ -49,7 +49,7 @@ __KERNEL_RCSID(0, "$NetBSD: altivec.c,v #include <powerpc/oea/spr.h> #include <powerpc/psl.h> -static void vec_state_load(lwp_t *, bool); +static void vec_state_load(lwp_t *, u_int); static void vec_state_save(lwp_t *); static void vec_state_release(lwp_t *); @@ -63,21 +63,21 @@ const pcu_ops_t vec_ops = { bool vec_used_p(lwp_t *l) { - return (l->l_md.md_flags & MDLWP_USEDVEC) != 0; + return pcu_valid_p(&vec_ops); } void vec_mark_used(lwp_t *l) { - l->l_md.md_flags |= MDLWP_USEDVEC; + return pcu_discard(&vec_ops, true); } void -vec_state_load(lwp_t *l, bool used) +vec_state_load(lwp_t *l, u_int flags) { struct pcb * const pcb = lwp_getpcb(l); - if (__predict_false(!vec_used_p(l))) { + if ((flags & PCU_VALID) == 0) { memset(&pcb->pcb_vr, 0, sizeof(pcb->pcb_vr)); vec_mark_used(l); } @@ -111,7 +111,7 @@ vec_state_load(lwp_t *l, bool used) /* * Mark vector registers as modified. */ - l->l_md.md_flags |= MDLWP_USEDVEC|PSL_VEC; + l->l_md.md_flags |= PSL_VEC; l->l_md.md_utf->tf_srr1 |= PSL_VEC; } @@ -166,7 +166,7 @@ vec_restore_from_mcontext(struct lwp *l, KASSERT(l == curlwp); /* we don't need to save the state, just drop it */ - pcu_discard(&vec_ops); + pcu_discard(&vec_ops, true); memcpy(pcb->pcb_vr.vreg, &mcp->__vrf.__vrs, sizeof (pcb->pcb_vr.vreg)); pcb->pcb_vr.vscr = mcp->__vrf.__vscr; pcb->pcb_vr.vrsave = mcp->__vrf.__vrsave; Index: src/sys/arch/powerpc/oea/oea_machdep.c diff -u src/sys/arch/powerpc/oea/oea_machdep.c:1.63.2.1 src/sys/arch/powerpc/oea/oea_machdep.c:1.63.2.2 --- src/sys/arch/powerpc/oea/oea_machdep.c:1.63.2.1 Sun Nov 15 16:36:57 2015 +++ src/sys/arch/powerpc/oea/oea_machdep.c Mon Nov 16 09:00:01 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: oea_machdep.c,v 1.63.2.1 2015/11/15 16:36:57 bouyer Exp $ */ +/* $NetBSD: oea_machdep.c,v 1.63.2.2 2015/11/16 09:00:01 bouyer Exp $ */ /* * Copyright (C) 2002 Matt Thomas @@ -33,7 +33,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: oea_machdep.c,v 1.63.2.1 2015/11/15 16:36:57 bouyer Exp $"); +__KERNEL_RCSID(0, "$NetBSD: oea_machdep.c,v 1.63.2.2 2015/11/16 09:00:01 bouyer Exp $"); #include "opt_ppcarch.h" #include "opt_compat_netbsd.h" @@ -56,6 +56,7 @@ __KERNEL_RCSID(0, "$NetBSD: oea_machdep. #include <sys/syscallargs.h> #include <sys/syslog.h> #include <sys/systm.h> +#include <sys/cpu.h> #include <uvm/uvm_extern.h> @@ -147,6 +148,14 @@ oea_init(void (*handler)(void)) #endif KASSERT(mfspr(SPR_SPRG0) == (uintptr_t)ci); +#if defined (PPC_OEA64_BRIDGE) && defined (PPC_OEA) + if (oeacpufeat & OEACPU_64_BRIDGE) + pmap_setup64bridge(); + else + pmap_setup32(); +#endif + + cpuvers = mfpvr() >> 16; /* @@ -280,8 +289,8 @@ oea_init(void (*handler)(void)) * Install a branch absolute to trap0 to force a panic. */ if ((uintptr_t)trap0 < 0x2000000) { - *(uint32_t *) 0 = 0x7c6802a6; - *(uint32_t *) 4 = 0x48000002 | (uintptr_t) trap0; + *(volatile uint32_t *) 0 = 0x7c6802a6; + *(volatile uint32_t *) 4 = 0x48000002 | (uintptr_t) trap0; } /* @@ -298,6 +307,16 @@ oea_init(void (*handler)(void)) #define B 0x48000000 #define TLBSYNC 0x7c00046c #define SYNC 0x7c0004ac +#ifdef PPC_OEA64_BRIDGE +#define MFMSR_MASK 0xfc1fffff +#define MFMSR 0x7c0000a6 +#define MTMSRD_MASK 0xfc1effff +#define MTMSRD 0x7c000164 +#define RLDICL_MASK 0xfc00001c +#define RLDICL 0x78000000 +#define RFID 0x4c000024 +#define RFI 0x4c000064 +#endif #ifdef ALTIVEC #define MFSPR_VRSAVE 0x7c0042a6 @@ -320,9 +339,7 @@ oea_init(void (*handler)(void)) if (scratch & PSL_VEC) { cpu_altivec = 1; } else { - int *ip = trapstart; - - for (; ip < trapend; ip++) { + for (int *ip = trapstart; ip < trapend; ip++) { if ((ip[0] & MxSPR_MASK) == MFSPR_VRSAVE) { ip[0] = NOP; /* mfspr */ ip[1] = NOP; /* stw */ @@ -343,9 +360,7 @@ oea_init(void (*handler)(void)) * sequences where we zap/restore BAT registers on kernel exit/entry. */ if (cpuvers != MPC601) { - int *ip = trapstart; - - for (; ip < trapend; ip++) { + for (int *ip = trapstart; ip < trapend; ip++) { if ((ip[0] & MxSPR_MASK) == MFSPR_MQ) { ip[0] = NOP; /* mfspr */ ip[1] = NOP; /* stw */ @@ -361,6 +376,39 @@ oea_init(void (*handler)(void)) } } +#ifdef PPC_OEA64_BRIDGE + if ((oeacpufeat & OEACPU_64_BRIDGE) == 0) { + for (int *ip = (int *)exc_base; + (uintptr_t)ip <= exc_base + EXC_LAST; + ip++) { + if ((ip[0] & MFMSR_MASK) == MFMSR + && (ip[1] & RLDICL_MASK) == RLDICL + && (ip[2] & MTMSRD_MASK) == MTMSRD) { + *ip++ = NOP; + *ip++ = NOP; + ip[0] = NOP; + } else if (*ip == RFID) { + *ip = RFI; + } + } + + /* + * Now replace each rfid instruction with a rfi instruction. + */ + for (int *ip = trapstart; ip < trapend; ip++) { + if ((ip[0] & MFMSR_MASK) == MFMSR + && (ip[1] & RLDICL_MASK) == RLDICL + && (ip[2] & MTMSRD_MASK) == MTMSRD) { + *ip++ = NOP; + *ip++ = NOP; + ip[0] = NOP; + } else if (*ip == RFID) { + *ip = RFI; + } + } + } +#endif /* PPC_OEA64_BRIDGE */ + /* * Sync the changed instructions. */ @@ -381,10 +429,11 @@ oea_init(void (*handler)(void)) extern int kernel_text[], etext[]; int *ip; - for (ip = kernel_text; ip < etext; ip++) + for (ip = kernel_text; ip < etext; ip++) { if (*ip == TLBSYNC) { *ip = SYNC; __syncicache(ip, sizeof(*ip)); + } } } #endif /* PPC_OEA601 */ @@ -445,9 +494,16 @@ mpc601_ioseg_add(paddr_t pa, register_t * in pmap_bootstrap(). */ iosrtable[i] = SR601(SR601_Ks, SR601_BUID_MEMFORCED, 0, i); + + /* + * XXX Setting segment register 0xf on my powermac 7200 + * wedges machine so set later in pmap.c + */ + /* __asm volatile ("mtsrin %0,%1" :: "r"(iosrtable[i]), "r"(pa)); + */ } #endif /* PPC_OEA601 */ @@ -470,12 +526,25 @@ void oea_iobat_add(paddr_t pa, register_t len) { static int z = 1; - const u_int n = __SHIFTOUT(len, (BAT_XBL|BAT_BL) & ~BAT_BL_8M); + const u_int n = BAT_BL_TO_SIZE(len) / BAT_BL_TO_SIZE(BAT_BL_8M); const u_int i = BAT_VA2IDX(pa) & -n; /* in case pa was in the middle */ const int after_bat3 = (oeacpufeat & OEACPU_HIGHBAT) ? 4 : 8; KASSERT(len >= BAT_BL_8M); + /* + * If the caller wanted a bigger BAT than the hardware supports, + * split it into smaller BATs. + */ + if (len > BAT_BL_256M && (oeacpufeat & OEACPU_XBSEN) == 0) { + u_int xn = BAT_BL_TO_SIZE(len) >> 28; + while (xn-- > 0) { + oea_iobat_add(pa, BAT_BL_256M); + pa += 0x10000000; + } + return; + } + const register_t batl = BATL(pa, BAT_I|BAT_G, BAT_PP_RW); const register_t batu = BATU(pa, len, BAT_Vs); @@ -592,11 +661,14 @@ void oea_batinit(paddr_t pa, ...) { struct mem_region *allmem, *availmem, *mp; - unsigned int cpuvers; register_t msr = mfmsr(); va_list ap; +#ifdef PPC_OEA601 + unsigned int cpuvers; cpuvers = mfpvr() >> 16; +#endif /* PPC_OEA601 */ + /* * we need to call this before zapping BATs so OF calls work */ @@ -813,6 +885,11 @@ oea_install_extint(void (*handler)(void) extern int extint[], extsize[]; extern int extint_call[]; uintptr_t offset = (uintptr_t)handler - (uintptr_t)extint_call; +#ifdef PPC_HIGH_VEC + const uintptr_t exc_exi_base = EXC_HIGHVEC + EXC_EXI; +#else + const uintptr_t exc_exi_base = EXC_EXI; +#endif int omsr, msr; #ifdef DIAGNOSTIC @@ -825,13 +902,26 @@ oea_install_extint(void (*handler)(void) : "K" ((u_short)~PSL_EE)); extint_call[0] = (extint_call[0] & 0xfc000003) | offset; __syncicache((void *)extint_call, sizeof extint_call[0]); -#ifdef PPC_HIGH_VEC - memcpy((void *)(EXC_HIGHVEC + EXC_EXI), extint, (size_t)extsize); - __syncicache((void *)(EXC_HIGHVEC + EXC_EXI), (int)extsize); -#else - memcpy((void *)EXC_EXI, extint, (size_t)extsize); - __syncicache((void *)EXC_EXI, (int)extsize); + memcpy((void *)exc_exi_base, extint, (size_t)extsize); +#ifdef PPC_OEA64_BRIDGE + if ((oeacpufeat & OEACPU_64_BRIDGE) == 0) { + for (int *ip = (int *)exc_exi_base; + (uintptr_t)ip <= exc_exi_base + (size_t)extsize; + ip++) { + if ((ip[0] & MFMSR_MASK) == MFMSR + && (ip[1] & RLDICL_MASK) == RLDICL + && (ip[2] & MTMSRD_MASK) == MTMSRD) { + *ip++ = NOP; + *ip++ = NOP; + ip[0] = NOP; + } else if (*ip == RFID) { + *ip = RFI; + } + } + } #endif + __syncicache((void *)exc_exi_base, (size_t)extsize); + __asm volatile ("mtmsr %0" :: "r"(omsr)); } @@ -844,7 +934,7 @@ oea_startup(const char *model) uintptr_t sz; void *v; vaddr_t minaddr, maxaddr; - char pbuf[9]; + char pbuf[9], mstr[128]; KASSERT(curcpu() != NULL); KASSERT(lwp0.l_cpu != NULL); @@ -881,7 +971,8 @@ oea_startup(const char *model) printf("%s%s", copyright, version); if (model != NULL) printf("Model: %s\n", model); - cpu_identify(NULL, 0); + cpu_identify(mstr, sizeof(mstr)); + cpu_setmodel("%s", mstr); format_bytes(pbuf, sizeof(pbuf), ctob((u_int)physmem)); printf("total memory = %s\n", pbuf); Index: src/sys/arch/powerpc/powerpc/fpu.c diff -u src/sys/arch/powerpc/powerpc/fpu.c:1.31.8.1 src/sys/arch/powerpc/powerpc/fpu.c:1.31.8.2 --- src/sys/arch/powerpc/powerpc/fpu.c:1.31.8.1 Sun Nov 15 16:36:57 2015 +++ src/sys/arch/powerpc/powerpc/fpu.c Mon Nov 16 09:00:01 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: fpu.c,v 1.31.8.1 2015/11/15 16:36:57 bouyer Exp $ */ +/* $NetBSD: fpu.c,v 1.31.8.2 2015/11/16 09:00:01 bouyer Exp $ */ /* * Copyright (C) 1996 Wolfgang Solfrank. @@ -32,7 +32,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: fpu.c,v 1.31.8.1 2015/11/15 16:36:57 bouyer Exp $"); +__KERNEL_RCSID(0, "$NetBSD: fpu.c,v 1.31.8.2 2015/11/16 09:00:01 bouyer Exp $"); #include "opt_multiprocessor.h" @@ -48,7 +48,7 @@ __KERNEL_RCSID(0, "$NetBSD: fpu.c,v 1.31 #include <machine/psl.h> #ifdef PPC_HAVE_FPU -static void fpu_state_load(lwp_t *, bool); +static void fpu_state_load(lwp_t *, u_int); static void fpu_state_save(lwp_t *); static void fpu_state_release(lwp_t *); #endif @@ -65,24 +65,23 @@ const pcu_ops_t fpu_ops = { bool fpu_used_p(lwp_t *l) { - return (l->l_md.md_flags & MDLWP_USEDFPU) != 0; + return pcu_valid_p(&fpu_ops); } void fpu_mark_used(lwp_t *l) { - l->l_md.md_flags |= MDLWP_USEDFPU; + pcu_discard(&fpu_ops, true); } #ifdef PPC_HAVE_FPU void -fpu_state_load(lwp_t *l, bool used) +fpu_state_load(lwp_t *l, u_int flags) { struct pcb * const pcb = lwp_getpcb(l); - if (__predict_false(!fpu_used_p(l))) { + if ((flags & PCU_VALID) == 0) { memset(&pcb->pcb_fpu, 0, sizeof(pcb->pcb_fpu)); - fpu_mark_used(l); } if ((flags & PCU_REENABLE) == 0) { @@ -99,7 +98,6 @@ fpu_state_load(lwp_t *l, bool used) curcpu()->ci_ev_fpusw.ev_count++; l->l_md.md_utf->tf_srr1 |= PSL_FP|(pcb->pcb_flags & (PCB_FE0|PCB_FE1)); - l->l_md.md_flags |= MDLWP_USEDFPU; } /* @@ -215,7 +213,7 @@ fpu_save_to_mcontext(lwp_t *l, mcontext_ { KASSERT(l == curlwp); - if (!pcu_used_p(&fpu_ops)) + if (!pcu_valid_p(&fpu_ops)) return false; struct pcb * const pcb = lwp_getpcb(l); @@ -244,7 +242,7 @@ fpu_restore_from_mcontext(lwp_t *l, cons #ifdef PPC_HAVE_FPU /* we don't need to save the state, just drop it */ if (l == curlwp) - pcu_discard(&fpu_ops); + pcu_discard(&fpu_ops, true); #endif (void)memcpy(&pcb->pcb_fpu.fpreg, &mcp->__fpregs.__fpu_regs, sizeof (pcb->pcb_fpu.fpreg));