/* * \brief Transition between kernel/userland * \author Adrian-Ken Rueegsegger * \author Martin Stein * \author Reto Buerki * \author Stefan Kalkowski * \date 2011-11-15 */ /* * Copyright (C) 2011-2017 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU Affero General Public License version 3. */ /* offsets of member variables in a CPU context */ .set IP_OFFSET, 17 * 8 .set SP_OFFSET, 20 * 8 /* virtual addresses */ .set BASE, 0xffffffc000000000 .set ISR, BASE .set ISR_ENTRY_SIZE, 12 .set IDT_FLAGS_PRIVILEGED, 0x8e01 .set IDT_FLAGS_UNPRIVILEGED, 0xee01 .macro _isr_entry .align 4, 0x90 .endm .macro _exception vector _isr_entry push $0 push $\vector jmp _kernel_entry .endm .macro _exception_with_code vector _isr_entry nop nop push $\vector jmp _kernel_entry .endm .macro _idt_entry addr flags .word \addr & 0xffff .word 0x0008 .word \flags .word (\addr >> 16) & 0xffff .long \addr >> 32 .long 0 .endm .macro _load_address label reg mov \label@GOTPCREL(%rip), %\reg .endm .section ".text.crt0" _begin: /* * On user exceptions the CPU has to jump to one of the following * Interrupt Service Routines (ISRs) to switch to a kernel context. */ _exception 0 _exception 1 _exception 2 _exception 3 _exception 4 _exception 5 _exception 6 _exception 7 _exception_with_code 8 _exception 9 _exception_with_code 10 _exception_with_code 11 _exception_with_code 12 _exception_with_code 13 _exception_with_code 14 _exception 15 _exception 16 _exception_with_code 17 _exception 18 _exception 19 .set vec, 20 .rept 236 _exception vec .set vec, vec + 1 .endr _kernel_entry: pushq %rbp pushq %rsi pushq %rdi pushq %rdx pushq %rcx pushq %rbx pushq %rax pushq %r15 pushq %r14 pushq %r13 pushq %r12 pushq %r11 pushq %r10 pushq %r9 pushq %r8 /** * Calculate offset into Kernel_stack member of Cpu::Context as defined * in cpu.h - struct Context : Cpu_state, Kernel_stack, Fpu_context */ .set REGISTER_COUNT, 22 .set REGISTER_SIZE, 8 .set SIZEOF_CPU_STATE, REGISTER_COUNT * REGISTER_SIZE /* sizeof (Cpu_state) */ .set KERNEL_STACK_OFFSET, SIZEOF_CPU_STATE /* rsp contains pointer to Cpu::Context */ /* Restore kernel stack and continue kernel execution */ movq %rsp, %rax addq $KERNEL_STACK_OFFSET, %rax movq (%rax), %rsp _load_address kernel rcx jmp *%rcx /***************************************** ** Interrupt Descriptor Table (IDT) ** ** See Intel SDM Vol. 3A, section 6.10 ** *****************************************/ .global __idt .align 8 __idt: /* first 128 entries */ .set isr_addr, ISR .rept 0x80 _idt_entry isr_addr IDT_FLAGS_PRIVILEGED .set isr_addr, isr_addr + ISR_ENTRY_SIZE .endr /* syscall entry 0x80 */ _idt_entry isr_addr IDT_FLAGS_UNPRIVILEGED .set isr_addr, isr_addr + ISR_ENTRY_SIZE /* remaing entries */ .rept 127 _idt_entry isr_addr IDT_FLAGS_PRIVILEGED .set isr_addr, isr_addr + ISR_ENTRY_SIZE .endr .global __idt_end .align 8 __idt_end: .section .text /******************************* ** idle loop for idle thread ** *******************************/ .global idle_thread_main idle_thread_main: sti hlt cli jmp idle_thread_main