211 lines
5.7 KiB
ArmAsm
211 lines
5.7 KiB
ArmAsm
/* Copyright (c) 2009, 2010, 2011, 2012 ARM Ltd. All rights reserved.
|
|
|
|
Redistribution and use in source and binary forms, with or without
|
|
modification, are permitted provided that the following conditions
|
|
are met:
|
|
1. Redistributions of source code must retain the above copyright
|
|
notice, this list of conditions and the following disclaimer.
|
|
2. Redistributions in binary form must reproduce the above copyright
|
|
notice, this list of conditions and the following disclaimer in the
|
|
documentation and/or other materials provided with the distribution.
|
|
3. The name of the company may not be used to endorse or promote
|
|
products derived from this software without specific prior written
|
|
permission.
|
|
|
|
THIS SOFTWARE IS PROVIDED BY ARM LTD ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
|
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
IN NO EVENT SHALL ARM LTD BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
|
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
|
|
|
|
#include "newlib.h"
|
|
#include "svc.h"
|
|
|
|
/* ANSI concatenation macros. */
|
|
#define CONCAT(a, b) CONCAT2(a, b)
|
|
#define CONCAT2(a, b) a ## b
|
|
|
|
#ifdef __USER_LABEL_PREFIX__
|
|
#define FUNCTION( name ) CONCAT (__USER_LABEL_PREFIX__, name)
|
|
#else
|
|
#error __USER_LABEL_PREFIX is not defined
|
|
#endif
|
|
|
|
|
|
.text
|
|
.align 2
|
|
_init_vectors:
|
|
/* Installs a table of exception vectors to catch and handle all
|
|
exceptions by terminating the process with a diagnostic. */
|
|
adr x0, vectors
|
|
#ifndef BUILD_FOR_R_PROFILE
|
|
msr vbar_el3, x0
|
|
#endif
|
|
msr vbar_el2, x0
|
|
msr vbar_el1, x0
|
|
ret
|
|
|
|
curr_sp0_sync:
|
|
curr_sp0_irq:
|
|
curr_sp0_fiq:
|
|
curr_sp0_serror:
|
|
curr_spx_sync:
|
|
curr_spx_irq:
|
|
curr_spx_fiq:
|
|
curr_spx_serror:
|
|
lower_a64_sync:
|
|
lower_a64_irq:
|
|
lower_a64_fiq:
|
|
lower_a64_serror:
|
|
lower_a32_sync:
|
|
lower_a32_irq:
|
|
lower_a32_fiq:
|
|
lower_a32_serror:
|
|
mov x0, 2
|
|
adr x1, .LC3
|
|
mov x2, 26
|
|
bl FUNCTION (write)
|
|
mov x0, 126
|
|
b FUNCTION (exit) /* Cannot return. */
|
|
.LC3:
|
|
.string "Terminated by exception.\n"
|
|
|
|
.macro ventry label
|
|
.align 7
|
|
b \label
|
|
.endm
|
|
|
|
/* AArch64 Exception Model -- 3.5.5 Exception Vectors. */
|
|
|
|
.align 12
|
|
vectors:
|
|
/* Current EL with SP0. */
|
|
ventry curr_sp0_sync /* Synchronous */
|
|
ventry curr_sp0_irq /* Irq/vIRQ */
|
|
ventry curr_sp0_fiq /* Fiq/vFIQ */
|
|
ventry curr_sp0_serror /* SError/VSError */
|
|
|
|
/* Current EL with SPx. */
|
|
ventry curr_spx_sync /* Synchronous */
|
|
ventry curr_spx_irq /* IRQ/vIRQ */
|
|
ventry curr_spx_fiq /* FIQ/vFIQ */
|
|
ventry curr_spx_serror /* SError/VSError */
|
|
|
|
/* Lower EL using AArch64. */
|
|
ventry lower_a64_sync /* Synchronous */
|
|
ventry lower_a64_irq /* IRQ/vIRQ */
|
|
ventry lower_a64_fiq /* FIQ/vFIQ */
|
|
ventry lower_a64_serror /* SError/VSError */
|
|
|
|
/* Lower EL using AArch32. */
|
|
ventry lower_a32_sync /* Synchronous */
|
|
ventry lower_a32_irq /* IRQ/vIRQ */
|
|
ventry lower_a32_fiq /* FIQ/vFIQ */
|
|
ventry lower_a32_serror /* SError/VSError */
|
|
|
|
|
|
.text
|
|
.align 2
|
|
_flat_map:
|
|
#ifdef BUILD_FOR_R_PROFILE
|
|
mrs x0, sctlr_el2
|
|
orr x0, x0, #1 // SCTLR_EL2.M (enable MPU)
|
|
orr x0, x0, #(1 << 17) // SCTLR_EL2.BR (background regions)
|
|
msr sctlr_el2, x0
|
|
isb
|
|
ret
|
|
#else
|
|
/* Page table setup (identity mapping). */
|
|
adrp x0, ttb
|
|
add x0, x0, :lo12:ttb
|
|
msr ttbr0_el3, x0
|
|
adr x1, . /* phys address */
|
|
bic x1, x1, #(1 << 30) - 1 /* 1GB block alignment */
|
|
add x2, x0, x1, lsr #(30 - 3) /* offset in level 1 page
|
|
table */
|
|
mov x3, #0x401 /* page table attributes
|
|
(AF, block) */
|
|
orr x1, x1, x3
|
|
mov x3, #(1 << 30) /* 1GB block */
|
|
str x1, [x2], #8 /* 1st GB */
|
|
add x1, x1, x3
|
|
str x1, [x2] /* 2nd GB */
|
|
|
|
/* Setup/enable the MMU. */
|
|
|
|
/* RES1, RES1, 40-bit PA, 39-bit VA, inner/outer cacheable WB */
|
|
ldr x0, =(1 << 31) | (1 << 23) | (2 << 16) | 25 | (3 << 10) | (3 << 8)
|
|
msr tcr_el3, x0
|
|
|
|
mov x0, #0xee /* Inner/outer cacheable WB */
|
|
msr mair_el3, x0
|
|
isb
|
|
|
|
mrs x0, sctlr_el3
|
|
ldr x1, =0x100d /* bits I(12) SA(3) C(2) M(0) */
|
|
bic x0, x0, #(1 << 1) /* clear bit A(1) */
|
|
bic x0, x0, #(1 << 19) /* clear WXN */
|
|
orr x0, x0, x1 /* set bits */
|
|
|
|
dsb sy
|
|
msr sctlr_el3, x0
|
|
isb
|
|
|
|
/* Determine if SVE is available. */
|
|
mrs x0, id_aa64pfr0_el1
|
|
tbz x0, 32, .Lnosve
|
|
|
|
/* set up CPTR_EL3.TZ to 1. */
|
|
mrs x0, cptr_el3
|
|
|
|
/* TZ is bit 8 of CPTR_EL3. */
|
|
orr x0, x0, #0x100
|
|
msr cptr_el3, x0
|
|
isb
|
|
|
|
/* set up vector lenght in ZCR_EL3 (4 LSB). */
|
|
mov x2, #0xF
|
|
|
|
/* Try to set the maximum value supported by the architecture (2048).
|
|
SVE Arch.
|
|
|
|
"If this field is set to a value that is not supported by the
|
|
implementation then reading the register must return the highest
|
|
supported vector length that is less than the value written." */
|
|
mrs x1, s3_6_c1_c2_0 /* mrs x1, zcr_el3. */
|
|
bfi x1, x2, 0, 4
|
|
msr s3_6_c1_c2_0, x1 /* msr zcr_el3, x1. */
|
|
isb
|
|
.Lnosve:
|
|
ret
|
|
#endif
|
|
|
|
.data
|
|
.align 12
|
|
ttb:
|
|
.space 4096, 0
|
|
|
|
|
|
.text
|
|
.align 2
|
|
.global FUNCTION (_cpu_init_hook)
|
|
.type FUNCTION (_cpu_init_hook), %function
|
|
.cfi_sections .debug_frame
|
|
FUNCTION (_cpu_init_hook):
|
|
.cfi_startproc
|
|
str x30, [sp, -16]!
|
|
.cfi_def_cfa_offset 16
|
|
.cfi_offset 30, -16
|
|
bl _init_vectors
|
|
bl _flat_map
|
|
ldr x30, [sp], 16
|
|
.cfi_restore 30
|
|
ret
|
|
.cfi_endproc
|
|
.size FUNCTION (_cpu_init_hook), .-FUNCTION (_cpu_init_hook)
|