1 /* 2 * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. 3 * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without modification, 6 * are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, this list of 9 * conditions and the following disclaimer. 10 * 11 * 2. Redistributions in binary form must reproduce the above copyright notice, this list 12 * of conditions and the following disclaimer in the documentation and/or other materials 13 * provided with the distribution. 14 * 15 * 3. Neither the name of the copyright holder nor the names of its contributors may be used 16 * to endorse or promote products derived from this software without specific prior written 17 * permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 26 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 28 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 29 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 #define ASSEMBLY 33 #include "arch_config.h" 34 #include "los_vm_boot.h" 35 #include "los_vm_zone.h" 36 #include "los_mmu_descriptor_v6.h" 37 #undef ASSEMBLY 38 39 40 .global __exc_stack_top 41 .global __svc_stack_top 42 .global __exc_stack 43 .global __svc_stack 44 45 .extern __bss_start 46 .extern __bss_end 47 .extern hal_clock_initialize_start 48 .extern los_bss_init 49 .extern _osExceptFiqHdl 50 .extern _osExceptAddrAbortHdl 51 .extern _osExceptDataAbortHdl 52 .extern _osExceptPrefetchAbortHdl 53 .extern _osExceptSwiHdl 54 .extern _osExceptUndefInstrHdl 55 .extern __stack_chk_guard_setup 56 .extern g_firstPageTable 57 .extern g_mmuJumpPageTable 58 .extern g_archMmuInitMapping 59 .extern HalSecondaryCpuStart 60 61 .equ MPIDR_CPUID_MASK, 0xffU 62 63 .fpu neon-vfpv4 64 .syntax unified 65 .arch armv7-a 66 .arm 67 68 /* param0 is stack bottom, param1 is stack size, r12 hold cpu id */ 69 .macro EXC_SP_SET param0, param1 70 ldr r1, =\param0 71 mov r0, \param1 72 bl sp_set 73 .endm 74 75 /* param0 is stack top, param1 is stack size, param2 is magic num */ 76 .macro STACK_MAGIC_SET param0, param1, param2 77 ldr r0, =\param0 78 mov r1, \param1 79 ldr r2, =\param2 80 bl excstack_magic 81 .endm 82 83 .code 32 84 .section ".vectors","ax" 85 86 .global __exception_handlers 87 __exception_handlers: 88 /* 89 *Assumption: ROM code has these vectors at the hardware reset address. 90 *A simple jump removes any address-space dependencies [i.e. safer] 91 */ 92 b reset_vector 93 b _osExceptUndefInstrHdl 94 b _osExceptSwiHdl 95 b _osExceptPrefetchAbortHdl 96 b _osExceptDataAbortHdl 97 b _osExceptAddrAbortHdl 98 b OsIrqHandler 99 b _osExceptFiqHdl 100 101 /* Startup code which will get the machine into supervisor mode */ 102 .global reset_vector 103 .type reset_vector,function 104 105 #ifdef LOSCFG_BOOTENV_RAM 106 __quickstart_args_start: 107 .fill LOSCFG_BOOTENV_RAMSIZE,1,0 108 __quickstart_args_end: 109 110 .global OsGetArgsAddr 111 .type OsGetArgsAddr,function 112 113 OsGetArgsAddr: 114 ldr r0, =__quickstart_args_start 115 bx lr 116 #endif 117 118 reset_vector: 119 /* clear register TPIDRPRW */ 120 mov r0, #0 121 mcr p15, 0, r0, c13, c0, 4 122 /* do some early cpu setup: i/d cache disable, mmu disabled */ 123 mrc p15, 0, r0, c1, c0, 0 124 bic r0, #(1 << 12) /* i cache */ 125 bic r0, #(1 << 2) /* d cache */ 126 bic r0, #(1 << 0) /* mmu */ 127 mcr p15, 0, r0, c1, c0, 0 128 129 /* enable fpu+neon */ 130 #ifndef LOSCFG_TEE_ENABLE 131 MRC p15, 0, r0, c1, c1, 2 132 ORR r0, r0, #0xC00 133 BIC r0, r0, #0xC000 134 MCR p15, 0, r0, c1, c1, 2 135 136 LDR r0, =(0xF << 20) 137 MCR p15, 0, r0, c1, c0, 2 138 ISB 139 #endif 140 MOV r3, #0x40000000 141 VMSR FPEXC, r3 142 143 /* r11: delta of physical address and virtual address */ 144 adr r11, pa_va_offset 145 ldr r0, [r11] 146 sub r11, r11, r0 147 148 mrc p15, 0, r12, c0, c0, 5 /* r12: get cpuid */ 149 and r12, r12, #MPIDR_CPUID_MASK 150 cmp r12, #0 151 bne secondary_cpu_init 152 153 /* if we need to relocate to proper location or not */ 154 adr r4, __exception_handlers /* r4: base of load address */ 155 ldr r5, =SYS_MEM_BASE /* r5: base of physical address */ 156 subs r12, r4, r5 /* r12: delta of load address and physical address */ 157 beq reloc_img_to_bottom_done /* if we load image at the bottom of physical address */ 158 159 /* we need to relocate image at the bottom of physical address */ 160 ldr r7, =__exception_handlers /* r7: base of linked address (or vm address) */ 161 ldr r6, =__bss_start /* r6: end of linked address (or vm address) */ 162 sub r6, r7 /* r6: delta of linked address (or vm address) */ 163 add r6, r4 /* r6: end of load address */ 164 165 reloc_img_to_bottom_loop: 166 ldr r7, [r4], #4 167 str r7, [r5], #4 168 cmp r4, r6 169 bne reloc_img_to_bottom_loop 170 sub pc, r12 171 nop 172 sub r11, r11, r12 /* r11: eventual address offset */ 173 174 reloc_img_to_bottom_done: 175 #ifdef LOSCFG_KERNEL_MMU 176 ldr r4, =g_firstPageTable /* r4: physical address of translation table and clear it */ 177 add r4, r4, r11 178 mov r0, r4 179 mov r1, #0 180 mov r2, #MMU_DESCRIPTOR_L1_SMALL_ENTRY_NUMBERS 181 bl memset_optimized /* optimized memset since r0 is 64-byte aligned */ 182 183 ldr r5, =g_archMmuInitMapping 184 add r5, r5, r11 185 init_mmu_loop: 186 ldmia r5!, {r6-r10} /* r6 = phys, r7 = virt, r8 = size, r9 = mmu_flags, r10 = name */ 187 cmp r8, 0 /* if size = 0, the mmu init done */ 188 beq init_mmu_done 189 bl page_table_build 190 b init_mmu_loop 191 init_mmu_done: 192 orr r8, r4, #MMU_TTBRx_FLAGS /* r8 = r4 and set cacheable attributes on translation walk */ 193 ldr r4, =g_mmuJumpPageTable /* r4: jump pagetable vaddr */ 194 add r4, r4, r11 195 ldr r4, [r4] 196 add r4, r4, r11 /* r4: jump pagetable paddr */ 197 198 /* build 1M section mapping, in order to jump va during turing on mmu:pa == pa, va == pa */ 199 mov r6, pc 200 mov r7, r6 /* r7: pa (MB aligned)*/ 201 lsr r6, r6, #20 /* r6: va l1 index */ 202 ldr r10, =MMU_DESCRIPTOR_KERNEL_L1_PTE_FLAGS 203 add r12, r10, r6, lsl #20 /* r12: pa |flags */ 204 str r12, [r4, r7, lsr #(20 - 2)] /* jumpTable[paIndex] = pt entry */ 205 rsb r7, r11, r6, lsl #20 /* r7: va */ 206 str r12, [r4, r7, lsr #(20 - 2)] /* jumpTable[vaIndex] = pt entry */ 207 208 bl mmu_setup /* set up the mmu */ 209 #endif 210 /* clear out the interrupt and exception stack and set magic num to check the overflow */ 211 ldr r0, =__svc_stack 212 ldr r1, =__exc_stack_top 213 bl stack_init 214 215 STACK_MAGIC_SET __svc_stack, #OS_EXC_SVC_STACK_SIZE, OS_STACK_MAGIC_WORD 216 STACK_MAGIC_SET __exc_stack, #OS_EXC_STACK_SIZE, OS_STACK_MAGIC_WORD 217 218 warm_reset: 219 /* initialize CPSR (machine state register) */ 220 mov r0, #(CPSR_IRQ_DISABLE|CPSR_FIQ_DISABLE|CPSR_SVC_MODE) 221 msr cpsr, r0 222 223 /* Note: some functions in LIBGCC1 will cause a "restore from SPSR"!! */ 224 msr spsr, r0 225 226 /* get cpuid and keep it in r12 */ 227 mrc p15, 0, r12, c0, c0, 5 228 and r12, r12, #MPIDR_CPUID_MASK 229 230 /* set svc stack, every cpu has OS_EXC_SVC_STACK_SIZE stack */ 231 ldr r0, =__svc_stack_top 232 mov r2, #OS_EXC_SVC_STACK_SIZE 233 mul r2, r2, r12 234 sub r0, r0, r2 235 mov sp, r0 236 237 LDR r0, =__exception_handlers 238 MCR p15, 0, r0, c12, c0, 0 239 240 cmp r12, #0 241 bne cpu_start 242 243 clear_bss: 244 ldr r0, =__bss_start 245 ldr r2, =__bss_end 246 mov r1, #0 247 sub r2, r2, r0 248 bl memset 249 250 #if defined(LOSCFG_CC_STACKPROTECTOR_ALL) || \ 251 defined(LOSCFG_CC_STACKPROTECTOR_STRONG) || \ 252 defined(LOSCFG_CC_STACKPROTECTOR) 253 bl __stack_chk_guard_setup 254 #endif 255 256 #ifdef LOSCFG_GDB_DEBUG 257 /* GDB_START - generate a compiled_breadk,This function will get GDB stubs started, with a proper environment */ 258 bl GDB_START 259 .word 0xe7ffdeff 260 #endif 261 262 bl main 263 264 _start_hang: 265 b _start_hang 266 #ifdef LOSCFG_KERNEL_MMU 267 mmu_setup: 268 mov r12, #0 269 mcr p15, 0, r12, c8, c7, 0 /* Set c8 to control the TLB and set the mapping to invalid */ 270 isb 271 mcr p15, 0, r12, c2, c0, 2 /* Initialize the c2 register */ 272 isb 273 orr r12, r4, #MMU_TTBRx_FLAGS 274 mcr p15, 0, r12, c2, c0, 0 /* Set attributes and set temp page table */ 275 isb 276 mov r12, #0x7 /* 0b0111 */ 277 mcr p15, 0, r12, c3, c0, 0 /* Set DACR with 0b0111, client and manager domian */ 278 isb 279 mrc p15, 0, r12, c1, c0, 1 /* ACTLR, Auxiliary Control Register */ 280 orr r12, r12, #(1 << 6) /* SMP, Enables coherent requests to the processor. */ 281 orr r12, r12, #(1 << 2) /* Enable D-side prefetch */ 282 orr r12, r12, #(1 << 11) /* Global BP Enable bit */ 283 mcr p15, 0, r12, c1, c0, 1 /* ACTLR, Auxiliary Control Register */ 284 dsb 285 mrc p15, 0, r12, c1, c0, 0 286 bic r12, #(1 << 29 | 1 << 28) /* Disable TRE/AFE */ 287 orr r12, #(1 << 0) /* mmu enable */ 288 bic r12, #(1 << 1) 289 orr r12, #(1 << 2) /* D cache enable */ 290 orr r12, #(1 << 12) /* I cache enable */ 291 mcr p15, 0, r12, c1, c0, 0 /* Set SCTLR with r12: Turn on the MMU, I/D cache Disable TRE/AFE */ 292 isb 293 ldr pc, =1f /* Convert to VA */ 294 1: 295 mcr p15, 0, r8, c2, c0, 0 /* Go to the base address saved in C2: Jump to the page table */ 296 isb 297 mov r12, #0 298 mcr p15, 0, r12, c8, c7, 0 299 isb 300 sub lr, r11 /* adjust lr with delta of physical address and virtual address */ 301 bx lr 302 #endif 303 .code 32 304 305 .global reset_platform 306 .type reset_platform,function 307 reset_platform: 308 #ifdef A7SEM_HAL_ROM_MONITOR 309 /* initialize CPSR (machine state register) */ 310 mov r0, #(CPSR_IRQ_DISABLE|CPSR_FIQ_DISABLE|CPSR_SVC_MODE) 311 msr cpsr, r0 312 b warm_reset 313 #else 314 mov r0, #0 315 mov pc, r0 // Jump to reset vector 316 #endif 317 318 cpu_start: 319 #ifdef LOSCFG_KERNEL_MMU 320 ldr r4, =g_firstPageTable /* r4 = physical address of translation table and clear it */ 321 add r4, r4, r11 322 orr r8, r4, #MMU_TTBRx_FLAGS 323 324 ldr r4, =g_mmuJumpPageTable /* r4 = tt_trampoline vaddr */ 325 add r4, r4, r11 326 ldr r4, [r4] 327 add r4, r4, r11 /* r4 = tt_trampoline paddr */ 328 329 bl mmu_setup 330 #endif 331 332 bl HalSecondaryCpuStart 333 b . 334 335 secondary_cpu_init: 336 #ifdef LOSCFG_TEE_ENABLE 337 /* enable fpu+neon */ 338 ldr r0, =0x60c00 339 MCR p15, 0, r0, c1, c1, 2 340 341 LDR r0, =(0xF << 20) 342 MCR p15, 0, r0, c1, c0, 2 343 cps #0x16 344 mov r1, #0x25 345 mcr p15, 0, r1, c1, c1, 0 346 cps #0x13 347 #endif 348 bl warm_reset 349 350 /* 351 * set sp for current cpu 352 * r1 is stack bottom, r0 is stack size, r12 hold cpu id 353 */ 354 sp_set: 355 mrc p15, 0, r12, c0, c0, 5 356 and r12, r12, #MPIDR_CPUID_MASK 357 mul r3, r0, r12 358 sub r2, r1, r3 359 mov sp, r2 360 bx lr /* set sp */ 361 362 /* 363 * r4: page table base address 364 * r6: physical address 365 * r7: virtual address 366 * r8: sizes 367 * r10: flags 368 * r9 and r12 will be used as variable 369 */ 370 #ifdef LOSCFG_KERNEL_MMU 371 page_table_build: 372 mov r10, r6 373 bfc r10, #20, #12 /* r9: pa % MB */ 374 add r8, r8, r10 375 add r8, r8, #(1 << 20) 376 sub r8, r8, #1 377 lsr r6, #20 /* r6 = physical address / MB */ 378 lsr r7, #20 /* r7 = virtual address / MB */ 379 lsr r8, #20 /* r8 = roundup(size, MB) */ 380 381 page_table_build_loop: 382 orr r12, r9, r6, lsl #20 /* r12: flags | physAddr */ 383 str r12, [r4, r7, lsl #2] /* gPgTable[l1Index] = physAddr | flags */ 384 add r6, #1 /* physAddr+ */ 385 add r7, #1 /* l1Index++ */ 386 subs r8, #1 /* sizes-- */ 387 bne page_table_build_loop 388 bx lr 389 #endif 390 /* 391 * init stack to initial value 392 * r0 is stack mem start, r1 is stack mem end 393 */ 394 stack_init: 395 ldr r2, =OS_STACK_INIT 396 ldr r3, =OS_STACK_INIT 397 /* Main loop sets 32 bytes at a time. */ 398 stack_init_loop: 399 .irp offset, #0, #8, #16, #24 400 strd r2, r3, [r0, \offset] 401 .endr 402 add r0, #32 403 cmp r0, r1 404 blt stack_init_loop 405 bx lr 406 407 pa_va_offset: 408 .word . 409 410 /* 411 * set magic num to stack top for all cpu 412 * r0 is stack top, r1 is stack size, r2 is magic num 413 */ 414 excstack_magic: 415 mov r3, #0 416 excstack_magic_loop: 417 str r2, [r0] 418 add r0, r0, r1 419 add r3, r3, #1 420 cmp r3, #CORE_NUM 421 blt excstack_magic_loop 422 bx lr 423 424 #ifdef LOSCFG_KERNEL_MMU 425 memset_optimized: 426 mov r3, r0 427 vdup.8 q0, r1 428 vmov q1, q0 429 vmov q2, q0 430 vmov q3, q0 431 memset_optimized_loop: 432 subs r2, #64 433 vstmia r3!, {d0 - d7} 434 bge memset_optimized_loop 435 bx lr 436 #endif 437 init_done: 438 .long 0xDEADB00B 439 440 .code 32 441 .data 442 443 init_flag: 444 .balign 4 445 .long 0 446 447 /* 448 * Temporary interrupt stack 449 */ 450 .section ".int_stack", "wa", %nobits 451 .align 3 452 453 __svc_stack: 454 .space OS_EXC_SVC_STACK_SIZE * CORE_NUM 455 __svc_stack_top: 456 457 __exc_stack: 458 .space OS_EXC_STACK_SIZE * CORE_NUM 459 __exc_stack_top: 460