[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v2 05/22] mini-os: add boot code for HVMlite support
Juergen Gross, on Wed 24 Aug 2016 12:11:27 +0200, wrote: > 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 Way clearer, thanks! Reviewed-by: Samuel Thibault <samuel.thibault@xxxxxxxxxxxx> > --- > 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 > -- Samuel +#if defined(__alpha__) && defined(CONFIG_PCI) + /* + * The meaning of life, the universe, and everything. Plus + * this makes the year come out right. + */ + year -= 42; +#endif (From the patch for 1.3.2: (kernel/time.c), submitted by Marcus Meissner) _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx https://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |