diff options
author | kaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk> | 2006-05-19 16:52:52 +0100 |
---|---|---|
committer | kaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk> | 2006-05-19 16:52:52 +0100 |
commit | 0306a3dcf80671190f188e9c9d3e4c98ba433113 (patch) | |
tree | 2d63ed08ad791cfff6194035ebc433a4b931d31b /extras/mini-os | |
parent | 71fd91f9bacb0d3a625e12f959c0fa1e922fdd99 (diff) | |
download | xen-0306a3dcf80671190f188e9c9d3e4c98ba433113.tar.gz xen-0306a3dcf80671190f188e9c9d3e4c98ba433113.tar.bz2 xen-0306a3dcf80671190f188e9c9d3e4c98ba433113.zip |
[MINIOS] PAE support.
Signed-off-by: Aravindh Puthiyaparambil <aravindh.puthiyaparambil@unisys.com>
Diffstat (limited to 'extras/mini-os')
-rw-r--r-- | extras/mini-os/Makefile | 6 | ||||
-rw-r--r-- | extras/mini-os/include/mm.h | 71 | ||||
-rw-r--r-- | extras/mini-os/include/types.h | 7 | ||||
-rw-r--r-- | extras/mini-os/kernel.c | 11 | ||||
-rw-r--r-- | extras/mini-os/mm.c | 67 | ||||
-rw-r--r-- | extras/mini-os/traps.c | 21 | ||||
-rw-r--r-- | extras/mini-os/x86_32.S | 8 |
7 files changed, 133 insertions, 58 deletions
diff --git a/extras/mini-os/Makefile b/extras/mini-os/Makefile index 56eb4ff1df..63cd9e8079 100644 --- a/extras/mini-os/Makefile +++ b/extras/mini-os/Makefile @@ -1,4 +1,5 @@ debug ?= y +pae ?= n include $(CURDIR)/../../Config.mk @@ -19,6 +20,11 @@ CFLAGS += -m32 -march=i686 LDFLAGS += -m elf_i386 endif +ifeq ($(TARGET_ARCH)$(pae),x86_32y) +CFLAGS += -DCONFIG_X86_PAE=1 +ASFLAGS += -DCONFIG_X86_PAE=1 +endif + ifeq ($(TARGET_ARCH),x86_64) CFLAGS += -m64 -mno-red-zone -fpic -fno-reorder-blocks CFLAGS += -fno-asynchronous-unwind-tables diff --git a/extras/mini-os/include/mm.h b/extras/mini-os/include/mm.h index 2b33c454c7..7d91471bb1 100644 --- a/extras/mini-os/include/mm.h +++ b/extras/mini-os/include/mm.h @@ -43,6 +43,8 @@ #if defined(__i386__) +#if !defined(CONFIG_X86_PAE) + #define L2_PAGETABLE_SHIFT 22 #define L1_PAGETABLE_ENTRIES 1024 @@ -51,6 +53,30 @@ #define PADDR_BITS 32 #define PADDR_MASK (~0UL) +#define UNMAPPED_PT_FRAMES 1 +#define PRIpte "08lx" +typedef unsigned long pgentry_t; + +#else /* defined(CONFIG_X86_PAE) */ + +#define L2_PAGETABLE_SHIFT 21 +#define L3_PAGETABLE_SHIFT 30 + +#define L1_PAGETABLE_ENTRIES 512 +#define L2_PAGETABLE_ENTRIES 512 +#define L3_PAGETABLE_ENTRIES 4 + +#define PADDR_BITS 44 +#define PADDR_MASK ((1ULL << PADDR_BITS)-1) + +#define L2_MASK ((1UL << L3_PAGETABLE_SHIFT) - 1) + +#define UNMAPPED_PT_FRAMES 2 +#define PRIpte "016llx" +typedef uint64_t pgentry_t; + +#endif /* !defined(CONFIG_X86_PAE) */ + #elif defined(__x86_64__) #define L2_PAGETABLE_SHIFT 21 @@ -81,6 +107,10 @@ #define L2_MASK ((1UL << L3_PAGETABLE_SHIFT) - 1) #define L3_MASK ((1UL << L4_PAGETABLE_SHIFT) - 1) +#define UNMAPPED_PT_FRAMES 3 +#define PRIpte "016lx" +typedef unsigned long pgentry_t; + #endif #define L1_MASK ((1UL << L2_PAGETABLE_SHIFT) - 1) @@ -90,9 +120,11 @@ (((_a) >> L1_PAGETABLE_SHIFT) & (L1_PAGETABLE_ENTRIES - 1)) #define l2_table_offset(_a) \ (((_a) >> L2_PAGETABLE_SHIFT) & (L2_PAGETABLE_ENTRIES - 1)) -#if defined(__x86_64__) +#if defined(__x86_64__) || defined(CONFIG_X86_PAE) #define l3_table_offset(_a) \ (((_a) >> L3_PAGETABLE_SHIFT) & (L3_PAGETABLE_ENTRIES - 1)) +#endif +#if defined(__x86_64__) #define l4_table_offset(_a) \ (((_a) >> L4_PAGETABLE_SHIFT) & (L4_PAGETABLE_ENTRIES - 1)) #endif @@ -111,14 +143,21 @@ #if defined(__i386__) #define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED) #define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY |_PAGE_USER) +#if defined(CONFIG_X86_PAE) +#define L3_PROT (_PAGE_PRESENT) +#endif /* CONFIG_X86_PAE */ #elif defined(__x86_64__) #define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_USER) #define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER) #define L3_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER) #define L4_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER) -#endif +#endif /* __i386__ || __x86_64__ */ +#ifndef CONFIG_X86_PAE #define PAGE_SIZE (1UL << L1_PAGETABLE_SHIFT) +#else +#define PAGE_SIZE (1ULL << L1_PAGETABLE_SHIFT) +#endif #define PAGE_SHIFT L1_PAGETABLE_SHIFT #define PAGE_MASK (~(PAGE_SIZE-1)) @@ -129,23 +168,31 @@ /* to align the pointer to the (next) page boundary */ #define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) +/* Definitions for machine and pseudophysical addresses. */ +#ifdef CONFIG_X86_PAE +typedef unsigned long long paddr_t; +typedef unsigned long long maddr_t; +#else +typedef unsigned long paddr_t; +typedef unsigned long maddr_t; +#endif + extern unsigned long *phys_to_machine_mapping; extern char _text, _etext, _edata, _end; #define pfn_to_mfn(_pfn) (phys_to_machine_mapping[(_pfn)]) -static __inline__ unsigned long phys_to_machine(unsigned long phys) +static __inline__ maddr_t phys_to_machine(paddr_t phys) { - unsigned long machine = pfn_to_mfn(phys >> L1_PAGETABLE_SHIFT); - machine = (machine << L1_PAGETABLE_SHIFT) | (phys & ~PAGE_MASK); - return machine; + maddr_t machine = pfn_to_mfn(phys >> PAGE_SHIFT); + machine = (machine << PAGE_SHIFT) | (phys & ~PAGE_MASK); + return machine; } - #define mfn_to_pfn(_mfn) (machine_to_phys_mapping[(_mfn)]) -static __inline__ unsigned long machine_to_phys(unsigned long machine) +static __inline__ paddr_t machine_to_phys(maddr_t machine) { - unsigned long phys = mfn_to_pfn(machine >> L1_PAGETABLE_SHIFT); - phys = (phys << L1_PAGETABLE_SHIFT) | (machine & ~PAGE_MASK); - return phys; + paddr_t phys = mfn_to_pfn(machine >> PAGE_SHIFT); + phys = (phys << PAGE_SHIFT) | (machine & ~PAGE_MASK); + return phys; } #define VIRT_START ((unsigned long)&_text) @@ -155,7 +202,7 @@ static __inline__ unsigned long machine_to_phys(unsigned long machine) #define virt_to_pfn(_virt) (PFN_DOWN(to_phys(_virt))) #define mach_to_virt(_mach) (to_virt(machine_to_phys(_mach))) -#define mfn_to_virt(_mfn) (mach_to_virt(_mfn << PAGE_SHIFT)) +#define mfn_to_virt(_mfn) (to_virt(mfn_to_pfn(_mfn) << PAGE_SHIFT)) #define pfn_to_virt(_pfn) (to_virt(_pfn << PAGE_SHIFT)) /* Pagetable walking. */ diff --git a/extras/mini-os/include/types.h b/extras/mini-os/include/types.h index 8194fba3c0..f6f3f94b03 100644 --- a/extras/mini-os/include/types.h +++ b/extras/mini-os/include/types.h @@ -43,14 +43,19 @@ typedef long long quad_t; typedef unsigned long long u_quad_t; typedef unsigned int uintptr_t; +#if !defined(CONFIG_X86_PAE) typedef struct { unsigned long pte_low; } pte_t; +#else +typedef struct { unsigned long pte_low, pte_high; } pte_t; +#endif /* CONFIG_X86_PAE */ + #elif defined(__x86_64__) typedef long quad_t; typedef unsigned long u_quad_t; typedef unsigned long uintptr_t; typedef struct { unsigned long pte; } pte_t; -#endif +#endif /* __i386__ || __x86_64__ */ typedef u8 uint8_t; typedef s8 int8_t; diff --git a/extras/mini-os/kernel.c b/extras/mini-os/kernel.c index 49dbf6034b..52e919e9a4 100644 --- a/extras/mini-os/kernel.c +++ b/extras/mini-os/kernel.c @@ -63,7 +63,12 @@ void failsafe_callback(void); extern char shared_info[PAGE_SIZE]; +#if !defined(CONFIG_X86_PAE) #define __pte(x) ((pte_t) { (x) } ) +#else +#define __pte(x) ({ unsigned long long _x = (x); \ + ((pte_t) {(unsigned long)(_x), (unsigned long)(_x>>32)}); }) +#endif static shared_info_t *map_shared_info(unsigned long pa) { @@ -71,7 +76,7 @@ static shared_info_t *map_shared_info(unsigned long pa) (unsigned long)shared_info, __pte(pa | 7), UVMF_INVLPG) ) { printk("Failed to map shared_info!!\n"); - *(int*)0=0; + do_exit(); } return (shared_info_t *)shared_info; } @@ -126,6 +131,10 @@ void start_kernel(start_info_t *si) /* WARN: don't do printk before here, it uses information from shared_info. Use xprintk instead. */ memcpy(&start_info, si, sizeof(*si)); + + /* set up minimal memory infos */ + phys_to_machine_mapping = (unsigned long *)start_info.mfn_list; + /* Grab the shared_info pointer and put it in a safe place. */ HYPERVISOR_shared_info = map_shared_info(start_info.shared_info); diff --git a/extras/mini-os/mm.c b/extras/mini-os/mm.c index f1fc5448b4..145e15c971 100644 --- a/extras/mini-os/mm.c +++ b/extras/mini-os/mm.c @@ -368,7 +368,7 @@ void free_pages(void *pointer, int order) void new_pt_frame(unsigned long *pt_pfn, unsigned long prev_l_mfn, unsigned long offset, unsigned long level) { - unsigned long *tab = (unsigned long *)start_info.pt_base; + pgentry_t *tab = (pgentry_t *)start_info.pt_base; unsigned long pt_page = (unsigned long)pfn_to_virt(*pt_pfn); unsigned long prot_e, prot_t, pincmd; mmu_update_t mmu_updates[1]; @@ -382,40 +382,45 @@ void new_pt_frame(unsigned long *pt_pfn, unsigned long prev_l_mfn, as a page table page */ memset((unsigned long*)pfn_to_virt(*pt_pfn), 0, PAGE_SIZE); - if (level == L1_FRAME) + switch ( level ) { + case L1_FRAME: prot_e = L1_PROT; prot_t = L2_PROT; pincmd = MMUEXT_PIN_L1_TABLE; - } -#if (defined __x86_64__) - else if (level == L2_FRAME) - { + break; +#if defined(__x86_64__) || defined(CONFIG_X86_PAE) + case L2_FRAME: prot_e = L2_PROT; prot_t = L3_PROT; pincmd = MMUEXT_PIN_L2_TABLE; - } - else if (level == L3_FRAME) - { + break; +#endif +#if defined(__x86_64__) + case L3_FRAME: prot_e = L3_PROT; prot_t = L4_PROT; pincmd = MMUEXT_PIN_L3_TABLE; - } + break; #endif - else - { + default: printk("new_pt_frame() called with invalid level number %d\n", level); do_exit(); - } + break; + } /* Update the entry */ -#if (defined __x86_64__) +#if defined(__x86_64__) tab = pte_to_virt(tab[l4_table_offset(pt_page)]); tab = pte_to_virt(tab[l3_table_offset(pt_page)]); #endif - mmu_updates[0].ptr = (tab[l2_table_offset(pt_page)] & PAGE_MASK) + - sizeof(void *)* l1_table_offset(pt_page); - mmu_updates[0].val = pfn_to_mfn(*pt_pfn) << PAGE_SHIFT | +#if defined(CONFIG_X86_PAE) + tab = pte_to_virt(tab[l3_table_offset(pt_page)]); +#endif + + mmu_updates[0].ptr = ((pgentry_t)tab[l2_table_offset(pt_page)] & PAGE_MASK) + + sizeof(pgentry_t) * l1_table_offset(pt_page); + mmu_updates[0].val = (pgentry_t)pfn_to_mfn(*pt_pfn) << PAGE_SHIFT | (prot_e & ~_PAGE_RW); if(HYPERVISOR_mmu_update(mmu_updates, 1, NULL, DOMID_SELF) < 0) { @@ -434,8 +439,8 @@ void new_pt_frame(unsigned long *pt_pfn, unsigned long prev_l_mfn, /* Now fill the new page table page with entries. Update the page directory as well. */ - mmu_updates[0].ptr = (prev_l_mfn << PAGE_SHIFT) + sizeof(void *) * offset; - mmu_updates[0].val = pfn_to_mfn(*pt_pfn) << PAGE_SHIFT | prot_t; + mmu_updates[0].ptr = ((pgentry_t)prev_l_mfn << PAGE_SHIFT) + sizeof(pgentry_t) * offset; + mmu_updates[0].val = (pgentry_t)pfn_to_mfn(*pt_pfn) << PAGE_SHIFT | prot_t; if(HYPERVISOR_mmu_update(mmu_updates, 1, NULL, DOMID_SELF) < 0) { printk("ERROR: mmu_update failed\n"); @@ -450,16 +455,13 @@ void build_pagetable(unsigned long *start_pfn, unsigned long *max_pfn) unsigned long start_address, end_address; unsigned long pfn_to_map, pt_pfn = *start_pfn; static mmu_update_t mmu_updates[L1_PAGETABLE_ENTRIES + 1]; - unsigned long *tab = (unsigned long *)start_info.pt_base; + pgentry_t *tab = (pgentry_t *)start_info.pt_base, page; unsigned long mfn = pfn_to_mfn(virt_to_pfn(start_info.pt_base)); - unsigned long page, offset; + unsigned long offset; int count = 0; -#if defined(__x86_64__) - pfn_to_map = (start_info.nr_pt_frames - 3) * L1_PAGETABLE_ENTRIES; -#else - pfn_to_map = (start_info.nr_pt_frames - 1) * L1_PAGETABLE_ENTRIES; -#endif + pfn_to_map = (start_info.nr_pt_frames - UNMAPPED_PT_FRAMES) * L1_PAGETABLE_ENTRIES; + start_address = (unsigned long)pfn_to_virt(pfn_to_map); end_address = (unsigned long)pfn_to_virt(*max_pfn); @@ -468,7 +470,7 @@ void build_pagetable(unsigned long *start_pfn, unsigned long *max_pfn) while(start_address < end_address) { - tab = (unsigned long *)start_info.pt_base; + tab = (pgentry_t *)start_info.pt_base; mfn = pfn_to_mfn(virt_to_pfn(start_info.pt_base)); #if defined(__x86_64__) @@ -480,6 +482,8 @@ void build_pagetable(unsigned long *start_pfn, unsigned long *max_pfn) page = tab[offset]; mfn = pte_to_mfn(page); tab = to_virt(mfn_to_pfn(mfn) << PAGE_SHIFT); +#endif +#if defined(__x86_64__) || defined(CONFIG_X86_PAE) offset = l3_table_offset(start_address); /* Need new L2 pt frame */ if(!(start_address & L2_MASK)) @@ -498,9 +502,9 @@ void build_pagetable(unsigned long *start_pfn, unsigned long *max_pfn) mfn = pte_to_mfn(page); offset = l1_table_offset(start_address); - mmu_updates[count].ptr = (mfn << PAGE_SHIFT) + sizeof(void *) * offset; + mmu_updates[count].ptr = ((pgentry_t)mfn << PAGE_SHIFT) + sizeof(pgentry_t) * offset; mmu_updates[count].val = - pfn_to_mfn(pfn_to_map++) << PAGE_SHIFT | L1_PROT; + (pgentry_t)pfn_to_mfn(pfn_to_map++) << PAGE_SHIFT | L1_PROT; count++; if (count == L1_PAGETABLE_ENTRIES || pfn_to_map == *max_pfn) { @@ -557,9 +561,6 @@ void init_mm(void) printk(" stack start: %p\n", &stack); printk(" _end: %p\n", &_end); - /* set up minimal memory infos */ - phys_to_machine_mapping = (unsigned long *)start_info.mfn_list; - /* First page follows page table pages and 3 more pages (store page etc) */ start_pfn = PFN_UP(to_phys(start_info.pt_base)) + start_info.nr_pt_frames + 3; @@ -569,7 +570,7 @@ void init_mm(void) printk(" max_pfn: %lx\n", max_pfn); build_pagetable(&start_pfn, &max_pfn); - + /* * now we can initialise the page allocator */ diff --git a/extras/mini-os/traps.c b/extras/mini-os/traps.c index 43dca39268..292c48b22b 100644 --- a/extras/mini-os/traps.c +++ b/extras/mini-os/traps.c @@ -95,25 +95,26 @@ DO_ERROR(18, "machine check", machine_check) void page_walk(unsigned long virt_address) { - unsigned long *tab = (unsigned long *)start_info.pt_base; - unsigned long addr = virt_address, page; + pgentry_t *tab = (pgentry_t *)start_info.pt_base, page; + unsigned long addr = virt_address; printk("Pagetable walk from virt %lx, base %lx:\n", virt_address, start_info.pt_base); #if defined(__x86_64__) page = tab[l4_table_offset(addr)]; - tab = to_virt(mfn_to_pfn(pte_to_mfn(page)) << PAGE_SHIFT); - printk(" L4 = %p (%p) [offset = %lx]\n", page, tab, l4_table_offset(addr)); - + tab = pte_to_virt(page); + printk(" L4 = %"PRIpte" (%p) [offset = %lx]\n", page, tab, l4_table_offset(addr)); +#endif +#if defined(__x86_64__) || defined(CONFIG_X86_PAE) page = tab[l3_table_offset(addr)]; - tab = to_virt(mfn_to_pfn(pte_to_mfn(page)) << PAGE_SHIFT); - printk(" L3 = %p (%p) [offset = %lx]\n", page, tab, l3_table_offset(addr)); + tab = pte_to_virt(page); + printk(" L3 = %"PRIpte" (%p) [offset = %lx]\n", page, tab, l3_table_offset(addr)); #endif page = tab[l2_table_offset(addr)]; - tab = to_virt(mfn_to_pfn(pte_to_mfn(page)) << PAGE_SHIFT); - printk(" L2 = %p (%p) [offset = %lx]\n", page, tab, l2_table_offset(addr)); + tab = pte_to_virt(page); + printk(" L2 = %"PRIpte" (%p) [offset = %lx]\n", page, tab, l2_table_offset(addr)); page = tab[l1_table_offset(addr)]; - printk(" L1 = %p (%p) [offset = %lx]\n", page, tab, l1_table_offset(addr)); + printk(" L1 = %"PRIpte" (%p) [offset = %lx]\n", page, tab, l1_table_offset(addr)); } diff --git a/extras/mini-os/x86_32.S b/extras/mini-os/x86_32.S index f434b3233e..7a3056f3b3 100644 --- a/extras/mini-os/x86_32.S +++ b/extras/mini-os/x86_32.S @@ -4,9 +4,15 @@ .section __xen_guest .ascii "GUEST_OS=Mini-OS" .ascii ",XEN_VER=xen-3.0" + .ascii ",VIRT_BASE=0xc0000000" /* &_text from minios_x86_32.lds */ + .ascii ",ELF_PADDR_OFFSET=0xc0000000" .ascii ",HYPERCALL_PAGE=0x2" +#ifdef CONFIG_X86_PAE + .ascii ",PAE=yes" +#else + .ascii ",PAE=no" +#endif .ascii ",LOADER=generic" - .ascii ",PT_MODE_WRITABLE" .byte 0 .text |