boot.S revision 11258
110037SARM gem5 Developers/*
210037SARM gem5 Developers * boot.S - simple register setup code for stand-alone Linux booting
310037SARM gem5 Developers *
410037SARM gem5 Developers * Copyright (C) 2012 ARM Limited. All rights reserved.
510037SARM gem5 Developers *
610037SARM gem5 Developers * Use of this source code is governed by a BSD-style license that can be
710037SARM gem5 Developers * found in the LICENSE.txt file.
810037SARM gem5 Developers */
910037SARM gem5 Developers
1010037SARM gem5 Developers        .text
1110037SARM gem5 Developers
1210037SARM gem5 Developers        .globl	_start
1310037SARM gem5 Developers_start:
1410037SARM gem5 Developers        /*
1510037SARM gem5 Developers         * EL3 initialisation
1610037SARM gem5 Developers         */
1710037SARM gem5 Developers        mrs	x0, CurrentEL
1810037SARM gem5 Developers        cmp	x0, #0xc			// EL3?
1910037SARM gem5 Developers        b.ne	start_ns			// skip EL3 initialisation
2010037SARM gem5 Developers
2110037SARM gem5 Developers        mov	x0, #0x30			// RES1
2210037SARM gem5 Developers        orr	x0, x0, #(1 << 0)		// Non-secure EL1
2310037SARM gem5 Developers        orr	x0, x0, #(1 << 8)		// HVC enable
2410037SARM gem5 Developers        orr	x0, x0, #(1 << 10)		// 64-bit EL2
2510037SARM gem5 Developers        msr	scr_el3, x0
2610037SARM gem5 Developers
2710037SARM gem5 Developers        msr	cptr_el3, xzr			// Disable copro. traps to EL3
2810037SARM gem5 Developers
2910037SARM gem5 Developers        ldr	x0, =CNTFRQ
3010037SARM gem5 Developers        msr	cntfrq_el0, x0
3110037SARM gem5 Developers
3210037SARM gem5 Developers        /*
3310037SARM gem5 Developers         * Check for the primary CPU to avoid a race on the distributor
3410037SARM gem5 Developers         * registers.
3510037SARM gem5 Developers         */
3610037SARM gem5 Developers        mrs	x0, mpidr_el1
3711258Skarthik.sangaiah@arm.com        // ARM MPIDR_EL1 bytes: Aff3 (AArch64), Stuff, Aff2, Aff1, Aff0
3811258Skarthik.sangaiah@arm.com        // Test the the MPIDR_EL1 register against 0xff00ffffff to
3911258Skarthik.sangaiah@arm.com        // extract the primary CPU.
4011258Skarthik.sangaiah@arm.com        ldr x1, =0xff00ffffff
4111258Skarthik.sangaiah@arm.com        tst x0, x1                    // check for cpuid==zero
4211258Skarthik.sangaiah@arm.com        b.ne	1f				      // secondary CPU
4310037SARM gem5 Developers
4410037SARM gem5 Developers        ldr	x1, =GIC_DIST_BASE		// GICD_CTLR
4510037SARM gem5 Developers        mov	w0, #3				// EnableGrp0 | EnableGrp1
4610037SARM gem5 Developers        str	w0, [x1]
4710037SARM gem5 Developers
4810037SARM gem5 Developers1:	ldr	x1, =GIC_DIST_BASE + 0x80	// GICD_IGROUPR
4910037SARM gem5 Developers        mov	w0, #~0				// Grp1 interrupts
5010037SARM gem5 Developers        str	w0, [x1], #4
5110037SARM gem5 Developers        b.ne	2f				// Only local interrupts for secondary CPUs
5210037SARM gem5 Developers        str	w0, [x1], #4
5310037SARM gem5 Developers        str	w0, [x1], #4
5410037SARM gem5 Developers
5510037SARM gem5 Developers2:	ldr	x1, =GIC_CPU_BASE		// GICC_CTLR
5610037SARM gem5 Developers        ldr	w0, [x1]
5710037SARM gem5 Developers        mov	w0, #3				// EnableGrp0 | EnableGrp1
5810037SARM gem5 Developers        str	w0, [x1]
5910037SARM gem5 Developers
6010037SARM gem5 Developers        mov	w0, #1 << 7			// allow NS access to GICC_PMR
6110037SARM gem5 Developers        str	w0, [x1, #4]			// GICC_PMR
6210037SARM gem5 Developers
6310037SARM gem5 Developers        msr	sctlr_el2, xzr
6410037SARM gem5 Developers
6510037SARM gem5 Developers        /*
6610037SARM gem5 Developers         * Prepare the switch to the EL2_SP1 mode from EL3
6710037SARM gem5 Developers         */
6810037SARM gem5 Developers        ldr	x0, =start_ns			// Return after mode switch
6910037SARM gem5 Developers        mov	x1, #0x3c9			// EL2_SP1 | D | A | I | F
7010037SARM gem5 Developers        msr	elr_el3, x0
7110037SARM gem5 Developers        msr	spsr_el3, x1
7210037SARM gem5 Developers        eret
7310037SARM gem5 Developers
7410037SARM gem5 Developersstart_ns:
7510037SARM gem5 Developers        /*
7610037SARM gem5 Developers         * Kernel parameters
7710037SARM gem5 Developers         */
7810037SARM gem5 Developers        mov	x0, xzr
7910037SARM gem5 Developers        mov	x1, xzr
8010037SARM gem5 Developers        mov	x2, xzr
8110037SARM gem5 Developers        mov	x3, xzr
8210037SARM gem5 Developers
8310037SARM gem5 Developers        mrs	x4, mpidr_el1
8411258Skarthik.sangaiah@arm.com        // ARM MPIDR_EL1 bytes: Aff3 (AArch64), Stuff, Aff2, Aff1, Aff0
8511258Skarthik.sangaiah@arm.com        // Test the the MPIDR_EL1 register against 0xff00ffffff to
8611258Skarthik.sangaiah@arm.com        // extract the primary CPU.
8711258Skarthik.sangaiah@arm.com        ldr x1, =0xff00ffffff
8811258Skarthik.sangaiah@arm.com        tst x4, x1                    // check for cpuid==zero
8911258Skarthik.sangaiah@arm.com        mov x1, xzr                   // load previous 'xzr' value back to x1
9011258Skarthik.sangaiah@arm.com        b.eq	2f				      // secondary CPU
9110037SARM gem5 Developers
9210037SARM gem5 Developers        /*
9310037SARM gem5 Developers         * Secondary CPUs
9410037SARM gem5 Developers         */
9510037SARM gem5 Developers1:	wfe
9610037SARM gem5 Developers        ldr	x4, =PHYS_OFFSET + 0xfff8
9710037SARM gem5 Developers        ldr     x4, [x4]
9810037SARM gem5 Developers        cbz	x4, 1b
9910037SARM gem5 Developers        br	x4				// branch to the given address
10010037SARM gem5 Developers
10110037SARM gem5 Developers2:
10210037SARM gem5 Developers        /*
10310037SARM gem5 Developers         * UART initialisation (38400 8N1)
10410037SARM gem5 Developers         */
10510037SARM gem5 Developers        ldr	x4, =UART_BASE			// UART base
10610037SARM gem5 Developers        mov	w5, #0x10			// ibrd
10710037SARM gem5 Developers        str	w5, [x4, #0x24]
10810037SARM gem5 Developers        mov	w5, #0xc300
10910037SARM gem5 Developers        orr	w5, w5, #0x0001			// cr
11010037SARM gem5 Developers        str	w5, [x4, #0x30]
11110037SARM gem5 Developers
11210037SARM gem5 Developers        /*
11310037SARM gem5 Developers         * CLCD output site MB
11410037SARM gem5 Developers         */
11510037SARM gem5 Developers        ldr	x4, =SYSREGS_BASE
11610037SARM gem5 Developers        ldr	w5, =(1 << 31) | (1 << 30) | (7 << 20) | (0 << 16)	// START|WRITE|MUXFPGA|SITE_MB
11710037SARM gem5 Developers        str	wzr, [x4, #0xa0]		// V2M_SYS_CFGDATA
11810037SARM gem5 Developers        str	w5, [x4, #0xa4]			// V2M_SYS_CFGCTRL
11910037SARM gem5 Developers
12010037SARM gem5 Developers        // set up the arch timer frequency
12110037SARM gem5 Developers        //ldr	x0, =CNTFRQ
12210037SARM gem5 Developers        //msr	cntfrq_el0, x0
12310037SARM gem5 Developers
12410037SARM gem5 Developers        /*
12510037SARM gem5 Developers         * Primary CPU
12610037SARM gem5 Developers         */
12710037SARM gem5 Developers        ldr	x0, =PHYS_OFFSET + 0x8000000	 // device tree blob
12810037SARM gem5 Developers        ldr     x6, =PHYS_OFFSET + 0x80000       // kernel start address
12910037SARM gem5 Developers        br	x6
13010037SARM gem5 Developers
13110037SARM gem5 Developers        .ltorg
13210037SARM gem5 Developers
13310037SARM gem5 Developers        .org	0x200
134