From 0ecd3402cf1e87e46681a45c04b370ae6a537082 Mon Sep 17 00:00:00 2001 From: jhibbits Date: Wed, 30 Dec 2015 03:43:25 +0000 Subject: Add platform support for QorIQ SoCs. This includes the following changes: * SMP kickoff for QorIQ (tested on P5020) * Errata fixes for some silicon revisions * Enables L2 (and L3 if available) caches Obtained from: Semihalf Sponsored by: Alex Perez/Inertial Computing --- sys/powerpc/booke/booke_machdep.c | 14 ++++- sys/powerpc/booke/locore.S | 109 +++++++++++++++++++++++++++++++++++++- sys/powerpc/booke/machdep_e500.c | 59 +++++---------------- 3 files changed, 135 insertions(+), 47 deletions(-) (limited to 'sys/powerpc/booke') diff --git a/sys/powerpc/booke/booke_machdep.c b/sys/powerpc/booke/booke_machdep.c index c98e301..f102677 100644 --- a/sys/powerpc/booke/booke_machdep.c +++ b/sys/powerpc/booke/booke_machdep.c @@ -316,8 +316,20 @@ booke_init(uint32_t arg1, uint32_t arg2) ret = powerpc_init(dtbp, 0, 0, mdp); - /* Enable L1 caches */ + /* Default to 32 byte cache line size. */ + switch ((mfpvr()) >> 16) { + case FSL_E500mc: + case FSL_E5500: + case FSL_E6500: + cacheline_size = 64; + break; + } + + /* Enable caches */ booke_enable_l1_cache(); + booke_enable_l2_cache(); + + booke_enable_bpred(); return (ret); } diff --git a/sys/powerpc/booke/locore.S b/sys/powerpc/booke/locore.S index 817cc4f..2d6c66d 100644 --- a/sys/powerpc/booke/locore.S +++ b/sys/powerpc/booke/locore.S @@ -301,7 +301,7 @@ bp_ntlb1s: .globl bp_tlb1 bp_tlb1: - .space 4 * 3 * 16 + .space 4 * 3 * 64 .globl bp_tlb1_end bp_tlb1_end: @@ -731,6 +731,113 @@ ENTRY(icache_enable) blr /* + * L2 cache disable/enable/inval sequences for E500mc. + */ + +ENTRY(l2cache_inval) + mfspr %r3, SPR_L2CSR0 + oris %r3, %r3, (L2CSR0_L2FI | L2CSR0_L2LFC)@h + ori %r3, %r3, (L2CSR0_L2FI | L2CSR0_L2LFC)@l + isync + mtspr SPR_L2CSR0, %r3 + isync +1: mfspr %r3, SPR_L2CSR0 + andis. %r3, %r3, L2CSR0_L2FI@h + bne 1b + blr + +ENTRY(l2cache_enable) + mfspr %r3, SPR_L2CSR0 + oris %r3, %r3, (L2CSR0_L2E | L2CSR0_L2PE)@h + isync + mtspr SPR_L2CSR0, %r3 + isync + blr + +/* + * Branch predictor setup. + */ +ENTRY(bpred_enable) + mfspr %r3, SPR_BUCSR + ori %r3, %r3, BUCSR_BBFI + isync + mtspr SPR_BUCSR, %r3 + isync + ori %r3, %r3, BUCSR_BPEN + isync + mtspr SPR_BUCSR, %r3 + isync + blr + +ENTRY(dataloss_erratum_access) + /* Lock two cache lines into I-Cache */ + sync + mfspr %r11, SPR_L1CSR1 + rlwinm %r11, %r11, 0, ~L1CSR1_ICUL + sync + isync + mtspr SPR_L1CSR1, %r11 + isync + + mflr %r9 + bl 1f + .long 2f-. +1: + mflr %r5 + lwz %r8, 0(%r5) + mtlr %r9 + add %r8, %r8, %r5 + icbtls 0, 0, %r8 + addi %r9, %r8, 64 + + sync + mfspr %r11, SPR_L1CSR1 +3: andi. %r11, %r11, L1CSR1_ICUL + bne 3b + + icbtls 0, 0, %r9 + + sync + mfspr %r11, SPR_L1CSR1 +3: andi. %r11, %r11, L1CSR1_ICUL + bne 3b + + b 2f + .align 6 + /* Inside a locked cacheline, wait a while, write, then wait a while */ +2: sync + + mfspr %r5, TBR_TBL +4: addis %r11, %r5, 0x100000@h /* wait around one million timebase ticks */ + mfspr %r5, TBR_TBL + subf. %r5, %r5, %r11 + bgt 4b + + stw %r4, 0(%r3) + + mfspr %r5, TBR_TBL +4: addis %r11, %r5, 0x100000@h /* wait around one million timebase ticks */ + mfspr %r5, TBR_TBL + subf. %r5, %r5, %r11 + bgt 4b + + sync + + /* + * Fill out the rest of this cache line and the next with nops, + * to ensure that nothing outside the locked area will be + * fetched due to a branch. + */ + .rept 19 + nop + .endr + + icblc 0, 0, %r8 + icblc 0, 0, %r9 + + blr + +/* * int setfault() * * Similar to setjmp to setup for handling faults on accesses to user memory. diff --git a/sys/powerpc/booke/machdep_e500.c b/sys/powerpc/booke/machdep_e500.c index ab47f62..e0e6095 100644 --- a/sys/powerpc/booke/machdep_e500.c +++ b/sys/powerpc/booke/machdep_e500.c @@ -27,9 +27,15 @@ #include __FBSDID("$FreeBSD$"); +#include #include +#include +#include #include +#include +#include + #include #include @@ -42,6 +48,7 @@ extern void icache_enable(void); extern void icache_inval(void); extern void l2cache_enable(void); extern void l2cache_inval(void); +extern void bpred_enable(void); void booke_init_tlb(vm_paddr_t fdt_immr_pa) @@ -79,7 +86,6 @@ booke_enable_l1_cache(void) (csr & L1CSR1_ICE) ? "en" : "dis"); } -#if 0 void booke_enable_l2_cache(void) { @@ -102,55 +108,18 @@ booke_enable_l2_cache(void) } void -booke_enable_l3_cache(void) +booke_enable_bpred(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(); - } + uint32_t csr; - 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"); - } - } + bpred_enable(); + csr = mfspr(SPR_BUCSR); + if ((boothowto & RB_VERBOSE) != 0 || (csr & BUCSR_BPEN) == 0) + printf("Branch Predictor %sabled\n", + (csr & BUCSR_BPEN) ? "en" : "dis"); } 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 -- cgit v1.1