aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--extras/mini-os/Makefile6
-rw-r--r--extras/mini-os/include/mm.h71
-rw-r--r--extras/mini-os/include/types.h7
-rw-r--r--extras/mini-os/kernel.c11
-rw-r--r--extras/mini-os/mm.c67
-rw-r--r--extras/mini-os/traps.c21
-rw-r--r--extras/mini-os/x86_32.S8
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