diff options
author | marcel <marcel@FreeBSD.org> | 2012-11-03 22:02:12 +0000 |
---|---|---|
committer | marcel <marcel@FreeBSD.org> | 2012-11-03 22:02:12 +0000 |
commit | 35b3593ff24bff29174560ecf0052522ba298d96 (patch) | |
tree | 05f3b3c36172a5e5f25a6d4e3c6e41fc8b4baa4a /sys/powerpc/booke/platform_bare.c | |
parent | 85823a3b2e747b0343cd12c3f6750c0f809cff56 (diff) | |
download | FreeBSD-src-35b3593ff24bff29174560ecf0052522ba298d96.zip FreeBSD-src-35b3593ff24bff29174560ecf0052522ba298d96.tar.gz |
1. Have the APs initialize the TLB1 entries from what has been
programmed on the BSP during (early) boot. This makes sure
that the APs get configured the same as the BSP, irrspective
of how FreeBSD was loaded.
2. Make sure to flush the dcache after writing the TLB1 entries
to the boot page. The APs aren't part of the coherency domain
just yet.
3. Set pmap_bootstrapped after calling pmap_bootstrap(). The
FDT code now maps the devices (like OF), and this resulted
in a panic.
4. Since we pre-wire the CCSR, make sure not to map chunks of
it in pmap_mapdev().
Diffstat (limited to 'sys/powerpc/booke/platform_bare.c')
-rw-r--r-- | sys/powerpc/booke/platform_bare.c | 40 |
1 files changed, 31 insertions, 9 deletions
diff --git a/sys/powerpc/booke/platform_bare.c b/sys/powerpc/booke/platform_bare.c index ebc5e11..c5739f7 100644 --- a/sys/powerpc/booke/platform_bare.c +++ b/sys/powerpc/booke/platform_bare.c @@ -55,9 +55,11 @@ __FBSDID("$FreeBSD$"); #ifdef SMP extern void *ap_pcpu; +extern vm_paddr_t kernload; /* Kernel physical load address */ extern uint8_t __boot_page[]; /* Boot page body */ -extern uint32_t bp_kernload; /* Kernel physical load address */ -extern uint32_t bp_trace; /* AP boot trace field */ +extern uint32_t bp_ntlb1s; +extern uint32_t bp_tlb1[]; +extern uint32_t bp_tlb1_end[]; #endif extern uint32_t *bootinfo; @@ -248,8 +250,9 @@ static int bare_smp_start_cpu(platform_t plat, struct pcpu *pc) { #ifdef SMP + uint32_t *tlb1; uint32_t bptr, eebpcr; - int timeout; + int i, timeout; eebpcr = ccsr_read4(OCP85XX_EEBPCR); if ((eebpcr & (1 << (pc->pc_cpuid + 24))) != 0) { @@ -259,18 +262,37 @@ bare_smp_start_cpu(platform_t plat, struct pcpu *pc) } ap_pcpu = pc; - __asm __volatile("msync; isync"); + + i = 0; + tlb1 = bp_tlb1; + while (i < bp_ntlb1s && tlb1 < bp_tlb1_end) { + mtspr(SPR_MAS0, MAS0_TLBSEL(1) | MAS0_ESEL(i)); + __asm __volatile("isync; tlbre"); + tlb1[0] = mfspr(SPR_MAS1); + tlb1[1] = mfspr(SPR_MAS2); + tlb1[2] = mfspr(SPR_MAS3); + i++; + tlb1 += 3; + } + if (i < bp_ntlb1s) + bp_ntlb1s = i; /* * Set BPTR to the physical address of the boot page */ - bptr = ((uint32_t)__boot_page - KERNBASE) + bp_kernload; - ccsr_write4(OCP85XX_BPTR, (bptr >> 12) | 0x80000000); + 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); /* * Release AP from hold-off state */ - bp_trace = 0; eebpcr |= (1 << (pc->pc_cpuid + 24)); ccsr_write4(OCP85XX_EEBPCR, eebpcr); __asm __volatile("isync; msync"); @@ -285,10 +307,10 @@ bare_smp_start_cpu(platform_t plat, struct pcpu *pc) * usable otherwise. */ ccsr_write4(OCP85XX_BPTR, 0); + __asm __volatile("isync; msync"); if (!pc->pc_awake) - printf("SMP: CPU %d didn't wake up (trace code %#x).\n", - pc->pc_awake, bp_trace); + printf("SMP: CPU %d didn't wake up.\n", pc->pc_cpuid); return ((pc->pc_awake) ? 0 : EBUSY); #else /* No SMP support */ |