Merge pull request #14 in SEL4/sel4 from ~ADANIS/sel4:x86_common to master

* commit 'fc27f47f0cbaa72734f820160db768cbaac3a898':
  x86: Move general x86 functions to common header
  x86: Rename constants and functions to have X86 prefix instead of IA32 prefix
  x86: Make parts of what have become 32-bit specific headers common
This commit is contained in:
Adrian Danis 2015-12-16 23:50:31 +00:00
commit d9ff68e40a
17 changed files with 562 additions and 565 deletions

View file

@ -11,47 +11,9 @@
#ifndef __MODE_MACHINE_H
#define __MODE_MACHINE_H
#include <arch/types.h>
#include <arch/object/structures.h>
#include <arch/machine/hardware.h>
#include <arch/machine/pat.h>
#include <arch/machine/cpu_registers.h>
#include <arch/model/statedata.h>
#define wordRadix 5
#define wordBits (1 << wordRadix)
#define IA32_APIC_BASE_MSR 0x01B
#define IA32_SYSENTER_CS_MSR 0x174
#define IA32_SYSENTER_ESP_MSR 0x175
#define IA32_SYSENTER_EIP_MSR 0x176
#define BROADWELL_MODEL_ID 0xD4
#define HASWELL_MODEL_ID 0xC3
#define IVY_BRIDGE_MODEL_ID 0xA9
#define SANDY_BRIDGE_1_MODEL_ID 0x2A /* Sandy Bridge */
#define SANDY_BRIDGE_2_MODEL_ID 0x2D /* Sandy Bridge-E, Sandy Bridge-EN and Sandy Bridge-EP */
#define WESTMERE_1_MODEL_ID 0x25 /* Arrandale and Clarksdale */
#define WESTMERE_2_MODEL_ID 0x2C /* Gulftown and Westmere-EP */
#define WESTMERE_3_MODEL_ID 0x2F /* Westemere-EX */
#define NEHALEM_1_MODEL_ID 0x1E /* Clarksfield, Lynnfield and Jasper Forest */
#define NEHALEM_2_MODEL_ID 0x1A /* Bloomfield and Nehalem-EP */
#define NEHALEM_3_MODEL_ID 0x2E /* Nehalem-EX */
#define MODEL_ID(x) ( ((x & 0xf0000) >> 16) + (x & 0xf0) )
/* This article discloses prefetcher control on Intel processors; Nehalem, Westmere, Sandy Bridge,
Ivy Bridge, Haswell, and Broadwell. It is currently undocumented in the regular intel manuals.
https://software.intel.com/en-us/articles/disclosure-of-hw-prefetcher-control-on-some-intel-processors */
#define IA32_PREFETCHER_MSR 0x1A4
#define IA32_PREFETCHER_MSR_L2 BIT(0)
#define IA32_PREFETCHER_MSR_L2_ADJACENT BIT(1)
#define IA32_PREFETCHER_MSR_DCU BIT(2)
#define IA32_PREFETCHER_MSR_DCU_IP BIT(3)
word_t PURE getRestartPC(tcb_t *thread);
void setNextPC(tcb_t *thread, word_t v);
/* Address space control */
static inline paddr_t getCurrentPD(void)
{
@ -71,18 +33,6 @@ static inline void invalidateTLB(void)
write_cr3(ia32KSCurrentPD);
}
static inline void invalidateTLBentry(vptr_t vptr)
{
asm volatile("invlpg (%[vptr])" :: [vptr] "r"(vptr));
}
/* Invalidates page structures cache */
static inline void invalidatePageStructureCache(void)
{
/* invalidate an arbitrary line to invalidate the page structure cache */
invalidateTLBentry(0);
}
/* Flushes entire CPU Cache */
static inline void ia32_wbinvd(void)
{
@ -110,353 +60,10 @@ static inline uint32_t getFaultAddr(void)
/* Get current stack pointer */
static inline void* get_current_esp(void)
{
uint32_t stack;
word_t stack;
void *result;
asm volatile("movl %[stack_address], %[result]" : [result] "=r"(result) : [stack_address] "r"(&stack));
return result;
}
/* Cleaning memory before user-level access */
static inline void clearMemory(void* ptr, word_t bits)
{
memzero(ptr, BIT(bits));
/* no cleaning of caches necessary on IA-32 */
}
/* Initialises MSRs required to setup sysenter and sysexit */
void init_sysenter_msrs(void);
static uint64_t ia32_rdmsr(const uint32_t reg)
{
uint64_t value;
asm volatile("rdmsr" : "=A"(value) : "c"(reg));
return value;
}
/* Read model specific register */
static inline uint32_t ia32_rdmsr_low(const uint32_t reg)
{
return (uint32_t)ia32_rdmsr(reg);
}
static inline uint32_t ia32_rdmsr_high(const uint32_t reg)
{
return (uint32_t)(ia32_rdmsr(reg) >> 32ull);
}
/* Write model specific register */
static inline void ia32_wrmsr(const uint32_t reg, const uint32_t val_high, const uint32_t val_low)
{
uint64_t val = ((uint64_t)val_high << 32ull) | (uint64_t)val_low;
asm volatile("wrmsr" :: "A"(val), "c"(reg));
}
/* Read different parts of CPUID */
static inline uint32_t ia32_cpuid_edx(uint32_t eax, uint32_t ecx)
{
uint32_t edx, ebx;
asm volatile("cpuid"
: "=a" (eax),
"=b" (ebx),
"=c" (ecx),
"=d" (edx)
: "a" (eax), "c" (ecx)
: "memory");
return edx;
}
static inline uint32_t ia32_cpuid_eax(uint32_t eax, uint32_t ecx)
{
uint32_t edx, ebx;
asm volatile("cpuid"
: "=a" (eax),
"=b" (ebx),
"=c" (ecx),
"=d" (edx)
: "a" (eax), "c" (ecx)
: "memory");
return eax;
}
/* Read/write memory fence */
static inline void ia32_mfence(void)
{
asm volatile("mfence" ::: "memory");
}
/* sysenter entry point */
void handle_syscall(void);
void int_00(void);
void int_01(void);
void int_02(void);
void int_03(void);
void int_04(void);
void int_05(void);
void int_06(void);
void int_07(void);
void int_08(void);
void int_09(void);
void int_0a(void);
void int_0b(void);
void int_0c(void);
void int_0d(void);
void int_0e(void);
void int_0f(void);
void int_10(void);
void int_11(void);
void int_12(void);
void int_13(void);
void int_14(void);
void int_15(void);
void int_16(void);
void int_17(void);
void int_18(void);
void int_19(void);
void int_1a(void);
void int_1b(void);
void int_1c(void);
void int_1d(void);
void int_1e(void);
void int_1f(void);
void int_20(void);
void int_21(void);
void int_22(void);
void int_23(void);
void int_24(void);
void int_25(void);
void int_26(void);
void int_27(void);
void int_28(void);
void int_29(void);
void int_2a(void);
void int_2b(void);
void int_2c(void);
void int_2d(void);
void int_2e(void);
void int_2f(void);
void int_30(void);
void int_31(void);
void int_32(void);
void int_33(void);
void int_34(void);
void int_35(void);
void int_36(void);
void int_37(void);
void int_38(void);
void int_39(void);
void int_3a(void);
void int_3b(void);
void int_3c(void);
void int_3d(void);
void int_3e(void);
void int_3f(void);
void int_40(void);
void int_41(void);
void int_42(void);
void int_43(void);
void int_44(void);
void int_45(void);
void int_46(void);
void int_47(void);
void int_48(void);
void int_49(void);
void int_4a(void);
void int_4b(void);
void int_4c(void);
void int_4d(void);
void int_4e(void);
void int_4f(void);
void int_50(void);
void int_51(void);
void int_52(void);
void int_53(void);
void int_54(void);
void int_55(void);
void int_56(void);
void int_57(void);
void int_58(void);
void int_59(void);
void int_5a(void);
void int_5b(void);
void int_5c(void);
void int_5d(void);
void int_5e(void);
void int_5f(void);
void int_60(void);
void int_61(void);
void int_62(void);
void int_63(void);
void int_64(void);
void int_65(void);
void int_66(void);
void int_67(void);
void int_68(void);
void int_69(void);
void int_6a(void);
void int_6b(void);
void int_6c(void);
void int_6d(void);
void int_6e(void);
void int_6f(void);
void int_70(void);
void int_71(void);
void int_72(void);
void int_73(void);
void int_74(void);
void int_75(void);
void int_76(void);
void int_77(void);
void int_78(void);
void int_79(void);
void int_7a(void);
void int_7b(void);
void int_7c(void);
void int_7d(void);
void int_7e(void);
void int_7f(void);
void int_80(void);
void int_81(void);
void int_82(void);
void int_83(void);
void int_84(void);
void int_85(void);
void int_86(void);
void int_87(void);
void int_88(void);
void int_89(void);
void int_8a(void);
void int_8b(void);
void int_8c(void);
void int_8d(void);
void int_8e(void);
void int_8f(void);
void int_90(void);
void int_91(void);
void int_92(void);
void int_93(void);
void int_94(void);
void int_95(void);
void int_96(void);
void int_97(void);
void int_98(void);
void int_99(void);
void int_9a(void);
void int_9b(void);
void int_9c(void);
void int_9d(void);
void int_9e(void);
void int_9f(void);
void int_a0(void);
void int_a1(void);
void int_a2(void);
void int_a3(void);
void int_a4(void);
void int_a5(void);
void int_a6(void);
void int_a7(void);
void int_a8(void);
void int_a9(void);
void int_aa(void);
void int_ab(void);
void int_ac(void);
void int_ad(void);
void int_ae(void);
void int_af(void);
void int_b0(void);
void int_b1(void);
void int_b2(void);
void int_b3(void);
void int_b4(void);
void int_b5(void);
void int_b6(void);
void int_b7(void);
void int_b8(void);
void int_b9(void);
void int_ba(void);
void int_bb(void);
void int_bc(void);
void int_bd(void);
void int_be(void);
void int_bf(void);
void int_c0(void);
void int_c1(void);
void int_c2(void);
void int_c3(void);
void int_c4(void);
void int_c5(void);
void int_c6(void);
void int_c7(void);
void int_c8(void);
void int_c9(void);
void int_ca(void);
void int_cb(void);
void int_cc(void);
void int_cd(void);
void int_ce(void);
void int_cf(void);
void int_d0(void);
void int_d1(void);
void int_d2(void);
void int_d3(void);
void int_d4(void);
void int_d5(void);
void int_d6(void);
void int_d7(void);
void int_d8(void);
void int_d9(void);
void int_da(void);
void int_db(void);
void int_dc(void);
void int_dd(void);
void int_de(void);
void int_df(void);
void int_e0(void);
void int_e1(void);
void int_e2(void);
void int_e3(void);
void int_e4(void);
void int_e5(void);
void int_e6(void);
void int_e7(void);
void int_e8(void);
void int_e9(void);
void int_ea(void);
void int_eb(void);
void int_ec(void);
void int_ed(void);
void int_ee(void);
void int_ef(void);
void int_f0(void);
void int_f1(void);
void int_f2(void);
void int_f3(void);
void int_f4(void);
void int_f5(void);
void int_f6(void);
void int_f7(void);
void int_f8(void);
void int_f9(void);
void int_fa(void);
void int_fb(void);
void int_fc(void);
void int_fd(void);
void int_fe(void);
void int_ff(void);
#endif

View file

@ -11,18 +11,6 @@
#ifndef __MODE_MACHINE_CPU_REGISTERS_H
#define __MODE_MACHINE_CPU_REGISTERS_H
#define CR0_MONITOR_COPROC BIT(1) /* Trap on FPU "WAIT" commands. */
#define CR0_EMULATION BIT(2) /* Enable OS emulation of FPU. */
#define CR0_TASK_SWITCH BIT(3) /* Trap on any FPU usage, for lazy FPU. */
#define CR0_NUMERIC_ERROR BIT(5) /* Internally handle FPU problems. */
#define CR4_OSFXSR BIT(9) /* Enable SSE et. al. features. */
#define CR4_OSXMMEXCPT BIT(10) /* Enable SSE exceptions. */
/* We use a dummy variable to synchronize reads and writes to the control registers.
* this allows us to write inline asm blocks that do not have enforced memory
* clobbers for ordering. */
static unsigned long __control_reg_order;
static inline unsigned long read_cr3(void)
{
unsigned long val;

View file

@ -11,16 +11,6 @@
#ifndef __MODE_MACHINE_REGISTERSET_H
#define __MODE_MACHINE_REGISTERSET_H
#include <arch/types.h>
#include <util.h>
#include <assert.h>
/* Number of bytes required to store FPU state. */
#define FPU_STATE_SIZE 512
/* Minimum hardware-enforced alignment needed for FPU state. */
#define MIN_FPU_ALIGNMENT 16
/* These are the indices of the registers in the
* saved thread context. The values are determined
* by the order in which they're saved in the trap
@ -84,33 +74,6 @@ extern const register_t gpRegisters[];
extern const register_t exceptionMessage[];
extern const register_t syscallMessage[];
/* IA32 FPU context. */
struct user_fpu_state {
uint8_t state[FPU_STATE_SIZE];
};
typedef struct user_fpu_state user_fpu_state_t;
/* IA32 user-code context */
struct user_context {
/* 76 bytes */
word_t registers[n_contextRegisters];
/*
* Padding to 16-byte boundary, required by the IA32 FPU state saving
* and restoring commands.
*/
word_t padding;
/* 512 bytes. */
user_fpu_state_t fpuState;
};
typedef struct user_context user_context_t;
void Arch_initContext(user_context_t* context);
word_t sanitiseRegister(register_t reg, word_t v);
/* Ensure FPU state is aligned within user context. */
compile_assert(fpu_state_alignment_valid,
OFFSETOF(user_context_t, fpuState) % MIN_FPU_ALIGNMENT == 0)
#define FPU_PADDING word_t padding;
#endif

View file

@ -11,24 +11,11 @@
#ifndef __MODE_OBJECT_STRUCTURES_H
#define __MODE_OBJECT_STRUCTURES_H
#include <assert.h>
#include <config.h>
#include <util.h>
#include <api/types.h>
#include <arch/types.h>
#include <arch/object/structures_gen.h>
#include <arch/machine/hardware.h>
#include <arch/machine/registerset.h>
/* Object sizes*/
#define EP_SIZE_BITS 4
#define NTFN_SIZE_BITS 4
#define CTE_SIZE_BITS 4
#define TCB_BLOCK_SIZE_BITS 10
typedef struct arch_tcb {
user_context_t tcbContext;
} arch_tcb_t;
/* update this when you modify the tcb struct */
#define EXPECTED_TCB_SIZE 660
@ -42,17 +29,6 @@ typedef struct arch_tcb {
#define GDT_IPCBUF 7
#define GDT_ENTRIES 8
#define SEL_NULL GDT_NULL
#define SEL_CS_0 (GDT_CS_0 << 3)
#define SEL_DS_0 (GDT_DS_0 << 3)
#define SEL_CS_3 ((GDT_CS_3 << 3) | 3)
#define SEL_DS_3 ((GDT_DS_3 << 3) | 3)
#define SEL_TSS (GDT_TSS << 3)
#define SEL_TLS ((GDT_TLS << 3) | 3)
#define SEL_IPCBUF ((GDT_IPCBUF << 3) | 3)
#define IDT_ENTRIES 256
#ifdef CONFIG_PAE_PAGING
#define PDPTE_SIZE_BITS 3
#define PDPT_BITS 2
@ -92,41 +68,11 @@ typedef struct arch_tcb {
#define PT_PTR(r) ((pte_t *)(r))
#define PT_REF(p) ((word_t)(p))
#ifdef CONFIG_IOMMU
#define VTD_RT_SIZE_BITS 12
#define VTD_CTE_SIZE_BITS 3
#define VTD_CTE_PTR(r) ((vtd_cte_t*)(r))
#define VTD_CT_BITS 9
#define VTD_CT_SIZE_BITS (VTD_CT_BITS + VTD_CTE_SIZE_BITS)
#define VTD_PTE_SIZE_BITS 3
#define VTD_PTE_PTR(r) ((vtd_pte_t*)(r))
#define VTD_PT_BITS 9
#define VTD_PT_SIZE_BITS (VTD_PT_BITS + VTD_PTE_SIZE_BITS)
#endif
/* helper structure for filling descriptor registers */
typedef struct gdt_idt_ptr {
uint16_t limit;
uint16_t basel;
uint16_t baseh;
} gdt_idt_ptr_t;
compile_assert(gdt_idt_ptr_packed,
sizeof(gdt_idt_ptr_t) == sizeof(uint16_t) * 3)
#define WORD_SIZE_BITS 2
enum vm_rights {
VMKernelOnly = 1,
VMReadOnly = 2,
VMReadWrite = 3
};
typedef word_t vm_rights_t;
enum asidSizeConstants {
asidHighBits = 6,
asidLowBits = 10

View file

@ -12,5 +12,397 @@
#define __ARCH_MACHINE_H
#include <mode/machine.h>
#include <arch/types.h>
#include <arch/object/structures.h>
#include <arch/machine/hardware.h>
#include <arch/machine/pat.h>
#include <arch/machine/cpu_registers.h>
#include <arch/model/statedata.h>
#define IA32_APIC_BASE_MSR 0x01B
#define IA32_SYSENTER_CS_MSR 0x174
#define IA32_SYSENTER_ESP_MSR 0x175
#define IA32_SYSENTER_EIP_MSR 0x176
#define BROADWELL_MODEL_ID 0xD4
#define HASWELL_MODEL_ID 0xC3
#define IVY_BRIDGE_MODEL_ID 0xA9
#define SANDY_BRIDGE_1_MODEL_ID 0x2A /* Sandy Bridge */
#define SANDY_BRIDGE_2_MODEL_ID 0x2D /* Sandy Bridge-E, Sandy Bridge-EN and Sandy Bridge-EP */
#define WESTMERE_1_MODEL_ID 0x25 /* Arrandale and Clarksdale */
#define WESTMERE_2_MODEL_ID 0x2C /* Gulftown and Westmere-EP */
#define WESTMERE_3_MODEL_ID 0x2F /* Westemere-EX */
#define NEHALEM_1_MODEL_ID 0x1E /* Clarksfield, Lynnfield and Jasper Forest */
#define NEHALEM_2_MODEL_ID 0x1A /* Bloomfield and Nehalem-EP */
#define NEHALEM_3_MODEL_ID 0x2E /* Nehalem-EX */
#define MODEL_ID(x) ( ((x & 0xf0000) >> 16) + (x & 0xf0) )
/* This article discloses prefetcher control on Intel processors; Nehalem, Westmere, Sandy Bridge,
Ivy Bridge, Haswell, and Broadwell. It is currently undocumented in the regular intel manuals.
https://software.intel.com/en-us/articles/disclosure-of-hw-prefetcher-control-on-some-intel-processors */
#define IA32_PREFETCHER_MSR 0x1A4
#define IA32_PREFETCHER_MSR_L2 BIT(0)
#define IA32_PREFETCHER_MSR_L2_ADJACENT BIT(1)
#define IA32_PREFETCHER_MSR_DCU BIT(2)
#define IA32_PREFETCHER_MSR_DCU_IP BIT(3)
word_t PURE getRestartPC(tcb_t *thread);
void setNextPC(tcb_t *thread, word_t v);
static inline void invalidateTLBentry(vptr_t vptr)
{
asm volatile("invlpg (%[vptr])" :: [vptr] "r"(vptr));
}
/* Invalidates page structures cache */
static inline void invalidatePageStructureCache(void)
{
/* invalidate an arbitrary line to invalidate the page structure cache */
invalidateTLBentry(0);
}
static uint64_t x86_rdmsr(const uint32_t reg)
{
uint64_t value;
asm volatile("rdmsr" : "=A"(value) : "c"(reg));
return value;
}
/* Read model specific register */
static inline uint32_t x86_rdmsr_low(const uint32_t reg)
{
return (uint32_t)x86_rdmsr(reg);
}
static inline uint32_t x86_rdmsr_high(const uint32_t reg)
{
return (uint32_t)(x86_rdmsr(reg) >> 32ull);
}
/* Write model specific register */
static inline void x86_wrmsr(const uint32_t reg, const uint64_t val)
{
asm volatile("wrmsr" :: "A"(val), "c"(reg));
}
/* Read different parts of CPUID */
static inline uint32_t x86_cpuid_edx(uint32_t eax, uint32_t ecx)
{
uint32_t edx, ebx;
asm volatile("cpuid"
: "=a" (eax),
"=b" (ebx),
"=c" (ecx),
"=d" (edx)
: "a" (eax), "c" (ecx)
: "memory");
return edx;
}
static inline uint32_t x86_cpuid_eax(uint32_t eax, uint32_t ecx)
{
uint32_t edx, ebx;
asm volatile("cpuid"
: "=a" (eax),
"=b" (ebx),
"=c" (ecx),
"=d" (edx)
: "a" (eax), "c" (ecx)
: "memory");
return eax;
}
/* Cleaning memory before user-level access */
static inline void clearMemory(void* ptr, unsigned int bits)
{
memzero(ptr, BIT(bits));
/* no cleaning of caches necessary on IA-32 */
}
/* Initialises MSRs required to setup sysenter and sysexit */
void init_sysenter_msrs(void);
/* Read/write memory fence */
static inline void x86_mfence(void)
{
asm volatile("mfence" ::: "memory");
}
/* sysenter entry point */
void handle_syscall(void);
void int_00(void);
void int_01(void);
void int_02(void);
void int_03(void);
void int_04(void);
void int_05(void);
void int_06(void);
void int_07(void);
void int_08(void);
void int_09(void);
void int_0a(void);
void int_0b(void);
void int_0c(void);
void int_0d(void);
void int_0e(void);
void int_0f(void);
void int_10(void);
void int_11(void);
void int_12(void);
void int_13(void);
void int_14(void);
void int_15(void);
void int_16(void);
void int_17(void);
void int_18(void);
void int_19(void);
void int_1a(void);
void int_1b(void);
void int_1c(void);
void int_1d(void);
void int_1e(void);
void int_1f(void);
void int_20(void);
void int_21(void);
void int_22(void);
void int_23(void);
void int_24(void);
void int_25(void);
void int_26(void);
void int_27(void);
void int_28(void);
void int_29(void);
void int_2a(void);
void int_2b(void);
void int_2c(void);
void int_2d(void);
void int_2e(void);
void int_2f(void);
void int_30(void);
void int_31(void);
void int_32(void);
void int_33(void);
void int_34(void);
void int_35(void);
void int_36(void);
void int_37(void);
void int_38(void);
void int_39(void);
void int_3a(void);
void int_3b(void);
void int_3c(void);
void int_3d(void);
void int_3e(void);
void int_3f(void);
void int_40(void);
void int_41(void);
void int_42(void);
void int_43(void);
void int_44(void);
void int_45(void);
void int_46(void);
void int_47(void);
void int_48(void);
void int_49(void);
void int_4a(void);
void int_4b(void);
void int_4c(void);
void int_4d(void);
void int_4e(void);
void int_4f(void);
void int_50(void);
void int_51(void);
void int_52(void);
void int_53(void);
void int_54(void);
void int_55(void);
void int_56(void);
void int_57(void);
void int_58(void);
void int_59(void);
void int_5a(void);
void int_5b(void);
void int_5c(void);
void int_5d(void);
void int_5e(void);
void int_5f(void);
void int_60(void);
void int_61(void);
void int_62(void);
void int_63(void);
void int_64(void);
void int_65(void);
void int_66(void);
void int_67(void);
void int_68(void);
void int_69(void);
void int_6a(void);
void int_6b(void);
void int_6c(void);
void int_6d(void);
void int_6e(void);
void int_6f(void);
void int_70(void);
void int_71(void);
void int_72(void);
void int_73(void);
void int_74(void);
void int_75(void);
void int_76(void);
void int_77(void);
void int_78(void);
void int_79(void);
void int_7a(void);
void int_7b(void);
void int_7c(void);
void int_7d(void);
void int_7e(void);
void int_7f(void);
void int_80(void);
void int_81(void);
void int_82(void);
void int_83(void);
void int_84(void);
void int_85(void);
void int_86(void);
void int_87(void);
void int_88(void);
void int_89(void);
void int_8a(void);
void int_8b(void);
void int_8c(void);
void int_8d(void);
void int_8e(void);
void int_8f(void);
void int_90(void);
void int_91(void);
void int_92(void);
void int_93(void);
void int_94(void);
void int_95(void);
void int_96(void);
void int_97(void);
void int_98(void);
void int_99(void);
void int_9a(void);
void int_9b(void);
void int_9c(void);
void int_9d(void);
void int_9e(void);
void int_9f(void);
void int_a0(void);
void int_a1(void);
void int_a2(void);
void int_a3(void);
void int_a4(void);
void int_a5(void);
void int_a6(void);
void int_a7(void);
void int_a8(void);
void int_a9(void);
void int_aa(void);
void int_ab(void);
void int_ac(void);
void int_ad(void);
void int_ae(void);
void int_af(void);
void int_b0(void);
void int_b1(void);
void int_b2(void);
void int_b3(void);
void int_b4(void);
void int_b5(void);
void int_b6(void);
void int_b7(void);
void int_b8(void);
void int_b9(void);
void int_ba(void);
void int_bb(void);
void int_bc(void);
void int_bd(void);
void int_be(void);
void int_bf(void);
void int_c0(void);
void int_c1(void);
void int_c2(void);
void int_c3(void);
void int_c4(void);
void int_c5(void);
void int_c6(void);
void int_c7(void);
void int_c8(void);
void int_c9(void);
void int_ca(void);
void int_cb(void);
void int_cc(void);
void int_cd(void);
void int_ce(void);
void int_cf(void);
void int_d0(void);
void int_d1(void);
void int_d2(void);
void int_d3(void);
void int_d4(void);
void int_d5(void);
void int_d6(void);
void int_d7(void);
void int_d8(void);
void int_d9(void);
void int_da(void);
void int_db(void);
void int_dc(void);
void int_dd(void);
void int_de(void);
void int_df(void);
void int_e0(void);
void int_e1(void);
void int_e2(void);
void int_e3(void);
void int_e4(void);
void int_e5(void);
void int_e6(void);
void int_e7(void);
void int_e8(void);
void int_e9(void);
void int_ea(void);
void int_eb(void);
void int_ec(void);
void int_ed(void);
void int_ee(void);
void int_ef(void);
void int_f0(void);
void int_f1(void);
void int_f2(void);
void int_f3(void);
void int_f4(void);
void int_f5(void);
void int_f6(void);
void int_f7(void);
void int_f8(void);
void int_f9(void);
void int_fa(void);
void int_fb(void);
void int_fc(void);
void int_fd(void);
void int_fe(void);
void int_ff(void);
#endif

View file

@ -11,6 +11,18 @@
#ifndef __ARCH_MACHINE_CPU_REGISTERS_H
#define __ARCH_MACHINE_CPU_REGISTERS_H
#define CR0_MONITOR_COPROC BIT(1) /* Trap on FPU "WAIT" commands. */
#define CR0_EMULATION BIT(2) /* Enable OS emulation of FPU. */
#define CR0_TASK_SWITCH BIT(3) /* Trap on any FPU usage, for lazy FPU. */
#define CR0_NUMERIC_ERROR BIT(5) /* Internally handle FPU problems. */
#define CR4_OSFXSR BIT(9) /* Enable SSE et. al. features. */
#define CR4_OSXMMEXCPT BIT(10) /* Enable SSE exceptions. */
/* We use a dummy variable to synchronize reads and writes to the control registers.
* this allows us to write inline asm blocks that do not have enforced memory
* clobbers for ordering. */
static unsigned long __control_reg_order;
#include <mode/machine/cpu_registers.h>
#endif

View file

@ -29,18 +29,18 @@ enum vm_page_size {
typedef word_t vm_page_size_t;
enum frameSizeConstants {
IA32_4K_bits = 12,
IA32_2M_bits = 21,
IA32_4M_bits = 22,
IA32_1G_bits = 30
X86_4K_bits = 12,
X86_2M_bits = 21,
X86_4M_bits = 22,
X86_1G_bits = 30
};
#define PAGE_BITS IA32_4K_bits
#define PAGE_BITS X86_4K_bits
#ifdef CONFIG_PAE_PAGING
#define LARGE_PAGE_BITS IA32_2M_bits
#define LARGE_PAGE_BITS X86_2M_bits
#else
#define LARGE_PAGE_BITS IA32_4M_bits
#define LARGE_PAGE_BITS X86_4M_bits
#endif
/* Any changes to this function need to be replicated in pageBitsForSize_phys.

View file

@ -11,6 +11,44 @@
#ifndef __ARCH_MACHINE_REGISTERSET_H
#define __ARCH_MACHINE_REGISTERSET_H
#include <arch/types.h>
#include <util.h>
#include <assert.h>
#include <mode/machine/registerset.h>
/* Number of bytes required to store FPU state. */
#define FPU_STATE_SIZE 512
/* Minimum hardware-enforced alignment needed for FPU state. */
#define MIN_FPU_ALIGNMENT 16
/* X86 FPU context. */
struct user_fpu_state {
uint8_t state[FPU_STATE_SIZE];
};
typedef struct user_fpu_state user_fpu_state_t;
/* X86 user-code context */
struct user_context {
word_t registers[n_contextRegisters];
/*
* Padding to 16-byte boundary, required by the FPU state saving
* and restoring commands.
*/
FPU_PADDING
/* 512 bytes. */
user_fpu_state_t fpuState;
};
typedef struct user_context user_context_t;
void Arch_initContext(user_context_t* context);
word_t sanitiseRegister(register_t reg, word_t v);
/* Ensure FPU state is aligned within user context. */
compile_assert(fpu_state_alignment_valid,
OFFSETOF(user_context_t, fpuState) % MIN_FPU_ALIGNMENT == 0)
#endif

View file

@ -11,6 +11,59 @@
#ifndef __ARCH_OBJECT_STRUCTURES_H
#define __ARCH_OBJECT_STRUCTURES_H
#include <assert.h>
#include <config.h>
#include <util.h>
#include <api/types.h>
#include <arch/types.h>
#include <arch/object/structures_gen.h>
#include <arch/machine/hardware.h>
#include <arch/machine/registerset.h>
typedef struct arch_tcb {
user_context_t tcbContext;
} arch_tcb_t;
#define SEL_NULL GDT_NULL
#define SEL_CS_0 (GDT_CS_0 << 3)
#define SEL_DS_0 (GDT_DS_0 << 3)
#define SEL_CS_3 ((GDT_CS_3 << 3) | 3)
#define SEL_DS_3 ((GDT_DS_3 << 3) | 3)
#define SEL_TSS (GDT_TSS << 3)
#define SEL_TLS ((GDT_TLS << 3) | 3)
#define SEL_IPCBUF ((GDT_IPCBUF << 3) | 3)
#define IDT_ENTRIES 256
#ifdef CONFIG_IOMMU
#define VTD_RT_SIZE_BITS 12
#define VTD_CTE_SIZE_BITS 3
#define VTD_CTE_PTR(r) ((vtd_cte_t*)(r))
#define VTD_CT_BITS 9
#define VTD_CT_SIZE_BITS (VTD_CT_BITS + VTD_CTE_SIZE_BITS)
#define VTD_PTE_SIZE_BITS 3
#define VTD_PTE_PTR(r) ((vtd_pte_t*)(r))
#define VTD_PT_BITS 9
#define VTD_PT_SIZE_BITS (VTD_PT_BITS + VTD_PTE_SIZE_BITS)
#endif
/* helper structure for filling descriptor registers */
typedef struct gdt_idt_ptr {
uint16_t limit;
word_t base;
} __attribute__((packed)) gdt_idt_ptr_t;
enum vm_rights {
VMKernelOnly = 1,
VMReadOnly = 2,
VMReadWrite = 3
};
typedef uint32_t vm_rights_t;
#include <mode/object/structures.h>
#endif

View file

@ -11,19 +11,14 @@
#ifndef __PLAT_MODE_MACHINE_HARDWARE_H
#define __PLAT_MODE_MACHINE_HARDWARE_H
#include <config.h>
#include <types.h>
#include <plat/machine.h>
#include <plat/machine/hardware_gen.h>
/* WARNING: some of these constants are also defined in linker.lds */
#define PADDR_BASE 0x00000000
#define PADDR_LOAD 0x00100000
#define PPTR_BASE 0xe0000000
#ifdef CONFIG_PAE_PAGING
#define PPTR_USER_TOP (PPTR_BASE & (~MASK(IA32_1G_bits)))
#define PPTR_USER_TOP (PPTR_BASE & (~MASK(X86_1G_bits)))
#else
#define PPTR_USER_TOP (PPTR_BASE & (~MASK(IA32_4M_bits)))
#define PPTR_USER_TOP (PPTR_BASE & (~MASK(X86_4M_bits)))
#endif
#if CONFIG_MAX_NUM_TRACE_POINTS > 0
#define PPTR_TOP (-BIT(LARGE_PAGE_BITS + 1))
@ -69,15 +64,4 @@ pptr_to_paddr_reg(region_t reg)
};
}
void handleReservedIRQ(irq_t irq);
void maskInterrupt(bool_t mask, irq_t irq);
void ackInterrupt(irq_t irq);
irq_t getActiveIRQ(void);
bool_t isIRQPending(void);
void setInterruptMode(irq_t irq, bool_t levelTrigger, bool_t polarityLow);
void resetTimer(void);
void platAddDevices(void);
void handleSpuriousIRQ(void);
#endif

View file

@ -11,6 +11,22 @@
#ifndef __PLAT_MACHINE_HARDWARE_H
#define __PLAT_MACHINE_HARDWARE_H
#include <config.h>
#include <types.h>
#include <plat/machine.h>
#include <plat/machine/hardware_gen.h>
#include <plat_mode/machine/hardware.h>
void handleReservedIRQ(irq_t irq);
void maskInterrupt(bool_t mask, irq_t irq);
void ackInterrupt(irq_t irq);
irq_t getActiveIRQ(void);
bool_t isIRQPending(void);
void setInterruptMode(irq_t irq, bool_t levelTrigger, bool_t polarityLow);
void resetTimer(void);
void platAddDevices(void);
void handleSpuriousIRQ(void);
#endif

View file

@ -70,10 +70,10 @@ init_boot_pd(void)
word_t i;
/* identity mapping from 0 up to PPTR_BASE (virtual address) */
for (i = 0; i < (PPTR_BASE >> IA32_4M_bits); i++) {
for (i = 0; i < (PPTR_BASE >> X86_4M_bits); i++) {
pde_pde_large_ptr_new_phys(
_boot_pd + i,
i << IA32_4M_bits, /* physical address */
i << X86_4M_bits, /* physical address */
0, /* pat */
0, /* avl */
1, /* global */
@ -88,10 +88,10 @@ init_boot_pd(void)
}
/* mapping of PPTR_BASE (virtual address) to PADDR_BASE up to end of virtual address space */
for (i = 0; i < ((-PPTR_BASE) >> IA32_4M_bits); i++) {
for (i = 0; i < ((-PPTR_BASE) >> X86_4M_bits); i++) {
pde_pde_large_ptr_new_phys(
_boot_pd + i + (PPTR_BASE >> IA32_4M_bits),
(i << IA32_4M_bits) + PADDR_BASE, /* physical address */
_boot_pd + i + (PPTR_BASE >> X86_4M_bits),
(i << X86_4M_bits) + PADDR_BASE, /* physical address */
0, /* pat */
0, /* avl */
1, /* global */
@ -115,7 +115,7 @@ map_it_pt_cap(cap_t vspace_cap, cap_t pt_cap)
assert(cap_page_table_cap_get_capPTIsMapped(pt_cap));
pde_pde_small_ptr_new(
pd + (vptr >> IA32_4M_bits),
pd + (vptr >> X86_4M_bits),
pptr_to_paddr(pt), /* pt_base_address */
0, /* avl */
0, /* accessed */
@ -144,10 +144,10 @@ map_it_frame_cap(cap_t pd_cap, cap_t frame_cap)
vptr_t vptr = cap_frame_cap_get_capFMappedAddress(frame_cap);
assert(cap_frame_cap_get_capFMappedASID(frame_cap) != 0);
pd += (vptr >> IA32_4M_bits);
pd += (vptr >> X86_4M_bits);
pt = paddr_to_pptr(pde_pde_small_ptr_get_pt_base_address(pd));
pte_ptr_new(
pt + ((vptr & MASK(IA32_4M_bits)) >> IA32_4K_bits),
pt + ((vptr & MASK(X86_4M_bits)) >> X86_4K_bits),
pptr_to_paddr(frame), /* page_base_address */
0, /* avl */
0, /* global */
@ -206,7 +206,7 @@ void copyGlobalMappings(void* new_vspace)
word_t i;
pde_t *newPD = (pde_t*)new_vspace;
for (i = PPTR_BASE >> IA32_4M_bits; i < BIT(PD_BITS); i++) {
for (i = PPTR_BASE >> X86_4M_bits; i < BIT(PD_BITS); i++) {
newPD[i] = ia32KSkernelPD[i];
}
}

View file

@ -93,10 +93,10 @@ init_boot_pd(void)
}
/* identity mapping from 0 up to PPTR_BASE (virtual address) */
for (i = 0; (i << IA32_2M_bits) < PPTR_BASE; i++) {
for (i = 0; (i << X86_2M_bits) < PPTR_BASE; i++) {
pde_pde_large_ptr_new_phys(
_boot_pds + i,
i << IA32_2M_bits, /* physical address */
i << X86_2M_bits, /* physical address */
0, /* pat */
0, /* avl */
1, /* global */
@ -111,10 +111,10 @@ init_boot_pd(void)
}
/* mapping of PPTR_BASE (virtual address) to PADDR_BASE up to end of virtual address space */
for (i = 0; (i << IA32_2M_bits) < -PPTR_BASE; i++) {
for (i = 0; (i << X86_2M_bits) < -PPTR_BASE; i++) {
pde_pde_large_ptr_new_phys(
_boot_pds + i + (PPTR_BASE >> IA32_2M_bits),
(i << IA32_2M_bits) + PADDR_BASE, /* physical address */
_boot_pds + i + (PPTR_BASE >> X86_2M_bits),
(i << X86_2M_bits) + PADDR_BASE, /* physical address */
0, /* pat */
0, /* avl */
1, /* global */
@ -139,14 +139,14 @@ map_it_frame_cap(cap_t vspace_cap, cap_t frame_cap)
vptr_t vptr = cap_frame_cap_get_capFMappedAddress(frame_cap);
assert(cap_frame_cap_get_capFMappedASID(frame_cap) != 0);
pdpt += (vptr >> IA32_1G_bits);
pdpt += (vptr >> X86_1G_bits);
assert(pdpte_ptr_get_present(pdpt));
pd = paddr_to_pptr(pdpte_ptr_get_pd_base_address(pdpt));
pd += ( (vptr & MASK(IA32_1G_bits)) >> IA32_2M_bits);
pd += ( (vptr & MASK(X86_1G_bits)) >> X86_2M_bits);
assert(pde_pde_small_ptr_get_present(pd));
pt = paddr_to_pptr(pde_pde_small_ptr_get_pt_base_address(pd));
pte_ptr_new(
pt + ((vptr & MASK(IA32_2M_bits)) >> IA32_4K_bits),
pt + ((vptr & MASK(X86_2M_bits)) >> X86_4K_bits),
pptr_to_paddr(frame),
0, /* avl */
0, /* global */
@ -171,11 +171,11 @@ map_it_pt_cap(cap_t vspace_cap, cap_t pt_cap)
vptr_t vptr = cap_page_table_cap_get_capPTMappedAddress(pt_cap);
assert(cap_page_table_cap_get_capPTIsMapped(pt_cap));
pdpt += (vptr >> IA32_1G_bits);
pdpt += (vptr >> X86_1G_bits);
assert(pdpte_ptr_get_present(pdpt));
pd = paddr_to_pptr(pdpte_ptr_get_pd_base_address(pdpt));
pde_pde_small_ptr_new(
pd + (vptr >> IA32_2M_bits),
pd + (vptr >> X86_2M_bits),
pptr_to_paddr(pt),
0, /* avl*/
0, /* accessed */
@ -197,7 +197,7 @@ map_it_pd_cap(cap_t vspace_cap, cap_t pd_cap)
assert(cap_page_directory_cap_get_capPDIsMapped(pd_cap));
pdpte_ptr_new(
pdpt + (vptr >> IA32_1G_bits),
pdpt + (vptr >> X86_1G_bits),
pptr_to_paddr(pd),
0, /* avl */
0, /* cache_disabled */
@ -214,7 +214,7 @@ void copyGlobalMappings(void* new_vspace)
word_t i;
pdpte_t *pdpt = (pdpte_t*)new_vspace;
for (i = PPTR_BASE >> IA32_1G_bits; i < BIT(PDPT_BITS); i++) {
for (i = PPTR_BASE >> X86_1G_bits; i < BIT(PDPT_BITS); i++) {
pdpt[i] = ia32KSkernelPDPT[i];
}
}
@ -249,7 +249,7 @@ void *getValidNativeRoot(cap_t vspace_cap)
static inline pdpte_t *lookupPDPTSlot(void *vspace, vptr_t vptr)
{
pdpte_t *pdpt = PDPT_PTR(vspace);
return pdpt + (vptr >> IA32_1G_bits);
return pdpt + (vptr >> X86_1G_bits);
}
lookupPDSlot_ret_t lookupPDSlot(void *vspace, vptr_t vptr)
@ -379,7 +379,7 @@ decodeIA32PageDirectoryInvocation(
return EXCEPTION_SYSCALL_ERROR;
}
vaddr = getSyscallArg(0, buffer) & (~MASK(IA32_1G_bits));
vaddr = getSyscallArg(0, buffer) & (~MASK(X86_1G_bits));
attr = vmAttributesFromWord(getSyscallArg(1, buffer));
vspaceCap = extraCaps.excaprefs[0]->cap;

View file

@ -78,7 +78,7 @@ apic_get_base_paddr(void)
{
apic_base_msr_t apic_base_msr;
apic_base_msr.words[0] = ia32_rdmsr_low(IA32_APIC_BASE_MSR);
apic_base_msr.words[0] = x86_rdmsr_low(IA32_APIC_BASE_MSR);
if (!apic_base_msr_get_enabled(apic_base_msr)) {
printf("APIC: Enabled bit not set\n");
}

View file

@ -410,7 +410,7 @@ BOOT_CODE static void
start_cpu(cpu_id_t cpu_id, paddr_t boot_fun_paddr)
{
/* memory fence needed before starting the other CPU */
ia32_mfence();
x86_mfence();
/* starting the other CPU */
apic_send_init_ipi(cpu_id);

View file

@ -824,14 +824,12 @@ init_dtrs(void)
{
/* setup the GDT pointer and limit and load into GDTR */
gdt_idt_ptr.limit = (sizeof(gdt_entry_t) * GDT_ENTRIES) - 1;
gdt_idt_ptr.basel = (uint32_t)ia32KSgdt;
gdt_idt_ptr.baseh = (uint16_t)((uint32_t)ia32KSgdt >> 16);
gdt_idt_ptr.base = (uint32_t)ia32KSgdt;
ia32_install_gdt(&gdt_idt_ptr);
/* setup the IDT pointer and limit and load into IDTR */
gdt_idt_ptr.limit = (sizeof(idt_entry_t) * (int_max + 1)) - 1;
gdt_idt_ptr.basel = (uint32_t)ia32KSidt;
gdt_idt_ptr.baseh = (uint16_t)((uint32_t)ia32KSidt >> 16);
gdt_idt_ptr.base = (uint32_t)ia32KSidt;
ia32_install_idt(&gdt_idt_ptr);
/* load NULL LDT selector into LDTR */
@ -855,12 +853,12 @@ init_pat_msr(void)
ia32_pat_msr_t pat_msr;
/* First verify PAT is supported by the machine.
* See section 11.12.1 of Volume 3 of the Intel manual */
if ( (ia32_cpuid_edx(0x1, 0x0) & BIT(16)) == 0) {
if ( (x86_cpuid_edx(0x1, 0x0) & BIT(16)) == 0) {
printf("PAT support not found\n");
return false;
}
pat_msr.words[0] = ia32_rdmsr_low(IA32_PAT_MSR);
pat_msr.words[1] = ia32_rdmsr_high(IA32_PAT_MSR);
pat_msr.words[0] = x86_rdmsr_low(IA32_PAT_MSR);
pat_msr.words[1] = x86_rdmsr_high(IA32_PAT_MSR);
/* Set up the PAT MSR to the Intel defaults, just in case
* they have been changed but a bootloader somewhere along the way */
ia32_pat_msr_ptr_set_pa0(&pat_msr, IA32_PAT_MT_WRITE_BACK);
@ -869,7 +867,7 @@ init_pat_msr(void)
ia32_pat_msr_ptr_set_pa3(&pat_msr, IA32_PAT_MT_UNCACHEABLE);
/* Add the WriteCombining cache type to the PAT */
ia32_pat_msr_ptr_set_pa4(&pat_msr, IA32_PAT_MT_WRITE_COMBINING);
ia32_wrmsr(IA32_PAT_MSR, pat_msr.words[1], pat_msr.words[0]);
x86_wrmsr(IA32_PAT_MSR, ((uint64_t)pat_msr.words[1]) << 32 | pat_msr.words[0]);
return true;
}

View file

@ -21,9 +21,9 @@
BOOT_CODE void
init_sysenter_msrs(void)
{
ia32_wrmsr(IA32_SYSENTER_CS_MSR, 0, (uint32_t)SEL_CS_0);
ia32_wrmsr(IA32_SYSENTER_EIP_MSR, 0, (uint32_t)&handle_syscall);
ia32_wrmsr(IA32_SYSENTER_ESP_MSR, 0, (uint32_t)&ia32KStss.words[1]);
x86_wrmsr(IA32_SYSENTER_CS_MSR, (uint64_t)(word_t)SEL_CS_0);
x86_wrmsr(IA32_SYSENTER_EIP_MSR, (uint64_t)(word_t)&handle_syscall);
x86_wrmsr(IA32_SYSENTER_ESP_MSR, (uint64_t)(word_t)&ia32KStss.words[1]);
}
word_t PURE getRestartPC(tcb_t *thread)
@ -73,14 +73,14 @@ void flushCacheRange(void* vaddr, uint32_t size_bits)
assert(size_bits < WORD_BITS);
assert(IS_ALIGNED((uint32_t)vaddr, size_bits));
ia32_mfence();
x86_mfence();
for (v = ROUND_DOWN((uint32_t)vaddr, ia32KScacheLineSizeBits);
v < (uint32_t)vaddr + BIT(size_bits);
v += BIT(ia32KScacheLineSizeBits)) {
flushCacheLine((void*)v);
}
ia32_mfence();
x86_mfence();
}
/* Disables as many prefetchers as possible */
@ -96,19 +96,19 @@ disablePrefetchers()
WESTMERE_3_MODEL_ID, NEHALEM_1_MODEL_ID, NEHALEM_2_MODEL_ID, NEHALEM_3_MODEL_ID
};
version_info = ia32_cpuid_eax(0x1, 0x0);
version_info = x86_cpuid_eax(0x1, 0x0);
for (i = 0; i < ARRAY_SIZE(valid_models); ++i) {
if (MODEL_ID(version_info) == valid_models[i]) {
low = ia32_rdmsr_low(IA32_PREFETCHER_MSR);
high = ia32_rdmsr_high(IA32_PREFETCHER_MSR);
low = x86_rdmsr_low(IA32_PREFETCHER_MSR);
high = x86_rdmsr_high(IA32_PREFETCHER_MSR);
low |= IA32_PREFETCHER_MSR_L2;
low |= IA32_PREFETCHER_MSR_L2_ADJACENT;
low |= IA32_PREFETCHER_MSR_DCU;
low |= IA32_PREFETCHER_MSR_DCU_IP;
ia32_wrmsr(IA32_PREFETCHER_MSR, high, low);
x86_wrmsr(IA32_PREFETCHER_MSR, ((uint64_t)high) << 32 | low);
return true;
}