boot.S revision 10037:5cac77888310
1/*
2 * boot.S - simple register setup code for stand-alone Linux booting
3 *
4 * Copyright (C) 2012 ARM Limited. All rights reserved.
5 *
6 * Use of this source code is governed by a BSD-style license that can be
7 * found in the LICENSE.txt file.
8 */
9
10        .text
11
12        .globl	_start
13_start:
14        /*
15         * EL3 initialisation
16         */
17        mrs	x0, CurrentEL
18        cmp	x0, #0xc			// EL3?
19        b.ne	start_ns			// skip EL3 initialisation
20
21        mov	x0, #0x30			// RES1
22        orr	x0, x0, #(1 << 0)		// Non-secure EL1
23        orr	x0, x0, #(1 << 8)		// HVC enable
24        orr	x0, x0, #(1 << 10)		// 64-bit EL2
25        msr	scr_el3, x0
26
27        msr	cptr_el3, xzr			// Disable copro. traps to EL3
28
29        ldr	x0, =CNTFRQ
30        msr	cntfrq_el0, x0
31
32        /*
33         * Check for the primary CPU to avoid a race on the distributor
34         * registers.
35         */
36        mrs	x0, mpidr_el1
37        tst	x0, #15
38        b.ne	1f				// secondary CPU
39
40        ldr	x1, =GIC_DIST_BASE		// GICD_CTLR
41        mov	w0, #3				// EnableGrp0 | EnableGrp1
42        str	w0, [x1]
43
441:	ldr	x1, =GIC_DIST_BASE + 0x80	// GICD_IGROUPR
45        mov	w0, #~0				// Grp1 interrupts
46        str	w0, [x1], #4
47        b.ne	2f				// Only local interrupts for secondary CPUs
48        str	w0, [x1], #4
49        str	w0, [x1], #4
50
512:	ldr	x1, =GIC_CPU_BASE		// GICC_CTLR
52        ldr	w0, [x1]
53        mov	w0, #3				// EnableGrp0 | EnableGrp1
54        str	w0, [x1]
55
56        mov	w0, #1 << 7			// allow NS access to GICC_PMR
57        str	w0, [x1, #4]			// GICC_PMR
58
59        msr	sctlr_el2, xzr
60
61        /*
62         * Prepare the switch to the EL2_SP1 mode from EL3
63         */
64        ldr	x0, =start_ns			// Return after mode switch
65        mov	x1, #0x3c9			// EL2_SP1 | D | A | I | F
66        msr	elr_el3, x0
67        msr	spsr_el3, x1
68        eret
69
70start_ns:
71        /*
72         * Kernel parameters
73         */
74        mov	x0, xzr
75        mov	x1, xzr
76        mov	x2, xzr
77        mov	x3, xzr
78
79        mrs	x4, mpidr_el1
80        tst	x4, #15
81        b.eq	2f
82
83        /*
84         * Secondary CPUs
85         */
861:	wfe
87        ldr	x4, =PHYS_OFFSET + 0xfff8
88        ldr     x4, [x4]
89        cbz	x4, 1b
90        br	x4				// branch to the given address
91
922:
93        /*
94         * UART initialisation (38400 8N1)
95         */
96        ldr	x4, =UART_BASE			// UART base
97        mov	w5, #0x10			// ibrd
98        str	w5, [x4, #0x24]
99        mov	w5, #0xc300
100        orr	w5, w5, #0x0001			// cr
101        str	w5, [x4, #0x30]
102
103        /*
104         * CLCD output site MB
105         */
106        ldr	x4, =SYSREGS_BASE
107        ldr	w5, =(1 << 31) | (1 << 30) | (7 << 20) | (0 << 16)	// START|WRITE|MUXFPGA|SITE_MB
108        str	wzr, [x4, #0xa0]		// V2M_SYS_CFGDATA
109        str	w5, [x4, #0xa4]			// V2M_SYS_CFGCTRL
110
111        // set up the arch timer frequency
112        //ldr	x0, =CNTFRQ
113        //msr	cntfrq_el0, x0
114
115        /*
116         * Primary CPU
117         */
118        ldr	x0, =PHYS_OFFSET + 0x8000000	 // device tree blob
119        ldr     x6, =PHYS_OFFSET + 0x80000       // kernel start address
120        br	x6
121
122        .ltorg
123
124        .org	0x200
125