Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/powerpc/oea Move the pmap_setup to the start oea_in...



details:   https://anonhg.NetBSD.org/src/rev/bc7d796affc8
branches:  trunk
changeset: 789665:bc7d796affc8
user:      matt <matt%NetBSD.org@localhost>
date:      Sat Aug 31 07:33:15 2013 +0000

description:
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).

diffstat:

 sys/arch/powerpc/oea/oea_machdep.c    |  92 +++++++++++++++++++++++++++++-----
 sys/arch/powerpc/oea/ofwoea_machdep.c |  11 +---
 2 files changed, 79 insertions(+), 24 deletions(-)

diffs (198 lines):

diff -r f25f765b7eb8 -r bc7d796affc8 sys/arch/powerpc/oea/oea_machdep.c
--- a/sys/arch/powerpc/oea/oea_machdep.c        Fri Aug 30 21:29:29 2013 +0000
+++ b/sys/arch/powerpc/oea/oea_machdep.c        Sat Aug 31 07:33:15 2013 +0000
@@ -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 @@
 #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 @@
 #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 @@
        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 @@
         * 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 @@
                }
        }
 
+#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 @@
                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 @@
        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 @@
            :   "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));
 }
 
diff -r f25f765b7eb8 -r bc7d796affc8 sys/arch/powerpc/oea/ofwoea_machdep.c
--- a/sys/arch/powerpc/oea/ofwoea_machdep.c     Fri Aug 30 21:29:29 2013 +0000
+++ b/sys/arch/powerpc/oea/ofwoea_machdep.c     Sat Aug 31 07:33:15 2013 +0000
@@ -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 @@
        }
 #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);



Home | Main Index | Thread Index | Old Index