[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v2 05/22] mini-os: add boot code for HVMlite support
A HVMlite domain is always starting in 32 bit mode. Add the appropriate boot code to arch/x86 for the non-paravirtualized case. For this boot code to become active we need to suppress the pv related elfnotes and add an appropriate elfnote for HVMlite. As the HVMlite boot code is more or less the same for 32- and 64-bit Mini-OS #include the new code from x86_[32|64].S in order to avoid error prone code duplication. The specific parts of 32- or 64-bit code are added to x86_[32|64].S This enables Mini-OS to start the boot process in HVMlite mode until it enters C code. This is working for 32- and for 64-bit mode. Signed-off-by: Juergen Gross <jgross@xxxxxxxx> --- V2: add some comments as requested by Samuel Thibault --- Makefile | 2 +- arch/x86/arch.mk | 4 + arch/x86/mm.c | 31 +++++ arch/x86/setup.c | 4 +- arch/x86/x86_32.S | 31 ++++- arch/x86/x86_64.S | 35 ++++- arch/x86/x86_hvm.S | 88 +++++++++++++ include/compiler.h | 1 + include/x86/desc.h | 367 +++++++++++++++++++++++++++++++++++++++++++++++++++++ include/x86/os.h | 5 + minios.mk | 2 +- 11 files changed, 556 insertions(+), 14 deletions(-) create mode 100644 arch/x86/x86_hvm.S create mode 100644 include/x86/desc.h diff --git a/Makefile b/Makefile index 779bc91..b783684 100644 --- a/Makefile +++ b/Makefile @@ -24,7 +24,7 @@ include minios.mk LDLIBS := APP_LDLIBS := LDARCHLIB := -L$(OBJ_DIR)/$(TARGET_ARCH_DIR) -l$(ARCH_LIB_NAME) -LDFLAGS_FINAL := -T $(TARGET_ARCH_DIR)/minios-$(MINIOS_TARGET_ARCH).lds +LDFLAGS_FINAL := -T $(TARGET_ARCH_DIR)/minios-$(MINIOS_TARGET_ARCH).lds $(ARCH_LDFLAGS_FINAL) # Prefix for global API names. All other symbols are localised before # linking with EXTRA_OBJS. diff --git a/arch/x86/arch.mk b/arch/x86/arch.mk index 81e8118..673a19d 100644 --- a/arch/x86/arch.mk +++ b/arch/x86/arch.mk @@ -20,3 +20,7 @@ EXTRA_INC += $(TARGET_ARCH_FAM)/$(MINIOS_TARGET_ARCH) EXTRA_SRC += arch/$(EXTRA_INC) endif +ifeq ($(CONFIG_PARAVIRT),n) +ARCH_LDFLAGS_FINAL := --oformat=elf32-i386 +ARCH_AS_DEPS += x86_hvm.S +endif diff --git a/arch/x86/mm.c b/arch/x86/mm.c index 88a928d..fe18f53 100644 --- a/arch/x86/mm.c +++ b/arch/x86/mm.c @@ -56,6 +56,37 @@ unsigned long mfn_zero; extern char stack[]; extern void page_walk(unsigned long va); +#ifndef CONFIG_PARAVIRT +#include <mini-os/desc.h> +user_desc gdt[NR_GDT_ENTRIES] = +{ + [GDTE_CS64_DPL0] = INIT_GDTE_SYM(0, 0xfffff, COMMON, CODE, DPL0, R, L), + [GDTE_CS32_DPL0] = INIT_GDTE_SYM(0, 0xfffff, COMMON, CODE, DPL0, R, D), + [GDTE_DS32_DPL0] = INIT_GDTE_SYM(0, 0xfffff, COMMON, DATA, DPL0, B, W), + + [GDTE_CS64_DPL3] = INIT_GDTE_SYM(0, 0xfffff, COMMON, CODE, DPL3, R, L), + [GDTE_CS32_DPL3] = INIT_GDTE_SYM(0, 0xfffff, COMMON, CODE, DPL3, R, D), + [GDTE_DS32_DPL3] = INIT_GDTE_SYM(0, 0xfffff, COMMON, DATA, DPL3, B, W), + + /* [GDTE_TSS] */ + /* [GDTE_TSS + 1] */ +}; + +desc_ptr gdt_ptr = +{ + .limit = sizeof(gdt) - 1, + .base = (unsigned long)&gdt, +}; + +gate_desc idt[256] = { }; + +desc_ptr idt_ptr = +{ + .limit = sizeof(idt) - 1, + .base = (unsigned long)&idt, +}; +#endif + /* * Make pt_pfn a new 'level' page table frame and hook it into the page * table at offset in previous level MFN (pref_l_mfn). pt_pfn is a guest diff --git a/arch/x86/setup.c b/arch/x86/setup.c index 5e87dd1..30a9143 100644 --- a/arch/x86/setup.c +++ b/arch/x86/setup.c @@ -94,9 +94,10 @@ static inline void sse_init(void) { * INITIAL C ENTRY POINT. */ void -arch_init(start_info_t *si) +arch_init(void *par) { static char hello[] = "Bootstrapping...\n"; + start_info_t *si; (void)HYPERVISOR_console_io(CONSOLEIO_write, strlen(hello), hello); @@ -111,6 +112,7 @@ arch_init(start_info_t *si) /* Copy the start_info struct to a globally-accessible area. */ /* WARN: don't do printk before here, it uses information from shared_info. Use xprintk instead. */ + si = par; memcpy(&start_info, si, sizeof(*si)); /* print out some useful information */ diff --git a/arch/x86/x86_32.S b/arch/x86/x86_32.S index 6dc985a..6f38708 100644 --- a/arch/x86/x86_32.S +++ b/arch/x86/x86_32.S @@ -1,20 +1,31 @@ #include <mini-os/os.h> #include <mini-os/x86/arch_limits.h> #include <mini-os/asm_macros.h> +#include <mini-os/arch_mm.h> +#include <mini-os/desc.h> +#include <xen/arch-x86_32.h> #include <xen/elfnote.h> #include <xen/arch-x86_32.h> +#ifdef CONFIG_PARAVIRT ELFNOTE(Xen, XEN_ELFNOTE_GUEST_OS, .asciz "Mini-OS") ELFNOTE(Xen, XEN_ELFNOTE_LOADER, .asciz "generic") ELFNOTE(Xen, XEN_ELFNOTE_HYPERCALL_PAGE, _WORD hypercall_page) ELFNOTE(Xen, XEN_ELFNOTE_XEN_VERSION, .asciz "xen-3.0") ELFNOTE(Xen, XEN_ELFNOTE_PAE_MODE, .asciz "yes") +.text -.globl _start, shared_info, hypercall_page +.globl _start _start: - cld lss stack_start,%esp +#else + +#include "x86_hvm.S" + movl stack_start,%esp + +#endif + cld andl $(~(__STACK_SIZE-1)), %esp push %esi call arch_init @@ -22,14 +33,15 @@ _start: stack_start: .long stack+(2*__STACK_SIZE), __KERNEL_SS +.globl shared_info, hypercall_page /* Unpleasant -- the PTE that maps this page is actually overwritten */ /* to map the real shared-info page! :-) */ - .org 0x1000 + .align __PAGE_SIZE shared_info: - .org 0x2000 + .fill __PAGE_SIZE,1,0 hypercall_page: - .org 0x3000 + .fill __PAGE_SIZE,1,0 ES = 0x20 ORIG_EAX = 0x24 @@ -300,3 +312,12 @@ ENTRY(__arch_switch_threads) popl %ebx popl %ebp ret + +#ifndef CONFIG_PARAVIRT +.data +.globl page_table_base + .align __PAGE_SIZE +page_table_base: + PTE(page_table_l2 + L3_PROT) + .align __PAGE_SIZE, 0 +#endif diff --git a/arch/x86/x86_64.S b/arch/x86/x86_64.S index 8ed452f..373f400 100644 --- a/arch/x86/x86_64.S +++ b/arch/x86/x86_64.S @@ -1,19 +1,29 @@ #include <mini-os/os.h> #include <mini-os/x86/arch_limits.h> #include <mini-os/asm_macros.h> +#include <mini-os/arch_mm.h> +#include <mini-os/desc.h> +#include <xen/features.h> #include <xen/elfnote.h> #include <xen/features.h> +#define ENTRY(X) .globl X ; X : + +#ifdef CONFIG_PARAVIRT ELFNOTE(Xen, XEN_ELFNOTE_GUEST_OS, .asciz "Mini-OS") ELFNOTE(Xen, XEN_ELFNOTE_LOADER, .asciz "generic") ELFNOTE(Xen, XEN_ELFNOTE_HYPERCALL_PAGE, _WORD hypercall_page) ELFNOTE(Xen, XEN_ELFNOTE_XEN_VERSION, .asciz "xen-3.0") +.text -#define ENTRY(X) .globl X ; X : -.globl _start, shared_info, hypercall_page - +.globl _start _start: +#else + +#include "x86_hvm.S" + +#endif cld movq stack_start(%rip),%rsp andq $(~(__STACK_SIZE-1)), %rsp @@ -23,14 +33,15 @@ _start: stack_start: .quad stack+(2*__STACK_SIZE) +.globl shared_info, hypercall_page /* Unpleasant -- the PTE that maps this page is actually overwritten */ /* to map the real shared-info page! :-) */ - .org 0x1000 + .align __PAGE_SIZE shared_info: - .org 0x2000 + .fill __PAGE_SIZE,1,0 hypercall_page: - .org 0x3000 + .fill __PAGE_SIZE,1,0 #define XEN_GET_VCPU_INFO(reg) movq HYPERVISOR_shared_info,reg @@ -378,3 +389,15 @@ ENTRY(__arch_switch_threads) popq %rbx popq %rbp ret + +#ifndef CONFIG_PARAVIRT +.data +.globl page_table_base + .align __PAGE_SIZE +page_table_l3: + PTE(page_table_l2 + L3_PROT) + .align __PAGE_SIZE, 0 +page_table_base: + PTE(page_table_l3 + L4_PROT) + .align __PAGE_SIZE, 0 +#endif diff --git a/arch/x86/x86_hvm.S b/arch/x86/x86_hvm.S new file mode 100644 index 0000000..6e8ad98 --- /dev/null +++ b/arch/x86/x86_hvm.S @@ -0,0 +1,88 @@ +/* Included by x86_[32|64].S */ + + ELFNOTE(Xen, XEN_ELFNOTE_PHYS32_ENTRY, .long _start) +.text + .code32 /* Always starts in 32bit flat mode. */ + +.globl _start + +_start: + mov $(X86_CR4_PAE | X86_CR4_OSFXSR), %eax + mov %eax, %cr4 + mov $page_table_base, %eax + mov %eax, %cr3 + +#ifdef __x86_64__ /* EFER.LME = 1 */ + mov $MSR_EFER, %ecx + rdmsr + bts $_EFER_LME, %eax + wrmsr +#endif /* __x86_64__ */ + + mov %cr0, %eax + or $X86_CR0_PG, %eax + mov %eax, %cr0 + + lgdt gdt_ptr + + /* Load code segment. */ + ljmp $__KERN_CS, $1f +#ifdef __x86_64__ + .code64 +#endif + + /* Load data segments. */ +1: + mov $__USER_DS, %eax + mov %eax, %ds + mov %eax, %es + mov %eax, %fs + mov %eax, %gs + mov $__KERN_DS, %eax + mov %eax, %ss + + mov %ebx, %esi + +.data +/* + * Macro to create a sequence of page table entries. + * As a loop can be done via recursion only and the nesting level is limited + * we treat the first 32 PTEs in a special way limiting nesting level to 64 + * in case of a complete page table (512 PTEs) to be filled. + * prot: protection bits in all PTEs + * addr: physical address of the area to map + * incr: increment of address for each PTE + * idx: index of first PTE in page table + * end: index of last PTE in page table + 1 + */ + .macro PTES prot, addr, incr, idx, end + .ifgt \end-\idx-32 + PTES \prot, \addr, \incr, \idx, "(\idx+32)" + PTES \prot, "(\addr+32*\incr)", \incr, "(\idx+32)", \end + .else + PTE(\addr + \prot) + .if \end-\idx-1 + PTES \prot, "(\addr+\incr)", \incr, "(\idx+1)", \end + .endif + .endif + .endm + .align __PAGE_SIZE +page_table_virt_l1: + PTE(0) + .align __PAGE_SIZE, 0 +page_table_l1: + PTES L1_PROT, 0x00000000, 0x00001000, 0, L1_PAGETABLE_ENTRIES + .align __PAGE_SIZE, 0 +page_table_l2: + /* Map the first 1GB of memory (on 32 bit 16MB less). */ + PTE(page_table_l1 + L2_PROT) +#ifdef __x86_64__ + PTES L2_PROT|_PAGE_PSE, 0x00200000, 0x00200000, 1, L2_PAGETABLE_ENTRIES +#else + /* At 3f000000 virtual kernel area is starting. */ + PTES L2_PROT|_PAGE_PSE, 0x00200000, 0x00200000, 1, l2_table_offset(VIRT_KERNEL_AREA) + PTE(page_table_virt_l1 + L2_PROT) +#endif + .align __PAGE_SIZE, 0 + +.text diff --git a/include/compiler.h b/include/compiler.h index 4188277..0cbad98 100644 --- a/include/compiler.h +++ b/include/compiler.h @@ -6,5 +6,6 @@ #endif #define unlikely(x) __builtin_expect(!!(x),0) #define likely(x) __builtin_expect(!!(x),1) +#define __packed __attribute__((__packed__)) #endif /* __MINIOS_COMPILER_H_ */ diff --git a/include/x86/desc.h b/include/x86/desc.h new file mode 100644 index 0000000..b9b921b --- /dev/null +++ b/include/x86/desc.h @@ -0,0 +1,367 @@ +/* -*- Mode:C; c-basic-offset:4; tab-width:4 -*- + * + * (C) 2016 - Juergen Gross, SUSE Linux GmbH + * based on some header files from Xen Test Framework by Andrew Cooper + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef _DESC_H_ +#define _DESC_H_ + +/* + * Count the number of varadic arguments provided. + * + * <pre> + * VA_NARGS() => 0 + * VA_NARGS(x) => 1 + * VA_NARGS(x, y) => 2 + * </pre> + * + * Currently functions for 0 to 11 arguments. + */ +#define VA_NARGS_(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, N, ...) N +#define VA_NARGS(...) \ + VA_NARGS_(X,##__VA_ARGS__, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) + +/* + * Call a macro variation, based on the number of varadic arguments. + * + * @param macro Partial token to call a variation of. + * @param c1 Constant parameter to pass through. + * @param ... Varadic arguments to pass through. + * + * Tokenises 'macro' with the count of varadic arguments, passing 'c1' and the + * varadic arguments. + * + * <pre> + * VAR_MACRO_C1(m, c) => m0(c) + * VAR_MACRO_C1(m, c, x) => m1(c, x) + * VAR_MACRO_C1(m, c, x, y) => m2(c, x, y) + * VAR_MACRO_C1(m, c, x, y, z) => m3(c, x, y, z) + * </pre> + */ +#define VAR_MACRO_C1__(macro, c1, count, ...) macro##count(c1, ##__VA_ARGS__) +#define VAR_MACRO_C1_(macro, c1, count, ...) \ + VAR_MACRO_C1__(macro, c1, count, ##__VA_ARGS__) +#define VAR_MACRO_C1(macro, c1, ...) \ + VAR_MACRO_C1_(macro, c1, VA_NARGS(__VA_ARGS__), ##__VA_ARGS__) + +/* + * GDT layout: + * + * 0 - null + * 1 - 64bit supervisor code + * 2 - 32bit supervisor code + * 3 - 32bit supervisor data + * 4 - 64bit userspace code + * 5 - 32bit userspace code + * 6 - 32bit userspace data + * 7 - TSS (two slots in long mode) + * + * 9-12 - Available for test use + */ + +#define GDTE_CS64_DPL0 1 +#define GDTE_CS32_DPL0 2 +#define GDTE_DS32_DPL0 3 +#define GDTE_CS64_DPL3 4 +#define GDTE_CS32_DPL3 5 +#define GDTE_DS32_DPL3 6 + +#define GDTE_TSS 7 + +#define GDTE_AVAIL0 9 +#define GDTE_AVAIL1 10 +#define GDTE_AVAIL2 11 +#define GDTE_AVAIL3 12 + +#define NR_GDT_ENTRIES 13 + +#ifdef __x86_64__ + +#define __KERN_CS (GDTE_CS64_DPL0 * 8) +#define __KERN_DS (0) +#define __USER_CS (GDTE_CS64_DPL3 * 8 + 3) +#define __USER_DS (GDTE_DS32_DPL3 * 8 + 3) + +#else /* __x86_64__ */ + +#define __KERN_CS (GDTE_CS32_DPL0 * 8) +#define __KERN_DS (GDTE_DS32_DPL0 * 8) +#define __USER_CS (GDTE_CS32_DPL3 * 8 + 3) +#define __USER_DS (GDTE_DS32_DPL3 * 8 + 3) + +#endif /* __x86_64__ */ + +#ifndef __ASSEMBLY__ +/* 8 byte user segment descriptor (GDT/LDT entries with .s = 1) */ +struct __packed seg_desc32 { + union { + /* Raw backing integers. */ + struct { + uint32_t lo, hi; + }; + /* Common named fields. */ + struct { + uint16_t limit0; + uint16_t base0; + uint8_t base1; + unsigned type: 4; + unsigned s: 1, dpl: 2, p: 1; + unsigned limit: 4; + unsigned avl: 1, l: 1, d: 1, g: 1; + uint8_t base2; + }; + /* Code segment specific field names. */ + struct { + uint16_t limit0; + uint16_t base0; + uint8_t base1; + unsigned a: 1, r: 1, c: 1, x: 1; + unsigned s: 1, dpl: 2, p: 1; + unsigned limit: 4; + unsigned avl: 1, l: 1, d: 1, g: 1; + uint8_t base2; + } code; + /* Data segment specific field names. */ + struct { + uint16_t limit0; + uint16_t base0; + uint8_t base1; + unsigned a: 1, w: 1, e: 1, x: 1; + unsigned s: 1, dpl: 2, p: 1; + unsigned limit: 4; + unsigned avl: 1, _r0: 1, b: 1, g: 1; + uint8_t base2; + } data; + }; +}; + +/* 8-byte gate - Protected mode IDT entry, GDT task/call gate. */ +struct __packed seg_gate32 { + union { + struct { + uint32_t lo, hi; + }; + struct { + uint16_t offset0; + uint16_t selector; + uint8_t _r0; + unsigned type: 4, s: 1, dpl: 2, p: 1; + uint16_t offset1; + }; + }; +}; + +/* 16-byte gate - Long mode IDT entry. */ +struct __packed seg_gate64 { + union { + struct { + uint64_t lo, hi; + }; + struct { + uint16_t offset0; + uint16_t selector; + unsigned ist: 3, _r0: 5, type: 4, s: 1, dpl: 2, p: 1; + uint16_t offset1; + uint32_t offset2; + uint32_t _r1; + }; + }; +}; + +/* GDT/LDT attribute flags for user segments */ + +/* Common */ +#define SEG_ATTR_G 0x8000 /* Granularity of limit (0 = 1, 1 = 4K) */ +#define SEG_ATTR_AVL 0x1000 /* Available for software use */ +#define SEG_ATTR_P 0x0080 /* Present? */ +#define SEG_ATTR_S 0x0010 /* !System desc (0 = system, 1 = user) */ +#define SEG_ATTR_A 0x0001 /* Accessed? (set by hardware) */ + +#define SEG_ATTR_COMMON 0x8091 /* Commonly set bits (G P S A) */ + +#define SEG_ATTR_DPL0 0x0000 /* Descriptor privilege level 0 */ +#define SEG_ATTR_DPL1 0x0020 /* Descriptor privilege level 1 */ +#define SEG_ATTR_DPL2 0x0040 /* Descriptor privilege level 2 */ +#define SEG_ATTR_DPL3 0x0060 /* Descriptor privilege level 3 */ +#define SEG_ATTR_CODE 0x0008 /* Type (0 = data, 1 = code) */ +#define SEG_ATTR_DATA 0x0000 /* Type (0 = data, 1 = code) */ + +/* Code segments */ +#define SEG_ATTR_D 0x4000 /* Default operand size (0 = 16bit, 1 = 32bit) */ +#define SEG_ATTR_L 0x2000 /* Long segment? (1 = 64bit) */ +#define SEG_ATTR_C 0x0004 /* Conforming? (0 = non, 1 = conforming) */ +#define SEG_ATTR_R 0x0002 /* Readable? (0 = XO seg, 1 = RX seg) */ + +/* Data segments */ +#define SEG_ATTR_B 0x4000 /* 'Big' flag. + * - For %ss, default operand size. + * - For expand-down segment, sets upper bound. */ +#define SEG_ATTR_E 0x0004 /* Expand-down? (0 = normal, 1 = expand-down) */ +#define SEG_ATTR_W 0x0002 /* Writable? (0 = RO seg, 1 = RW seg) */ + +/* + * Initialise an LDT/GDT entry using a raw attribute number. + * + * @param base Segment base. + * @param limit Segment limit. + * @param attr Segment attributes. + */ +#define INIT_GDTE(base, limit, attr) { { { \ + .lo = (((base) & 0xffff) << 16) | ((limit) & 0xffff), \ + .hi = ((base) & 0xff000000) | ((limit) & 0xf0000) | \ + (((attr) & 0xf0ff) << 8) | (((base) & 0xff0000) >> 16) \ + } } } + +/* + * Tokenise and OR together. + * + * For each varadic parameter, tokenise with 't' and OR together. + * + * @param t Common stem partial token. + * @param ... Partial tokens. + * + * Example: + * <pre> + * TOK_OR(t, x, y) => (t ## x | t ## y) + * TOK_OR(t, x, y, z) => (t ## x | t ## y | t ## z) + * </pre> + */ +#define TOK_OR0(t) (0) +#define TOK_OR1(t, x) (t ## x) +#define TOK_OR2(t, x, ...) (t ## x | TOK_OR1(t, ##__VA_ARGS__)) +#define TOK_OR3(t, x, ...) (t ## x | TOK_OR2(t, ##__VA_ARGS__)) +#define TOK_OR4(t, x, ...) (t ## x | TOK_OR3(t, ##__VA_ARGS__)) +#define TOK_OR5(t, x, ...) (t ## x | TOK_OR4(t, ##__VA_ARGS__)) +#define TOK_OR6(t, x, ...) (t ## x | TOK_OR5(t, ##__VA_ARGS__)) +#define TOK_OR7(t, x, ...) (t ## x | TOK_OR6(t, ##__VA_ARGS__)) +#define TOK_OR8(t, x, ...) (t ## x | TOK_OR7(t, ##__VA_ARGS__)) +#define TOK_OR(t, ...) VAR_MACRO_C1(TOK_OR, t, ##__VA_ARGS__) + +/* + * Initialise an LDT/GDT entry using SEG_ATTR_ mnemonics. + * + * @param base Segment base. + * @param limit Segment limit. + * @param ... Partial SEG_ATTR_ tokens for attributes. + * + * Example usage: + * - INIT_GDTE_SYM(0, 0xfffff, P) + * - uses @ref SEG_ATTR_P + * + * - INIT_GDTE_SYM(0, 0xfffff, CODE, L) + * - uses @ref SEG_ATTR_CODE and @ref SEG_ATTR_L + */ +#define INIT_GDTE_SYM(base, limit, ...) \ + INIT_GDTE(base, limit, TOK_OR(SEG_ATTR_, ##__VA_ARGS__)) + +/* Long mode lgdt/lidt table pointer. */ +struct __packed desc_ptr64 { + uint16_t limit; + uint64_t base; +}; + +/* Protected mode lgdt/lidt table pointer. */ +struct __packed desc_ptr32 { + uint16_t limit; + uint32_t base; +}; + +struct __packed hw_tss32 { + uint16_t link; uint16_t _r0; + + uint32_t esp0; + uint16_t ss0; uint16_t _r1; + + uint32_t esp1; + uint16_t ss1; uint16_t _r2; + + uint32_t esp2; + uint16_t ss2; uint16_t _r3; + + uint32_t cr3; + uint32_t eip; + uint32_t eflags; + uint32_t eax; + uint32_t ecx; + uint32_t edx; + uint32_t ebx; + uint32_t esp; + uint32_t ebp; + uint32_t esi; + uint32_t edi; + + uint16_t es; uint16_t _r4; + uint16_t cs; uint16_t _r5; + uint16_t ss; uint16_t _r6; + uint16_t ds; uint16_t _r7; + uint16_t fs; uint16_t _r8; + uint16_t gs; uint16_t _r9; + uint16_t ldtr; uint16_t _r10; + uint16_t t; uint16_t iopb; +}; + +struct __packed hw_tss64 { + uint16_t link; uint16_t _r0; + + uint64_t rsp0; + uint64_t rsp1; + uint64_t rsp2; + + uint64_t _r1; + + uint64_t ist[7]; /* 1-based structure */ + + uint64_t _r2; + + uint16_t t; + uint16_t iopb; +}; + +#define X86_TSS_INVALID_IO_BITMAP 0x8000 + +#if defined(__x86_64__) + +typedef struct desc_ptr64 desc_ptr; +typedef struct seg_desc32 user_desc; +typedef struct seg_gate64 gate_desc; +typedef struct hw_tss64 hw_tss; + +#elif defined(__i386__) + +typedef struct desc_ptr32 desc_ptr; +typedef struct seg_desc32 user_desc; +typedef struct seg_gate32 gate_desc; +typedef struct hw_tss32 hw_tss; + +#endif + +extern user_desc gdt[NR_GDT_ENTRIES]; +extern desc_ptr gdt_ptr; + +extern gate_desc idt[256]; +extern desc_ptr idt_ptr; + +extern hw_tss tss; + +#endif + +#endif /* _DESC_H_ */ diff --git a/include/x86/os.h b/include/x86/os.h index ee9050b..eeefbe2 100644 --- a/include/x86/os.h +++ b/include/x86/os.h @@ -24,7 +24,12 @@ #endif #include <xen/xen.h> +#define MSR_EFER 0xc0000080 +#define _EFER_LME 8 /* Long mode enable */ +#define X86_CR0_PG 0x80000000 /* Paging */ +#define X86_CR4_PAE 0x00000020 /* enable physical address extensions */ +#define X86_CR4_OSFXSR 0x00000200 /* enable fast FPU save and restore */ #define __KERNEL_CS FLAT_KERNEL_CS #define __KERNEL_DS FLAT_KERNEL_DS diff --git a/minios.mk b/minios.mk index 1d1cc99..9ff6bf7 100644 --- a/minios.mk +++ b/minios.mk @@ -68,7 +68,7 @@ HEAD_OBJ := $(OBJ_DIR)/$(TARGET_ARCH_DIR)/$(HEAD_ARCH_OBJ) $(OBJ_DIR)/%.o: %.c $(HDRS) Makefile $(EXTRA_DEPS) $(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@ -$(OBJ_DIR)/%.o: %.S $(HDRS) Makefile $(EXTRA_DEPS) +$(OBJ_DIR)/%.o: %.S $(HDRS) Makefile $(EXTRA_DEPS) $(ARCH_AS_DEPS) $(CC) $(ASFLAGS) $(CPPFLAGS) -c $< -o $@ -- 2.6.6 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx https://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |