Use the common code in <arm/cortex/a9_mpsubr.S>

This commit is contained in:
matt 2012-09-02 05:02:36 +00:00
parent cd57af6ece
commit d5a9a9283f
1 changed files with 39 additions and 394 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: bcm53xx_start.S,v 1.1 2012/09/01 00:15:11 matt Exp $ */
/* $NetBSD: bcm53xx_start.S,v 1.2 2012/09/02 05:02:36 matt Exp $ */
/*-
* Copyright (c) 2012 The NetBSD Foundation, Inc.
* All rights reserved.
@ -41,15 +41,20 @@
#include <arm/cortex/a9tmr_reg.h>
RCSID("$NetBSD: bcm53xx_start.S,v 1.1 2012/09/01 00:15:11 matt Exp $")
#ifndef CONADDR
#define CONADDR 0x18000300
#endif
RCSID("$NetBSD: bcm53xx_start.S,v 1.2 2012/09/02 05:02:36 matt Exp $")
#undef VERBOSE_INIT_ARM
#define VERBOSE_INIT_ARM
#if defined(VERBOSE_INIT_ARM)
#define PUTC(n) mov r0, n; bl xputc
#define XPUTC(n) mov r0, n; bl xputc
#define XPUTC_COM 1
#else
#define PUTC(n)
#define XPUTC(n)
#endif
/*
@ -61,150 +66,55 @@ RCSID("$NetBSD: bcm53xx_start.S,v 1.1 2012/09/01 00:15:11 matt Exp $")
.global _C_LABEL(bcm53xx_start)
_C_LABEL(bcm53xx_start):
cpsid if, #PSR_SVC32_MODE
PUTC(#64)
bl _C_LABEL(armv7_icache_inv_all) @ invalidate i-cache
/*
* Let's turn on the CCA watchdog in case something goes horribly wrong.
*/
ldr r0, .Lcca_wdog
ldr r1, .Lcca_wdog + 4
str r1, [r0]
/*
* Step 1a, invalidate the all cache tags in all ways on the SCU.
* Cal the initial start code for the a9
*/
PUTC(#65)
mrc p15, 4, r3, c15, c0, 0 @ read cbar
bl a9_start
mrc p15, 0, r0, c0, c0, 5 @ get MPIDR
and r0, r0, #7 @ get our cpu numder
lsl r0, r0, #2 @ multiply by 4
mov r1, #0xf @ select all ways
lsl r1, r1, r0 @ shift into place
str r1, [r3, #12] @ write scu invalidate all
dsb
isb
/*
* Step 1b, invalidate the data cache
*/
PUTC(#66)
bl _C_LABEL(armv7_dcache_wbinv_all) @ writeback/invalidate d-cache
/*
* Step 2, disable the data cache
*/
mrc p15, 0, r2, c1, c0, 0 @ get system ctl register (save)
bic r1, r2, #CPU_CONTROL_DC_ENABLE @ clear data cache enable
mcr p15, 0, r1, c1, c0, 0 @ set system ctl register
isb
/*
* Step 3, enable the SCU (and set SMP mode)
*/
ldr r1, [r3, #4] @ read scu config
orr r1, r1, #0xf0 @ set smp mode
str r1, [r3, #4] @ write scu config
ldr r1, [r3, #0] @ read scu control
orr r1, r1, #1 @ set scu enable flag
str r1, [r3, #4] @ write scu control
dsb
isb
/*
* Step 4a, enable the data cache
*/
mcr p15, 0, r2, c1, c0, 0 @ reenable caches
isb
/*
* Step 4b, set ACTLR.SMP=1 (and ACTRL.FX=1)
*/
mrc p15, 0, r0, c1, c0, 1 @ read aux ctl
orr r0, #0x40 @ enable SMP mode
mcr p15, 0, r0, c1, c0, 1 @ write aux ctl
isb
orr r0, #0x1 @ enable cache/tlb/coherency
mcr p15, 0, r0, c1, c0, 1 @ write aux ctl
isb
PUTC(#67)
/*
* Set up a preliminary mapping in the MMU to allow us to run
* at KERNEL_BASE with caches on.
*/
/* Build page table from scratch */
ldr r0, .Ltemp_l1_table /* The page table address - entered into TTB later */
mov r1, r0 /* Start address to clear memory. */
/* Zero the entire table so all virtual addresses are invalid. */
mov r2, #L1_TABLE_SIZE /* in bytes */
mov r3, #0
mov r4, r3
mov r5, r3
mov r6, r3
mov r7, r3
mov r8, r3
mov r10, r3
mov r11, r3
1: stmia r1!, {r3-r8,r10-r11}
stmia r1!, {r3-r8,r10-r11}
stmia r1!, {r3-r8,r10-r11}
stmia r1!, {r3-r8,r10-r11}
subs r2, r2, #(4 * 4 * 8) /* bytes per loop */
bne 1b
ldr r0, .Ltemp_l1_table /* The L1PT address - entered into TTB later */
adr r1, mmu_init_table
bl arm_boot_l1pt_init
/* Now create our entries per the mmu_init_table. */
l1table .req r0
va .req r1
pa .req r2
n_sec .req r3
attr .req r4
itable .req r5
adr itable, mmu_init_table
b 3f
2: str pa, [l1table, va]
add va, va, #4
add pa, pa, #(L1_S_SIZE)
subs n_sec, n_sec, #1
bhi 2b
3: ldmia itable!, {va,pa,n_sec,attr}
/* Convert va to l1 offset: va = 4 * (va >> L1_S_SHIFT) */
lsr va, va, #L1_S_SHIFT
lsl va, va, #2
/* Convert pa to l1 entry: pa = (pa & L1_S_FRAME) | attr */
bfc pa, #0, #L1_S_SHIFT
orr pa, pa, attr
cmp n_sec, #0
bne 2b
.unreq va
.unreq pa
.unreq n_sec
.unreq attr
.unreq itable
.unreq l1table
PUTC(#68)
XPUTC(#68)
/*
* Before we turn on the MMU, let's the other process out of the
* SKU ROM but setting the magic LUT address to our own mp_start
* routine.
*/
ldr r1, .Lsku_rom_lut
adr r2, mp_start
adr r2, a9_mpstart
str r2, [r1]
sev /* wake up the others */
/*
* init the CPU TLB, Cache, MMU.
*/
PUTC(#69)
XPUTC(#69)
ldr r0, .Ltemp_l1_table /* The page table address */
bl cpu_init
bl a9_cpuinit
PUTC(#33)
PUTC(#10)
PUTC(#13)
XPUTC(#33)
XPUTC(#10)
XPUTC(#13)
/*
* Let's turn off the CCA watchdog since nothing went horribly wrong.
*/
ldr r0, .Lcca_wdog
mov r1, #0
str r1, [r0]
/*
* Jump to start in locore.S, which in turn will call initarm and main.
@ -220,44 +130,15 @@ _C_LABEL(bcm53xx_start):
.Lsku_rom_lut:
.word 0xffff0400
.Lcca_wdog:
.word 0x18000080
.word 0x0fffffff /* maximum watchdog time out, about 10 seconds */
.Ltemp_l1_table:
/* Put the temporary L1 translation table far enough away. */
.word KERNEL_BASE_phys + 31 * 0x100000 - L1_TABLE_SIZE
/*
* Coprocessor register initialization values
*/
.p2align 3
/* bits to clear in the Control Register */
.Lcontrol_clr:
.word 0
/* bits to set in the Control Register */
.Lcontrol_set:
.word CPU_CONTROL_MMU_ENABLE | \
CPU_CONTROL_AFLT_ENABLE | \
CPU_CONTROL_DC_ENABLE | \
CPU_CONTROL_SYST_ENABLE | \
CPU_CONTROL_SWP_ENABLE | \
CPU_CONTROL_IC_ENABLE
#if 0
(15 << 3) | /* SBOP */ \
(1 << 16) | /* SBO */ \
(1 << 18) | /* SBO */ \
(3 << 22) /* SB0 */
#endif
/* bits to disable the caches */
.Lctl_ID_dis:
.word ~(CPU_CONTROL_IC_ENABLE|CPU_CONTROL_DC_ENABLE)
/* We'll modify va and pa at run time so we can use relocatable addresses. */
#define MMU_INIT(va,pa,n_sec,attr) \
.word va ; \
.word pa ; \
.word n_sec ; \
.word attr ;
#include <arm/cortex/a9_mpsubr.S>
mmu_init_table:
/* Add 32MB of VA==PA at 0x80000000 so we can keep the kernel going */
@ -287,239 +168,3 @@ mmu_init_table:
/* end of table */
MMU_INIT(0, 0, 0, 0)
cpu_init:
/*
* In theory, because the MMU is off, we shouldn't need all of this,
* but let's not take any chances and do a typical sequence to set
* the Translation Table Base.
*/
mov ip, lr
mov r10, r0
mov r1, #0 /* SBZ */
ldr r3, .Lctl_ID_dis /* Disable I+D caches */
mrc p15, 0, r2, c1, c0, 0 /* " " " */
and r2, r2, r3 /* " " " */
mcr p15, 0, r2, c1, c0, 0 /* " " " */
PUTC(#70)
mov r1, #0
mcr p15, 0, r1, c7, c10, 4 /* Drain the write buffers. */
PUTC(#71)
mcr p15, 0, r10, c2, c0, 0 /* Set Translation Table Base */
PUTC(#72)
mov r1, #0
mcr p15, 0, r1, c8, c7, 0 /* Invalidate TLBs */
/* Set the Domain Access register. Very important! */
PUTC(#74)
mov r1, #((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT)
mcr p15, 0, r1, c3, c0, 0
/*
* Enable the MMU, etc.
*/
PUTC(#75)
mrc p15, 0, r0, c1, c0, 0
ldr r2, .Lcontrol_clr
bic r0, r0, r2
ldr r3, .Lcontrol_set
orr r0, r0, r3
dsb
.align 5
@ turn mmu on!
mov r0, r0
mcr p15, 0, r0, c1, c0, 0
/*
* Ensure that the coprocessor has finished turning on the MMU.
*/
mrc p15, 0, r0, c0, c0, 0 /* Read an arbitrary value. */
mov r0, r0 /* Stall until read completes. */
bx ip /* return */
#if defined(VERBOSE_INIT_ARM)
#define TIMO 0x25000
xputc:
mov r2, #1
ldr r3, .Lcomlock
10:
ldrex r1, [r3]
cmp r1, #0
bne 10b
strex r1, r2, [r3]
cmp r1, #0
bne 10b
mov r2, #TIMO
ldr r3, .Luart0
1: ldrb r1, [r3, #COM_LSR]
tst r1, #LSR_TXRDY
bne 2f
subs r2, r2, #1
bne 1b
2:
strb r0, [r3, #COM_DATA]
mov r2, #TIMO
3: ldrb r1, [r3, #COM_LSR]
tst r1, #LSR_TSRE
bne 4f
subs r2, r2, #1
bne 3b
4:
ldr r3, .Lcomlock
mov r0, #0
str r0, [r3]
dsb
bx lr
.Luart0:
.word 0x18000300
.Lcomlock:
.word comlock
.pushsection .data
comlock:
.p2align 2
.word 0 @ not in bss
.popsection
#endif /* VERBOSE_INIT_ARM */
/*
* Secondary processors come here after exiting the SKU ROM.
*/
mp_start:
#ifdef MULTIPROCESSOR
/*
* Step 1, invalidate the caches
*/
bl _C_LABEL(armv7_icache_inv_all) @ toss i-cache
bl _C_LABEL(armv7_dcache_inv_all) @ toss d-cache
mrc p15, 0, r4, c0, c0, 5 @ get MPIDR
and r4, r4, #7 @ get our cpu numder
/*
* Step 2, wait for the SCU to be enabled
*/
mrc p15, 4, r3, c15, c0, 0 @ read cbar
1: ldr r0, [r3, #0] @ read scu control
tst r0, #1 @ enable bit set yet?
bne 1b @ try again
lsl r0, r4, #2 @ multiply our cpu num by 4
mov r1, #0xf @ select all ways
lsl r1, r1, r0 @ shift into place
str r1, [r3, #12] @ write scu invalidate all
dsb
isb
/*
* Step 3, set ACTLR.SMP=1 (and ACTRL.FX=1)
*/
mrc p15, 0, r0, c1, c0, 1 @ read aux ctl
orr r0, #0x40 @ enable SMP
mcr p15, 0, r0, c1, c0, 1 @ write aux ctl
isb
orr r0, #0x01 @ enable cache/tlb/coherency
mcr p15, 0, r0, c1, c0, 1 @ write aux ctl
isb
/*
* We should be in SMP mode now.
*/
#if defined(VERBOSE_INIT_ARM)
add r0, r4, #48
bl xputc
#endif
ldr r0, .Lcpu_hatched @ now show we've hatched
mov r5, #1
lsl r5, r5, r4
mov r1, r5
bl _C_LABEL(atomic_or_32)
PUTC(#97)
#endif
cpsid if, #PSR_SVC32_MODE @ make sure we are in SVC mode
/* Now we will wait for someone tell this cpu to start running */
#ifdef MULTIPROCESSOR
ldr r0, .Lcpu_mbox
#else
cmp r0, r0
#endif
2:
#ifdef MULTIPROCESSOR
dmb
ldr r2, [r0]
tst r2, r5
#endif
@wfeeq
beq 2b
#ifdef MULTIPROCESSOR
3: PUTC(#98)
ldr r0, .Lcpu_marker
str pc, [r0]
ldr r0, .Lkernel_l1pt /* get address of l1pt pvaddr */
ldr r0, [r0, #PV_PA] /* Now get the phys addr */
bl cpu_init
ldr r0, .Lcpu_marker
str pc, [r0]
/* MMU, L1, are now on. */
ldr r0, .Lcpu_info /* get pointer to cpu_infos */
ldr r5, [r0, r4, lsl #2] /* load our cpu_info */
ldr r6, [r5, #CI_IDLELWP] /* get the idlelwp */
ldr r7, [r6, #L_PCB] /* now get its pcb */
ldr sp, [r7, #PCB_SP] /* finally, we can load our SP */
#ifdef TPIDRPRW_IS_CURCPU
mcr p15, 0, r5, c13, c0, 4 /* squirrel away curcpu() */
#elif defined(TPIDRPRW_IS_CURLWP)
mcr p15, 0, r6, c13, c0, 4 /* squirrel away curlwp() */
#else
#error either TPIDRPRW_IS_CURCPU or TPIDRPRW_IS_CURLWP must be defined
#endif
str r6, [r5, #CI_CURLWP] /* and note we are running on it */
ldr r0, .Lcpu_marker
str pc, [r0]
mov r0, r5 /* pass cpu_info */
mov r1, r4 /* pass cpu_id */
ldr r2, .Lbcm53xx_cpu_hatch /* pass md_cpu_hatch */
bl _C_LABEL(cpu_hatch)
b _C_LABEL(idle_loop)
/* NOT REACHED */
.Lkernel_l1pt:
.word _C_LABEL(kernel_l1pt)
.Lcpu_info:
.word _C_LABEL(cpu_info)
.Lcpu_max:
.word _C_LABEL(arm_cpu_max)
.Lcpu_hatched:
.word _C_LABEL(arm_cpu_hatched)
.Lcpu_mbox:
.word _C_LABEL(arm_cpu_mbox)
.Lcpu_marker:
.word _C_LABEL(arm_cpu_marker)
.Lbcm53xx_cpu_hatch:
.word _C_LABEL(bcm53xx_cpu_hatch)
#endif /* MULTIPROCESSOR */