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