diff options
author | raj <raj@FreeBSD.org> | 2012-05-30 17:34:40 +0000 |
---|---|---|
committer | raj <raj@FreeBSD.org> | 2012-05-30 17:34:40 +0000 |
commit | 76640cb48b9113f0c84a50175e359b5771b9b5c4 (patch) | |
tree | 5d1ae61614544c1de79b2edcfcab911f167648bb /sys/powerpc/booke | |
parent | 6927a0f2fc97960910acfb0b7aae0d56b45c2859 (diff) | |
download | FreeBSD-src-76640cb48b9113f0c84a50175e359b5771b9b5c4.zip FreeBSD-src-76640cb48b9113f0c84a50175e359b5771b9b5c4.tar.gz |
Extract vendor specific Book-E pieces into separate files and have a common
skeleton (maybe we should kobj-tize this one day).
Note the PPC4xx bit is not connected to the build yet.
Obtained from: AppliedMicro, Semihalf.
Diffstat (limited to 'sys/powerpc/booke')
-rw-r--r-- | sys/powerpc/booke/machdep.c | 46 | ||||
-rw-r--r-- | sys/powerpc/booke/machdep_e500.c | 158 | ||||
-rw-r--r-- | sys/powerpc/booke/machdep_ppc4xx.c | 219 |
3 files changed, 384 insertions, 39 deletions
diff --git a/sys/powerpc/booke/machdep.c b/sys/powerpc/booke/machdep.c index 09377fe..47ce206 100644 --- a/sys/powerpc/booke/machdep.c +++ b/sys/powerpc/booke/machdep.c @@ -1,5 +1,5 @@ /*- - * Copyright (C) 2006 Semihalf, Marian Balakowicz <m8@semihalf.com> + * Copyright (C) 2006-2012 Semihalf * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -129,6 +129,7 @@ __FBSDID("$FreeBSD$"); #include <machine/md_var.h> #include <machine/mmuvar.h> #include <machine/sigframe.h> +#include <machine/machdep.h> #include <machine/metadata.h> #include <machine/platform.h> @@ -138,8 +139,6 @@ __FBSDID("$FreeBSD$"); #include <dev/fdt/fdt_common.h> #include <dev/ofw/openfirm.h> -#include <powerpc/mpc85xx/mpc85xx.h> - #ifdef DDB extern vm_offset_t ksym_start, ksym_end; #endif @@ -158,11 +157,6 @@ extern unsigned char __sbss_start[]; extern unsigned char __sbss_end[]; extern unsigned char _end[]; -extern void dcache_enable(void); -extern void dcache_inval(void); -extern void icache_enable(void); -extern void icache_inval(void); - /* * Bootinfo is passed to us by legacy loaders. Save the address of the * structure to handle backward compatibility. @@ -286,7 +280,6 @@ booke_init(uint32_t arg1, uint32_t arg2) struct pcpu *pc; void *kmdp, *mdp; vm_offset_t dtbp, end; - uint32_t csr; kmdp = NULL; @@ -359,9 +352,9 @@ booke_init(uint32_t arg1, uint32_t arg2) while (1); OF_interpret("perform-fixup", 0); - - /* Initialize TLB1 handling */ - tlb1_init(fdt_immr_pa); + + /* Set up TLB initially */ + booke_init_tlb(fdt_immr_pa); /* Reset Time Base */ mttb(0); @@ -396,10 +389,6 @@ booke_init(uint32_t arg1, uint32_t arg2) debugf(" HID0 = 0x%08x\n", mfspr(SPR_HID0)); debugf(" HID1 = 0x%08x\n", mfspr(SPR_HID1)); debugf(" BUCSR = 0x%08x\n", mfspr(SPR_BUCSR)); - - __asm __volatile("msync; isync"); - csr = ccsr_read4(OCP85XX_L2CTL); - debugf(" L2CTL = 0x%08x\n", csr); #endif debugf(" dtbp = 0x%08x\n", (uint32_t)dtbp); @@ -447,29 +436,8 @@ booke_init(uint32_t arg1, uint32_t arg2) mtmsr(mfmsr() | PSL_ME); isync(); - /* Enable D-cache if applicable */ - csr = mfspr(SPR_L1CSR0); - if ((csr & L1CSR0_DCE) == 0) { - dcache_inval(); - dcache_enable(); - } - - csr = mfspr(SPR_L1CSR0); - if ((boothowto & RB_VERBOSE) != 0 || (csr & L1CSR0_DCE) == 0) - printf("L1 D-cache %sabled\n", - (csr & L1CSR0_DCE) ? "en" : "dis"); - - /* Enable L1 I-cache if applicable. */ - csr = mfspr(SPR_L1CSR1); - if ((csr & L1CSR1_ICE) == 0) { - icache_inval(); - icache_enable(); - } - - csr = mfspr(SPR_L1CSR1); - if ((boothowto & RB_VERBOSE) != 0 || (csr & L1CSR1_ICE) == 0) - printf("L1 I-cache %sabled\n", - (csr & L1CSR1_ICE) ? "en" : "dis"); + /* Enable L1 caches */ + booke_enable_l1_cache(); debugf("%s: SP = 0x%08x\n", __func__, ((uintptr_t)thread0.td_pcb - 16) & ~15); diff --git a/sys/powerpc/booke/machdep_e500.c b/sys/powerpc/booke/machdep_e500.c new file mode 100644 index 0000000..85805a2 --- /dev/null +++ b/sys/powerpc/booke/machdep_e500.c @@ -0,0 +1,158 @@ +/*- + * Copyright (c) 2011-2012 Semihalf. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/types.h> +#include <sys/reboot.h> + +#include <machine/machdep.h> + +#include <dev/fdt/fdt_common.h> + +#include <powerpc/mpc85xx/mpc85xx.h> + +extern void dcache_enable(void); +extern void dcache_inval(void); +extern void icache_enable(void); +extern void icache_inval(void); +extern void l2cache_enable(void); +extern void l2cache_inval(void); + +void +booke_init_tlb(vm_paddr_t fdt_immr_pa) +{ + + /* Initialize TLB1 handling */ + tlb1_init(fdt_immr_pa); +} + +void +booke_enable_l1_cache(void) +{ + uint32_t csr; + + /* Enable D-cache if applicable */ + csr = mfspr(SPR_L1CSR0); + if ((csr & L1CSR0_DCE) == 0) { + dcache_inval(); + dcache_enable(); + } + + csr = mfspr(SPR_L1CSR0); + if ((boothowto & RB_VERBOSE) != 0 || (csr & L1CSR0_DCE) == 0) + printf("L1 D-cache %sabled\n", + (csr & L1CSR0_DCE) ? "en" : "dis"); + + /* Enable L1 I-cache if applicable. */ + csr = mfspr(SPR_L1CSR1); + if ((csr & L1CSR1_ICE) == 0) { + icache_inval(); + icache_enable(); + } + + csr = mfspr(SPR_L1CSR1); + if ((boothowto & RB_VERBOSE) != 0 || (csr & L1CSR1_ICE) == 0) + printf("L1 I-cache %sabled\n", + (csr & L1CSR1_ICE) ? "en" : "dis"); +} + +#if 0 +void +booke_enable_l2_cache(void) +{ + uint32_t csr; + + /* Enable L2 cache on E500mc */ + if ((((mfpvr() >> 16) & 0xFFFF) == FSL_E500mc) || + (((mfpvr() >> 16) & 0xFFFF) == FSL_E5500)) { + csr = mfspr(SPR_L2CSR0); + if ((csr & L2CSR0_L2E) == 0) { + l2cache_inval(); + l2cache_enable(); + } + + csr = mfspr(SPR_L2CSR0); + if ((boothowto & RB_VERBOSE) != 0 || (csr & L2CSR0_L2E) == 0) + printf("L2 cache %sabled\n", + (csr & L2CSR0_L2E) ? "en" : "dis"); + } +} + +void +booke_enable_l3_cache(void) +{ + uint32_t csr, size, ver; + + /* Enable L3 CoreNet Platform Cache (CPC) */ + ver = SVR_VER(mfspr(SPR_SVR)); + if (ver == SVR_P2041 || ver == SVR_P2041E || ver == SVR_P3041 || + ver == SVR_P3041E || ver == SVR_P5020 || ver == SVR_P5020E) { + csr = ccsr_read4(OCP85XX_CPC_CSR0); + if ((csr & OCP85XX_CPC_CSR0_CE) == 0) { + l3cache_inval(); + l3cache_enable(); + } + + csr = ccsr_read4(OCP85XX_CPC_CSR0); + if ((boothowto & RB_VERBOSE) != 0 || + (csr & OCP85XX_CPC_CSR0_CE) == 0) { + size = OCP85XX_CPC_CFG0_SZ_K(ccsr_read4(OCP85XX_CPC_CFG0)); + printf("L3 Corenet Platform Cache: %d KB %sabled\n", + size, (csr & OCP85XX_CPC_CSR0_CE) == 0 ? + "dis" : "en"); + } + } +} + +void +booke_disable_l2_cache(void) +{ +} + +static void +l3cache_inval(void) +{ + + /* Flash invalidate the CPC and clear all the locks */ + ccsr_write4(OCP85XX_CPC_CSR0, OCP85XX_CPC_CSR0_FI | + OCP85XX_CPC_CSR0_LFC); + while (ccsr_read4(OCP85XX_CPC_CSR0) & (OCP85XX_CPC_CSR0_FI | + OCP85XX_CPC_CSR0_LFC)) + ; +} + +static void +l3cache_enable(void) +{ + + ccsr_write4(OCP85XX_CPC_CSR0, OCP85XX_CPC_CSR0_CE | + OCP85XX_CPC_CSR0_PE); + /* Read back to sync write */ + ccsr_read4(OCP85XX_CPC_CSR0); +} +#endif diff --git a/sys/powerpc/booke/machdep_ppc4xx.c b/sys/powerpc/booke/machdep_ppc4xx.c new file mode 100644 index 0000000..69a1e2e --- /dev/null +++ b/sys/powerpc/booke/machdep_ppc4xx.c @@ -0,0 +1,219 @@ +/*- + * Copyright (c) 2011-2012 Semihalf. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/types.h> +#include <sys/systm.h> + +#include <machine/machdep.h> + +#include <powerpc/booke/dcr.h> +#include <powerpc/apm86xxx/apm86xxx.h> + +#include <dev/fdt/fdt_common.h> + +#define OCP_ADDR_WORDLO(addr) ((uint32_t)((uint64_t)(addr) & 0xFFFFFFFF)) +#define OCP_ADDR_WORDHI(addr) ((uint32_t)((uint64_t)(addr) >> 32)) + +extern void tlb_write(u_int, uint32_t, uint32_t, uint32_t, tlbtid_t, uint32_t, + uint32_t); +extern void tlb_read(u_int, uint32_t *, uint32_t *, uint32_t *, uint32_t *, + uint32_t *, uint32_t *); + +unsigned int tlb_static_entries; +unsigned int tlb_current_entry = TLB_SIZE; +unsigned int tlb_misses = 0; +unsigned int tlb_invals = 0; + +void tlb_map(uint32_t, uint32_t, uint32_t, uint32_t, uint32_t); +void tlb_map_mem(uint32_t, uint32_t, uint32_t); +void tlb_dump(void); + +void +booke_init_tlb(vm_paddr_t fdt_immr_pa) +{ + + /* Map register space */ + tlb_map(APM86XXX_DEEP_SLEEP_VA, + OCP_ADDR_WORDLO(APM86XXX_DEEP_SLEEP_PA), + OCP_ADDR_WORDHI(APM86XXX_DEEP_SLEEP_PA), TLB_VALID | TLB_SIZE_16M, + TLB_SW | TLB_SR | TLB_I | TLB_G); + + tlb_map(APM86XXX_CSR_VA, OCP_ADDR_WORDLO(APM86XXX_CSR_PA), + OCP_ADDR_WORDHI(APM86XXX_CSR_PA), TLB_VALID | TLB_SIZE_16M, + TLB_SW | TLB_SR | TLB_I | TLB_G); + + tlb_map(APM86XXX_PRIMARY_FABRIC_VA, + OCP_ADDR_WORDLO(APM86XXX_PRIMARY_FABRIC_PA), + OCP_ADDR_WORDHI(APM86XXX_PRIMARY_FABRIC_PA), + TLB_VALID | TLB_SIZE_16M, + TLB_SW | TLB_SR | TLB_I | TLB_G); + + tlb_map(APM86XXX_AHB_VA, OCP_ADDR_WORDLO(APM86XXX_AHB_PA), + OCP_ADDR_WORDHI(APM86XXX_AHB_PA), + TLB_VALID | TLB_SIZE_16M, + TLB_SW | TLB_SR | TLB_I | TLB_G); + + /* Map MailBox space */ + tlb_map(APM86XXX_MBOX_VA, OCP_ADDR_WORDLO(APM86XXX_MBOX_PA), + OCP_ADDR_WORDHI(APM86XXX_MBOX_PA), + TLB_VALID | TLB_SIZE_4K, + TLB_UX | TLB_UW | TLB_UR | + TLB_SX | TLB_SW | TLB_SR | + TLB_I | TLB_G); + + tlb_map(APM86XXX_MBOX_VA + 0x1000, + OCP_ADDR_WORDLO(APM86XXX_MBOX_PA) + 0x1000, + OCP_ADDR_WORDHI(APM86XXX_MBOX_PA), + TLB_VALID | TLB_SIZE_4K, + TLB_UX | TLB_UW | TLB_UR | + TLB_SX | TLB_SW | TLB_SR | + TLB_I | TLB_G); + + tlb_map(APM86XXX_MBOX_VA + 0x2000, + OCP_ADDR_WORDLO(APM86XXX_MBOX_PA)+ 0x2000, + OCP_ADDR_WORDHI(APM86XXX_MBOX_PA), + TLB_VALID | TLB_SIZE_4K, + TLB_UX | TLB_UW | TLB_UR | + TLB_SX | TLB_SW | TLB_SR | + TLB_I | TLB_G); +} + +void +booke_enable_l1_cache(void) +{ +} + +void +booke_enable_l2_cache(void) +{ +} + +void +booke_enable_l3_cache(void) +{ +} + +void +booke_disable_l2_cache(void) +{ + uint32_t ccr1,l2cr0; + + /* Disable L2 cache op broadcast */ + ccr1 = mfspr(SPR_CCR1); + ccr1 &= ~CCR1_L2COBE; + mtspr(SPR_CCR1, ccr1); + + /* Set L2 array size to 0 i.e. disable L2 cache */ + mtdcr(DCR_L2DCDCRAI, DCR_L2CR0); + l2cr0 = mfdcr(DCR_L2DCDCRDI); + l2cr0 &= ~L2CR0_AS; + mtdcr(DCR_L2DCDCRDI, l2cr0); +} + +void tlb_map(uint32_t epn, uint32_t rpn, uint32_t erpn, uint32_t flags, + uint32_t perms) +{ + + tlb_write(++tlb_static_entries, epn, rpn, erpn, 0, flags, perms); +} + +static void tlb_dump_entry(u_int entry) +{ + uint32_t epn, rpn, erpn, tid, flags, perms; + const char *size; + + tlb_read(entry, &epn, &rpn, &erpn, &tid, &flags, &perms); + + switch (flags & TLB_SIZE_MASK) { + case TLB_SIZE_1K: + size = " 1k"; + break; + case TLB_SIZE_4K: + size = " 4k"; + break; + case TLB_SIZE_16K: + size = " 16k"; + break; + case TLB_SIZE_256K: + size = "256k"; + break; + case TLB_SIZE_1M: + size = " 1M"; + break; + case TLB_SIZE_16M: + size = " 16M"; + break; + case TLB_SIZE_256M: + size = "256M"; + break; + case TLB_SIZE_1G: + size = " 1G"; + break; + default: + size = "????"; + break; + } + + + printf("TLB[%02u]: 0x%08X => " + "0x%01X_%08X %s %c %c %s %s %s %s %s " + "%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c (%u)\n", + entry, epn, erpn, rpn, size, + (flags & TLB_TS) ? '1' : '0', + (flags & TLB_VALID) ? 'V' : '.', + (perms & TLB_WL1) ? "WL1" : "___", + (perms & TLB_IL1I) ? "IL1I" : "____", + (perms & TLB_IL1D) ? "IL1D" : "____", + (perms & TLB_IL2I) ? "IL2I" : "____", + (perms & TLB_IL2D) ? "IL2D" : "____", + (perms & TLB_U0) ? '1' : '.', + (perms & TLB_U1) ? '2' : '.', + (perms & TLB_U2) ? '3' : '.', + (perms & TLB_U3) ? '4' : '.', + (perms & TLB_W) ? 'W' : '.', + (perms & TLB_I) ? 'I' : '.', + (perms & TLB_M) ? 'M' : '.', + (perms & TLB_G) ? 'G' : '.', + (perms & TLB_E) ? 'E' : '.', + (perms & TLB_UX) ? 'x' : '.', + (perms & TLB_UW) ? 'w' : '.', + (perms & TLB_UR) ? 'r' : '.', + (perms & TLB_SX) ? 'X' : '.', + (perms & TLB_SW) ? 'W' : '.', + (perms & TLB_SR) ? 'R' : '.', + tid); +} + +void tlb_dump(void) +{ + int i; + + for (i = 0; i < TLB_SIZE; i++) + tlb_dump_entry(i); +} |