boot.S revision 11258
1955SN/A/*
2955SN/A * boot.S - simple register setup code for stand-alone Linux booting
31762SN/A *
4955SN/A * Copyright (C) 2012 ARM Limited. All rights reserved.
5955SN/A *
6955SN/A * Use of this source code is governed by a BSD-style license that can be
7955SN/A * found in the LICENSE.txt file.
8955SN/A */
9955SN/A
10955SN/A        .text
11955SN/A
12955SN/A        .globl	_start
13955SN/A_start:
14955SN/A        /*
15955SN/A         * EL3 initialisation
16955SN/A         */
17955SN/A        mrs	x0, CurrentEL
18955SN/A        cmp	x0, #0xc			// EL3?
19955SN/A        b.ne	start_ns			// skip EL3 initialisation
20955SN/A
21955SN/A        mov	x0, #0x30			// RES1
22955SN/A        orr	x0, x0, #(1 << 0)		// Non-secure EL1
23955SN/A        orr	x0, x0, #(1 << 8)		// HVC enable
24955SN/A        orr	x0, x0, #(1 << 10)		// 64-bit EL2
25955SN/A        msr	scr_el3, x0
26955SN/A
27955SN/A        msr	cptr_el3, xzr			// Disable copro. traps to EL3
28955SN/A
29955SN/A        ldr	x0, =CNTFRQ
30955SN/A        msr	cntfrq_el0, x0
31955SN/A
32955SN/A        /*
332632Sstever@eecs.umich.edu         * Check for the primary CPU to avoid a race on the distributor
342632Sstever@eecs.umich.edu         * registers.
352632Sstever@eecs.umich.edu         */
362632Sstever@eecs.umich.edu        mrs	x0, mpidr_el1
37955SN/A        // ARM MPIDR_EL1 bytes: Aff3 (AArch64), Stuff, Aff2, Aff1, Aff0
382632Sstever@eecs.umich.edu        // Test the the MPIDR_EL1 register against 0xff00ffffff to
392632Sstever@eecs.umich.edu        // extract the primary CPU.
402632Sstever@eecs.umich.edu        ldr x1, =0xff00ffffff
412632Sstever@eecs.umich.edu        tst x0, x1                    // check for cpuid==zero
422632Sstever@eecs.umich.edu        b.ne	1f				      // secondary CPU
432632Sstever@eecs.umich.edu
442632Sstever@eecs.umich.edu        ldr	x1, =GIC_DIST_BASE		// GICD_CTLR
452632Sstever@eecs.umich.edu        mov	w0, #3				// EnableGrp0 | EnableGrp1
462632Sstever@eecs.umich.edu        str	w0, [x1]
472632Sstever@eecs.umich.edu
482632Sstever@eecs.umich.edu1:	ldr	x1, =GIC_DIST_BASE + 0x80	// GICD_IGROUPR
492632Sstever@eecs.umich.edu        mov	w0, #~0				// Grp1 interrupts
502632Sstever@eecs.umich.edu        str	w0, [x1], #4
512632Sstever@eecs.umich.edu        b.ne	2f				// Only local interrupts for secondary CPUs
522632Sstever@eecs.umich.edu        str	w0, [x1], #4
532632Sstever@eecs.umich.edu        str	w0, [x1], #4
542632Sstever@eecs.umich.edu
552632Sstever@eecs.umich.edu2:	ldr	x1, =GIC_CPU_BASE		// GICC_CTLR
562632Sstever@eecs.umich.edu        ldr	w0, [x1]
572632Sstever@eecs.umich.edu        mov	w0, #3				// EnableGrp0 | EnableGrp1
58955SN/A        str	w0, [x1]
59955SN/A
60955SN/A        mov	w0, #1 << 7			// allow NS access to GICC_PMR
61955SN/A        str	w0, [x1, #4]			// GICC_PMR
62955SN/A
63955SN/A        msr	sctlr_el2, xzr
64955SN/A
651858SN/A        /*
661858SN/A         * Prepare the switch to the EL2_SP1 mode from EL3
672653Sstever@eecs.umich.edu         */
682653Sstever@eecs.umich.edu        ldr	x0, =start_ns			// Return after mode switch
692653Sstever@eecs.umich.edu        mov	x1, #0x3c9			// EL2_SP1 | D | A | I | F
702653Sstever@eecs.umich.edu        msr	elr_el3, x0
712653Sstever@eecs.umich.edu        msr	spsr_el3, x1
722653Sstever@eecs.umich.edu        eret
732653Sstever@eecs.umich.edu
742653Sstever@eecs.umich.edustart_ns:
752653Sstever@eecs.umich.edu        /*
762653Sstever@eecs.umich.edu         * Kernel parameters
772653Sstever@eecs.umich.edu         */
781852SN/A        mov	x0, xzr
79955SN/A        mov	x1, xzr
80955SN/A        mov	x2, xzr
81955SN/A        mov	x3, xzr
822632Sstever@eecs.umich.edu
832632Sstever@eecs.umich.edu        mrs	x4, mpidr_el1
84955SN/A        // ARM MPIDR_EL1 bytes: Aff3 (AArch64), Stuff, Aff2, Aff1, Aff0
851533SN/A        // Test the the MPIDR_EL1 register against 0xff00ffffff to
862632Sstever@eecs.umich.edu        // extract the primary CPU.
871533SN/A        ldr x1, =0xff00ffffff
88955SN/A        tst x4, x1                    // check for cpuid==zero
89955SN/A        mov x1, xzr                   // load previous 'xzr' value back to x1
902632Sstever@eecs.umich.edu        b.eq	2f				      // secondary CPU
912632Sstever@eecs.umich.edu
92955SN/A        /*
93955SN/A         * Secondary CPUs
94955SN/A         */
95955SN/A1:	wfe
962632Sstever@eecs.umich.edu        ldr	x4, =PHYS_OFFSET + 0xfff8
97955SN/A        ldr     x4, [x4]
982632Sstever@eecs.umich.edu        cbz	x4, 1b
99955SN/A        br	x4				// branch to the given address
100955SN/A
1012632Sstever@eecs.umich.edu2:
1022632Sstever@eecs.umich.edu        /*
1032632Sstever@eecs.umich.edu         * UART initialisation (38400 8N1)
1042632Sstever@eecs.umich.edu         */
1052632Sstever@eecs.umich.edu        ldr	x4, =UART_BASE			// UART base
1062632Sstever@eecs.umich.edu        mov	w5, #0x10			// ibrd
1072632Sstever@eecs.umich.edu        str	w5, [x4, #0x24]
1082632Sstever@eecs.umich.edu        mov	w5, #0xc300
1092632Sstever@eecs.umich.edu        orr	w5, w5, #0x0001			// cr
1102632Sstever@eecs.umich.edu        str	w5, [x4, #0x30]
1112632Sstever@eecs.umich.edu
1122632Sstever@eecs.umich.edu        /*
1132632Sstever@eecs.umich.edu         * CLCD output site MB
1142632Sstever@eecs.umich.edu         */
1152632Sstever@eecs.umich.edu        ldr	x4, =SYSREGS_BASE
1162632Sstever@eecs.umich.edu        ldr	w5, =(1 << 31) | (1 << 30) | (7 << 20) | (0 << 16)	// START|WRITE|MUXFPGA|SITE_MB
1172632Sstever@eecs.umich.edu        str	wzr, [x4, #0xa0]		// V2M_SYS_CFGDATA
1182634Sstever@eecs.umich.edu        str	w5, [x4, #0xa4]			// V2M_SYS_CFGCTRL
1192634Sstever@eecs.umich.edu
1202632Sstever@eecs.umich.edu        // set up the arch timer frequency
1212638Sstever@eecs.umich.edu        //ldr	x0, =CNTFRQ
1222632Sstever@eecs.umich.edu        //msr	cntfrq_el0, x0
1232632Sstever@eecs.umich.edu
1242632Sstever@eecs.umich.edu        /*
1252632Sstever@eecs.umich.edu         * Primary CPU
1262632Sstever@eecs.umich.edu         */
1272632Sstever@eecs.umich.edu        ldr	x0, =PHYS_OFFSET + 0x8000000	 // device tree blob
1281858SN/A        ldr     x6, =PHYS_OFFSET + 0x80000       // kernel start address
1292638Sstever@eecs.umich.edu        br	x6
1302638Sstever@eecs.umich.edu
1312638Sstever@eecs.umich.edu        .ltorg
1322638Sstever@eecs.umich.edu
1332638Sstever@eecs.umich.edu        .org	0x200
1342638Sstever@eecs.umich.edu