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 */