mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-20 17:52:52 +00:00
parent
323de9b229
commit
219615b0eb
@ -19,6 +19,21 @@
|
||||
extern int __idt;
|
||||
extern int __idt_end;
|
||||
|
||||
/**
|
||||
* Pseudo Descriptor
|
||||
*
|
||||
* See Intel SDM Vol. 3A, section 3.5.1
|
||||
*/
|
||||
struct Pseudo_descriptor
|
||||
{
|
||||
Genode::uint16_t const limit = 0;
|
||||
Genode::uint64_t const base = 0;
|
||||
|
||||
constexpr Pseudo_descriptor(Genode::uint16_t l, Genode::uint64_t b)
|
||||
: limit(l), base(b) {}
|
||||
} __attribute__((packed));
|
||||
|
||||
|
||||
Genode::Cpu::Context::Context(bool core)
|
||||
{
|
||||
eflags = EFLAGS_IF_SET;
|
||||
@ -88,3 +103,14 @@ void Genode::Cpu::mmu_fault(Context & regs, Kernel::Thread_fault & fault)
|
||||
fault.addr = Genode::Cpu::Cr2::read();
|
||||
fault.type = fault_lambda(regs.errcode);
|
||||
}
|
||||
|
||||
|
||||
void Genode::Cpu::switch_to(Context & context, Mmu_context &mmu_context)
|
||||
{
|
||||
_fpu.switch_to(context);
|
||||
|
||||
if ((context.cs != 0x8) && (mmu_context.cr3 != Cr3::read()))
|
||||
Cr3::write(mmu_context.cr3);
|
||||
|
||||
tss.ist[0] = (addr_t)&context + sizeof(Genode::Cpu_state);
|
||||
}
|
||||
|
@ -22,6 +22,8 @@
|
||||
#include <kernel/interface_support.h>
|
||||
#include <cpu/cpu_state.h>
|
||||
|
||||
#include <hw/spec/x86_64/cpu.h>
|
||||
|
||||
/* base includes */
|
||||
#include <base/internal/align_at.h>
|
||||
#include <base/internal/unmanaged_singleton.h>
|
||||
@ -37,20 +39,14 @@ namespace Genode {
|
||||
}
|
||||
|
||||
|
||||
class Genode::Cpu
|
||||
class Genode::Cpu : public Hw::X86_64_cpu
|
||||
{
|
||||
protected:
|
||||
|
||||
Fpu _fpu;
|
||||
|
||||
public:
|
||||
|
||||
struct Pd {};
|
||||
|
||||
struct Pseudo_descriptor;
|
||||
|
||||
struct Cr0; /* Control register 0 */
|
||||
struct Cr2; /* Control register 2 */
|
||||
struct Cr3; /* Control register 3 */
|
||||
struct Cr4; /* Control register 4 */
|
||||
|
||||
|
||||
/**
|
||||
* Task State Segment (TSS)
|
||||
*
|
||||
@ -115,12 +111,6 @@ class Genode::Cpu
|
||||
};
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
Fpu _fpu;
|
||||
|
||||
public:
|
||||
|
||||
Fpu & fpu() { return _fpu; }
|
||||
|
||||
/**
|
||||
@ -128,7 +118,6 @@ class Genode::Cpu
|
||||
*/
|
||||
bool retry_undefined_instr(Context&) { return false; }
|
||||
|
||||
|
||||
/**
|
||||
* Return kernel name of the executing CPU
|
||||
*/
|
||||
@ -144,146 +133,10 @@ class Genode::Cpu
|
||||
*
|
||||
* \param context next CPU context
|
||||
*/
|
||||
inline void switch_to(Context & context, Mmu_context &);
|
||||
void switch_to(Context & context, Mmu_context &mmu_context);
|
||||
|
||||
static void mmu_fault(Context & regs, Kernel::Thread_fault & fault);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Pseudo Descriptor
|
||||
*
|
||||
* See Intel SDM Vol. 3A, section 3.5.1
|
||||
*/
|
||||
struct Genode::Cpu::Pseudo_descriptor
|
||||
{
|
||||
uint16_t const limit = 0;
|
||||
uint64_t const base = 0;
|
||||
|
||||
constexpr Pseudo_descriptor(uint16_t l, uint64_t b) : limit(l), base(b) {}
|
||||
} __attribute__((packed));
|
||||
|
||||
|
||||
struct Genode::Cpu::Cr0 : Register<64>
|
||||
{
|
||||
struct Pe : Bitfield< 0, 1> { }; /* Protection Enable */
|
||||
struct Mp : Bitfield< 1, 1> { }; /* Monitor Coprocessor */
|
||||
struct Em : Bitfield< 2, 1> { }; /* Emulation */
|
||||
struct Ts : Bitfield< 3, 1> { }; /* Task Switched */
|
||||
struct Et : Bitfield< 4, 1> { }; /* Extension Type */
|
||||
struct Ne : Bitfield< 5, 1> { }; /* Numeric Error */
|
||||
struct Wp : Bitfield<16, 1> { }; /* Write Protect */
|
||||
struct Am : Bitfield<18, 1> { }; /* Alignment Mask */
|
||||
struct Nw : Bitfield<29, 1> { }; /* Not Write-through */
|
||||
struct Cd : Bitfield<30, 1> { }; /* Cache Disable */
|
||||
struct Pg : Bitfield<31, 1> { }; /* Paging */
|
||||
|
||||
static void write(access_t const v) {
|
||||
asm volatile ("mov %0, %%cr0" :: "r" (v) : ); }
|
||||
|
||||
static access_t read()
|
||||
{
|
||||
access_t v;
|
||||
asm volatile ("mov %%cr0, %0" : "=r" (v) :: );
|
||||
return v;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Control register 2: Page-fault linear address
|
||||
*
|
||||
* See Intel SDM Vol. 3A, section 2.5.
|
||||
*/
|
||||
struct Genode::Cpu::Cr2 : Register<64>
|
||||
{
|
||||
struct Addr : Bitfield<0, 63> { };
|
||||
|
||||
static access_t read()
|
||||
{
|
||||
access_t v;
|
||||
asm volatile ("mov %%cr2, %0" : "=r" (v) :: );
|
||||
return v;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Control register 3: Page-Directory base register
|
||||
*
|
||||
* See Intel SDM Vol. 3A, section 2.5.
|
||||
*/
|
||||
struct Genode::Cpu::Cr3 : Register<64>
|
||||
{
|
||||
struct Pwt : Bitfield<3,1> { }; /* Page-level write-through */
|
||||
struct Pcd : Bitfield<4,1> { }; /* Page-level cache disable */
|
||||
struct Pdb : Bitfield<12, 36> { }; /* Page-directory base address */
|
||||
|
||||
static void write(access_t const v) {
|
||||
asm volatile ("mov %0, %%cr3" :: "r" (v) : ); }
|
||||
|
||||
static access_t read()
|
||||
{
|
||||
access_t v;
|
||||
asm volatile ("mov %%cr3, %0" : "=r" (v) :: );
|
||||
return v;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return initialized value
|
||||
*
|
||||
* \param table base of targeted translation table
|
||||
*/
|
||||
static access_t init(addr_t const table) {
|
||||
return Pdb::masked(table); }
|
||||
};
|
||||
|
||||
|
||||
struct Genode::Cpu::Cr4 : Register<64>
|
||||
{
|
||||
struct Vme : Bitfield< 0, 1> { }; /* Virtual-8086 Mode Extensions */
|
||||
struct Pvi : Bitfield< 1, 1> { }; /* Protected-Mode Virtual IRQs */
|
||||
struct Tsd : Bitfield< 2, 1> { }; /* Time Stamp Disable */
|
||||
struct De : Bitfield< 3, 1> { }; /* Debugging Exceptions */
|
||||
struct Pse : Bitfield< 4, 1> { }; /* Page Size Extensions */
|
||||
struct Pae : Bitfield< 5, 1> { }; /* Physical Address Extension */
|
||||
struct Mce : Bitfield< 6, 1> { }; /* Machine-Check Enable */
|
||||
struct Pge : Bitfield< 7, 1> { }; /* Page Global Enable */
|
||||
struct Pce : Bitfield< 8, 1> { }; /* Performance-Monitoring Counter
|
||||
Enable*/
|
||||
struct Osfxsr : Bitfield< 9, 1> { }; /* OS Support for FXSAVE and
|
||||
FXRSTOR instructions*/
|
||||
struct Osxmmexcpt : Bitfield<10, 1> { }; /* OS Support for Unmasked
|
||||
SIMD/FPU Exceptions */
|
||||
struct Vmxe : Bitfield<13, 1> { }; /* VMX Enable */
|
||||
struct Smxe : Bitfield<14, 1> { }; /* SMX Enable */
|
||||
struct Fsgsbase : Bitfield<16, 1> { }; /* FSGSBASE-Enable */
|
||||
struct Pcide : Bitfield<17, 1> { }; /* PCIDE Enable */
|
||||
struct Osxsave : Bitfield<18, 1> { }; /* XSAVE and Processor Extended
|
||||
States-Enable */
|
||||
struct Smep : Bitfield<20, 1> { }; /* SMEP Enable */
|
||||
struct Smap : Bitfield<21, 1> { }; /* SMAP Enable */
|
||||
|
||||
static void write(access_t const v) {
|
||||
asm volatile ("mov %0, %%cr4" :: "r" (v) : ); }
|
||||
|
||||
static access_t read()
|
||||
{
|
||||
access_t v;
|
||||
asm volatile ("mov %%cr4, %0" : "=r" (v) :: );
|
||||
return v;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
void Genode::Cpu::switch_to(Context & context, Mmu_context & mmu_context)
|
||||
{
|
||||
_fpu.switch_to(context);
|
||||
|
||||
if ((context.cs != 0x8) && (mmu_context.cr3 != Cr3::read()))
|
||||
Cr3::write(mmu_context.cr3);
|
||||
|
||||
tss.ist[0] = (addr_t)&context + sizeof(Genode::Cpu_state);
|
||||
};
|
||||
|
||||
#endif /* _CORE__SPEC__X86_64__CPU_H_ */
|
||||
|
Loading…
x
Reference in New Issue
Block a user