unsigned long virt_kernel_area_end; /* TODO: find a virtual area */
-int arch_expand_p2m(unsigned long max_pfn)
-{
- return 0;
-}
-
void arch_pfn_add(unsigned long pfn, unsigned long mfn)
{
}
*max_pfn_p = to_phys(new_device_tree) >> PAGE_SHIFT;
}
-void arch_init_p2m(unsigned long max_pfn)
-{
-}
-
void arch_init_demand_mapping_area(void)
{
}
#include <mini-os/errno.h>
#include <mini-os/lib.h>
#include <mini-os/mm.h>
+#include <mini-os/paravirt.h>
#ifdef CONFIG_BALLOON
unsigned long virt_kernel_area_end = VIRT_KERNEL_AREA;
+#ifdef CONFIG_PARAVIRT
static void p2m_invalidate(unsigned long *list, unsigned long start_idx)
{
unsigned long idx;
do_exit();
}
}
+#else
+void arch_pfn_add(unsigned long pfn, unsigned long mfn)
+{
+ pgentry_t *pgt;
+
+ pgt = need_pgt((unsigned long)pfn_to_virt(pfn));
+ ASSERT(pgt);
+ if ( !(*pgt & _PAGE_PSE) )
+ *pgt = (pgentry_t)(mfn << PAGE_SHIFT) | _PAGE_PRESENT | _PAGE_RW;
+}
+#endif
#endif
#include <mini-os/hypervisor.h>
#include <mini-os/balloon.h>
#include <mini-os/mm.h>
+#include <mini-os/paravirt.h>
#include <mini-os/types.h>
#include <mini-os/lib.h>
#include <mini-os/xmalloc.h>
unsigned long *phys_to_machine_mapping;
unsigned long mfn_zero;
+pgentry_t *pt_base;
+static unsigned long first_free_pfn;
+static unsigned long last_free_pfn;
+
extern char stack[];
extern void page_walk(unsigned long va);
-#ifndef CONFIG_PARAVIRT
+#ifdef CONFIG_PARAVIRT
+void arch_mm_preinit(void *p)
+{
+ start_info_t *si = p;
+
+ phys_to_machine_mapping = (unsigned long *)si->mfn_list;
+ pt_base = (pgentry_t *)si->pt_base;
+ first_free_pfn = PFN_UP(to_phys(pt_base)) + si->nr_pt_frames;
+ last_free_pfn = si->nr_pages;
+}
+#else
#include <mini-os/desc.h>
user_desc gdt[NR_GDT_ENTRIES] =
{
.limit = sizeof(idt) - 1,
.base = (unsigned long)&idt,
};
+
+void arch_mm_preinit(void *p)
+{
+ long ret;
+ domid_t domid = DOMID_SELF;
+
+ pt_base = page_table_base;
+ first_free_pfn = PFN_UP(to_phys(&_end));
+ ret = HYPERVISOR_memory_op(XENMEM_current_reservation, &domid);
+ if ( ret < 0 )
+ {
+ xprintk("could not get memory size\n");
+ do_exit();
+ }
+ last_free_pfn = ret;
+}
#endif
/*
static void new_pt_frame(unsigned long *pt_pfn, unsigned long prev_l_mfn,
unsigned long offset, unsigned long level)
{
- pgentry_t *tab = (pgentry_t *)start_info.pt_base;
+ pgentry_t *tab = pt_base;
unsigned long pt_page = (unsigned long)pfn_to_virt(*pt_pfn);
pgentry_t prot_e, prot_t;
mmu_update_t mmu_updates[1];
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];
- pgentry_t *tab = (pgentry_t *)start_info.pt_base, page;
- unsigned long pt_mfn = pfn_to_mfn(virt_to_pfn(start_info.pt_base));
+ pgentry_t *tab = pt_base, page;
+ unsigned long pt_mfn = pfn_to_mfn(virt_to_pfn(pt_base));
unsigned long offset;
int count = 0;
int rc;
mapped, start the loop at the very beginning. */
pfn_to_map = *start_pfn;
+#ifdef CONFIG_PARAVIRT
if ( *max_pfn >= virt_to_pfn(HYPERVISOR_VIRT_START) )
{
printk("WARNING: Mini-OS trying to use Xen virtual space. "
((unsigned long)pfn_to_virt(*max_pfn) -
(unsigned long)&_text)>>20);
}
+#endif
start_address = (unsigned long)pfn_to_virt(pfn_to_map);
end_address = (unsigned long)pfn_to_virt(*max_pfn);
while ( start_address < end_address )
{
- tab = (pgentry_t *)start_info.pt_base;
- pt_mfn = pfn_to_mfn(virt_to_pfn(start_info.pt_base));
+ tab = pt_base;
+ pt_mfn = pfn_to_mfn(virt_to_pfn(pt_base));
#if defined(__x86_64__)
offset = l4_table_offset(start_address);
((unsigned long) text + PAGE_SIZE - 1) & PAGE_MASK;
unsigned long end_address = (unsigned long) etext;
static mmu_update_t mmu_updates[L1_PAGETABLE_ENTRIES + 1];
- pgentry_t *tab = (pgentry_t *)start_info.pt_base, page;
- unsigned long mfn = pfn_to_mfn(virt_to_pfn(start_info.pt_base));
+ pgentry_t *tab = pt_base, page;
+ unsigned long mfn = pfn_to_mfn(virt_to_pfn(pt_base));
unsigned long offset;
int count = 0;
int rc;
while ( start_address + PAGE_SIZE <= end_address )
{
- tab = (pgentry_t *)start_info.pt_base;
- mfn = pfn_to_mfn(virt_to_pfn(start_info.pt_base));
+ tab = pt_base;
+ mfn = pfn_to_mfn(virt_to_pfn(pt_base));
#if defined(__x86_64__)
offset = l4_table_offset(start_address);
pgentry_t *tab;
unsigned offset;
- tab = (pgentry_t *)start_info.pt_base;
- mfn = virt_to_mfn(start_info.pt_base);
+ tab = pt_base;
+ mfn = virt_to_mfn(pt_base);
#if defined(__x86_64__)
offset = l4_table_offset(va);
unsigned long pt_pfn;
unsigned offset;
- tab = (pgentry_t *)start_info.pt_base;
- pt_mfn = virt_to_mfn(start_info.pt_base);
+ tab = pt_base;
+ pt_mfn = virt_to_mfn(pt_base);
#if defined(__x86_64__)
offset = l4_table_offset(va);
printk("Unable to unmap NULL page. rc=%d\n", rc);
}
+#ifdef CONFIG_PARAVIRT
void p2m_chk_pfn(unsigned long pfn)
{
if ( (pfn >> L3_P2M_SHIFT) > 0 )
arch_remap_p2m(max_pfn);
}
+#endif
void arch_init_mm(unsigned long* start_pfn_p, unsigned long* max_pfn_p)
{
printk(" _end: %p(VA)\n", &_end);
/* First page follows page table pages. */
- start_pfn = PFN_UP(to_phys(start_info.pt_base)) + start_info.nr_pt_frames;
- max_pfn = start_info.nr_pages;
+ start_pfn = first_free_pfn;
+ max_pfn = last_free_pfn;
if ( max_pfn >= MAX_MEM_SIZE / PAGE_SIZE )
max_pfn = MAX_MEM_SIZE / PAGE_SIZE - 1;
/* Initialize SSE */
sse_init();
+ /* Setup memory management info from start_info. */
+ arch_mm_preinit(par);
+
/* 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->cmd_line ? (const char *)si->cmd_line : "NULL");
printk(" stack: %p-%p\n", stack, stack + sizeof(stack));
- /* 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);
void page_walk(unsigned long virt_address)
{
- pgentry_t *tab = (pgentry_t *)start_info.pt_base, page;
+ pgentry_t *tab = pt_base, page;
unsigned long addr = virt_address;
- printk("Pagetable walk from virt %lx, base %lx:\n", virt_address, start_info.pt_base);
+ printk("Pagetable walk from virt %lx, base %p:\n", virt_address, pt_base);
#if defined(__x86_64__)
page = tab[l4_table_offset(addr)];
}
static int handle_cow(unsigned long addr) {
- pgentry_t *tab = (pgentry_t *)start_info.pt_base, page;
+ pgentry_t *tab = pt_base, page;
unsigned long new_page;
int rc;
#include <mini-os/balloon.h>
#include <mini-os/errno.h>
#include <mini-os/lib.h>
+#include <mini-os/paravirt.h>
#include <xen/xen.h>
#include <xen/memory.h>
#define mfn_to_virt(_mfn) (to_virt(PFN_PHYS(_mfn)))
#define pfn_to_virt(_pfn) (to_virt(PFN_PHYS(_pfn)))
-#define mfn_to_pfn(x) (x)
-#define pfn_to_mfn(x) (x)
-
#define virtual_to_mfn(_virt) virt_to_mfn(_virt)
// FIXME
void get_max_pages(void);
int balloon_up(unsigned long n_pages);
-void arch_remap_p2m(unsigned long max_pfn);
void mm_alloc_bitmap_remap(void);
-int arch_expand_p2m(unsigned long max_pfn);
void arch_pfn_add(unsigned long pfn, unsigned long mfn);
int chk_free_pages(unsigned long needed);
#else /* CONFIG_BALLOON */
static inline void get_max_pages(void) { }
-static inline void arch_remap_p2m(unsigned long max_pfn) { }
static inline void mm_alloc_bitmap_remap(void) { }
static inline int chk_free_pages(unsigned long needed)
{
#endif
#include <xen/xen.h>
+#include <mini-os/paravirt.h>
#include <mini-os/arch_limits.h>
#include <mini-os/arch_mm.h>
void arch_init_demand_mapping_area(void);
void arch_init_mm(unsigned long* start_pfn_p, unsigned long* max_pfn_p);
-void arch_init_p2m(unsigned long max_pfn_p);
unsigned long allocate_ondemand(unsigned long n, unsigned long alignment);
/* map f[i*stride]+i*increment for i in 0..n-1, aligned on alignment pages */
#if defined(CONFIG_PARAVIRT)
+#define mfn_to_pfn(_mfn) (machine_to_phys_mapping[(_mfn)])
+#define pfn_to_mfn(_pfn) (phys_to_machine_mapping[(_pfn)])
+
+/* for P2M */
+#ifdef __x86_64__
+#define P2M_SHIFT 9
+#else
+#define P2M_SHIFT 10
+#endif
+#define P2M_ENTRIES (1UL << P2M_SHIFT)
+#define P2M_MASK (P2M_ENTRIES - 1)
+#define L1_P2M_SHIFT P2M_SHIFT
+#define L2_P2M_SHIFT (2 * P2M_SHIFT)
+#define L3_P2M_SHIFT (3 * P2M_SHIFT)
+#define L1_P2M_IDX(pfn) ((pfn) & P2M_MASK)
+#define L2_P2M_IDX(pfn) (((pfn) >> L1_P2M_SHIFT) & P2M_MASK)
+#define L3_P2M_IDX(pfn) (((pfn) >> L2_P2M_SHIFT) & P2M_MASK)
+#define INVALID_P2M_ENTRY (~0UL)
+
+void p2m_chk_pfn(unsigned long pfn);
+
+static inline unsigned long p2m_pages(unsigned long pages)
+{
+ return (pages + P2M_ENTRIES - 1) >> L1_P2M_SHIFT;
+}
+
+void arch_init_p2m(unsigned long max_pfn_p);
+
+#else
+
+#define mfn_to_pfn(_mfn) ((unsigned long)(_mfn))
+#define pfn_to_mfn(_pfn) ((unsigned long)(_pfn))
+
+static inline void arch_init_p2m(unsigned long max_pfn_p) { }
+
+#endif
+
+#if defined(CONFIG_PARAVIRT) && defined(CONFIG_BALLOON)
+
+void arch_remap_p2m(unsigned long max_pfn);
+int arch_expand_p2m(unsigned long max_pfn);
+
#else
+static inline void arch_remap_p2m(unsigned long max_pfn) { }
+static inline int arch_expand_p2m(unsigned long max_pfn)
+{
+ return 0;
+}
+
#endif
#endif /* _PARAVIRT_H */
#define IO_PROT (L1_PROT)
#define IO_PROT_NOCACHE (L1_PROT | _PAGE_PCD)
-/* for P2M */
-#ifdef __x86_64__
-#define P2M_SHIFT 9
-#else
-#define P2M_SHIFT 10
-#endif
-#define P2M_ENTRIES (1UL << P2M_SHIFT)
-#define P2M_MASK (P2M_ENTRIES - 1)
-#define L1_P2M_SHIFT P2M_SHIFT
-#define L2_P2M_SHIFT (2 * P2M_SHIFT)
-#define L3_P2M_SHIFT (3 * P2M_SHIFT)
-#define L1_P2M_IDX(pfn) ((pfn) & P2M_MASK)
-#define L2_P2M_IDX(pfn) (((pfn) >> L1_P2M_SHIFT) & P2M_MASK)
-#define L3_P2M_IDX(pfn) (((pfn) >> L2_P2M_SHIFT) & P2M_MASK)
-#define INVALID_P2M_ENTRY (~0UL)
-
-#ifndef __ASSEMBLY__
-void p2m_chk_pfn(unsigned long pfn);
-
-static inline unsigned long p2m_pages(unsigned long pages)
-{
- return (pages + P2M_ENTRIES - 1) >> L1_P2M_SHIFT;
-}
-#endif
-
#include "arch_limits.h"
#define PAGE_SIZE __PAGE_SIZE
#define PAGE_SHIFT __PAGE_SHIFT
typedef unsigned long maddr_t;
#endif
+extern pgentry_t *pt_base;
+#ifdef CONFIG_PARAVIRT
extern unsigned long *phys_to_machine_mapping;
+#else
+extern pgentry_t page_table_base[];
+#endif
extern char _text, _etext, _erodata, _edata, _end;
extern unsigned long mfn_zero;
-#define pfn_to_mfn(_pfn) (phys_to_machine_mapping[(_pfn)])
static __inline__ maddr_t phys_to_machine(paddr_t phys)
{
maddr_t machine = pfn_to_mfn(phys >> PAGE_SHIFT);
return machine;
}
-#define mfn_to_pfn(_mfn) (machine_to_phys_mapping[(_mfn)])
static __inline__ paddr_t machine_to_phys(maddr_t machine)
{
paddr_t phys = mfn_to_pfn(machine >> PAGE_SHIFT);
#define pte_to_mfn(_pte) (((_pte) & (PADDR_MASK&PAGE_MASK)) >> L1_PAGETABLE_SHIFT)
#define pte_to_virt(_pte) to_virt(mfn_to_pfn(pte_to_mfn(_pte)) << PAGE_SHIFT)
-
-#define PT_BASE ((pgentry_t *)start_info.pt_base)
-
#ifdef __x86_64__
-#define virtual_to_l3(_virt) ((pgentry_t *)pte_to_virt(PT_BASE[l4_table_offset(_virt)]))
+#define virtual_to_l3(_virt) ((pgentry_t *)pte_to_virt(pt_base[l4_table_offset(_virt)]))
#else
-#define virtual_to_l3(_virt) PT_BASE
+#define virtual_to_l3(_virt) pt_base
#endif
#define virtual_to_l2(_virt) ({ \
#define do_map_zero(start, n) do_map_frames(start, &mfn_zero, n, 0, 0, DOMID_SELF, NULL, L1_PROT_RO)
pgentry_t *need_pgt(unsigned long addr);
+void arch_mm_preinit(void *p);
#endif
#define FLAT_USER_DS FLAT_RING3_DS
#define FLAT_USER_SS FLAT_RING3_SS
+#ifdef CONFIG_PARAVIRT
#define __HYPERVISOR_VIRT_START_PAE 0xF5800000
#define __MACH2PHYS_VIRT_START_PAE 0xF5800000
#define __MACH2PHYS_VIRT_END_PAE 0xF6800000
#ifndef machine_to_phys_mapping
#define machine_to_phys_mapping ((unsigned long *)MACH2PHYS_VIRT_START)
#endif
+#endif
/* 32-/64-bit invariability for control interfaces (domctl/sysctl). */
#if defined(__XEN__) || defined(__XEN_TOOLS__)
#define FLAT_USER_SS32 FLAT_RING3_SS32
#define FLAT_USER_SS FLAT_USER_SS64
+#ifdef CONFIG_PARAVIRT
#define __HYPERVISOR_VIRT_START 0xFFFF800000000000
#define __HYPERVISOR_VIRT_END 0xFFFF880000000000
#define __MACH2PHYS_VIRT_START 0xFFFF800000000000
#ifndef machine_to_phys_mapping
#define machine_to_phys_mapping ((unsigned long *)HYPERVISOR_VIRT_START)
#endif
+#endif
/*
* int HYPERVISOR_set_segment_base(unsigned int which, unsigned long base)
#include <xen/memory.h>
#include <mini-os/mm.h>
#include <mini-os/balloon.h>
+#include <mini-os/paravirt.h>
#include <mini-os/types.h>
#include <mini-os/lib.h>
#include <mini-os/xmalloc.h>