From owner-svn-src-all@freebsd.org Wed Dec 30 03:43:27 2015 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id C0742A55DB5; Wed, 30 Dec 2015 03:43:27 +0000 (UTC) (envelope-from jhibbits@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 82DF11BBE; Wed, 30 Dec 2015 03:43:27 +0000 (UTC) (envelope-from jhibbits@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id tBU3hQVi003548; Wed, 30 Dec 2015 03:43:26 GMT (envelope-from jhibbits@FreeBSD.org) Received: (from jhibbits@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id tBU3hQEt003542; Wed, 30 Dec 2015 03:43:26 GMT (envelope-from jhibbits@FreeBSD.org) Message-Id: <201512300343.tBU3hQEt003542@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: jhibbits set sender to jhibbits@FreeBSD.org using -f From: Justin Hibbits Date: Wed, 30 Dec 2015 03:43:26 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r292903 - in head/sys/powerpc: booke mpc85xx X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 30 Dec 2015 03:43:27 -0000 Author: jhibbits Date: Wed Dec 30 03:43:25 2015 New Revision: 292903 URL: https://svnweb.freebsd.org/changeset/base/292903 Log: 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 Modified: head/sys/powerpc/booke/booke_machdep.c head/sys/powerpc/booke/locore.S head/sys/powerpc/booke/machdep_e500.c head/sys/powerpc/mpc85xx/mpc85xx.c head/sys/powerpc/mpc85xx/mpc85xx.h head/sys/powerpc/mpc85xx/platform_mpc85xx.c Modified: head/sys/powerpc/booke/booke_machdep.c ============================================================================== --- head/sys/powerpc/booke/booke_machdep.c Wed Dec 30 03:36:22 2015 (r292902) +++ head/sys/powerpc/booke/booke_machdep.c Wed Dec 30 03:43:25 2015 (r292903) @@ -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); } Modified: head/sys/powerpc/booke/locore.S ============================================================================== --- head/sys/powerpc/booke/locore.S Wed Dec 30 03:36:22 2015 (r292902) +++ head/sys/powerpc/booke/locore.S Wed Dec 30 03:43:25 2015 (r292903) @@ -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. Modified: head/sys/powerpc/booke/machdep_e500.c ============================================================================== --- head/sys/powerpc/booke/machdep_e500.c Wed Dec 30 03:36:22 2015 (r292902) +++ head/sys/powerpc/booke/machdep_e500.c Wed Dec 30 03:43:25 2015 (r292903) @@ -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 Modified: head/sys/powerpc/mpc85xx/mpc85xx.c ============================================================================== --- head/sys/powerpc/mpc85xx/mpc85xx.c Wed Dec 30 03:36:22 2015 (r292902) +++ head/sys/powerpc/mpc85xx/mpc85xx.c Wed Dec 30 03:43:25 2015 (r292903) @@ -32,18 +32,26 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include +#include #include #include +#include #include #include #include +#include +#include +#include +#include + #include @@ -249,3 +257,166 @@ law_pci_target(struct resource *res, int return (rv); } +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); +} + +void +mpc85xx_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"); + } + } +} + +static void +mpc85xx_dataloss_erratum_spr976(void) +{ + uint32_t svr = SVR_VER(mfspr(SPR_SVR)); + + /* Ignore whether it's the E variant */ + svr &= ~0x8; + + if (svr != SVR_P3041 && svr != SVR_P4040 && + svr != SVR_P4080 && svr != SVR_P5020) + return; + + mb(); + isync(); + mtspr(976, (mfspr(976) & ~0x1f8) | 0x48); + isync(); +} + +static vm_offset_t +mpc85xx_map_dcsr(void) +{ + phandle_t node; + u_long b, s; + int err; + + /* + * Try to access the dcsr node directly i.e. through /aliases/. + */ + if ((node = OF_finddevice("dcsr")) != -1) + if (fdt_is_compatible_strict(node, "fsl,dcsr")) + goto moveon; + /* + * Find the node the long way. + */ + if ((node = OF_finddevice("/")) == -1) + return (ENXIO); + + if ((node = ofw_bus_find_compatible(node, "fsl,dcsr")) == 0) + return (ENXIO); + +moveon: + err = fdt_get_range(node, 0, &b, &s); + + if (err != 0) + return (err); + +#ifdef QORIQ_DPAA + law_enable(OCP85XX_TGTIF_DCSR, b, 0x400000); +#endif + return pmap_early_io_map(b, 0x400000); +} + + + +void +mpc85xx_fix_errata(vm_offset_t va_ccsr) +{ + uint32_t svr = SVR_VER(mfspr(SPR_SVR)); + vm_offset_t va_dcsr; + + /* Ignore whether it's the E variant */ + svr &= ~0x8; + + if (svr != SVR_P3041 && svr != SVR_P4040 && + svr != SVR_P4080 && svr != SVR_P5020) + return; + + if (mfmsr() & PSL_EE) + return; + + /* + * dcsr region need to be mapped thus patch can refer to. + * Align dcsr right after ccsbar. + */ + va_dcsr = mpc85xx_map_dcsr(); + if (va_dcsr == 0) + goto err; + + /* + * As A004510 errata specify, special purpose register 976 + * SPR976[56:60] = 6'b001001 must be set. e500mc core reference manual + * does not document SPR976 register. + */ + mpc85xx_dataloss_erratum_spr976(); + + /* + * Specific settings in the CCF and core platform cache (CPC) + * are required to reconfigure the CoreNet coherency fabric. + * The register settings that should be updated are described + * in errata and relay on base address, offset and updated value. + * Special conditions must be used to update these registers correctly. + */ + dataloss_erratum_access(va_dcsr + 0xb0e08, 0xe0201800); + dataloss_erratum_access(va_dcsr + 0xb0e18, 0xe0201800); + dataloss_erratum_access(va_dcsr + 0xb0e38, 0xe0400000); + dataloss_erratum_access(va_dcsr + 0xb0008, 0x00900000); + dataloss_erratum_access(va_dcsr + 0xb0e40, 0xe00a0000); + + switch (svr) { + case SVR_P5020: + dataloss_erratum_access(va_ccsr + 0x18600, 0xc0000000); + break; + case SVR_P4040: + case SVR_P4080: + dataloss_erratum_access(va_ccsr + 0x18600, 0xff000000); + break; + case SVR_P3041: + dataloss_erratum_access(va_ccsr + 0x18600, 0xf0000000); + } + dataloss_erratum_access(va_ccsr + 0x10f00, 0x415e5000); + dataloss_erratum_access(va_ccsr + 0x11f00, 0x415e5000); + +err: + return; +} Modified: head/sys/powerpc/mpc85xx/mpc85xx.h ============================================================================== --- head/sys/powerpc/mpc85xx/mpc85xx.h Wed Dec 30 03:36:22 2015 (r292902) +++ head/sys/powerpc/mpc85xx/mpc85xx.h Wed Dec 30 03:43:25 2015 (r292903) @@ -40,6 +40,25 @@ extern vm_offset_t ccsrbar_va; #define OCP85XX_CCSRBAR (CCSRBAR_VA + 0x0) #define OCP85XX_BPTR (CCSRBAR_VA + 0x20) +#define OCP85XX_BSTRH (CCSRBAR_VA + 0x20) +#define OCP85XX_BSTRL (CCSRBAR_VA + 0x24) +#define OCP85XX_BSTAR (CCSRBAR_VA + 0x28) + +#define OCP85XX_COREDISR (CCSRBAR_VA + 0xE0094) +#define OCP85XX_BRR (CCSRBAR_VA + 0xE00E4) + +/* + * Run Control and Power Management registers + */ +#define CCSR_CTBENR (CCSRBAR_VA + 0xE2084) +#define CCSR_CTBCKSELR (CCSRBAR_VA + 0xE208C) +#define CCSR_CTBCHLTCR (CCSRBAR_VA + 0xE2094) + +/* + * DDR Memory controller. + */ +#define OCP85XX_DDR1_CS0_CONFIG (CCSRBAR_VA + 0x8080) + /* * E500 Coherency Module registers */ @@ -68,6 +87,7 @@ extern vm_offset_t ccsrbar_va; #define OCP85XX_TGTIF_RAM1 0x10 #define OCP85XX_TGTIF_RAM2 0x11 #define OCP85XX_TGTIF_BMAN 0x18 +#define OCP85XX_TGTIF_DCSR 0x1D #define OCP85XX_TGTIF_QMAN 0x3C #define OCP85XX_TRGT_SHIFT 20 #else @@ -84,6 +104,20 @@ extern vm_offset_t ccsrbar_va; #define OCP85XX_L2CTL (CCSRBAR_VA + 0x20000) /* + * L3 CoreNet platform cache (CPC) registers + */ +#define OCP85XX_CPC_CSR0 (CCSRBAR_VA + 0x10000) +#define OCP85XX_CPC_CSR0_CE 0x80000000 +#define OCP85XX_CPC_CSR0_PE 0x40000000 +#define OCP85XX_CPC_CSR0_FI 0x00200000 +#define OCP85XX_CPC_CSR0_WT 0x00080000 +#define OCP85XX_CPC_CSR0_FL 0x00000800 +#define OCP85XX_CPC_CSR0_LFC 0x00000400 +#define OCP85XX_CPC_CFG0 (CCSRBAR_VA + 0x10008) +#define OCP85XX_CPC_CFG_SZ_MASK 0x00003fff +#define OCP85XX_CPC_CFG0_SZ_K(x) (((x) & OCP85XX_CPC_CFG_SZ_MASK) << 6) + +/* * Power-On Reset configuration */ #define OCP85XX_PORDEVSR (CCSRBAR_VA + 0xe000c) @@ -110,4 +144,8 @@ int law_pci_target(struct resource *, in DECLARE_CLASS(mpc85xx_platform); int mpc85xx_attach(platform_t); +void mpc85xx_enable_l3_cache(void); +void mpc85xx_fix_errata(vm_offset_t); +void dataloss_erratum_access(vm_offset_t, uint32_t); + #endif /* _MPC85XX_H_ */ Modified: head/sys/powerpc/mpc85xx/platform_mpc85xx.c ============================================================================== --- head/sys/powerpc/mpc85xx/platform_mpc85xx.c Wed Dec 30 03:36:22 2015 (r292902) +++ head/sys/powerpc/mpc85xx/platform_mpc85xx.c Wed Dec 30 03:43:25 2015 (r292903) @@ -24,6 +24,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include "opt_platform.h" #include __FBSDID("$FreeBSD$"); @@ -38,6 +39,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -175,6 +177,9 @@ mpc85xx_attach(platform_t plat) } ccsrbar_va = pmap_early_io_map(ccsrbar, ccsrsize); + mpc85xx_fix_errata(ccsrbar_va); + mpc85xx_enable_l3_cache(); + /* * Clear local access windows. Skip DRAM entries, so we don't shoot * ourselves in the foot. @@ -182,14 +187,14 @@ mpc85xx_attach(platform_t plat) law_max = law_getmax(); for (i = 0; i < law_max; i++) { sr = ccsr_read4(OCP85XX_LAWSR(i)); - if ((sr & 0x80000000) == 0) + if ((sr & OCP85XX_ENA_MASK) == 0) continue; tgt = (sr & 0x01f00000) >> 20; if (tgt == OCP85XX_TGTIF_RAM1 || tgt == OCP85XX_TGTIF_RAM2 || tgt == OCP85XX_TGTIF_RAM_INTL) continue; - ccsr_write4(OCP85XX_LAWSR(i), sr & 0x7fffffff); + ccsr_write4(OCP85XX_LAWSR(i), sr & OCP85XX_DIS_MASK); } return (0); @@ -256,7 +261,11 @@ mpc85xx_timebase_freq(platform_t plat, s * HID0[SEL_TBCLK] = 0 */ if (freq != 0) +#ifdef QORIQ_DPAA + ticks = freq / 32; +#else ticks = freq / 8; +#endif out: if (ticks <= 0) @@ -309,17 +318,37 @@ mpc85xx_smp_start_cpu(platform_t plat, s { #ifdef SMP uint32_t *tlb1; - uint32_t bptr, eebpcr; + vm_paddr_t bptr; + uint32_t reg; int i, timeout; + uintptr_t brr; + int cpuid; + +#ifdef QORIQ_DPAA + uint32_t tgt; - eebpcr = ccsr_read4(OCP85XX_EEBPCR); - if ((eebpcr & (1 << (pc->pc_cpuid + 24))) != 0) { + reg = ccsr_read4(OCP85XX_COREDISR); + cpuid = pc->pc_cpuid; + + if ((reg & cpuid) != 0) { + printf("%s: CPU %d is disabled!\n", __func__, pc->pc_cpuid); + return (-1); + } + + brr = OCP85XX_BRR; +#else /* QORIQ_DPAA */ + brr = OCP85XX_EEBPCR; + cpuid = pc->pc_cpuid + 24; +#endif + reg = ccsr_read4(brr); + if ((reg & (1 << cpuid)) != 0) { printf("SMP: CPU %d already out of hold-off state!\n", pc->pc_cpuid); return (ENXIO); } ap_pcpu = pc; + __asm __volatile("msync; isync"); i = 0; tlb1 = bp_tlb1; @@ -335,24 +364,67 @@ mpc85xx_smp_start_cpu(platform_t plat, s if (i < bp_ntlb1s) bp_ntlb1s = i; + /* Flush caches to have our changes hit DRAM. */ + cpu_flush_dcache(__boot_page, 4096); + + bptr = ((vm_paddr_t)(uintptr_t)__boot_page - KERNBASE) + kernload; + KASSERT((bptr & 0xfff) == 0, + ("%s: boot page is not aligned (%#jx)", __func__, (uintmax_t)bptr)); +#ifdef QORIQ_DPAA + + /* + * Read DDR controller configuration to select proper BPTR target ID. + * + * On P5020 bit 29 of DDR1_CS0_CONFIG enables DDR controllers + * interleaving. If this bit is set, we have to use + * OCP85XX_TGTIF_RAM_INTL as BPTR target ID. On other QorIQ DPAA SoCs, + * this bit is reserved and always 0. + */ + + reg = ccsr_read4(OCP85XX_DDR1_CS0_CONFIG); + if (reg & (1 << 29)) + tgt = OCP85XX_TGTIF_RAM_INTL; + else + tgt = OCP85XX_TGTIF_RAM1; + + /* + * Set BSTR to the physical address of the boot page + */ + ccsr_write4(OCP85XX_BSTRH, bptr >> 32); + ccsr_write4(OCP85XX_BSTRL, bptr); + ccsr_write4(OCP85XX_BSTAR, OCP85XX_ENA_MASK | + (tgt << OCP85XX_TRGT_SHIFT) | (ffsl(PAGE_SIZE) - 2)); + + /* Read back OCP85XX_BSTAR to synchronize write */ + ccsr_read4(OCP85XX_BSTAR); + + /* + * Enable and configure time base on new CPU. + */ + + /* Set TB clock source to platform clock / 32 */ + reg = ccsr_read4(CCSR_CTBCKSELR); + ccsr_write4(CCSR_CTBCKSELR, reg & ~(1 << pc->pc_cpuid)); + + /* Enable TB */ + reg = ccsr_read4(CCSR_CTBENR); + ccsr_write4(CCSR_CTBENR, reg | (1 << pc->pc_cpuid)); +#else + /* * Set BPTR to the physical address of the boot page */ - bptr = ((uint32_t)__boot_page - KERNBASE) + kernload; - KASSERT((bptr & 0xfff) == 0, - ("%s: boot page is not aligned (%#x)", __func__, bptr)); bptr = (bptr >> 12) | 0x80000000u; ccsr_write4(OCP85XX_BPTR, bptr); __asm __volatile("isync; msync"); - /* Flush caches to have our changes hit DRAM. */ - cpu_flush_dcache(__boot_page, 4096); +#endif /* QORIQ_DPAA */ /* * Release AP from hold-off state */ - eebpcr |= (1 << (pc->pc_cpuid + 24)); - ccsr_write4(OCP85XX_EEBPCR, eebpcr); + reg = ccsr_read4(brr); + ccsr_write4(brr, reg | (1 << cpuid)); __asm __volatile("isync; msync"); timeout = 500; @@ -364,7 +436,11 @@ mpc85xx_smp_start_cpu(platform_t plat, s * address (= 0xfffff000) isn't permanently remapped and thus not * usable otherwise. */ +#ifdef QORIQ_DPAA + ccsr_write4(OCP85XX_BSTAR, 0); +#else ccsr_write4(OCP85XX_BPTR, 0); +#endif __asm __volatile("isync; msync"); if (!pc->pc_awake)