Module Name: src
Committed By: matt
Date: Fri Jan 28 04:37:25 UTC 2011
Modified Files:
src/sys/arch/powerpc/oea [matt-nb5-pq3]: oea_machdep.c
src/sys/arch/powerpc/powerpc [matt-nb5-pq3]: db_interface.c trap_subr.S
Log Message:
If a CPU has HIGHBAT, then use them. We dynamically change dsitrap to
select between bats 4-7 when HIGHBAT is detected.
To generate a diff of this commit:
cvs rdiff -u -r1.46.18.3 -r1.46.18.4 src/sys/arch/powerpc/oea/oea_machdep.c
cvs rdiff -u -r1.39.42.1 -r1.39.42.2 \
src/sys/arch/powerpc/powerpc/db_interface.c
cvs rdiff -u -r1.65.16.3 -r1.65.16.4 src/sys/arch/powerpc/powerpc/trap_subr.S
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.46.18.3 src/sys/arch/powerpc/oea/oea_machdep.c:1.46.18.4
--- src/sys/arch/powerpc/oea/oea_machdep.c:1.46.18.3 Wed Jan 26 08:52:26 2011
+++ src/sys/arch/powerpc/oea/oea_machdep.c Fri Jan 28 04:37:25 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: oea_machdep.c,v 1.46.18.3 2011/01/26 08:52:26 matt Exp $ */
+/* $NetBSD: oea_machdep.c,v 1.46.18.4 2011/01/28 04:37:25 matt Exp $ */
/*
* Copyright (C) 2002 Matt Thomas
@@ -33,7 +33,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: oea_machdep.c,v 1.46.18.3 2011/01/26 08:52:26 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: oea_machdep.c,v 1.46.18.4 2011/01/28 04:37:25 matt Exp $");
#include "opt_ppcarch.h"
#include "opt_compat_netbsd.h"
@@ -106,6 +106,11 @@
register_t iosrtable[16]; /* I/O segments, for kernel_pmap setup */
paddr_t msgbuf_paddr;
+extern int dsitrap_fix_dbat4[];
+extern int dsitrap_fix_dbat5[];
+extern int dsitrap_fix_dbat6[];
+extern int dsitrap_fix_dbat7[];
+
void
oea_init(void (*handler)(void))
{
@@ -372,6 +377,8 @@
*/
__syncicache((void *) trapstart,
(uintptr_t) trapend - (uintptr_t) trapstart);
+ __syncicache(dsitrap_fix_dbat4, 16);
+ __syncicache(dsitrap_fix_dbat7, 8);
#ifdef PPC_OEA601
/*
@@ -453,19 +460,36 @@
#endif /* PPC_OEA601 */
#if defined (PPC_OEA) || defined (PPC_OEA64_BRIDGE)
+#define DBAT_SET(n, batl, batu) \
+ do { \
+ mtspr(SPR_DBAT##n##L, (batl)); \
+ mtspr(SPR_DBAT##n##U, (batu)); \
+ } while (/*CONSTCOND*/ 0)
+#define DBAT_RESET(n) DBAT_SET(n, 0, 0)
+#define DBATU_GET(n) mfspr(SPR_DBAT##n##U)
+#define IBAT_SET(n, batl, batu) \
+ do { \
+ mtspr(SPR_IBAT##n##L, (batl)); \
+ mtspr(SPR_IBAT##n##U, (batu)); \
+ } while (/*CONSTCOND*/ 0)
+#define IBAT_RESET(n) IBAT_SET(n, 0, 0)
+
void
oea_iobat_add(paddr_t pa, register_t len)
{
static int z = 1;
- const u_int i = BAT_VA2IDX(pa);
const u_int n = __SHIFTOUT(len, (BAT_XBL|BAT_BL) & ~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);
- battable[i].batl = BATL(pa, BAT_I|BAT_G, BAT_PP_RW);
- battable[i].batu = BATU(pa, len, BAT_Vs);
+ const register_t batl = BATL(pa, BAT_I|BAT_G, BAT_PP_RW);
+ const register_t batu = BATU(pa, len, BAT_Vs);
+
for (u_int j = 0; j < n; j++) {
- battable[i + j] = battable[i];
+ battable[i + j].batl = batl;
+ battable[i + j].batu = batu;
}
/*
@@ -473,22 +497,32 @@
*/
switch (z) {
case 1:
- __asm volatile ("mtdbatl 1,%0; mtdbatu 1,%1;"
- :: "r"(battable[i].batl),
- "r"(battable[i].batu));
+ DBAT_SET(1, batl, batu);
z = 2;
break;
case 2:
- __asm volatile ("mtdbatl 2,%0; mtdbatu 2,%1;"
- :: "r"(battable[i].batl),
- "r"(battable[i].batu));
+ DBAT_SET(2, batl, batu);
z = 3;
break;
case 3:
- __asm volatile ("mtdbatl 3,%0; mtdbatu 3,%1;"
- :: "r"(battable[i].batl),
- "r"(battable[i].batu));
- z = 4;
+ DBAT_SET(3, batl, batu);
+ z = after_bat3; /* no highbat, skip to end */
+ break;
+ case 4:
+ DBAT_SET(4, batl, batu);
+ z = 5;
+ break;
+ case 5:
+ DBAT_SET(5, batl, batu);
+ z = 6;
+ break;
+ case 6:
+ DBAT_SET(6, batl, batu);
+ z = 7;
+ break;
+ case 7:
+ DBAT_SET(7, batl, batu);
+ z = 8;
break;
default:
break;
@@ -510,30 +544,51 @@
memset(&battable[i], 0, n*sizeof(battable[0]));
-#define BAT_RESET(n) \
- __asm volatile("mtdbatu %0,%1; mtdbatl %0,%1" :: "n"(n), "r"(0))
-#define BATU_GET(n, r) __asm volatile("mfdbatu %0,%1" : "=r"(r) : "n"(n))
-
- for (u_int k = 1 ; k < 4; k++) {
+ const int maxbat = oeacpufeat & OEACPU_HIGHBAT ? 8 : 4;
+ for (u_int k = 1 ; k < maxbat; k++) {
register_t batu;
switch (k) {
case 1:
- BATU_GET(1, batu);
+ batu = DBATU_GET(1);
if (BAT_VA_MATCH_P(batu, pa) &&
BAT_VALID_P(batu, PSL_PR))
- BAT_RESET(1);
+ DBAT_RESET(1);
break;
case 2:
- BATU_GET(2, batu);
+ batu = DBATU_GET(2);
if (BAT_VA_MATCH_P(batu, pa) &&
BAT_VALID_P(batu, PSL_PR))
- BAT_RESET(2);
+ DBAT_RESET(2);
break;
case 3:
- BATU_GET(3, batu);
+ batu = DBATU_GET(3);
+ if (BAT_VA_MATCH_P(batu, pa) &&
+ BAT_VALID_P(batu, PSL_PR))
+ DBAT_RESET(3);
+ break;
+ case 4:
+ batu = DBATU_GET(4);
+ if (BAT_VA_MATCH_P(batu, pa) &&
+ BAT_VALID_P(batu, PSL_PR))
+ DBAT_RESET(4);
+ break;
+ case 5:
+ batu = DBATU_GET(5);
if (BAT_VA_MATCH_P(batu, pa) &&
BAT_VALID_P(batu, PSL_PR))
- BAT_RESET(3);
+ DBAT_RESET(5);
+ break;
+ case 6:
+ batu = DBATU_GET(6);
+ if (BAT_VA_MATCH_P(batu, pa) &&
+ BAT_VALID_P(batu, PSL_PR))
+ DBAT_RESET(6);
+ break;
+ case 7:
+ batu = DBATU_GET(7);
+ if (BAT_VA_MATCH_P(batu, pa) &&
+ BAT_VALID_P(batu, PSL_PR))
+ DBAT_RESET(7);
break;
default:
break;
@@ -573,14 +628,46 @@
} else
#endif /* PPC_OEA601 */
{
- __asm volatile ("mtibatu 0,%0" :: "r"(0));
- __asm volatile ("mtibatu 1,%0" :: "r"(0));
- __asm volatile ("mtibatu 2,%0" :: "r"(0));
- __asm volatile ("mtibatu 3,%0" :: "r"(0));
- __asm volatile ("mtdbatu 0,%0" :: "r"(0));
- __asm volatile ("mtdbatu 1,%0" :: "r"(0));
- __asm volatile ("mtdbatu 2,%0" :: "r"(0));
- __asm volatile ("mtdbatu 3,%0" :: "r"(0));
+ DBAT_RESET(0); IBAT_RESET(0);
+ DBAT_RESET(1); IBAT_RESET(1);
+ DBAT_RESET(2); IBAT_RESET(2);
+ DBAT_RESET(3); IBAT_RESET(3);
+ if (oeacpufeat & OEACPU_HIGHBAT) {
+ DBAT_RESET(4); IBAT_RESET(4);
+ DBAT_RESET(5); IBAT_RESET(5);
+ DBAT_RESET(6); IBAT_RESET(6);
+ DBAT_RESET(7); IBAT_RESET(7);
+
+ /*
+ * Change the first instruction to branch to
+ * dsitrap_fix_dbat6
+ */
+ dsitrap_fix_dbat4[0] &= ~0xfffc;
+ dsitrap_fix_dbat4[0]
+ += (uintptr_t)dsitrap_fix_dbat6
+ - (uintptr_t)&dsitrap_fix_dbat4[0];
+
+ /*
+ * Change the second instruction to branch to
+ * dsitrap_fix_dbat5 if bit 30 (aka bit 1) is
+ * true.
+ */
+ dsitrap_fix_dbat4[1] = 0x419e0000
+ + (uintptr_t)dsitrap_fix_dbat5
+ - (uintptr_t)&dsitrap_fix_dbat4[1];
+
+ /*
+ * Change it load dbat4 instead of dbat2
+ */
+ dsitrap_fix_dbat4[2] = 0x7fd88ba6;
+ dsitrap_fix_dbat4[3] = 0x7ff98ba6;
+
+ /*
+ * Change it load dbat7 instead of dbat3
+ */
+ dsitrap_fix_dbat7[0] = 0x7fde8ba6;
+ dsitrap_fix_dbat7[1] = 0x7fff8ba6;
+ }
}
}
Index: src/sys/arch/powerpc/powerpc/db_interface.c
diff -u src/sys/arch/powerpc/powerpc/db_interface.c:1.39.42.1 src/sys/arch/powerpc/powerpc/db_interface.c:1.39.42.2
--- src/sys/arch/powerpc/powerpc/db_interface.c:1.39.42.1 Fri Jan 7 02:01:21 2011
+++ src/sys/arch/powerpc/powerpc/db_interface.c Fri Jan 28 04:37:25 2011
@@ -1,8 +1,8 @@
-/* $NetBSD: db_interface.c,v 1.39.42.1 2011/01/07 02:01:21 matt Exp $ */
+/* $NetBSD: db_interface.c,v 1.39.42.2 2011/01/28 04:37:25 matt Exp $ */
/* $OpenBSD: db_interface.c,v 1.2 1996/12/28 06:21:50 rahnds Exp $ */
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: db_interface.c,v 1.39.42.1 2011/01/07 02:01:21 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: db_interface.c,v 1.39.42.2 2011/01/28 04:37:25 matt Exp $");
#define USERACC
@@ -24,6 +24,7 @@
#include <powerpc/pte.h>
#if defined (PPC_OEA) || defined(PPC_OEA64) || defined (PPC_OEA64_BRIDGE)
+#include <powerpc/oea/cpufeat.h>
#include <powerpc/oea/spr.h>
#endif
@@ -314,10 +315,11 @@
static void
db_show_bat(db_expr_t addr, bool have_addr, db_expr_t count, const char *modif)
{
- struct bat ibat[4];
- struct bat dbat[4];
+ struct bat ibat[8];
+ struct bat dbat[8];
unsigned int cpuvers;
int i;
+ const int maxbat = oeacpufeat & OEACPU_HIGHBAT ? 8 : 4;
cpuvers = mfpvr() >> 16;
@@ -340,9 +342,27 @@
__asm volatile ("mfdbatl %0,2" : "=r"(dbat[2].batl));
__asm volatile ("mfdbatu %0,3" : "=r"(dbat[3].batu));
__asm volatile ("mfdbatl %0,3" : "=r"(dbat[3].batl));
+ if (maxbat == 8) {
+ ibat[4].batu = mfspr(SPR_IBAT4U);
+ ibat[4].batl = mfspr(SPR_IBAT4L);
+ ibat[5].batu = mfspr(SPR_IBAT5U);
+ ibat[5].batl = mfspr(SPR_IBAT5L);
+ ibat[6].batu = mfspr(SPR_IBAT6U);
+ ibat[6].batl = mfspr(SPR_IBAT6L);
+ ibat[7].batu = mfspr(SPR_IBAT7U);
+ ibat[7].batl = mfspr(SPR_IBAT7L);
+ dbat[4].batu = mfspr(SPR_DBAT4U);
+ dbat[4].batl = mfspr(SPR_DBAT4L);
+ dbat[5].batu = mfspr(SPR_DBAT5U);
+ dbat[5].batl = mfspr(SPR_DBAT5L);
+ dbat[6].batu = mfspr(SPR_DBAT6U);
+ dbat[6].batl = mfspr(SPR_DBAT6L);
+ dbat[7].batu = mfspr(SPR_DBAT7U);
+ dbat[7].batl = mfspr(SPR_DBAT7L);
+ }
}
- for (i = 0; i < 4; i++) {
+ for (i = 0; i < maxbat; i++) {
#ifdef PPC_OEA601
if (cpuvers == MPC601) {
db_printf("bat%d:", i);
@@ -355,7 +375,7 @@
}
}
if (cpuvers != MPC601) {
- for (i = 0; i < 4; i++) {
+ for (i = 0; i < maxbat; i++) {
db_printf("dbat%d:", i);
print_bat(&dbat[i]);
}
Index: src/sys/arch/powerpc/powerpc/trap_subr.S
diff -u src/sys/arch/powerpc/powerpc/trap_subr.S:1.65.16.3 src/sys/arch/powerpc/powerpc/trap_subr.S:1.65.16.4
--- src/sys/arch/powerpc/powerpc/trap_subr.S:1.65.16.3 Wed Jan 26 08:52:25 2011
+++ src/sys/arch/powerpc/powerpc/trap_subr.S Fri Jan 28 04:37:25 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: trap_subr.S,v 1.65.16.3 2011/01/26 08:52:25 matt Exp $ */
+/* $NetBSD: trap_subr.S,v 1.65.16.4 2011/01/28 04:37:25 matt Exp $ */
/*
* Copyright (C) 1995, 1996 Wolfgang Solfrank.
@@ -251,15 +251,39 @@
ldreg %r31,_C_LABEL(battable)+SZREG@l(%r31)
/* We randomly use the highest two bat registers here */
mftb %r28
- andi. %r28,%r28,1
- bne 2f
- mtdbatu 2,%r30
- mtdbatl 2,%r31
- b 3f
-2:
- mtdbatu 3,%r30
- mtdbatl 3,%r31
+ mtcr %r28
+ .globl dsitrap_fix_dbat4, dsitrap_fix_dbat5
+ .globl dsitrap_fix_dbat6, dsitrap_fix_dbat7
+dsitrap_fix_dbat4:
+ bt 31,3f
+ /*
+ * If we are running on a CPU that has HIGHBAT, these will be replaced
+ * by instructions to test bit 30 (aka bit 1 for normal people) and if
+ * set skip ahead to 5f (4 instructions), follored by instructions to
+ * update BAT4.
+ */
+ mtspr SPR_DBAT2U,%r30 /* bt 30,dsitrap_fix_dbat5 */
+ mtspr SPR_DBAT2L,%r31 /* mtspr SPR_DBAT4U,%r30 */
+ b 8f /* mtspr SPR_DBAT4L,%r31 */
+ b 8f /* do not remove */
+dsitrap_fix_dbat5:
+ mtspr SPR_DBAT5U,%r30
+ mtspr SPR_DBAT5L,%r31
+ b 8f
+dsitrap_fix_dbat6:
+ bt 30,3f
+ mtspr SPR_DBAT6U,%r30
+ mtspr SPR_DBAT6L,%r31
+ b 8f
3:
+dsitrap_fix_dbat7:
+ /*
+ * If we are running on a CPU that has HIGHBAT, these will be replaced
+ * by instructions to update BAT7.
+ */
+ mtspr SPR_DBAT3U,%r30 /* mtspr SPR_DBAT7U,%r30 */
+ mtspr SPR_DBAT3L,%r31 /* mtspr SPR_DBAT7L,%r31 */
+8:
mfsprg2 %r30 /* restore XER */
mtxer %r30
mtcr %r29 /* restore CR */