From 6729ce782379cbbfe453252ab64264f018612d4c Mon Sep 17 00:00:00 2001 From: Adrian Danis Date: Fri, 6 Nov 2015 15:19:50 +1100 Subject: [PATCH 1/3] x86: Make parts of what have become 32-bit specific headers common The reason these were not made common to begin with is so that there was a commit that was just a rename of these files to make any merges with other branches that might exist easier --- include/arch/x86/arch/32/mode/machine.h | 315 +----------------- .../x86/arch/32/mode/machine/cpu_registers.h | 12 - .../x86/arch/32/mode/machine/registerset.h | 39 +-- .../arch/x86/arch/32/mode/object/structures.h | 54 --- include/arch/x86/arch/machine.h | 313 +++++++++++++++++ include/arch/x86/arch/machine/cpu_registers.h | 12 + include/arch/x86/arch/machine/registerset.h | 38 +++ include/arch/x86/arch/object/structures.h | 53 +++ .../pc99/plat/32/plat_mode/machine/hardware.h | 16 - include/plat/pc99/plat/machine/hardware.h | 16 + src/arch/x86/kernel/vspace.c | 6 +- 11 files changed, 436 insertions(+), 438 deletions(-) diff --git a/include/arch/x86/arch/32/mode/machine.h b/include/arch/x86/arch/32/mode/machine.h index aad8311e1..20788f78f 100644 --- a/include/arch/x86/arch/32/mode/machine.h +++ b/include/arch/x86/arch/32/mode/machine.h @@ -11,47 +11,9 @@ #ifndef __MODE_MACHINE_H #define __MODE_MACHINE_H -#include -#include -#include -#include -#include -#include - #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) { @@ -110,7 +72,7 @@ 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; @@ -184,279 +146,4 @@ 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 diff --git a/include/arch/x86/arch/32/mode/machine/cpu_registers.h b/include/arch/x86/arch/32/mode/machine/cpu_registers.h index ee57338f2..2fa525372 100644 --- a/include/arch/x86/arch/32/mode/machine/cpu_registers.h +++ b/include/arch/x86/arch/32/mode/machine/cpu_registers.h @@ -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; diff --git a/include/arch/x86/arch/32/mode/machine/registerset.h b/include/arch/x86/arch/32/mode/machine/registerset.h index 5e0c32a6e..341d411cb 100644 --- a/include/arch/x86/arch/32/mode/machine/registerset.h +++ b/include/arch/x86/arch/32/mode/machine/registerset.h @@ -11,16 +11,6 @@ #ifndef __MODE_MACHINE_REGISTERSET_H #define __MODE_MACHINE_REGISTERSET_H -#include -#include -#include - -/* 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 diff --git a/include/arch/x86/arch/32/mode/object/structures.h b/include/arch/x86/arch/32/mode/object/structures.h index 52e35878c..06d8dc3c3 100644 --- a/include/arch/x86/arch/32/mode/object/structures.h +++ b/include/arch/x86/arch/32/mode/object/structures.h @@ -11,24 +11,11 @@ #ifndef __MODE_OBJECT_STRUCTURES_H #define __MODE_OBJECT_STRUCTURES_H -#include -#include -#include -#include -#include -#include -#include -#include - /* 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 diff --git a/include/arch/x86/arch/machine.h b/include/arch/x86/arch/machine.h index 4d043e6dd..77103c115 100644 --- a/include/arch/x86/arch/machine.h +++ b/include/arch/x86/arch/machine.h @@ -12,5 +12,318 @@ #define __ARCH_MACHINE_H #include +#include +#include +#include +#include +#include +#include + + +#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); + +/* 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 diff --git a/include/arch/x86/arch/machine/cpu_registers.h b/include/arch/x86/arch/machine/cpu_registers.h index ac9046bd9..3e6a590f9 100644 --- a/include/arch/x86/arch/machine/cpu_registers.h +++ b/include/arch/x86/arch/machine/cpu_registers.h @@ -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 #endif diff --git a/include/arch/x86/arch/machine/registerset.h b/include/arch/x86/arch/machine/registerset.h index 912fc7012..562477ddb 100644 --- a/include/arch/x86/arch/machine/registerset.h +++ b/include/arch/x86/arch/machine/registerset.h @@ -11,6 +11,44 @@ #ifndef __ARCH_MACHINE_REGISTERSET_H #define __ARCH_MACHINE_REGISTERSET_H +#include +#include +#include + #include +/* 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 diff --git a/include/arch/x86/arch/object/structures.h b/include/arch/x86/arch/object/structures.h index 796e35d82..1662431d1 100644 --- a/include/arch/x86/arch/object/structures.h +++ b/include/arch/x86/arch/object/structures.h @@ -11,6 +11,59 @@ #ifndef __ARCH_OBJECT_STRUCTURES_H #define __ARCH_OBJECT_STRUCTURES_H +#include +#include +#include +#include +#include +#include +#include +#include + +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 #endif diff --git a/include/plat/pc99/plat/32/plat_mode/machine/hardware.h b/include/plat/pc99/plat/32/plat_mode/machine/hardware.h index 9325cc66a..81203d592 100644 --- a/include/plat/pc99/plat/32/plat_mode/machine/hardware.h +++ b/include/plat/pc99/plat/32/plat_mode/machine/hardware.h @@ -11,11 +11,6 @@ #ifndef __PLAT_MODE_MACHINE_HARDWARE_H #define __PLAT_MODE_MACHINE_HARDWARE_H -#include -#include -#include -#include - /* WARNING: some of these constants are also defined in linker.lds */ #define PADDR_BASE 0x00000000 #define PADDR_LOAD 0x00100000 @@ -64,15 +59,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 diff --git a/include/plat/pc99/plat/machine/hardware.h b/include/plat/pc99/plat/machine/hardware.h index bac2d2ab3..be5a521a5 100644 --- a/include/plat/pc99/plat/machine/hardware.h +++ b/include/plat/pc99/plat/machine/hardware.h @@ -11,6 +11,22 @@ #ifndef __PLAT_MACHINE_HARDWARE_H #define __PLAT_MACHINE_HARDWARE_H +#include +#include +#include +#include + #include +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 diff --git a/src/arch/x86/kernel/vspace.c b/src/arch/x86/kernel/vspace.c index aa706c707..adcd84288 100644 --- a/src/arch/x86/kernel/vspace.c +++ b/src/arch/x86/kernel/vspace.c @@ -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 */ From ef85f94a99ca454a3f79188243bdc59617f00a3a Mon Sep 17 00:00:00 2001 From: Adrian Danis Date: Fri, 6 Nov 2015 15:19:50 +1100 Subject: [PATCH 2/3] x86: Rename constants and functions to have X86 prefix instead of IA32 prefix --- include/arch/x86/arch/32/mode/machine.h | 19 ++++++------- include/arch/x86/arch/machine/hardware.h | 14 +++++----- .../pc99/plat/32/plat_mode/machine/hardware.h | 4 +-- src/arch/x86/32/kernel/vspace_32paging.c | 18 ++++++------ src/arch/x86/32/kernel/vspace_pae.c | 28 +++++++++---------- src/arch/x86/kernel/apic.c | 2 +- src/arch/x86/kernel/boot_sys.c | 2 +- src/arch/x86/kernel/vspace.c | 8 +++--- src/arch/x86/machine/hardware.c | 18 ++++++------ 9 files changed, 56 insertions(+), 57 deletions(-) diff --git a/include/arch/x86/arch/32/mode/machine.h b/include/arch/x86/arch/32/mode/machine.h index 20788f78f..824e08dde 100644 --- a/include/arch/x86/arch/32/mode/machine.h +++ b/include/arch/x86/arch/32/mode/machine.h @@ -88,7 +88,7 @@ static inline void clearMemory(void* ptr, word_t bits) /* Initialises MSRs required to setup sysenter and sysexit */ void init_sysenter_msrs(void); -static uint64_t ia32_rdmsr(const uint32_t reg) +static uint64_t x86_rdmsr(const uint32_t reg) { uint64_t value; asm volatile("rdmsr" : "=A"(value) : "c"(reg)); @@ -96,25 +96,24 @@ static uint64_t ia32_rdmsr(const uint32_t reg) } /* Read model specific register */ -static inline uint32_t ia32_rdmsr_low(const uint32_t reg) +static inline uint32_t x86_rdmsr_low(const uint32_t reg) { - return (uint32_t)ia32_rdmsr(reg); + return (uint32_t)x86_rdmsr(reg); } -static inline uint32_t ia32_rdmsr_high(const uint32_t reg) +static inline uint32_t x86_rdmsr_high(const uint32_t reg) { - return (uint32_t)(ia32_rdmsr(reg) >> 32ull); + return (uint32_t)(x86_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) +static inline void x86_wrmsr(const uint32_t reg, const uint64_t val) { - 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) +static inline uint32_t x86_cpuid_edx(uint32_t eax, uint32_t ecx) { uint32_t edx, ebx; asm volatile("cpuid" @@ -127,7 +126,7 @@ static inline uint32_t ia32_cpuid_edx(uint32_t eax, uint32_t ecx) return edx; } -static inline uint32_t ia32_cpuid_eax(uint32_t eax, uint32_t ecx) +static inline uint32_t x86_cpuid_eax(uint32_t eax, uint32_t ecx) { uint32_t edx, ebx; asm volatile("cpuid" @@ -141,7 +140,7 @@ static inline uint32_t ia32_cpuid_eax(uint32_t eax, uint32_t ecx) } /* Read/write memory fence */ -static inline void ia32_mfence(void) +static inline void x86_mfence(void) { asm volatile("mfence" ::: "memory"); } diff --git a/include/arch/x86/arch/machine/hardware.h b/include/arch/x86/arch/machine/hardware.h index f44fb19b2..8b4c326d4 100644 --- a/include/arch/x86/arch/machine/hardware.h +++ b/include/arch/x86/arch/machine/hardware.h @@ -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. diff --git a/include/plat/pc99/plat/32/plat_mode/machine/hardware.h b/include/plat/pc99/plat/32/plat_mode/machine/hardware.h index 81203d592..04e769305 100644 --- a/include/plat/pc99/plat/32/plat_mode/machine/hardware.h +++ b/include/plat/pc99/plat/32/plat_mode/machine/hardware.h @@ -16,9 +16,9 @@ #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)) diff --git a/src/arch/x86/32/kernel/vspace_32paging.c b/src/arch/x86/32/kernel/vspace_32paging.c index 7c9f1fc16..e760cabb5 100644 --- a/src/arch/x86/32/kernel/vspace_32paging.c +++ b/src/arch/x86/32/kernel/vspace_32paging.c @@ -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]; } } diff --git a/src/arch/x86/32/kernel/vspace_pae.c b/src/arch/x86/32/kernel/vspace_pae.c index 6eb18df1d..f704bdfad 100644 --- a/src/arch/x86/32/kernel/vspace_pae.c +++ b/src/arch/x86/32/kernel/vspace_pae.c @@ -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; diff --git a/src/arch/x86/kernel/apic.c b/src/arch/x86/kernel/apic.c index 379d5fd2c..93aa43d1f 100644 --- a/src/arch/x86/kernel/apic.c +++ b/src/arch/x86/kernel/apic.c @@ -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"); } diff --git a/src/arch/x86/kernel/boot_sys.c b/src/arch/x86/kernel/boot_sys.c index 40ea1bde2..5171d16b8 100644 --- a/src/arch/x86/kernel/boot_sys.c +++ b/src/arch/x86/kernel/boot_sys.c @@ -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); diff --git a/src/arch/x86/kernel/vspace.c b/src/arch/x86/kernel/vspace.c index adcd84288..12651ce7f 100644 --- a/src/arch/x86/kernel/vspace.c +++ b/src/arch/x86/kernel/vspace.c @@ -853,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); @@ -867,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; } diff --git a/src/arch/x86/machine/hardware.c b/src/arch/x86/machine/hardware.c index f4646c37d..858686a95 100644 --- a/src/arch/x86/machine/hardware.c +++ b/src/arch/x86/machine/hardware.c @@ -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; } From fc27f47f0cbaa72734f820160db768cbaac3a898 Mon Sep 17 00:00:00 2001 From: Adrian Danis Date: Mon, 29 Jun 2015 14:57:13 +1000 Subject: [PATCH 3/3] x86: Move general x86 functions to common header --- include/arch/x86/arch/32/mode/machine.h | 79 ------------------------- include/arch/x86/arch/machine.h | 79 +++++++++++++++++++++++++ 2 files changed, 79 insertions(+), 79 deletions(-) diff --git a/include/arch/x86/arch/32/mode/machine.h b/include/arch/x86/arch/32/mode/machine.h index 824e08dde..0d93a51a4 100644 --- a/include/arch/x86/arch/32/mode/machine.h +++ b/include/arch/x86/arch/32/mode/machine.h @@ -33,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) { @@ -78,71 +66,4 @@ static inline void* get_current_esp(void) 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 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; -} - -/* Read/write memory fence */ -static inline void x86_mfence(void) -{ - asm volatile("mfence" ::: "memory"); -} - #endif diff --git a/include/arch/x86/arch/machine.h b/include/arch/x86/arch/machine.h index 77103c115..1234d33a7 100644 --- a/include/arch/x86/arch/machine.h +++ b/include/arch/x86/arch/machine.h @@ -51,6 +51,85 @@ 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);