1/* 2 * Copyright 2017, Data61 3 * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 * ABN 41 687 119 230. 5 * 6 * This software may be distributed and modified according to the terms of 7 * the GNU General Public License version 2. Note that NO WARRANTY is provided. 8 * See "LICENSE_GPLv2.txt" for details. 9 * 10 * @TAG(DATA61_GPL) 11 */ 12 13#include <config.h> 14#include <machine/assembler.h> 15#include <arch/machine/hardware.h> 16#include <arch/machine/registerset.h> 17#include <util.h> 18 19#ifndef ALLOW_UNALIGNED_ACCESS 20#define ALLOW_UNALIGNED_ACCESS 1 21#endif 22 23#if ALLOW_UNALIGNED_ACCESS 24#define CR_ALIGN_SET 0 25#define CR_ALIGN_CLEAR BIT(CONTROL_A) 26#else 27#define CR_ALIGN_SET BIT(CONTROL_A) 28#define CR_ALIGN_CLEAR 0 29#endif 30 31#ifndef CONFIG_DEBUG_DISABLE_L1_ICACHE 32 #define CR_L1_ICACHE_SET BIT(CONTROL_I) 33 #define CR_L1_ICACHE_CLEAR 0 34#else 35 #define CR_L1_ICACHE_SET 0 36 #define CR_L1_ICACHE_CLEAR BIT(CONTROL_I) 37#endif 38 39#ifndef CONFIG_DEBUG_DISABLE_L1_DCACHE 40 #define CR_L1_DCACHE_SET BIT(CONTROL_C) 41 #define CR_L1_DCACHE_CLEAR 0 42#else 43 #define CR_L1_DCACHE_SET 0 44 #define CR_L1_DCACHE_CLEAR BIT(CONTROL_C) 45#endif 46 47#define CR_BITS_SET (CR_ALIGN_SET | \ 48 CR_L1_ICACHE_SET | \ 49 CR_L1_DCACHE_SET | \ 50 BIT(CONTROL_M)) 51 52#define CR_BITS_CLEAR (CR_ALIGN_CLEAR | \ 53 CR_L1_ICACHE_CLEAR | \ 54 CR_L1_DCACHE_CLEAR | \ 55 BIT(CONTROL_SA0) | \ 56 BIT(CONTROL_EE) | \ 57 BIT(CONTROL_E0E)) 58 59/* 60 * Entry point of the kernel ELF image. 61 * X0-X3 contain parameters that are passed to init_kernel(). 62 * 63 * Note that for SMP kernel, the tpidr_el1 is used to pass 64 * the logical core ID. 65 */ 66 67#ifdef CONFIG_ARM_HYPERVISOR_SUPPORT 68#define SCTLR sctlr_el2 69#else 70#define SCTLR sctlr_el1 71#endif 72 73.section .boot.text 74BEGIN_FUNC(_start) 75 /* Make sure interrupts are disable */ 76 msr daifset, #DAIFSET_MASK 77 78 /* Initialise sctlr_el1 or sctlr_el2 register */ 79 msr spsel, #1 80 mrs x4, SCTLR 81 ldr x19, =CR_BITS_SET 82 ldr x20, =CR_BITS_CLEAR 83 orr x4, x4, x19 84 bic x4, x4, x20 85 msr SCTLR, x4 86 87#ifdef ENABLE_SMP_SUPPORT 88 /* tpidr_el1 has the logic ID of the core, starting from 0 */ 89 mrs x6, tpidr_el1 90 /* Set the sp for each core assuming linear indices */ 91 ldr x5, =BIT(CONFIG_KERNEL_STACK_BITS) 92 mul x5, x5, x6 93 ldr x4, =kernel_stack_alloc + BIT(CONFIG_KERNEL_STACK_BITS) 94 add x4, x4, x5 95 mov sp, x4 96 /* the kernel stack must be 4-KiB aligned since we use the 97 lowest 12 bits to store the logical core ID. */ 98 orr x6, x6, x4 99#ifdef CONFIG_ARM_HYPERVISOR_SUPPORT 100 msr tpidr_el2, x6 101#else 102 msr tpidr_el1, x6 103#endif 104#else 105 ldr x4, =kernel_stack_alloc + BIT(CONFIG_KERNEL_STACK_BITS) 106 mov sp, x4 107#endif /* ENABLE_SMP_SUPPORT */ 108 109 /* Attempt to workaround any known ARM errata. */ 110 stp x0, x1, [sp, #-16]! 111 stp x2, x3, [sp, #-16]! 112 bl arm_errata 113 ldp x2, x3, [sp], #16 114 ldp x0, x1, [sp], #16 115 116 /* Call bootstrapping implemented in C */ 117 bl init_kernel 118 119 /* Restore the initial thread */ 120 b restore_user_context 121END_FUNC(_start) 122