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 // ARM MPIDR_EL1 bytes: Aff3 (AArch64), Stuff, Aff2, Aff1, Aff0 38 // Test the the MPIDR_EL1 register against 0xff00ffffff to 39 // extract the primary CPU. 40 ldr x1, =0xff00ffffff 41 tst x0, x1 // check for cpuid==zero 42 b.ne 1f // secondary CPU 43 44 ldr x1, =GIC_DIST_BASE // GICD_CTLR 45 mov w0, #3 // EnableGrp0 | EnableGrp1 46 str w0, [x1] 47 481: ldr x1, =GIC_DIST_BASE + 0x80 // GICD_IGROUPR 49 mov w0, #~0 // Grp1 interrupts 50 str w0, [x1], #4 51 b.ne 2f // Only local interrupts for secondary CPUs 52 str w0, [x1], #4 53 str w0, [x1], #4 54 552: ldr x1, =GIC_CPU_BASE // GICC_CTLR 56 ldr w0, [x1] 57 mov w0, #3 // EnableGrp0 | EnableGrp1 58 str w0, [x1] 59 60 mov w0, #1 << 7 // allow NS access to GICC_PMR 61 str w0, [x1, #4] // GICC_PMR 62 63 msr sctlr_el2, xzr 64 65 /* 66 * Prepare the switch to the EL2_SP1 mode from EL3 67 */ 68 ldr x0, =start_ns // Return after mode switch 69 mov x1, #0x3c9 // EL2_SP1 | D | A | I | F 70 msr elr_el3, x0 71 msr spsr_el3, x1 72 eret 73 74start_ns: 75 /* 76 * Kernel parameters 77 */ 78 mov x0, xzr 79 mov x1, xzr 80 mov x2, xzr 81 mov x3, xzr 82 83 mrs x4, mpidr_el1 84 // ARM MPIDR_EL1 bytes: Aff3 (AArch64), Stuff, Aff2, Aff1, Aff0 85 // Test the the MPIDR_EL1 register against 0xff00ffffff to 86 // extract the primary CPU. 87 ldr x1, =0xff00ffffff 88 tst x4, x1 // check for cpuid==zero 89 mov x1, xzr // load previous 'xzr' value back to x1 90 b.eq 2f // secondary CPU 91 92 /* 93 * Secondary CPUs 94 */ 951: wfe 96 ldr x4, =PHYS_OFFSET + 0xfff8 97 ldr x4, [x4] 98 cbz x4, 1b 99 br x4 // branch to the given address 100 1012: 102 /* 103 * UART initialisation (38400 8N1) 104 */ 105 ldr x4, =UART_BASE // UART base 106 mov w5, #0x10 // ibrd 107 str w5, [x4, #0x24] 108 mov w5, #0xc300 109 orr w5, w5, #0x0001 // cr 110 str w5, [x4, #0x30] 111 112 /* 113 * CLCD output site MB 114 */ 115 ldr x4, =SYSREGS_BASE 116 ldr w5, =(1 << 31) | (1 << 30) | (7 << 20) | (0 << 16) // START|WRITE|MUXFPGA|SITE_MB 117 str wzr, [x4, #0xa0] // V2M_SYS_CFGDATA 118 str w5, [x4, #0xa4] // V2M_SYS_CFGCTRL 119 120 // set up the arch timer frequency 121 //ldr x0, =CNTFRQ 122 //msr cntfrq_el0, x0 123 124 /* 125 * Primary CPU 126 */ 127 ldr x0, =PHYS_OFFSET + 0x8000000 // device tree blob 128 ldr x6, =PHYS_OFFSET + 0x80000 // kernel start address 129 br x6 130 131 .ltorg 132 133 .org 0x200
| 37 */ 38 39 .text 40 41 .globl _start 42_start: 43 /* 44 * EL3 initialisation 45 */ 46 mrs x0, CurrentEL 47 cmp x0, #0xc // EL3? 48 b.ne start_ns // skip EL3 initialisation 49 50 mov x0, #0x30 // RES1 51 orr x0, x0, #(1 << 0) // Non-secure EL1 52 orr x0, x0, #(1 << 8) // HVC enable 53 orr x0, x0, #(1 << 10) // 64-bit EL2 54 msr scr_el3, x0 55 56 msr cptr_el3, xzr // Disable copro. traps to EL3 57 58 ldr x0, =CNTFRQ 59 msr cntfrq_el0, x0 60 61 /* 62 * Check for the primary CPU to avoid a race on the distributor 63 * registers. 64 */ 65 mrs x0, mpidr_el1 66 // ARM MPIDR_EL1 bytes: Aff3 (AArch64), Stuff, Aff2, Aff1, Aff0 67 // Test the the MPIDR_EL1 register against 0xff00ffffff to 68 // extract the primary CPU. 69 ldr x1, =0xff00ffffff 70 tst x0, x1 // check for cpuid==zero 71 b.ne 1f // secondary CPU 72 73 ldr x1, =GIC_DIST_BASE // GICD_CTLR 74 mov w0, #3 // EnableGrp0 | EnableGrp1 75 str w0, [x1] 76 771: ldr x1, =GIC_DIST_BASE + 0x80 // GICD_IGROUPR 78 mov w0, #~0 // Grp1 interrupts 79 str w0, [x1], #4 80 b.ne 2f // Only local interrupts for secondary CPUs 81 str w0, [x1], #4 82 str w0, [x1], #4 83 842: ldr x1, =GIC_CPU_BASE // GICC_CTLR 85 ldr w0, [x1] 86 mov w0, #3 // EnableGrp0 | EnableGrp1 87 str w0, [x1] 88 89 mov w0, #1 << 7 // allow NS access to GICC_PMR 90 str w0, [x1, #4] // GICC_PMR 91 92 msr sctlr_el2, xzr 93 94 /* 95 * Prepare the switch to the EL2_SP1 mode from EL3 96 */ 97 ldr x0, =start_ns // Return after mode switch 98 mov x1, #0x3c9 // EL2_SP1 | D | A | I | F 99 msr elr_el3, x0 100 msr spsr_el3, x1 101 eret 102 103start_ns: 104 /* 105 * Kernel parameters 106 */ 107 mov x0, xzr 108 mov x1, xzr 109 mov x2, xzr 110 mov x3, xzr 111 112 mrs x4, mpidr_el1 113 // ARM MPIDR_EL1 bytes: Aff3 (AArch64), Stuff, Aff2, Aff1, Aff0 114 // Test the the MPIDR_EL1 register against 0xff00ffffff to 115 // extract the primary CPU. 116 ldr x1, =0xff00ffffff 117 tst x4, x1 // check for cpuid==zero 118 mov x1, xzr // load previous 'xzr' value back to x1 119 b.eq 2f // secondary CPU 120 121 /* 122 * Secondary CPUs 123 */ 1241: wfe 125 ldr x4, =PHYS_OFFSET + 0xfff8 126 ldr x4, [x4] 127 cbz x4, 1b 128 br x4 // branch to the given address 129 1302: 131 /* 132 * UART initialisation (38400 8N1) 133 */ 134 ldr x4, =UART_BASE // UART base 135 mov w5, #0x10 // ibrd 136 str w5, [x4, #0x24] 137 mov w5, #0xc300 138 orr w5, w5, #0x0001 // cr 139 str w5, [x4, #0x30] 140 141 /* 142 * CLCD output site MB 143 */ 144 ldr x4, =SYSREGS_BASE 145 ldr w5, =(1 << 31) | (1 << 30) | (7 << 20) | (0 << 16) // START|WRITE|MUXFPGA|SITE_MB 146 str wzr, [x4, #0xa0] // V2M_SYS_CFGDATA 147 str w5, [x4, #0xa4] // V2M_SYS_CFGCTRL 148 149 // set up the arch timer frequency 150 //ldr x0, =CNTFRQ 151 //msr cntfrq_el0, x0 152 153 /* 154 * Primary CPU 155 */ 156 ldr x0, =PHYS_OFFSET + 0x8000000 // device tree blob 157 ldr x6, =PHYS_OFFSET + 0x80000 // kernel start address 158 br x6 159 160 .ltorg 161 162 .org 0x200
|