[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

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.