99 lines
2.4 KiB
ArmAsm
99 lines
2.4 KiB
ArmAsm
/*
|
|
* \brief Transition between kernel/userland, and secure/non-secure world
|
|
* \author Martin Stein
|
|
* \author Stefan Kalkowski
|
|
* \date 2011-11-15
|
|
*/
|
|
|
|
/*
|
|
* Copyright (C) 2011-2013 Genode Labs GmbH
|
|
*
|
|
* This file is part of the Genode OS framework, which is distributed
|
|
* under the terms of the GNU General Public License version 2.
|
|
*/
|
|
|
|
.include "macros.s"
|
|
|
|
/* size of pointer to CPU context */
|
|
.set CONTEXT_PTR_SIZE, 1 * 8
|
|
|
|
/* globally mapped buffer storage */
|
|
.set BUFFER_SIZE, 6 * 8
|
|
|
|
/* offsets of the member variables in a CPU context */
|
|
.set SP_OFFSET, 1 * 8
|
|
.set R8_OFFSET, 2 * 8
|
|
.set RAX_OFFSET, 10 * 8
|
|
.set FLAGS_OFFSET, 18 * 8
|
|
.set CR3_OFFSET, 20 * 8
|
|
|
|
.section .text
|
|
|
|
/*
|
|
* Page aligned base of mode transition code.
|
|
*
|
|
* This position independent code switches between a kernel context and a
|
|
* user context and thereby between their address spaces. Due to the latter
|
|
* it must be mapped executable to the same region in every address space.
|
|
* To enable such switching, the kernel context must be stored within this
|
|
* region, thus one should map it solely accessable for privileged modes.
|
|
*/
|
|
.p2align MIN_PAGE_SIZE_LOG2
|
|
.global _mt_begin
|
|
_mt_begin:
|
|
|
|
/* space for a copy of the kernel context */
|
|
.p2align 2
|
|
.global _mt_master_context_begin
|
|
_mt_master_context_begin:
|
|
|
|
/* space must be at least as large as 'Cpu_state' */
|
|
.space 21*8
|
|
|
|
.global _mt_master_context_end
|
|
_mt_master_context_end:
|
|
|
|
/* space for a client context-pointer per CPU */
|
|
.p2align 2
|
|
.global _mt_client_context_ptr
|
|
_mt_client_context_ptr:
|
|
.space CONTEXT_PTR_SIZE
|
|
|
|
/* a globally mapped buffer per CPU */
|
|
.p2align 2
|
|
.global _mt_buffer
|
|
_mt_buffer:
|
|
.space BUFFER_SIZE
|
|
|
|
/*
|
|
* On user exceptions the CPU has to jump to one of the following
|
|
* seven entry vectors to switch to a kernel context.
|
|
*/
|
|
.global _mt_kernel_entry_pic
|
|
_mt_kernel_entry_pic:
|
|
1: jmp 1b
|
|
|
|
.global _mt_user_entry_pic
|
|
_mt_user_entry_pic:
|
|
|
|
/* Prepare stack frame in mt buffer (Intel SDM Vol. 3A, figure 6-8) */
|
|
mov _mt_client_context_ptr, %rax
|
|
mov $_mt_buffer+BUFFER_SIZE, %rsp
|
|
pushq $0x23
|
|
pushq SP_OFFSET(%rax)
|
|
|
|
/* Set I/O privilege level to 3 */
|
|
orq $0x3000, FLAGS_OFFSET(%rax)
|
|
btrq $9, FLAGS_OFFSET(%rax) /* XXX: Drop once interrupt handling is done */
|
|
pushq FLAGS_OFFSET(%rax)
|
|
|
|
pushq $0x1b
|
|
pushq (%rax)
|
|
|
|
1: jmp 1b
|
|
|
|
/* end of the mode transition code */
|
|
.global _mt_end
|
|
_mt_end:
|
|
1: jmp 1b
|