Module Name: src Committed By: matt Date: Sat Aug 31 07:33:15 UTC 2013
Modified Files: src/sys/arch/powerpc/oea: oea_machdep.c ofwoea_machdep.c Log Message: Move the pmap_setup to the start oea_init (no non-OFW ports can use it). If PPC_OEA64_BRIDGE is defined, add code so that when OEACPU_64_BRIDGE is not present, it replaces the rfid with rfi and mfmsr/rldicl/mtmsrd sequence with NOPs. This allows plain OEA kernels to work. (tested on PMPPC with PPC_OEA64_BRIDGE option added). To generate a diff of this commit: cvs rdiff -u -r1.65 -r1.66 src/sys/arch/powerpc/oea/oea_machdep.c cvs rdiff -u -r1.33 -r1.34 src/sys/arch/powerpc/oea/ofwoea_machdep.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/oea/oea_machdep.c diff -u src/sys/arch/powerpc/oea/oea_machdep.c:1.65 src/sys/arch/powerpc/oea/oea_machdep.c:1.66 --- src/sys/arch/powerpc/oea/oea_machdep.c:1.65 Thu Jul 4 22:59:27 2013 +++ src/sys/arch/powerpc/oea/oea_machdep.c Sat Aug 31 07:33:15 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: oea_machdep.c,v 1.65 2013/07/04 22:59:27 joerg Exp $ */ +/* $NetBSD: oea_machdep.c,v 1.66 2013/08/31 07:33:15 matt Exp $ */ /* * Copyright (C) 2002 Matt Thomas @@ -33,7 +33,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: oea_machdep.c,v 1.65 2013/07/04 22:59:27 joerg Exp $"); +__KERNEL_RCSID(0, "$NetBSD: oea_machdep.c,v 1.66 2013/08/31 07:33:15 matt Exp $"); #include "opt_ppcarch.h" #include "opt_compat_netbsd.h" @@ -147,6 +147,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; /* @@ -298,6 +306,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 +338,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 +359,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 +375,37 @@ 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; + } + } + + /* + * 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 +426,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 */ @@ -830,6 +876,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 @@ -842,13 +893,24 @@ 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; + } + } + } #endif + __syncicache((void *)exc_exi_base, (int)extsize); + __asm volatile ("mtmsr %0" :: "r"(omsr)); } Index: src/sys/arch/powerpc/oea/ofwoea_machdep.c diff -u src/sys/arch/powerpc/oea/ofwoea_machdep.c:1.33 src/sys/arch/powerpc/oea/ofwoea_machdep.c:1.34 --- src/sys/arch/powerpc/oea/ofwoea_machdep.c:1.33 Mon May 13 00:12:01 2013 +++ src/sys/arch/powerpc/oea/ofwoea_machdep.c Sat Aug 31 07:33:15 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: ofwoea_machdep.c,v 1.33 2013/05/13 00:12:01 macallan Exp $ */ +/* $NetBSD: ofwoea_machdep.c,v 1.34 2013/08/31 07:33:15 matt Exp $ */ /*- * Copyright (c) 2007 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ofwoea_machdep.c,v 1.33 2013/05/13 00:12:01 macallan Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ofwoea_machdep.c,v 1.34 2013/08/31 07:33:15 matt Exp $"); #include "opt_ppcarch.h" #include "opt_compat_netbsd.h" @@ -201,13 +201,6 @@ ofwoea_initppc(u_int startkernel, u_int } #endif -#if defined (PPC_OEA64_BRIDGE) && defined (PPC_OEA) - if (oeacpufeat & OEACPU_64_BRIDGE) - pmap_setup64bridge(); - else - pmap_setup32(); -#endif - oea_init(pic_ext_intr); ofmaplen = save_ofmap(NULL, 0);