1/* 2 * Copyright 2014, General Dynamics C4 Systems 3 * 4 * This software may be distributed and modified according to the terms of 5 * the GNU General Public License version 2. Note that NO WARRANTY is provided. 6 * See "LICENSE_GPLv2.txt" for details. 7 * 8 * @TAG(GD_GPL) 9 */ 10 11#include <config.h> 12#include <machine/assembler.h> 13#include <arch/machine/hardware.h> 14#include <arch/machine/registerset.h> 15#include <util.h> 16 17#ifndef ALLOW_UNALIGNED_ACCESS 18#define ALLOW_UNALIGNED_ACCESS 1 19#endif 20 21#if ALLOW_UNALIGNED_ACCESS 22#define CR_ALIGN_SET BIT(CONTROL_U) 23#define CR_ALIGN_CLEAR BIT(CONTROL_A) 24#else 25#define CR_ALIGN_SET BIT(CONTROL_A) 26#define CR_ALIGN_CLEAR BIT(CONTROL_U) 27#endif 28 29#ifndef CONFIG_DEBUG_DISABLE_L1_ICACHE 30 #define CR_L1_ICACHE_SET BIT(CONTROL_I) 31 #define CR_L1_ICACHE_CLEAR 0 32#else 33 #define CR_L1_ICACHE_SET 0 34 #define CR_L1_ICACHE_CLEAR BIT(CONTROL_I) 35#endif 36 37#ifndef CONFIG_DEBUG_DISABLE_L1_DCACHE 38 #define CR_L1_DCACHE_SET BIT(CONTROL_C) 39 #define CR_L1_DCACHE_CLEAR 0 40#else 41 #define CR_L1_DCACHE_SET 0 42 #define CR_L1_DCACHE_CLEAR BIT(CONTROL_C) 43#endif 44 45#ifndef CONFIG_DEBUG_DISABLE_BRANCH_PREDICTION 46 #define CR_BRANCH_PREDICTION_SET BIT(CONTROL_Z) 47 #define CR_BRANCH_PREDICTION_CLEAR 0 48#else 49 #define CR_BRANCH_PREDICTION_SET 0 50 #define CR_BRANCH_PREDICTION_CLEAR BIT(CONTROL_Z) 51#endif 52 53#define CR_BITS_SET (CR_ALIGN_SET | \ 54 CR_L1_ICACHE_SET | \ 55 CR_L1_DCACHE_SET | \ 56 BIT(CONTROL_M) | \ 57 CR_BRANCH_PREDICTION_SET | \ 58 BIT(CONTROL_V) | \ 59 BIT(CONTROL_XP)) 60 61#define CR_BITS_CLEAR (CR_ALIGN_CLEAR | \ 62 CR_L1_ICACHE_CLEAR | \ 63 CR_L1_DCACHE_CLEAR | \ 64 CR_BRANCH_PREDICTION_CLEAR | \ 65 BIT(CONTROL_B) | \ 66 BIT(CONTROL_S) | \ 67 BIT(CONTROL_R) | \ 68 BIT(CONTROL_VE) | \ 69 BIT(CONTROL_RR) | \ 70 BIT(CONTROL_EE) | \ 71 BIT(CONTROL_TRE) | \ 72 BIT(CONTROL_AP)) 73 74/* 75 * Entry point of the kernel ELF image. 76 * R0-R3 contain parameters that are passed to init_kernel(). 77 */ 78 79.code 32 80.section .boot.text, "ax" 81BEGIN_FUNC(_start) 82 83 /* Supervisor/hypervisor mode, interrupts disabled */ 84 ldr r5, =CPSR_KERNEL 85 msr cpsr_fc, r5 86 87 /* Initialise CP15 control register */ 88#ifdef CONFIG_ARM_HYPERVISOR_SUPPORT 89 mrc p15, 4, r4, c1, c0, 0 90#else 91 mrc p15, 0, r4, c1, c0, 0 92#endif 93 ldr r5, =CR_BITS_SET 94 ldr r6, =CR_BITS_CLEAR 95 orr r4, r4, r5 96 bic r4, r4, r6 97#ifdef CONFIG_ARM_HYPERVISOR_SUPPORT 98 mcr p15, 4, r4, c1, c0, 0 99 100 /* Initialise vector base */ 101 ldr r4, =PPTR_VECTOR_TABLE 102 mcr p15, 4, r4, c12, c0, 0 103#else 104 mcr p15, 0, r4, c1, c0, 0 105#endif 106 107#if defined(CONFIG_ARM_CORTEX_A9) && defined(CONFIG_ENABLE_A9_PREFETCHER) 108 /* Set bit 2 in the ACTLR, which on the cortex-a9 is the l1 prefetch enable 109 * bit. See section 4.3.10 of the Cortex-A9 Technical Reference Manual */ 110 mrc p15, 0, r4, c1, c0, 1 111 ldr r5, =BIT(2) 112 orr r4, r4, r5 113 mcr p15, 0, r4, c1, c0, 1 114#endif 115 116#if defined(CONFIG_PLAT_HIKEY) 117 /* Prefetcher configuration */ 118 mrrc p15, 0, r4, r5, c15 119 ldr r6, =PREFETCHER_MASK 120 bic r4, r4, r6 121 ldr r6, =PREFETCHER 122 orr r4, r4, r6 123 mcrr p15, 0, r4, r5, c15 124#endif 125 126 /* Load kernel stack pointer 127 * On ARM SMP, kernel_stack_alloc is indexed by CPU ID 128 * to get different stacks for each core 129 */ 130 ldr sp, =kernel_stack_alloc + BIT(CONFIG_KERNEL_STACK_BITS) 131 132#ifdef ENABLE_SMP_SUPPORT 133 /* 134 * Read MPIDR in r4 135 * See ARM Referce Manual (ARMv7-A and ARMv7-R edition), Section B4.1.106 136 * for more details about MPIDR register. 137 */ 138 mrc p15, 0, r4, c0, c0, 5 139 and r4, r4, #0xff 140 /* Set the sp for each core assuming linear indices */ 141 ldr r5, =BIT(CONFIG_KERNEL_STACK_BITS) 142 mul r5, r4 143 add sp, sp, r5 144#endif /* ENABLE_SMP_SUPPORT */ 145 146 /* Attempt to workaround any known ARM errata. */ 147 push {r0-r3} 148 blx arm_errata 149 pop {r0-r3} 150 151 /* Hyp kernel always run in Hyp mode. */ 152#ifndef CONFIG_ARM_HYPERVISOR_SUPPORT 153 /* Initialise ABORT stack pointer */ 154 cps #PMODE_ABORT 155 ldr sp, =_breakpoint_stack_top 156 cps #PMODE_SUPERVISOR 157#endif 158 159 /* Call bootstrapping implemented in C */ 160 blx init_kernel 161 162 /* Restore the initial thread */ 163 b restore_user_context 164 165END_FUNC(_start) 166