genode/repos/base-hw/src/core/spec/x86_64/cpu_driver.h

136 lines
2.8 KiB
C++

/*
* \brief x86_64 CPU driver for core
* \author Adrian-Ken Rueegsegger
* \author Martin stein
* \author Reto Buerki
* \author Stefan Kalkowski
* \date 2015-02-06
*/
/*
* Copyright (C) 2015-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.
*/
#ifndef _CORE__SPEC__X86_64__CPU_H_
#define _CORE__SPEC__X86_64__CPU_H_
/* Genode includes */
#include <util/register.h>
#include <kernel/interface_support.h>
#include <cpu/cpu_state.h>
#include "../../../include/hw/spec/x86_64/cpu_registers.h"
/* base includes */
#include <base/internal/align_at.h>
#include <base/internal/unmanaged_singleton.h>
/* core includes */
#include <fpu.h>
namespace Kernel { struct Thread_fault; }
namespace Genode {
class Cpu;
using sizet_arithm_t = __uint128_t;
}
class Genode::Cpu : public Hw::X86_64_cpu
{
protected:
public:
/**
* Task State Segment (TSS)
*
* See Intel SDM Vol. 3A, section 7.7
*/
struct alignas(8) Tss
{
uint32_t reserved0;
uint64_t rsp[3]; /* pl0-3 stack pointer */
uint64_t reserved1;
uint64_t ist[7]; /* irq stack pointer */
uint64_t reserved2;
static void init();
} __attribute__((packed)) tss { };
/**
* Interrupt Descriptor Table (IDT)
*
* See Intel SDM Vol. 3A, section 6.10
*/
struct Idt { static void init(); };
/**
* Global Descriptor Table (GDT)
* See Intel SDM Vol. 3A, section 3.5.1
*/
struct alignas(8) Gdt
{
uint64_t null_desc = 0;
uint64_t sys_cs_64bit_desc = 0x20980000000000;
uint64_t sys_ds_64bit_desc = 0x20930000000000;
uint64_t usr_cs_64bit_desc = 0x20f80000000000;
uint64_t usr_ds_64bit_desc = 0x20f30000000000;
uint64_t tss_desc[2];
void init(addr_t tss_addr);
} __attribute__((packed)) gdt { };
/**
* Extend basic CPU state by members relevant for 'base-hw' only
*/
struct Kernel_stack { unsigned long kernel_stack { }; };
/* exception_vector.s depends on the position of the Kernel_stack */
struct alignas(16) Context : Cpu_state, Kernel_stack, Fpu_context
{
enum Eflags {
EFLAGS_IF_SET = 1 << 9,
EFLAGS_IOPL_3 = 3 << 12,
};
Context(bool privileged);
} __attribute__((packed));
struct Mmu_context
{
addr_t cr3;
Mmu_context(addr_t page_table_base);
};
/**
* Return kernel name of the executing CPU
*/
static unsigned executing_id();
/**
* Switch to new context
*
* \param context next CPU context
*/
void switch_to(Context & context, Mmu_context &mmu_context);
static void mmu_fault(Context & regs, Kernel::Thread_fault & fault);
/**
* Invalidate the whole TLB
*/
static void invalidate_tlb() {
Genode::Cpu::Cr3::write(Genode::Cpu::Cr3::read()); }
};
#endif /* _CORE__SPEC__X86_64__CPU_H_ */