summaryrefslogtreecommitdiffstats
path: root/sys/powerpc/booke/platform_bare.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/powerpc/booke/platform_bare.c')
-rw-r--r--sys/powerpc/booke/platform_bare.c40
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 */
OpenPOWER on IntegriCloud