Arquivos
magenta/kernel/arch/arm64/asm.S
T
Abdulla Kamar 627e15ffbf [arm64][hypervisor] Add El2CpuState.
Add code to manage EL2 CPU state. Currently this does the very minimum
and sets the EL2 stack for each CPU.

Next, I'll start setting up more of the EL2 state and also guest
physical address space.

Change-Id: I18b7f9d00b236e52cdc317dffe3b42fcffbcb8fe
2017-09-12 08:22:07 +00:00

143 linhas
3.0 KiB
ArmAsm

// Copyright 2016 The Fuchsia Authors
// Copyright (c) 2014 Travis Geiselbrecht
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT
#include <asm.h>
#include <arch/asm_macros.h>
#define HCR_EL2_RW (1 << 31)
#define SCR_EL3_HCE (1 << 1)
#define SCR_EL3_RW (1 << 10)
/* void arm64_context_switch(vaddr_t *old_sp, vaddr_t new_sp); */
FUNCTION(arm64_context_switch)
/* save old frame */
/* This layout should match struct context_switch_frame */
push_regs x29, x30
push_regs x27, x28
push_regs x25, x26
push_regs x23, x24
push_regs x21, x22
push_regs x19, x20
mrs x19, tpidr_el0
mrs x20, tpidrro_el0
push_regs x19, x20
/* save old sp */
mov x15, sp
str x15, [x0]
/* load new sp */
mov sp, x1
/* restore new frame */
pop_regs x19, x20
msr tpidr_el0, x19
msr tpidrro_el0, x20
pop_regs x19, x20
pop_regs x21, x22
pop_regs x23, x24
pop_regs x25, x26
pop_regs x27, x28
pop_regs x29, x30
ret
END_FUNCTION(arm64_context_switch)
FUNCTION(arm64_elX_to_el1)
mrs x9, CurrentEL
cmp x9, #(0b01 << 2)
bne .notEL1
/* Already in EL1 */
ret
.notEL1:
cmp x9, #(0b10 << 2)
beq .inEL2
/* set EL2 to 64bit and enable HVC instruction */
mrs x9, scr_el3
orr x9, x9, #SCR_EL3_HCE
orr x9, x9, #SCR_EL3_RW
msr scr_el3, x9
adr x9, .Ltarget
msr elr_el3, x9
mov x9, #((0b1111 << 6) | (0b0101)) /* EL1h runlevel */
msr spsr_el3, x9
b .confEL1
.inEL2:
/* Set the vector base for EL2 */
adr_global x9, arm64_el2_exception_base
msr vbar_el2, x9
/* Ensure EL1 timers are properly configured, disable EL2 trapping of
EL1 access to timer control registers. Also clear virtual offset.
*/
mrs x9, cnthctl_el2
orr x9, x9, #3
msr cnthctl_el2, x9
msr cntvoff_el2, xzr
/* clear out stage 2 translations */
msr vttbr_el2, xzr
adr x9, .Ltarget
msr elr_el2, x9
mov x9, #((0b1111 << 6) | (0b0101)) /* EL1h runlevel */
msr spsr_el2, x9
.confEL1:
/* disable EL2 coprocessor traps */
mov x9, #0x33ff
msr cptr_el2, x9
/* set EL1 to 64bit */
mov x9, #HCR_EL2_RW
msr hcr_el2, x9
/* disable EL1 FPU traps */
mov x9, #(0b11<<20)
msr cpacr_el1, x9
/* set up the EL1 bounce interrupt */
mov x9, sp
msr sp_el1, x9
isb
eret
.Ltarget:
ret
END_FUNCTION(arm64_elX_to_el1)
FUNCTION(arm64_get_secondary_sp)
mrs x9, mpidr_el1
and x9, x9, #0xffff /* only use id/cluster */
mov x10, #SMP_MAX_CPUS
adr_global x11, arm64_secondary_sp_list
.Lsp_loop:
ldr x12, [x11, #0]
cmp x12, x9
beq .Lsp_found
add x11, x11, #32
subs x10, x10, #1
bne .Lsp_loop
mov x0, xzr
mov x1, xzr
ret
.Lsp_found:
ldr x0, [x11, #8]
add x1, x11, #32
ret
END_FUNCTION(arm64_get_secondary_sp)