hw: remove code duplication of core and hw lib

Fix #2593
This commit is contained in:
Stefan Kalkowski 2017-11-10 22:15:43 +01:00 committed by Christian Helmuth
parent 323de9b229
commit 219615b0eb
2 changed files with 34 additions and 155 deletions

View File

@ -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);
}

View File

@ -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_ */