#include "opt_arm_debug.h"
#include "opt_console.h"
#include "opt_cpuoptions.h"
#include "opt_cputypes.h"
#include "opt_fdt.h"
#include "opt_kasan.h"
#include "opt_multiprocessor.h"
#include <sys/cdefs.h>
#include <arm/asm.h>
#include <arm/armreg.h>
#include <arm/locore.h>
#include "assym.h"
#if defined(CONSADDR) && defined(CONADDR)
#error Only one of CONSADDR and CONADDR should be defined
#endif
#if defined(CONSADDR)
#define START_CONSADDR CONSADDR
#endif
#if defined(CONADDR)
#define START_CONSADDR CONADDR
#endif
#if defined(VERBOSE_INIT_ARM)
#define XPUTC(n) mov r0, n; bl uartputc
#define VPRINTF(string) bl generic_vprint; .asciz string; .align 2
#define VPRINTX(regno) mov r0, regno; bl generic_printx
#else
#define XPUTC(c)
#define VPRINTF(string)
#define VPRINTX(regno)
#endif
#if defined(FDT)
#define MD_CPU_HATCH arm_fdt_cpu_hatch
#endif
#if defined(_ARM_ARCH_6)
#define L1_S_KRW_NOCACHE (L1_S_PROTO | L1_S_AP_KRW | L1_S_NOCACHE_armv6n)
#else
#define L1_S_KRW_NOCACHE (L1_S_PROTO | L1_S_AP_KRW | L1_S_NOCACHE_generic)
#endif
R_L1TABLE .req r4
R_VA .req r5
R_PA .req r6
R_NSEC .req r7
R_ATTR .req r8
R_DEVATTR .req r9
R_TMP1 .req r8
R_TMP2 .req r9
R_VTOPDIFF .req r10
R_FDTADDR .req r11
R_INDEX .req r11
.text
ENTRY_NP(generic_start)
#if defined(__ARMEB__)
mrc p15, 0, R_TMP1, c1, c0, 0
orr R_TMP1, R_TMP1, #CPU_CONTROL_UNAL_ENABLE
mcr p15, 0, R_TMP1, c1, c0, 0
setend be
#endif
INTERRUPT_DISABLE(r0)
adr R_TMP1, generic_start
ldr R_VTOPDIFF, =generic_start
sub R_VTOPDIFF, R_VTOPDIFF, R_TMP1
ldr R_TMP1, =start_stacks_top
sub sp, R_TMP1, R_VTOPDIFF
mov r4, r0
mov r5, r1
mov r6, r2
mov r7, r3
VPRINTF("\n\rpc : ")
VPRINTX(pc)
VPRINTF("\n\roff : ")
VPRINTX(R_VTOPDIFF)
VPRINTF("\n\rsp : ")
VPRINTX(sp)
ldr R_TMP1, =(L1_S_SIZE - 1)
ands R_TMP2, R_VTOPDIFF, R_TMP1
bne arm_bad_vtopdiff
#if defined(FDTBASE)
VPRINTF("\n\rfdt : ")
mov R_FDTADDR, r6
VPRINTX(r6)
#endif
#if defined(VERBOSE_INIT_ARM)
VPRINTF("\n\rmidr : ")
mrc p15, 0, r0, c0, c0, 0
VPRINTX(r0)
VPRINTF("\n\rrevidr: ")
mrc p15, 0, r0, c0, c0, 6
VPRINTX(r0)
VPRINTF("\n\rmpidr : ")
mrc p15, 0, r0, c0, c0, 5
VPRINTX(r0)
VPRINTF("\n\rttb0 : ")
mrc p15, 0, r0, c2, c0, 0
VPRINTX(r0)
#if defined(_ARM_ARCH_6)
VPRINTF("\n\rttb1 : ")
mrc p15, 0, r0, c2, c0, 1
VPRINTX(r0)
VPRINTF("\n\rttcr : ")
mrc p15, 0, r0, c2, c0, 2
VPRINTX(r0)
#endif
VPRINTF("\n\r")
#endif
#if defined(_ARM_ARCH_7)
b generic_startv7
#elif defined(_ARM_ARCH_6)
b generic_startv6
#elif defined(_ARM_ARCH_5)
b generic_startv5
#else
#error Unsupported CPU
#endif
arm_bad_vtopdiff:
VPRINTF("\n\rpanic: vtop not L1_FRAME aligned (")
VPRINTX(R_VTOPDIFF)
VPRINTF(")\n\r")
1: b 1b
ASEND(generic_start)
generic_savevars:
mov R_TMP1, lr
ldr R_TMP2, =kern_vtopdiff
sub R_TMP2, R_TMP2, R_VTOPDIFF
str R_VTOPDIFF, [R_TMP2]
ldr R_TMP2, =uboot_args
sub R_TMP2, R_VTOPDIFF
VPRINTF("\n\ruboot : ")
VPRINTX(R_TMP2)
str r4, [R_TMP2, #(4*0)]
str r5, [R_TMP2, #(4*1)]
str r6, [R_TMP2, #(4*2)]
str r7, [R_TMP2, #(4*3)]
#if defined(FDTBASE)
VPRINTF("\n\rfdt : ")
ldr R_TMP2, =fdt_addr_r
sub R_TMP2, R_VTOPDIFF
str r6, [R_TMP2]
VPRINTX(r6)
#endif
RETr(R_TMP1)
.ltorg
.section "_init_memory", "aw", %nobits
.p2align INIT_ARM_STACK_SHIFT
.global start_stacks_bottom
.global start_stacks_top
start_stacks_bottom:
.space INIT_ARM_TOTAL_STACK
start_stacks_top:
.section "_init_memory", "aw", %nobits
.p2align 14
.global ARM_BOOTSTRAP_LxPT
ARM_BOOTSTRAP_LxPT:
TEMP_L1_TABLE:
.space L1_TABLE_SIZE
TEMP_L1_TABLE_END:
.text
.align 2
arm_build_translation_table:
push {r0, lr}
ldr R_L1TABLE, =TEMP_L1_TABLE
sub R_L1TABLE, R_VTOPDIFF
adr R_PA, generic_start
ldr r0, =(L1_S_SIZE - 1)
bic R_PA, R_PA, r0
ldr R_ATTR, =L1_S_KRW_NOCACHE
bl arm_boot_l1pt_init
ldr R_L1TABLE, =TEMP_L1_TABLE
sub R_L1TABLE, R_VTOPDIFF
ldr r0, =generic_start
ldr r1, =TEMP_L1_TABLE_END
add r1, #L1_S_SIZE
ldr r2, =(L1_S_SIZE - 1)
bic r0, r2
add r1, r2
bic r1, r2
sub r1, r0
mov R_NSEC, r1, lsr #(L1_S_SHIFT)
ldr R_VA, =generic_start
bic R_VA, r2
adr R_PA, generic_start
bic R_PA, r2
ldr R_ATTR, =L1_S_KRW_NOCACHE
bl arm_boot_l1pt_entry
#if defined(FDTBASE)
VPRINTF("\n\rDTB")
ldr r0, =(L1_S_SIZE - 1)
bic R_VA, R_FDTADDR, r0
mov R_PA, R_VA
mov R_NSEC, #1
ldr R_L1TABLE, =TEMP_L1_TABLE
sub R_L1TABLE, R_VTOPDIFF
bl arm_boot_l1pt_entry
#endif
#if defined(START_CONSADDR)
VPRINTF("\n\rCONSADDR")
ldr r0, =(L1_S_SIZE - 1)
ldr R_VA, =START_CONSADDR
bic R_VA, R_VA, r0
mov R_PA, R_VA
mov R_NSEC, #1
ldr R_ATTR, =(L1_S_PROTO | L1_S_AP_KRW)
orr R_ATTR, R_DEVATTR
ldr R_L1TABLE, =TEMP_L1_TABLE
sub R_L1TABLE, R_VTOPDIFF
bl arm_boot_l1pt_entry
#endif
XPUTC(#'M')
pop {r0, pc}
.ltorg
arm_boot_l1pt_init:
push {r0, lr}
mov r0, R_L1TABLE
add r1, r0, #L1_TABLE_SIZE
mov r2, #0
mov r3, #0
1: stmia r0!, {r2-r3}
stmia r0!, {r2-r3}
cmp r0, r1
blt 1b
ldr r0, =generic_start
ldr r1, =TEMP_L1_TABLE_END
ldr r2, =(L1_S_SIZE - 1)
bic r0, r2
add r1, r2
bic r1, r2
sub r1, r0
mov R_NSEC, r1, lsr #(L1_S_SHIFT)
adr R_VA, generic_start
bic R_VA, r2
mov R_PA, R_VA
pop {r0, lr}
arm_boot_l1pt_entry:
push {r0, lr}
VPRINTF("\n\r")
VPRINTX(R_L1TABLE)
VPRINTF(" va:")
VPRINTX(R_VA)
VPRINTF(" pa:")
VPRINTX(R_PA)
VPRINTF(" nsec:")
VPRINTX(R_NSEC)
VPRINTF(" attr:")
VPRINTX(R_ATTR)
VPRINTF("\n\r")
lsr R_VA, R_VA, #L1_S_SHIFT
orr R_PA, R_ATTR
2:
VPRINTX(R_L1TABLE)
XPUTC('[')
VPRINTX(R_VA)
XPUTC(']')
XPUTC('=')
VPRINTX(R_PA)
ldr r0, [R_L1TABLE, R_VA, lsl #2]
cmp r0, #0
cmpne r0, R_PA
bne arm_boot_overlap
str R_PA, [R_L1TABLE, R_VA, lsl #2]
add R_VA, R_VA, #1
add R_PA, R_PA, #(L1_S_SIZE)
VPRINTF("\n\r")
subs R_NSEC, R_NSEC, #1
bhi 2b
pop {r0, pc}
arm_boot_overlap:
VPRINTF("\n\rpanic: overlapping mappings\n\r")
3:
b 3b
#if defined(_ARM_ARCH_7)
generic_startv7:
.arch armv7a
.arch_extension sec
.arch_extension virt
VPRINTF("v7 : ")
bl armv7_init
bl generic_savevars
mov R_DEVATTR, #L1_S_V6_XN
bl arm_build_translation_table
movw r0, #:lower16:TEMP_L1_TABLE
movt r0, #:upper16:TEMP_L1_TABLE
sub r0, R_VTOPDIFF
movw lr, #:lower16:generic_vstartv7
movt lr, #:upper16:generic_vstartv7
b armv7_mmuinit
generic_vstartv7:
add sp, sp, R_VTOPDIFF
VPRINTF("virtual\n\r")
VPRINTF("prrr : ")
mrc p15, 0, r0, c10, c2, 0
VPRINTX(r0)
VPRINTF("\n\rnmrr : ")
mrc p15, 0, r0, c10, c2, 1
VPRINTX(r0)
VPRINTF("\n\r")
#if defined(KASAN)
ldr r0, =start_stacks_bottom
bl _C_LABEL(kasan_early_init)
VPRINTF("kasan\n\r")
#endif
movw r0, #:lower16:cpu_info_store
movt r0, #:upper16:cpu_info_store
mrc p15, 0, r1, c0, c0, 0
str r1, [r0, #CI_MIDR]
mrc p15, 0, r1, c0, c0, 5
str r1, [r0, #CI_MPIDR]
bl arm_cpu_topology_set
VPRINTF("go\n\r")
b start
.ltorg
#elif defined(_ARM_ARCH_6)
generic_startv6:
VPRINTF("v6 : ")
bl armv6_init
bl generic_savevars
#if defined(ARM_MMU_EXTENDED)
mov R_DEVATTR, #L1_S_V6_XN
#else
mov R_DEVATTR, #0
#endif
bl arm_build_translation_table
XPUTC(#'E')
ldr r0, =TEMP_L1_TABLE
sub r0, R_VTOPDIFF
ldr lr, =generic_vstartv6
b armv6_mmuinit
generic_vstartv6:
add sp, sp, R_VTOPDIFF
VPRINTF("virtual\n\r")
#if defined(KASAN)
ldr r0, =start_stacks_bottom
bl _C_LABEL(kasan_early_init)
VPRINTF("kasan\n\r")
#endif
VPRINTF("go\n\r")
b start
.ltorg
#elif defined(_ARM_ARCH_5)
generic_startv5:
VPRINTF("v5 : ")
bl armv5_init
bl generic_savevars
mov R_DEVATTR, #0
bl arm_build_translation_table
XPUTC(#'E')
ldr r0, =TEMP_L1_TABLE
sub r0, R_VTOPDIFF
ldr lr, =generic_vstartv5
b armv5_mmuinit
generic_vstartv5:
add sp, sp, R_VTOPDIFF
VPRINTF("virtual\n\r")
#if defined(KASAN)
ldr r0, =start_stacks_bottom
bl _C_LABEL(kasan_early_init)
VPRINTF("kasan\n\r")
#endif
VPRINTF("rgo\n\r")
b start
.ltorg
#endif
#if defined(_ARM_ARCH_7)
#if defined(__ARMEL__)
#define CPU_CONTROL_EX_BEND_SET 0
#else
#define CPU_CONTROL_EX_BEND_SET CPU_CONTROL_EX_BEND
#endif
#if defined(ARM32_DISABLE_ALIGNMENT_FAULTS)
#define CPU_CONTROL_AFLT_ENABLE_CLR CPU_CONTROL_AFLT_ENABLE
#define CPU_CONTROL_AFLT_ENABLE_SET 0
#else
#define CPU_CONTROL_AFLT_ENABLE_CLR 0
#define CPU_CONTROL_AFLT_ENABLE_SET CPU_CONTROL_AFLT_ENABLE
#endif
#if defined(ARM_MMU_EXTENDED)
#define CPU_CONTROL_XP_ENABLE_CLR 0
#define CPU_CONTROL_XP_ENABLE_SET CPU_CONTROL_XP_ENABLE
#else
#define CPU_CONTROL_XP_ENABLE_CLR CPU_CONTROL_XP_ENABLE
#define CPU_CONTROL_XP_ENABLE_SET 0
#endif
#ifdef MULTIPROCESSOR
#define CPU_CONTROL_XP_SWP_ENABLE 0
#else
#define CPU_CONTROL_XP_SWP_ENABLE CPU_CONTROL_SWP_ENABLE
#endif
#define CPU_CONTROL_SET ( \
CPU_CONTROL_MMU_ENABLE | \
CPU_CONTROL_UNAL_ENABLE | \
CPU_CONTROL_EX_BEND_SET | \
CPU_CONTROL_AFLT_ENABLE_SET | \
CPU_CONTROL_XP_ENABLE_SET | \
0)
#define CPU_CONTROL_CLR ( \
CPU_CONTROL_AFLT_ENABLE_CLR | \
CPU_CONTROL_XP_ENABLE_CLR | \
0)
armv7_init:
.arch armv7a
.arch_extension sec
.arch_extension virt
mov R_TMP1, lr
mov R_TMP2, sp
mrs r0, cpsr
and r0, r0, #(PSR_MODE)
teq r0, #(PSR_HYP32_MODE)
bne 1f
XPUTC('h')
mov sp, #0
mov r1, #0
mcrr p15, 4, r1, r1, c14
mrs r0, cpsr
bic r0, r0, #(PSR_MODE)
orr r0, r0, #(PSR_SVC32_MODE)
orr r0, r0, #(I32_bit | F32_bit)
msr spsr_cxsf, r0
adr lr, 2f
msr elr_hyp, lr
eret
1:
cpsid if, #PSR_SVC32_MODE
2:
mov r0, #0
msr spsr_sxc, r0
mov sp, R_TMP2
XPUTC('A')
mrc p15, 0, r0, c1, c0, 0
tst r0, #CPU_CONTROL_DC_ENABLE
blne armv7_dcache_wbinv_all
#define ARMV7_SCTLR_CLEAR ( \
CPU_CONTROL_IC_ENABLE | \
CPU_CONTROL_DC_ENABLE | \
CPU_CONTROL_MMU_ENABLE | \
CPU_CONTROL_BPRD_ENABLE | \
CPU_CONTROL_TR_ENABLE | \
0)
#define ARMV7_SCTLR_SET ( \
CPU_CONTROL_UNAL_ENABLE | \
CPU_CONTROL_XP_SWP_ENABLE | \
0)
mrc p15, 0, r0, c1, c0, 0
movw r1, #:lower16:ARMV7_SCTLR_CLEAR
movt r1, #:upper16:ARMV7_SCTLR_CLEAR
movw r2, #:lower16:ARMV7_SCTLR_SET
movt r2, #:upper16:ARMV7_SCTLR_SET
mov R_TMP2, r0
bic r0, r0, r1
orr r0, r0, r2
mcr p15, 0, r0, c1, c0, 0
dsb
isb
bl armv7_dcache_inv_all
mcr p15, 0, r0, c7, c5, 0
dsb
isb
#if defined(VERBOSE_INIT_ARM)
XPUTC(#'B')
VPRINTF(" sctlr:")
VPRINTX(R_TMP2)
VPRINTF("/")
mrc p15, 0, r0, c1, c0, 0
VPRINTX(r0)
VPRINTF(" ")
XPUTC(#'C')
#endif
bx R_TMP1
.ltorg
armv7_mmuinit:
mov r4, lr
mov r5, r0
XPUTC(#'F')
dsb
XPUTC(#'G')
mrc p15, 0, r1, c0, c0, 5
cmp r1, #0
orrlt r5, r5, #TTBR_MPATTR
orrge r5, r5, #TTBR_UPATTR
XPUTC(#'0')
mcr p15, 0, r5, c2, c0, 0
#if defined(ARM_MMU_EXTENDED)
XPUTC(#'1')
mcr p15, 0, r5, c2, c0, 1
#endif
XPUTC(#'H')
#if defined(ARM_MMU_EXTENDED)
XPUTC(#'1')
mov r1, #TTBCR_S_N_1
#else
XPUTC(#'0')
mov r1, #0
#endif
mcr p15, 0, r1, c2, c0, 2
XPUTC(#'J')
mov r1, #0
mcr p15, 0, r1, c13, c0, 1
isb
XPUTC(#'K')
mov r1, #DOMAIN_DEFAULT
mcr p15, 0, r1, c3, c0, 0
#if 0
ldr r0, =0xAAAAA
mcr CP15_PRRR(r0)
mov r0, #0
mcr CP15_NMRR(r0)
#endif
XPUTC(#'I')
mov r1, #0
mcr p15, 0, r1, c8, c7, 0
dsb
isb
XPUTC(#'L')
XPUTC(#'\n')
XPUTC(#'\r')
mrc p15, 0, r1, c1, c0, 0
movw r3, #:lower16:CPU_CONTROL_SET
movt r3, #:upper16:CPU_CONTROL_SET
movw r2, #:lower16:CPU_CONTROL_CLR
movt r2, #:upper16:CPU_CONTROL_CLR
orr r0, r1, r3
bic r0, r0, r2
mcr p15, 0, r0, c1, c0, 0
dsb
isb
mcr p15, 0, r0, c8, c7, 0
mcr p15, 0, r0, c7, c5, 6
dsb
isb
VPRINTF("MMU\n\r")
bx r4
.p2align 2
.text
ENTRY_NP(cpu_mpstart)
#ifndef MULTIPROCESSOR
3: wfi
b 3b
#else
#if defined(__ARMEB__)
setend be
#endif
cpsid if
adr R_TMP2, cpu_mpstart
ldr R_VTOPDIFF, =cpu_mpstart
sub R_VTOPDIFF, R_VTOPDIFF, R_TMP2
mrc p15, 0, r4, c0, c0, 5
and r4, #(MPIDR_AFF2|MPIDR_AFF1|MPIDR_AFF0)
mov r0, #0
ldr r1, =cpu_mpidr
sub r1, R_VTOPDIFF
1:
ldr r2, [r1, r0, lsl #2]
cmp r2, r4
beq 2f
add r0, #1
cmp r0, #MAXCPUS
bne 1b
and r0, r4, #7
2:
mov R_INDEX, r0
ldr R_TMP1, =start_stacks_top
sub sp, R_TMP1, R_VTOPDIFF
mov r5, R_INDEX
lsl r5, #INIT_ARM_STACK_SHIFT
sub sp, sp, r5
#if defined(VERBOSE_INIT_ARM)
VPRINTF("\n\rmidr : ")
mrc p15, 0, r0, c0, c0, 0
VPRINTX(r0)
VPRINTF("\n\rrevidr: ")
mrc p15, 0, r0, c0, c0, 6
VPRINTX(r0)
VPRINTF("\n\rmpidr : ")
mrc p15, 0, r0, c0, c0, 5
VPRINTX(r0)
#endif
VPRINTF("\n\rindex : ")
VPRINTX(R_INDEX)
VPRINTF("\n\rsp : ")
VPRINTX(sp)
XPUTC('\n')
XPUTC('\r')
bl armv7_init
movw r0, #:lower16:TEMP_L1_TABLE
movt r0, #:upper16:TEMP_L1_TABLE
sub r0, R_VTOPDIFF
movw lr, #:lower16:armv7_mpcontinuation
movt lr, #:upper16:armv7_mpcontinuation
b armv7_mmuinit
ASEND(cpu_mpstart)
armv7_mpcontinuation:
add sp, sp, R_VTOPDIFF
VPRINTF("virtual\n\r")
mov r0, R_INDEX
bl cpu_init_secondary_processor
movw r6, #:lower16:arm_cpu_mbox
movt r6, #:upper16:arm_cpu_mbox
mov r5, #1
lsl r5, R_INDEX
1: ldr r2, [r6]
dmb
tst r2, r5
wfeeq
beq 1b
movw r0, #:lower16:cpu_info
movt r0, #:upper16:cpu_info
ldr r5, [r0, R_INDEX, lsl #2]
ldr r6, [r5, #CI_IDLELWP]
ldr r7, [r6, #L_PCB]
ldr sp, [r7, #PCB_KSP]
#if defined(TPIDRPRW_IS_CURCPU)
mcr p15, 0, r5, c13, c0, 4
#elif defined(TPIDRPRW_IS_CURLWP)
mcr p15, 0, r6, c13, c0, 4
#else
#error either TPIDRPRW_IS_CURCPU or TPIDRPRW_IS_CURLWP must be defined
#endif
str r6, [r5, #CI_CURLWP]
mov r0, r5
mov r1, R_INDEX
movw r2, #:lower16:MD_CPU_HATCH
movt r2, #:upper16:MD_CPU_HATCH
bl _C_LABEL(cpu_hatch)
b _C_LABEL(idle_loop)
ASEND(armv7_mpcontinuation)
#endif
#elif defined(_ARM_ARCH_6)
ENTRY_NP(armv6_init)
#define Invalidate_I_cache(reg) \
.p2align 5; \
mcr p15, 0, reg, c7, c5, 0; \
mcr p15, 0, reg, c7, c5, 0; \
mcr p15, 0, reg, c7, c5, 0; \
mcr p15, 0, reg, c7, c5, 0; \
nop; \
nop; \
nop; \
nop; \
nop; \
nop; \
nop; \
nop; \
nop; \
nop; \
nop;
mov R_TMP1, lr
mov r0, #0
Invalidate_I_cache(r0)
mcr p15, 0, r0, c7, c14, 0
ldr r2, =(CPU_CONTROL_IC_ENABLE|CPU_CONTROL_DC_ENABLE)
mrc p15, 0, r1, c1, c0, 0
mov R_TMP2, r1
bic r1, r1, r2
mcr p15, 0, r1, c1, c0, 0
mcr p15, 0, r0, c7, c10, 4
#if defined(VERBOSE_INIT_ARM)
XPUTC(#'B')
VPRINTF(" sctlr:")
VPRINTX(R_TMP2)
VPRINTF("/")
mrc p15, 0, r0, c1, c0, 0
VPRINTX(r0)
VPRINTF(" ")
XPUTC(#'C')
#endif
bx R_TMP1
.ltorg
armv6_mmuinit:
mov r4, lr
mov r5, r0
XPUTC(#'0')
mcr p15, 0, r5, c2, c0, 0
#if defined(ARM_MMU_EXTENDED)
XPUTC(#'1')
mcr p15, 0, r5, c2, c0, 1
#endif
XPUTC(#'H')
#if defined(ARM_MMU_EXTENDED)
XPUTC(#'1')
mov r1, #TTBCR_S_N_1
#else
XPUTC(#'0')
mov r1, #0
#endif
mcr p15, 0, r1, c2, c0, 2
XPUTC(#'I')
mov r0, #0
mcr p15, 0, r0, c8, c7, 0
XPUTC(#'K')
mov r0, #DOMAIN_DEFAULT
mcr p15, 0, r0, c3, c0, 0
#if defined(VERBOSE_INIT_ARM)
VPRINTF(" sctlr:")
mrc p15, 0, r0, c1, c0, 0
VPRINTX(r0)
VPRINTF("/")
#endif
mrc p15, 0, r0, c1, c0, 0
ldr r1, Lcontrol_wax
and r0, r0, r1
ldr r1, Lcontrol_clr
bic r0, r0, r1
ldr r1, Lcontrol_set
orr r0, r0, r1
mov r6, r0
VPRINTX(r6)
VPRINTF(" ")
.align 5
mov r0, r6
mcr p15, 0, r0, c1, c0, 0
mrc p15, 0, r0, c0, c0, 0
mov r0, r0
nop
nop
nop
nop
nop
mov pc, r4
.ltorg
Lcontrol_set:
#if defined(ARM_MMU_EXTENDED)
#define CPU_CONTROL_EXTRA CPU_CONTROL_XP_ENABLE
#else
#define CPU_CONTROL_EXTRA CPU_CONTROL_SYST_ENABLE
#endif
#if defined(__ARMEL__)
#define CPU_CONTROL_EX_BEND_SET 0
#else
#define CPU_CONTROL_EX_BEND_SET CPU_CONTROL_EX_BEND
#endif
.word CPU_CONTROL_MMU_ENABLE | \
CPU_CONTROL_WBUF_ENABLE | \
CPU_CONTROL_32BP_ENABLE | \
CPU_CONTROL_32BD_ENABLE | \
CPU_CONTROL_LABT_ENABLE | \
(1 << 16) | \
(1 << 18) | \
CPU_CONTROL_UNAL_ENABLE | \
CPU_CONTROL_EXTRA | \
CPU_CONTROL_EX_BEND_SET
Lcontrol_clr:
.word 0
Lcontrol_wax:
.word (3 << 30) | \
(1 << 29) | \
(1 << 28) | \
(3 << 26) | \
(3 << 19) | \
(1 << 17) | \
(1 << 10)
#elif defined(_ARM_ARCH_5)
armv5_init:
bx lr
.ltorg
armv5_mmu_enable_bits:
.word CPU_CONTROL_MMU_ENABLE | \
CPU_CONTROL_WBUF_ENABLE | \
CPU_CONTROL_32BP_ENABLE | \
CPU_CONTROL_32BD_ENABLE | \
CPU_CONTROL_LABT_ENABLE | \
(1 << 16) | \
(1 << 18)
armv5_mmuinit:
mov r4, lr
mov r5, r0
mcr p15, 0, r5, c2, c0, 0
VPRINTF("\n\rTTBR : ")
VPRINTX(r5)
mov r1, #0
mcr p15, 0, r1, c8, c7, 0
mov r5, #DOMAIN_DEFAULT
mcr p15, 0, r5, c3, c0, 0
VPRINTF("\n\rDACR : ")
VPRINTX(r5)
VPRINTF("\n\rSCTLR: ")
#if defined(VERBOSE_INIT_ARM)
mrc p15, 0, r5, c1, c0, 0
VPRINTX(r5)
VPRINTF("/")
#endif
mrc p15, 0, r0, c1, c0, 0
mov r5, r0
ldr r1, armv5_mmu_enable_bits
orr r0, r0, r1
mov r6, r0
VPRINTX(r6)
mcr p15, 0, r6, c1, c0, 0
nop
nop
nop
VPRINTF("\n\rMMU")
bx r4
#endif
ENTRY_NP(generic_vprint)
push {r4, lr}
mov r4, lr
b 2f
1:
bl uartputc
2:
ldrb r0, [r4], #1
cmp r0, #0
bne 1b
add lr, r4, #3
bic lr, #3
pop {r4}
add sp, sp, #4
mov pc, lr
ASEND(generic_vprint)
ENTRY_NP(generic_prints)
push {r4, lr}
mov r4, r0
1:
ldrb r0, [r4], #1
cmp r0, #0
popeq {r4, pc}
bl uartputc
b 1b
ASEND(generic_prints)
ENTRY_NP(generic_printx)
push {r4, r5, r6, lr}
mov r5, r0
mov r0, #'0'
bl uartputc
mov r0, #'x'
bl uartputc
mov r4, #32
1:
sub r4, r4, #4
lsr r3, r5, r4
and r3, r3, #0xf
cmp r3, #9
add r0, r3, #'0'
addgt r0, r3, #'a' - 10
bl uartputc
cmp r4, #0
bne 1b
pop {r4, r5, r6, pc}
ASEND(generic_printx)