Port-powerpc archive

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

High-vector configs and kernels at distant locations



Hi,

the diff file below shows a patch to make oea_init() support systems with
high-vector configurations (i.e. exception vectors at 0xfff00000), and
trap_subr.S allows the kernel to be in a memory region which is not reachable
by absolute branch instructions (ba and bla).

High-vector support can be enabled by option PPC_HIGH_VEC, and long-branches
to the kernel are enabled by the option DISTANT_KERNEL. Port amigappc needs
both, so I would like to have this feature included in the powerpc/ tree.
Having my own copies of oea_init() and trap_subr.S would lead to divergence
sooner or later.

The patch is tested. Compiles and runs with ofppc on my Pegasos2. But I
would like to give everybody the chance to object, as I'm changing important
code used by any powerpc port!

--- powerpc/include/CVS/Base/trap.h 2006-08-05 23:26:49.000000000 +0200
+++ powerpc/include/trap.h  2008-05-22 01:29:04.000000000 +0200
@@ -90,6 +90,8 @@
 /* Trap was in user mode */
 #define    EXC_USER    0x10000
 
+/* Exception vector base address when MSR[IP] is set */
+#define EXC_HIGHVEC    0xfff00000
 
 /*
  * EXC_ALI sets bits in the DSISR and DAR to provide enough
--- powerpc/oea/CVS/Base/oea_machdep.c  2008-03-01 11:00:55.000000000 +0100
+++ powerpc/oea/oea_machdep.c   2008-05-22 22:36:22.000000000 +0200
@@ -130,7 +130,7 @@
 #ifdef ALTIVEC
    register_t msr;
 #endif
-   uintptr_t exc;
+   uintptr_t exc, exc_base;
 #if defined(ALTIVEC) || defined(PPC_OEA)
    register_t scratch;
 #endif
@@ -138,6 +138,11 @@
    size_t size;
    struct cpu_info * const ci = &cpu_info[0];
 
+#ifdef PPC_HIGH_VEC
+   exc_base = EXC_HIGHVEC;
+#else
+   exc_base = 0;
+#endif
    mtspr(SPR_SPRG0, ci);
    cpuvers = mfpvr() >> 16;
 
@@ -180,8 +185,8 @@
    /*
     * Set up trap vectors.  Don't assume vectors are on 0x100.
     */
-   for (exc = 0x0; exc <= EXC_LAST; exc += 0x100) {
-       switch (exc) {
+   for (exc = exc_base; exc <= exc_base + EXC_LAST; exc += 0x100) {
+       switch (exc - exc_base) {
        default:
            size = (size_t)trapsize;
            memcpy((void *)exc, trapcode, size);
@@ -195,48 +200,48 @@
 #endif
        case EXC_SC:
            size = (size_t)scsize;
-           memcpy((void *)EXC_SC, sctrap, size);
+           memcpy((void *)exc, sctrap, size);
            break;
        case EXC_ALI:
            size = (size_t)alisize;
-           memcpy((void *)EXC_ALI, alitrap, size);
+           memcpy((void *)exc, alitrap, size);
            break;
        case EXC_DSI:
 #ifdef PPC_OEA601
            if (cpuvers == MPC601) {
                size = (size_t)dsi601size;
-               memcpy((void *)EXC_DSI, dsi601trap, size);
+               memcpy((void *)exc, dsi601trap, size);
                break;
            } else
 #endif /* PPC_OEA601 */
            if (oeacpufeat & OEACPU_NOBAT) {
                size = (size_t)alisize;
-               memcpy((void *)EXC_DSI, alitrap, size);
+               memcpy((void *)exc, alitrap, size);
            } else {
                size = (size_t)dsisize;
-               memcpy((void *)EXC_DSI, dsitrap, size);
+               memcpy((void *)exc, dsitrap, size);
            }
            break;
        case EXC_DECR:
            size = (size_t)decrsize;
-           memcpy((void *)EXC_DECR, decrint, size);
+           memcpy((void *)exc, decrint, size);
            break;
        case EXC_IMISS:
            size = (size_t)tlbimsize;
-           memcpy((void *)EXC_IMISS, tlbimiss, size);
+           memcpy((void *)exc, tlbimiss, size);
            break;
        case EXC_DLMISS:
            size = (size_t)tlbdlmsize;
-           memcpy((void *)EXC_DLMISS, tlbdlmiss, size);
+           memcpy((void *)exc, tlbdlmiss, size);
            break;
        case EXC_DSMISS:
            size = (size_t)tlbdsmsize;
-           memcpy((void *)EXC_DSMISS, tlbdsmiss, size);
+           memcpy((void *)exc, tlbdsmiss, size);
            break;
        case EXC_PERF:
            size = (size_t)trapsize;
-           memcpy((void *)EXC_PERF, trapcode, size);
-           memcpy((void *)EXC_VEC,  trapcode, size);
+           memcpy((void *)exc, trapcode, size);
+           memcpy((void *)(exc_base + EXC_VEC),  trapcode, size);
            break;
 #if defined(DDB) || defined(IPKDB) || defined(KGDB)
        case EXC_RUNMODETRC:
@@ -244,7 +249,7 @@
            if (cpuvers != MPC601) {
 #endif
                size = (size_t)trapsize;
-               memcpy((void *)EXC_RUNMODETRC, trapcode, size);
+               memcpy((void *)exc, trapcode, size);
                break;
 #ifdef PPC_OEA601
            }
@@ -274,8 +279,10 @@
    /*
     * Install a branch absolute to trap0 to force a panic.
     */
-   *(uint32_t *) 0 = 0x7c6802a6;
-   *(uint32_t *) 4 = 0x48000002 | (uintptr_t) trap0;
+   if ((uintptr_t)trap0 < 0x2000000) {
+       *(uint32_t *) 0 = 0x7c6802a6;
+       *(uint32_t *) 4 = 0x48000002 | (uintptr_t) trap0;
+   }
 
    /*
     * Get the cache sizes because install_extint calls __syncicache.
@@ -395,6 +402,9 @@
    if (cpu_altivec)
        cpu_pslusermod |= PSL_VEC;
 #endif
+#ifdef PPC_HIGH_VEC
+   cpu_psluserset |= PSL_IP;   /* XXX ok? */
+#endif
 
    /*
     * external interrupt handler install
@@ -402,7 +412,7 @@
    if (handler)
        oea_install_extint(handler);
 
-   __syncicache(0, EXC_LAST + 0x100);
+   __syncicache((void *)exc_base, EXC_LAST + 0x100);
 
    /*
     * Now enable translation (and machine checks/recoverable interrupts).
@@ -692,9 +702,14 @@
        :   "=r" (omsr), "=r" (msr)
        :   "K" ((u_short)~PSL_EE));
    extint_call[0] = (extint_call[0] & 0xfc000003) | offset;
-   memcpy((void *)EXC_EXI, extint, (size_t)extsize);
    __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);
+#endif
    __asm volatile ("mtmsr %0" :: "r"(omsr));
 }
 
--- powerpc/powerpc/CVS/Base/trap_subr.S    2008-05-22 11:43:38.000000000 +0200
+++ powerpc/powerpc/trap_subr.S 2008-05-22 12:48:09.000000000 +0200
@@ -173,7 +173,14 @@
 /* Test whether we already had PR set */
    mfsrr1  %r31
    mtcr    %r31
+#if defined(DISTANT_KERNEL)
+   lis %r31,s_trap@ha
+   addi    %r31,%r31,s_trap@l
+   mtlr    %r31
+   blrl
+#else
    bla s_trap
+#endif
 _C_LABEL(trapsize) = .-_C_LABEL(trapcode)
 
 /*
@@ -199,7 +206,14 @@
 /* Test whether we already had PR set */
    mfsrr1  %r31
    mtcr    %r31
+#if defined(DISTANT_KERNEL)
+   lis %r31,s_trap@ha
+   addi    %r31,%r31,s_trap@l
+   mtlr    %r31
+   blrl
+#else
    bla s_trap
+#endif
 _C_LABEL(alisize) = .-_C_LABEL(alitrap)
 
 /*
@@ -259,7 +273,14 @@
 1:
    mflr    %r28            /* save LR */
    mtsprg1 %r1         /* save SP */
+#if defined(DISTANT_KERNEL)
+   lis %r31,disitrap@ha
+   addi    %r31,%r31,disitrap@l
+   mtlr    %r31
+   blrl
+#else
    bla disitrap
+#endif
 _C_LABEL(dsisize) = .-_C_LABEL(dsitrap)
 
 #if defined(PPC_OEA601)
@@ -321,7 +342,14 @@
 1:
    mflr    %r28            /* save LR */
    mtsprg1 %r1
+#if defined(DISTANT_KERNEL)
+   lis %r31,disitrap@ha
+   addi    %r31,%r31,disitrap@l
+   mtlr    %r31
+   blrl
+#else
    bla disitrap
+#endif
 _C_LABEL(dsi601size) = .-_C_LABEL(dsi601trap)
 #endif /* defined(PPC_OEA601) */
 
@@ -347,7 +375,14 @@
    beq 1f
    mfsprg1 %r1         /* yes, get old SP */
 1:
+#if defined(DISTANT_KERNEL)
+   lis %r31,extintr@ha
+   addi    %r31,%r31,extintr@l
+   mtlr    %r31
+   blr
+#else
    ba  extintr
+#endif
 _C_LABEL(extsize) = .-_C_LABEL(extint)
 
 /*
@@ -372,7 +407,14 @@
    beq 1f
    mfsprg1 %r1         /* yes, get old SP */
 1:
+#if defined(DISTANT_KERNEL)
+   lis %r31,decrintr@ha
+   addi    %r31,%r31,decrintr@l
+   mtlr    %r31
+   blr
+#else
    ba  decrintr
+#endif
 _C_LABEL(decrsize) = .-_C_LABEL(decrint)
 
 #if !defined(PPC_OEA64)
@@ -435,7 +477,11 @@
    mtcrf   0x80,%r3        /* restore cr0 */
    mtmsr   %r0         /* now with native gprs */
    isync
+#if defined(PPC_HIGH_VEC)
+   ba  EXC_HIGHVEC+EXC_ISI
+#else
    ba  EXC_ISI
+#endif
 _C_LABEL(tlbimsize) = .-_C_LABEL(tlbimiss)
 
 /* LINTSTUB: Var: int tlbdlmiss[1], tlbdlmsize[1]; */
@@ -487,7 +533,11 @@
    mtcrf   0x80,%r3        /* restore cr0 */
    mtmsr   %r0         /* now with native gprs */
    isync
+#if defined(PPC_HIGH_VEC)
+   ba  EXC_HIGHVEC+EXC_DSI
+#else
    ba  EXC_DSI
+#endif
 _C_LABEL(tlbdlmsize) = .-_C_LABEL(tlbdlmiss)
 
 /* LINTSTUB: Var: int tlbdsmiss[1], tlbdsmsize[1]; */
@@ -565,7 +615,11 @@
    mtcrf   0x80,%r3        /* restore cr0 */
    mtmsr   %r0         /* now with native gprs */
    isync
+#if defined(PPC_HIGH_VEC)
+   ba  EXC_HIGHVEC+EXC_DSI
+#else
    ba  EXC_DSI
+#endif
 _C_LABEL(tlbdsmsize) = .-_C_LABEL(tlbdsmiss)
 #endif /* !defined(PPC_OEA64) */
 
@@ -592,7 +646,14 @@
    streg   %r30,(CI_TEMPSAVE+CPUSAVE_R30)(%r1) /* free r30 */
    streg   %r31,(CI_TEMPSAVE+CPUSAVE_R31)(%r1) /* free r31 */
    mflr    %r28            /* save LR */
+#if defined(DISTANT_KERNEL)
+   lis %r31,u_trap@ha
+   addi    %r31,%r31,u_trap@l
+   mtlr    %r31
+   blrl
+#else
    bla u_trap
+#endif
 1:
    streg   %r28,(CI_DDBSAVE+CPUSAVE_R28)(%r1) /* save r28 */
    mfsprg2 %r28
@@ -602,11 +663,20 @@
    mflr    %r28            /* save LR */
    lis %r1,ddbstk+INTSTK@ha    /* get new SP */
    addi    %r1,%r1,ddbstk+INTSTK@l
+#if defined(DISTANT_KERNEL)
+   lis %r31,ddbtrap@ha
+   addi    %r31,%r31,ddbtrap@l
+   mtlr    %r31
+   blrl
+#else
    bla ddbtrap
+#endif
 _C_LABEL(ddbsize) = .-_C_LABEL(ddblow)
 #endif /* DDB || KGDB */
 
-#ifdef IPKDB
+#if defined(IPKDB) && !defined(DISTANT_KERNEL)
+/* IPKDB doesn't work together with DISTANT_KERNEL at the moment! */
+
 #define    ipkdbsave   0xde0       /* primary save area for IPKDB */
 /*
  * In case of IPKDB we want a separate trap catcher for it
@@ -628,7 +698,14 @@
    mfcr    %r29            /* save CR */
    lis %r1,ipkdbstk+INTSTK@ha  /* get new SP */
    addi    %r1,%r1,ipkdbstk+INTSTK@l
+#if defined(DISTANT_KERNEL)
+   lis %r31,ipkdbtrap@ha
+   addi    %r31,%r31,ipkdbtrap@l
+   mtlr    %r31
+   blrl
+#else
    bla ipkdbtrap
+#endif
 _C_LABEL(ipkdbsize) = .-_C_LABEL(ipkdblow)
 #endif /* IPKDB */
 
@@ -906,7 +983,14 @@
    streg   %r31,(CI_TEMPSAVE+CPUSAVE_R31)(%r1) /* save r31 */
    mflr    %r28            /* save LR */
    mfcr    %r29            /* save CR */
+#if defined(DISTANT_KERNEL)
+   lis %r31,s_sctrap@ha
+   addi    %r31,%r31,s_sctrap@l
+   mtlr    %r31
+   blrl
+#else
    bla s_sctrap
+#endif
    _C_LABEL(scsize) = .-_C_LABEL(sctrap)
 
 s_sctrap:
@@ -1131,7 +1215,7 @@
    RFI
 #endif /* DDB || KGDB */
 
-#ifdef IPKDB
+#if defined(IPKDB) && !defined(DISTANT_KERNEL)
 /*
  * Deliberate entry to ipkdbtrap
  */


-- 
    _  Frank Wille (frank%phoenix.owl.de@localhost)
 _ //  http://sun.hasenbraten.de/~frank/
 \X/   Phx @ #AmigaGer



Home | Main Index | Thread Index | Old Index