Module Name: src
Committed By: matt
Date: Wed Feb 1 05:25:58 UTC 2012
Modified Files:
src/sys/arch/powerpc/include/oea: bat.h spr.h
src/sys/arch/powerpc/oea: cpu_subr.c genassym.cf oea_machdep.c
ofw_rascons.c pmap.c
src/sys/arch/powerpc/powerpc: bus_space.c db_interface.c trap_subr.S
Log Message:
Enable XBSEN and HIGHBAT for OEA 7455 and related CPUs.
The BAT entries now have a resolution of 8MB. (Adjacent entries are merged
up to a total of 2GB per entry).
To generate a diff of this commit:
cvs rdiff -u -r1.14 -r1.15 src/sys/arch/powerpc/include/oea/bat.h
cvs rdiff -u -r1.1 -r1.2 src/sys/arch/powerpc/include/oea/spr.h
cvs rdiff -u -r1.71 -r1.72 src/sys/arch/powerpc/oea/cpu_subr.c
cvs rdiff -u -r1.25 -r1.26 src/sys/arch/powerpc/oea/genassym.cf
cvs rdiff -u -r1.60 -r1.61 src/sys/arch/powerpc/oea/oea_machdep.c
cvs rdiff -u -r1.6 -r1.7 src/sys/arch/powerpc/oea/ofw_rascons.c
cvs rdiff -u -r1.82 -r1.83 src/sys/arch/powerpc/oea/pmap.c
cvs rdiff -u -r1.30 -r1.31 src/sys/arch/powerpc/powerpc/bus_space.c
cvs rdiff -u -r1.48 -r1.49 src/sys/arch/powerpc/powerpc/db_interface.c
cvs rdiff -u -r1.72 -r1.73 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/include/oea/bat.h
diff -u src/sys/arch/powerpc/include/oea/bat.h:1.14 src/sys/arch/powerpc/include/oea/bat.h:1.15
--- src/sys/arch/powerpc/include/oea/bat.h:1.14 Mon Jun 20 06:04:33 2011
+++ src/sys/arch/powerpc/include/oea/bat.h Wed Feb 1 05:25:57 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: bat.h,v 1.14 2011/06/20 06:04:33 matt Exp $ */
+/* $NetBSD: bat.h,v 1.15 2012/02/01 05:25:57 matt Exp $ */
/*-
* Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -126,6 +126,8 @@ struct bat {
#define BAT_BL_2G 0x0000fffc
#define BAT_BL_4G 0x0001fffc
+#define BAT_BL_TO_SIZE(bl) (((bl)+4) << 15)
+
#define BATU(va, len, v) \
(((va) & BAT_EPI) | ((len) & BAT_BL) | ((v) & BAT_V))
@@ -196,7 +198,8 @@ struct bat {
#define BAT601_VALID_P(batl) \
((batl) & BAT601_V)
-#define BAT_VA2IDX(va) ((va) >> ADDR_SR_SHFT)
+#define BAT_VA2IDX(va) ((va) / (8*1024*1024))
+#define BAT_IDX2VA(i) ((i) * (8*1024*1024))
#if defined(_KERNEL) && !defined(_LOCORE)
void oea_batinit(paddr_t, ...);
Index: src/sys/arch/powerpc/include/oea/spr.h
diff -u src/sys/arch/powerpc/include/oea/spr.h:1.1 src/sys/arch/powerpc/include/oea/spr.h:1.2
--- src/sys/arch/powerpc/include/oea/spr.h:1.1 Thu Feb 25 23:30:05 2010
+++ src/sys/arch/powerpc/include/oea/spr.h Wed Feb 1 05:25:57 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: spr.h,v 1.1 2010/02/25 23:30:05 matt Exp $ */
+/* $NetBSD: spr.h,v 1.2 2012/02/01 05:25:57 matt Exp $ */
#ifndef _POWERPC_OEA_SPR_H_
#define _POWERPC_OEA_SPR_H_
@@ -108,6 +108,7 @@
#define SPR_DBAT6U 0x23c /* ..6. Data BAT Reg 6 Upper */
#define SPR_DBAT6L 0x23d /* ..6. Data BAT Reg 6 Lower */
#define SPR_DBAT7U 0x23e /* ..6. Data BAT Reg 7 Upper */
+#define SPR_DBAT7L 0x23f /* ..6. Data BAT Reg 7 Upper */
#define SPR_UMMCR2 0x3a0 /* ..6. User Monitor Mode Control Register 2 */
#define SPR_UMMCR0 0x3a8 /* ..6. User Monitor Mode Control Register 0 */
#define SPR_USIA 0x3ab /* ..6. User Sampled Instruction Address */
Index: src/sys/arch/powerpc/oea/cpu_subr.c
diff -u src/sys/arch/powerpc/oea/cpu_subr.c:1.71 src/sys/arch/powerpc/oea/cpu_subr.c:1.72
--- src/sys/arch/powerpc/oea/cpu_subr.c:1.71 Mon Jan 23 16:22:57 2012
+++ src/sys/arch/powerpc/oea/cpu_subr.c Wed Feb 1 05:25:57 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: cpu_subr.c,v 1.71 2012/01/23 16:22:57 phx Exp $ */
+/* $NetBSD: cpu_subr.c,v 1.72 2012/02/01 05:25:57 matt Exp $ */
/*-
* Copyright (c) 2001 Matt Thomas.
@@ -34,7 +34,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cpu_subr.c,v 1.71 2012/01/23 16:22:57 phx Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cpu_subr.c,v 1.72 2012/02/01 05:25:57 matt Exp $");
#include "opt_ppcparam.h"
#include "opt_multiprocessor.h"
@@ -269,17 +269,27 @@ cpu_model_init(void)
oeacpufeat = 0;
if ((vers >= IBMRS64II && vers <= IBM970GX) || vers == MPC620 ||
- vers == IBMCELL || vers == IBMPOWER6P5)
- oeacpufeat |= OEACPU_64 | OEACPU_64_BRIDGE | OEACPU_NOBAT;
+ vers == IBMCELL || vers == IBMPOWER6P5) {
+ oeacpufeat |= OEACPU_64;
+ oeacpufeat |= OEACPU_64_BRIDGE;
+ oeacpufeat |= OEACPU_NOBAT;
- else if (vers == MPC601)
+ } else if (vers == MPC601) {
oeacpufeat |= OEACPU_601;
- else if (MPC745X_P(vers) && vers != MPC7450)
- oeacpufeat |= OEACPU_XBSEN | OEACPU_HIGHBAT | OEACPU_HIGHSPRG;
+ } else if (MPC745X_P(vers) && vers != MPC7450) {
+ oeacpufeat |= OEACPU_HIGHSPRG;
+ oeacpufeat |= OEACPU_XBSEN;
+ oeacpufeat |= OEACPU_HIGHBAT;
+ /* Enable more and larger BAT registers */
+ register_t hid0 = mfspr(SPR_HID0);
+ hid0 |= HID0_XBSEN;
+ hid0 |= HID0_HIGH_BAT_EN;
+ mtspr(SPR_HID0, hid0);
- else if (vers == IBM750FX || vers == IBM750GX)
+ } else if (vers == IBM750FX || vers == IBM750GX) {
oeacpufeat |= OEACPU_HIGHBAT;
+ }
}
void
@@ -525,11 +535,6 @@ cpu_setup(device_t self, struct cpu_info
/* Enable the 7450 branch caches */
hid0 |= HID0_SGE | HID0_BTIC;
hid0 |= HID0_LRSTK | HID0_FOLD | HID0_BHT;
- /* Enable more and larger BAT registers */
- if (oeacpufeat & OEACPU_XBSEN)
- hid0 |= HID0_XBSEN;
- if (oeacpufeat & OEACPU_HIGHBAT)
- hid0 |= HID0_HIGH_BAT_EN;
/* Disable BTIC on 7450 Rev 2.0 or earlier */
if (vers == MPC7450 && (pvr & 0xFFFF) <= 0x0200)
hid0 &= ~HID0_BTIC;
Index: src/sys/arch/powerpc/oea/genassym.cf
diff -u src/sys/arch/powerpc/oea/genassym.cf:1.25 src/sys/arch/powerpc/oea/genassym.cf:1.26
--- src/sys/arch/powerpc/oea/genassym.cf:1.25 Mon Jun 20 19:56:12 2011
+++ src/sys/arch/powerpc/oea/genassym.cf Wed Feb 1 05:25:57 2012
@@ -1,4 +1,4 @@
-# $NetBSD: genassym.cf,v 1.25 2011/06/20 19:56:12 matt Exp $
+# $NetBSD: genassym.cf,v 1.26 2012/02/01 05:25:57 matt Exp $
#
# Copyright (C) 1995, 1996 Wolfgang Solfrank.
@@ -46,6 +46,7 @@ include <machine/pcb.h>
include <machine/pmap.h>
include <powerpc/cpu.h>
+include <powerpc/oea/bat.h>
include <powerpc/oea/cpufeat.h>
define FRAME_DAR offsetof(struct ktrapframe, ktf_tf.tf_dar)
@@ -85,6 +86,8 @@ define OEACPU_601 OEACPU_601
define OEACPU_HIGHSPRG OEACPU_HIGHSPRG
define OEACPU_ALTIVEC OEACPU_ALTIVEC
+define BAT_ADDR_SHIFT ilog2(BAT_IDX2VA(1))
+
define PTE_REF PTE_REF
define PTE_CHG PTE_CHG
define PTE_HID PTE_HID
Index: src/sys/arch/powerpc/oea/oea_machdep.c
diff -u src/sys/arch/powerpc/oea/oea_machdep.c:1.60 src/sys/arch/powerpc/oea/oea_machdep.c:1.61
--- src/sys/arch/powerpc/oea/oea_machdep.c:1.60 Sun Jul 17 20:54:46 2011
+++ src/sys/arch/powerpc/oea/oea_machdep.c Wed Feb 1 05:25:57 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: oea_machdep.c,v 1.60 2011/07/17 20:54:46 joerg Exp $ */
+/* $NetBSD: oea_machdep.c,v 1.61 2012/02/01 05:25:57 matt Exp $ */
/*
* Copyright (C) 2002 Matt Thomas
@@ -33,7 +33,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: oea_machdep.c,v 1.60 2011/07/17 20:54:46 joerg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: oea_machdep.c,v 1.61 2012/02/01 05:25:57 matt Exp $");
#include "opt_ppcarch.h"
#include "opt_compat_netbsd.h"
@@ -81,10 +81,10 @@ __KERNEL_RCSID(0, "$NetBSD: oea_machdep.
#include <powerpc/altivec.h>
#include <powerpc/pcb.h>
-#include <powerpc/oea/spr.h>
#include <powerpc/oea/bat.h>
-#include <powerpc/oea/sr_601.h>
#include <powerpc/oea/cpufeat.h>
+#include <powerpc/oea/spr.h>
+#include <powerpc/oea/sr_601.h>
char machine[] = MACHINE; /* from <machine/param.h> */
char machine_arch[] = MACHINE_ARCH; /* from <machine/param.h> */
@@ -97,13 +97,18 @@ struct vm_map *phys_map = NULL;
static void trap0(void *);
/* XXXSL: The battable is not initialized to non-zero for PPC_OEA64 and PPC_OEA64_BRIDGE */
-struct bat battable[512];
+struct bat battable[BAT_VA2IDX(0xffffffff)+1];
register_t iosrtable[16]; /* I/O segments, for kernel_pmap setup */
#ifndef MSGBUFADDR
paddr_t msgbuf_paddr;
#endif
+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))
{
@@ -362,6 +367,8 @@ oea_init(void (*handler)(void))
*/
__syncicache((void *) trapstart,
(uintptr_t) trapend - (uintptr_t) trapstart);
+ __syncicache(dsitrap_fix_dbat4, 16);
+ __syncicache(dsitrap_fix_dbat7, 8);
#ifdef PPC_OEA601
/*
@@ -449,35 +456,69 @@ mpc601_ioseg_add(paddr_t pa, register_t
#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 n = 1;
- const u_int i = pa >> 28;
- battable[i].batl = BATL(pa, BAT_I|BAT_G, BAT_PP_RW);
- battable[i].batu = BATU(pa, len, BAT_Vs);
+ static int z = 1;
+ 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);
+
+ 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].batl = batl;
+ battable[i + j].batu = batu;
+ }
/*
* Let's start loading the BAT registers.
*/
- switch (n) {
+ switch (z) {
case 1:
- __asm volatile ("mtdbatl 1,%0; mtdbatu 1,%1;"
- :: "r"(battable[i].batl),
- "r"(battable[i].batu));
- n = 2;
+ 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));
- n = 3;
+ 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));
- n = 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;
@@ -487,38 +528,63 @@ oea_iobat_add(paddr_t pa, register_t len
void
oea_iobat_remove(paddr_t pa)
{
- register_t batu;
- int i, n;
+ const u_int i = BAT_VA2IDX(pa);
- n = pa >> ADDR_SR_SHFT;
- if (!BAT_VA_MATCH_P(battable[n].batu, pa) ||
- !BAT_VALID_P(battable[n].batu, PSL_PR))
+ if (!BAT_VA_MATCH_P(battable[i].batu, pa) ||
+ !BAT_VALID_P(battable[i].batu, PSL_PR))
return;
- battable[n].batl = 0;
- battable[n].batu = 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 (i=1 ; i<4 ; i++) {
- switch (i) {
+ const int n =
+ __SHIFTOUT(battable[i].batu, (BAT_XBL|BAT_BL) & ~BAT_BL_8M) + 1;
+ KASSERT((n & (n-1)) == 0); /* power of 2 */
+ KASSERT((i & (n-1)) == 0); /* multiple of n */
+
+ memset(&battable[i], 0, n*sizeof(battable[0]));
+
+ 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))
- BAT_RESET(3);
+ 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))
+ 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;
@@ -558,14 +624,46 @@ oea_batinit(paddr_t pa, ...)
} 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 to load dbat4 instead of dbat2
+ */
+ dsitrap_fix_dbat4[2] = 0x7fd88ba6;
+ dsitrap_fix_dbat4[3] = 0x7ff98ba6;
+
+ /*
+ * Change it to load dbat7 instead of dbat3
+ */
+ dsitrap_fix_dbat7[0] = 0x7fde8ba6;
+ dsitrap_fix_dbat7[1] = 0x7fff8ba6;
+ }
}
}
@@ -599,19 +697,8 @@ oea_batinit(paddr_t pa, ...)
__asm volatile ("mtibatu 3,%1; mtibatl 3,%0"
:: "r"(battable[0x01800000 >> 23].batl),
"r"(battable[0x01800000 >> 23].batu));
- } else
-#endif /* PPC_OEA601 */
- {
- /*
- * Set up BAT0 to only map the lowest 256 MB area
- */
- battable[0].batl = BATL(0x00000000, BAT_M, BAT_PP_RW);
- battable[0].batu = BATU(0x00000000, BAT_BL_256M, BAT_Vs);
-
- __asm volatile ("mtibatl 0,%0; mtibatu 0,%1;"
- "mtdbatl 0,%0; mtdbatu 0,%1;"
- :: "r"(battable[0].batl), "r"(battable[0].batu));
}
+#endif /* PPC_OEA601 */
/*
* Now setup other fixed bat registers
@@ -669,20 +756,55 @@ oea_batinit(paddr_t pa, ...)
} else
#endif
{
+ const register_t bat_inc = BAT_IDX2VA(1);
for (mp = allmem; mp->size; mp++) {
- paddr_t paddr = mp->start & 0xf0000000;
- paddr_t end = mp->start + mp->size;
+ paddr_t paddr = mp->start & -bat_inc;
+ paddr_t end = roundup2(mp->start + mp->size, bat_inc);
- do {
- u_int ix = paddr >> 28;
+ /*
+ * If the next entries are adjacent, merge them
+ * into this one
+ */
+ while (mp[1].size && end == (mp[1].start & -bat_inc)) {
+ mp++;
+ end = roundup2(mp->start + mp->size, bat_inc);
+ }
- battable[ix].batl =
- BATL(paddr, BAT_M, BAT_PP_RW);
- battable[ix].batu =
- BATU(paddr, BAT_BL_256M, BAT_Vs);
- paddr += SEGMENT_LENGTH;
- } while (paddr < end);
+ while (paddr < end) {
+ register_t bl = (oeacpufeat & OEACPU_XBSEN
+ ? BAT_BL_2G
+ : BAT_BL_256M);
+ psize_t size = BAT_BL_TO_SIZE(bl);
+ u_int n = BAT_VA2IDX(size);
+ u_int i = BAT_VA2IDX(paddr);
+
+ while ((paddr & (size - 1))
+ || paddr + size > end) {
+ size >>= 1;
+ bl = (bl >> 1) & (BAT_XBL|BAT_BL);
+ n >>= 1;
+ }
+
+ KASSERT(size >= bat_inc);
+ KASSERT(n >= 1);
+ KASSERT(bl >= BAT_BL_8M);
+
+ register_t batl = BATL(paddr, BAT_M, BAT_PP_RW);
+ register_t batu = BATU(paddr, bl, BAT_Vs);
+
+ for (; n-- > 0; i++) {
+ battable[i].batl = batl;
+ battable[i].batu = batu;
+ }
+ paddr += size;
+ }
}
+ /*
+ * Set up BAT0 to only map the lowest area.
+ */
+ __asm volatile ("mtibatl 0,%0; mtibatu 0,%1;"
+ "mtdbatl 0,%0; mtdbatu 0,%1;"
+ :: "r"(battable[0].batl), "r"(battable[0].batu));
}
}
#endif /* PPC_OEA || PPC_OEA64_BRIDGE */
Index: src/sys/arch/powerpc/oea/ofw_rascons.c
diff -u src/sys/arch/powerpc/oea/ofw_rascons.c:1.6 src/sys/arch/powerpc/oea/ofw_rascons.c:1.7
--- src/sys/arch/powerpc/oea/ofw_rascons.c:1.6 Fri Jul 1 18:59:19 2011
+++ src/sys/arch/powerpc/oea/ofw_rascons.c Wed Feb 1 05:25:57 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: ofw_rascons.c,v 1.6 2011/07/01 18:59:19 dyoung Exp $ */
+/* $NetBSD: ofw_rascons.c,v 1.7 2012/02/01 05:25:57 matt Exp $ */
/*
* Copyright (c) 1995, 1996 Carnegie-Mellon University.
@@ -28,7 +28,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ofw_rascons.c,v 1.6 2011/07/01 18:59:19 dyoung Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ofw_rascons.c,v 1.7 2012/02/01 05:25:57 matt Exp $");
#include <sys/param.h>
#include <sys/buf.h>
@@ -199,17 +199,27 @@ rascons_init_rasops(int node, struct ras
if (rascons_enable_cache) {
vaddr_t va;
/*
- * Let's try to find an empty BAT to use
+ * Let's try to find an empty 256M BAT to use
*/
for (va = SEGMENT_LENGTH; va < (USER_SR << ADDR_SR_SHFT);
va += SEGMENT_LENGTH) {
- if (battable[va >> ADDR_SR_SHFT].batu == 0) {
- battable[va >> ADDR_SR_SHFT].batl =
- BATL(fbaddr & 0xf0000000,
- BAT_G | BAT_W | BAT_M, BAT_PP_RW);
- battable[va >> ADDR_SR_SHFT].batu =
- BATL(va, BAT_BL_256M, BAT_Vs);
- fbaddr &= 0x0fffffff;
+ const u_int i = BAT_VA2IDX(va);
+ const u_int n = BAT_VA2IDX(SEGMENT_LENGTH);
+ u_int j;
+ for (j = 0; j < n; j++) {
+ if (battable[i+j].batu != 0) {
+ break;
+ }
+ }
+ if (j == n) {
+ register_t batl = BATL(fbaddr & 0xf0000000,
+ BAT_G | BAT_W | BAT_M, BAT_PP_RW);
+ register_t batu = BATL(va, BAT_BL_256M, BAT_Vs);
+ for (j = 0; j < n; j++) {
+ battable[i+j].batl = batl;
+ battable[i+j].batu = batu;
+ }
+ fbaddr &= SEGMENT_MASK;
fbaddr |= va;
break;
}
Index: src/sys/arch/powerpc/oea/pmap.c
diff -u src/sys/arch/powerpc/oea/pmap.c:1.82 src/sys/arch/powerpc/oea/pmap.c:1.83
--- src/sys/arch/powerpc/oea/pmap.c:1.82 Sun Jul 17 20:54:46 2011
+++ src/sys/arch/powerpc/oea/pmap.c Wed Feb 1 05:25:57 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: pmap.c,v 1.82 2011/07/17 20:54:46 joerg Exp $ */
+/* $NetBSD: pmap.c,v 1.83 2012/02/01 05:25:57 matt Exp $ */
/*-
* Copyright (c) 2001 The NetBSD Foundation, Inc.
* All rights reserved.
@@ -63,7 +63,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.82 2011/07/17 20:54:46 joerg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.83 2012/02/01 05:25:57 matt Exp $");
#define PMAP_NOOPNAMES
@@ -2131,12 +2131,11 @@ pmap_extract(pmap_t pm, vaddr_t va, padd
} else
#endif /* PPC_OEA601 */
{
- register_t batu = battable[va >> ADDR_SR_SHFT].batu;
+ register_t batu = battable[BAT_VA2IDX(va)].batu;
if (BAT_VALID_P(batu,0) && BAT_VA_MATCH_P(batu,va)) {
- register_t batl =
- battable[va >> ADDR_SR_SHFT].batl;
+ register_t batl = battable[BAT_VA2IDX(va)].batl;
register_t mask =
- (~(batu & BAT_BL) << 15) & ~0x1ffffL;
+ (~(batu & (BAT_XBL|BAT_BL)) << 15) & ~0x1ffffL;
if (pap)
*pap = (batl & mask) | (va & ~mask);
PMAP_UNLOCK();
Index: src/sys/arch/powerpc/powerpc/bus_space.c
diff -u src/sys/arch/powerpc/powerpc/bus_space.c:1.30 src/sys/arch/powerpc/powerpc/bus_space.c:1.31
--- src/sys/arch/powerpc/powerpc/bus_space.c:1.30 Fri Jan 27 18:53:00 2012
+++ src/sys/arch/powerpc/powerpc/bus_space.c Wed Feb 1 05:25:58 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: bus_space.c,v 1.30 2012/01/27 18:53:00 para Exp $ */
+/* $NetBSD: bus_space.c,v 1.31 2012/02/01 05:25:58 matt Exp $ */
/*-
* Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc.
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: bus_space.c,v 1.30 2012/01/27 18:53:00 para Exp $");
+__KERNEL_RCSID(0, "$NetBSD: bus_space.c,v 1.31 2012/02/01 05:25:58 matt Exp $");
#define _POWERPC_BUS_SPACE_PRIVATE
@@ -550,20 +550,21 @@ memio_map(bus_space_tag_t t, bus_addr_t
*/
if (extent_flags) {
#endif
- /*
- * Before we go any further, let's make sure that this
- * region is available.
- */
- error = extent_alloc_region(t->pbs_extent, bpa, size,
- EX_NOWAIT | extent_flags);
- if (error) {
+ /*
+ * Before we go any further, let's make sure that this
+ * region is available.
+ */
+ error = extent_alloc_region(t->pbs_extent, bpa, size,
+ EX_NOWAIT | extent_flags);
+ if (error) {
#ifdef DEBUG
- printf("bus_space_map(%p[%x:%x], %#x, %#x) failed"
- ": %d\n",
- t, t->pbs_base, t->pbs_limit, bpa, size, error);
+ printf("bus_space_map(%p[%x:%x], %#x, %#x)"
+ " failed: %d\n",
+ t, t->pbs_base, t->pbs_limit,
+ bpa, size, error);
#endif
- return (error);
- }
+ return (error);
+ }
#ifdef PPC_IBM4XX
}
#endif
@@ -600,14 +601,15 @@ memio_map(bus_space_tag_t t, bus_addr_t
if (t->pbs_extent != NULL) {
#if !defined(PPC_IBM4XX)
- if (extent_flags == 0) {
- extent_free(t->pbs_extent, bpa, size, EX_NOWAIT);
+ if (extent_flags == 0) {
+ extent_free(t->pbs_extent, bpa, size, EX_NOWAIT);
#ifdef DEBUG
- printf("bus_space_map(%p[%x:%x], %#x, %#x) failed: ENOMEM\n",
- t, t->pbs_base, t->pbs_limit, bpa, size);
+ printf("bus_space_map(%p[%x:%x], %#x, %#x)"
+ " failed: ENOMEM\n",
+ t, t->pbs_base, t->pbs_limit, bpa, size);
#endif
- return (ENOMEM);
- }
+ return (ENOMEM);
+ }
#endif
}
@@ -617,7 +619,10 @@ memio_map(bus_space_tag_t t, bus_addr_t
*bshp = (bus_space_handle_t) mapiodev(pa, size,
(flags & BUS_SPACE_MAP_PREFETCHABLE) != 0);
if (*bshp == 0) {
- extent_free(t->pbs_extent, bpa, size, EX_NOWAIT | extent_flags);
+ if (t->pbs_extent != NULL) {
+ extent_free(t->pbs_extent, bpa, size,
+ EX_NOWAIT | extent_flags);
+ }
#ifdef DEBUG
printf("bus_space_map(%p[%x:%x], %#x, %#x) failed: ENOMEM\n",
t, t->pbs_base, t->pbs_limit, bpa, size);
Index: src/sys/arch/powerpc/powerpc/db_interface.c
diff -u src/sys/arch/powerpc/powerpc/db_interface.c:1.48 src/sys/arch/powerpc/powerpc/db_interface.c:1.49
--- src/sys/arch/powerpc/powerpc/db_interface.c:1.48 Tue Dec 13 11:03:52 2011
+++ src/sys/arch/powerpc/powerpc/db_interface.c Wed Feb 1 05:25:58 2012
@@ -1,8 +1,8 @@
-/* $NetBSD: db_interface.c,v 1.48 2011/12/13 11:03:52 kiyohara Exp $ */
+/* $NetBSD: db_interface.c,v 1.49 2012/02/01 05:25:58 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.48 2011/12/13 11:03:52 kiyohara Exp $");
+__KERNEL_RCSID(0, "$NetBSD: db_interface.c,v 1.49 2012/02/01 05:25:58 matt Exp $");
#define USERACC
@@ -26,6 +26,7 @@ __KERNEL_RCSID(0, "$NetBSD: db_interface
#if defined (PPC_OEA) || defined(PPC_OEA64) || defined (PPC_OEA64_BRIDGE)
#include <powerpc/oea/spr.h>
#include <powerpc/oea/bat.h>
+#include <powerpc/oea/cpufeat.h>
#endif
#ifdef PPC_IBM4XX
@@ -249,10 +250,10 @@ kdb_trap(int type, void *v)
static void
print_battranslation(struct bat *bat, unsigned int blidx)
{
- static const char *const batsizes[] = {
- "128kB",
- "256kB",
- "512kB",
+ static const char const batsizes[][6] = {
+ "128KB",
+ "256KB",
+ "512KB",
"1MB",
"2MB",
"4MB",
@@ -261,7 +262,11 @@ print_battranslation(struct bat *bat, un
"32MB",
"64MB",
"128MB",
- "256MB"
+ "256MB",
+ "512MB",
+ "1GB",
+ "2GB",
+ "4GB",
};
vsize_t len;
@@ -305,7 +310,8 @@ print_bat(struct bat *bat)
db_printf("\tdisabled\n\n");
return;
}
- print_battranslation(bat, 30 - __builtin_clz((bat->batu & BAT_BL)|2));
+ print_battranslation(bat,
+ 30 - __builtin_clz((bat->batu & (BAT_XBL|BAT_BL))|2));
print_batmodes(bat->batu & BAT_Vs, bat->batu & BAT_Vu,
bat->batl & BAT_PP);
print_wimg(bat->batl & BAT_WIMG);
@@ -331,49 +337,66 @@ print_bat601(struct bat *bat)
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;
+ u_int i;
+ u_int maxbat = (oeacpufeat & OEACPU_HIGHBAT) ? 8 : 4;
cpuvers = mfpvr() >> 16;
- __asm volatile ("mfibatu %0,0" : "=r"(ibat[0].batu));
- __asm volatile ("mfibatl %0,0" : "=r"(ibat[0].batl));
- __asm volatile ("mfibatu %0,1" : "=r"(ibat[1].batu));
- __asm volatile ("mfibatl %0,1" : "=r"(ibat[1].batl));
- __asm volatile ("mfibatu %0,2" : "=r"(ibat[2].batu));
- __asm volatile ("mfibatl %0,2" : "=r"(ibat[2].batl));
- __asm volatile ("mfibatu %0,3" : "=r"(ibat[3].batu));
- __asm volatile ("mfibatl %0,3" : "=r"(ibat[3].batl));
+ ibat[0].batu = mfspr(SPR_IBAT0U);
+ ibat[0].batl = mfspr(SPR_IBAT0L);
+ ibat[1].batu = mfspr(SPR_IBAT1U);
+ ibat[1].batl = mfspr(SPR_IBAT1L);
+ ibat[2].batu = mfspr(SPR_IBAT2U);
+ ibat[2].batl = mfspr(SPR_IBAT2L);
+ ibat[3].batu = mfspr(SPR_IBAT3U);
+ ibat[3].batl = mfspr(SPR_IBAT3L);
+ 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);
+ }
if (cpuvers != MPC601) {
/* The 601 has only four unified BATs */
- __asm volatile ("mfdbatu %0,0" : "=r"(dbat[0].batu));
- __asm volatile ("mfdbatl %0,0" : "=r"(dbat[0].batl));
- __asm volatile ("mfdbatu %0,1" : "=r"(dbat[1].batu));
- __asm volatile ("mfdbatl %0,1" : "=r"(dbat[1].batl));
- __asm volatile ("mfdbatu %0,2" : "=r"(dbat[2].batu));
- __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));
+ dbat[0].batu = mfspr(SPR_DBAT0U);
+ dbat[0].batl = mfspr(SPR_DBAT0L);
+ dbat[1].batu = mfspr(SPR_DBAT1U);
+ dbat[1].batl = mfspr(SPR_DBAT1L);
+ dbat[2].batu = mfspr(SPR_DBAT2U);
+ dbat[2].batl = mfspr(SPR_DBAT2L);
+ dbat[3].batu = mfspr(SPR_DBAT3U);
+ dbat[3].batl = mfspr(SPR_DBAT3L);
+ if (maxbat == 8) {
+ 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);
+ db_printf("bat[%u]:\n", i);
print_bat601(&ibat[i]);
} else
#endif
{
- db_printf("ibat%d:", i);
+ db_printf("ibat[%u]:\n", i);
print_bat(&ibat[i]);
- }
- }
- if (cpuvers != MPC601) {
- for (i = 0; i < 4; i++) {
- db_printf("dbat%d:", i);
+ db_printf("dbat[%u]:\n", 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.72 src/sys/arch/powerpc/powerpc/trap_subr.S:1.73
--- src/sys/arch/powerpc/powerpc/trap_subr.S:1.72 Tue Dec 13 11:03:51 2011
+++ src/sys/arch/powerpc/powerpc/trap_subr.S Wed Feb 1 05:25:58 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: trap_subr.S,v 1.72 2011/12/13 11:03:51 kiyohara Exp $ */
+/* $NetBSD: trap_subr.S,v 1.73 2012/02/01 05:25:58 matt Exp $ */
/*
* Copyright (C) 1995, 1996 Wolfgang Solfrank.
@@ -238,7 +238,8 @@ _C_LABEL(dsitrap):
mtcr %r31
bt MSR_PR,1f /* branch if PSL_PR is set */
mfdar %r31 /* get fault address */
- rlwinm %r31,%r31,7,25,28 /* get segment * 8 */
+ rlwinm %r31,%r31,3+(32-BAT_ADDR_SHIFT),BAT_ADDR_SHIFT-3,28
+ /* get segment * 8 */
/* get batu */
addis %r31,%r31,_C_LABEL(battable)@ha
@@ -250,15 +251,39 @@ _C_LABEL(dsitrap):
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 */