|
[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 |