ia64/xen-unstable

changeset 6433:0610add7c3fe

merge?
author cl349@firebug.cl.cam.ac.uk
date Thu Aug 25 16:27:04 2005 +0000 (2005-08-25)
parents b54144915ae6 98a6eb458c78
children 6ac24e39c9a4
files Config.mk extras/mini-os/include/hypervisor.h extras/mini-os/include/mm.h extras/mini-os/kernel.c extras/mini-os/mm.c linux-2.6-xen-sparse/arch/xen/configs/xenU_defconfig_x86_64 linux-2.6-xen-sparse/arch/xen/i386/kernel/cpu/common.c linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c linux-2.6-xen-sparse/arch/xen/i386/kernel/traps.c linux-2.6-xen-sparse/arch/xen/kernel/gnttab.c linux-2.6-xen-sparse/arch/xen/kernel/reboot.c linux-2.6-xen-sparse/arch/xen/x86_64/ia32/syscall32.c linux-2.6-xen-sparse/arch/xen/x86_64/kernel/early_printk.c linux-2.6-xen-sparse/arch/xen/x86_64/kernel/head.S linux-2.6-xen-sparse/arch/xen/x86_64/kernel/head64.c linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup.c linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup64.c linux-2.6-xen-sparse/arch/xen/x86_64/kernel/smpboot.c linux-2.6-xen-sparse/arch/xen/x86_64/mm/init.c linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c linux-2.6-xen-sparse/drivers/xen/blkfront/block.h linux-2.6-xen-sparse/drivers/xen/console/console.c linux-2.6-xen-sparse/drivers/xen/netback/Makefile linux-2.6-xen-sparse/drivers/xen/netback/common.h linux-2.6-xen-sparse/drivers/xen/netback/interface.c linux-2.6-xen-sparse/drivers/xen/netback/netback.c linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c linux-2.6-xen-sparse/include/asm-xen/asm-i386/mach-xen/setup_arch_post.h linux-2.6-xen-sparse/include/asm-xen/asm-i386/page.h linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/page.h linux-2.6-xen-sparse/include/asm-xen/gnttab.h tools/blktap/blktaplib.h tools/blktap/parallax/block-async.h tools/blktap/parallax/blockstore.h tools/console/Makefile tools/console/client/main.c tools/console/daemon/io.c tools/console/daemon/main.c tools/console/daemon/utils.c tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/linux-xen-low.c tools/debugger/libxendebug/Makefile tools/debugger/libxendebug/xendebug.c tools/debugger/libxendebug/xendebug.h tools/debugger/pdb/pdb_caml_domain.c tools/debugger/pdb/pdb_caml_evtchn.c tools/debugger/pdb/pdb_caml_process.c tools/debugger/pdb/pdb_caml_xc.c tools/debugger/pdb/pdb_caml_xcs.c tools/debugger/pdb/pdb_xen.c tools/examples/README tools/examples/vif-bridge tools/firmware/acpi/acpi2_0.h tools/ioemu/hw/i8254.c tools/ioemu/hw/i8259.c tools/ioemu/hw/ioapic.h tools/ioemu/target-i386-dm/Makefile tools/ioemu/target-i386-dm/helper2.c tools/ioemu/vl.c tools/libxc/Makefile tools/libxc/xc_core.c tools/libxc/xc_domain.c tools/libxc/xc_linux_build.c tools/libxc/xc_linux_restore.c tools/libxc/xc_linux_save.c tools/libxc/xc_load_aout9.c tools/libxc/xc_load_bin.c tools/libxc/xc_load_elf.c tools/libxc/xc_private.c tools/libxc/xc_private.h tools/libxc/xc_vmx_build.c tools/libxc/xenctrl.h tools/libxc/xenguest.h tools/libxc/xg_private.c tools/libxc/xg_private.h tools/misc/Makefile tools/misc/cpuperf/Makefile tools/misc/cpuperf/cpuperf_xeno.h tools/misc/xc_shadow.c tools/misc/xenperf.c tools/python/setup.py tools/python/xen/lowlevel/xc/xc.c tools/python/xen/lowlevel/xu/xu.c tools/python/xen/xend/XendDomainInfo.py tools/python/xen/xm/main.py tools/xcs/Makefile tools/xcs/dump.h tools/xcs/xcs.h tools/xcs/xcsdump.c tools/xcutils/Makefile tools/xcutils/xc_restore.c tools/xcutils/xc_save.c tools/xenstore/Makefile tools/xenstore/xs_dom0_test.c tools/xenstore/xs_lib.h tools/xentrace/Makefile tools/xentrace/xenctx.c xen/arch/x86/cpu/amd.c xen/arch/x86/mm.c xen/arch/x86/x86_64/mm.c
line diff
     2.1 --- a/extras/mini-os/include/hypervisor.h	Thu Aug 25 16:26:30 2005 +0000
     2.2 +++ b/extras/mini-os/include/hypervisor.h	Thu Aug 25 16:27:04 2005 +0000
     2.3 @@ -80,17 +80,43 @@ static __inline__ int HYPERVISOR_set_tra
     2.4  
     2.5  static __inline__ int HYPERVISOR_mmu_update(mmu_update_t *req, 
     2.6                                              int count, 
     2.7 -                                            int *success_count)
     2.8 +                                            int *success_count, 
     2.9 +                                            domid_t domid)
    2.10  {
    2.11      int ret;
    2.12 +    unsigned long ign1, ign2, ign3, ign4;
    2.13 +
    2.14      __asm__ __volatile__ (
    2.15          TRAP_INSTR
    2.16 -        : "=a" (ret) : "0" (__HYPERVISOR_mmu_update), 
    2.17 -        _a1 (req), _a2 (count), _a3 (success_count)  : "memory" );
    2.18 +        : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4)
    2.19 +        : "0" (__HYPERVISOR_mmu_update), "1" (req), "2" (count),
    2.20 +          "3" (success_count), "4" (domid)
    2.21 +        : "memory" );
    2.22  
    2.23      return ret;
    2.24  }
    2.25  
    2.26 +
    2.27 +static __inline__ int HYPERVISOR_mmuext_op(struct mmuext_op *op, 
    2.28 +                                           int count, 
    2.29 +                                           int *success_count, 
    2.30 +                                           domid_t domid)
    2.31 +{
    2.32 +    int ret;
    2.33 +    unsigned long ign1, ign2, ign3, ign4;
    2.34 +
    2.35 +    __asm__ __volatile__ (
    2.36 +        TRAP_INSTR
    2.37 +        : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4)
    2.38 +        : "0" (__HYPERVISOR_mmuext_op), "1" (op), "2" (count),
    2.39 +          "3" (success_count), "4" (domid)
    2.40 +        : "memory" );
    2.41 +
    2.42 +    return ret;
    2.43 +}
    2.44 +
    2.45 +
    2.46 +
    2.47  static __inline__ int HYPERVISOR_set_gdt(unsigned long *frame_list, int entries)
    2.48  {
    2.49      int ret;
     3.1 --- a/extras/mini-os/include/mm.h	Thu Aug 25 16:26:30 2005 +0000
     3.2 +++ b/extras/mini-os/include/mm.h	Thu Aug 25 16:27:04 2005 +0000
     3.3 @@ -43,13 +43,27 @@
     3.4  #define PADDR_MASK              ((1UL << PADDR_BITS)-1)
     3.5  #define VADDR_MASK              ((1UL << VADDR_BITS)-1)
     3.6  
     3.7 -#define pte_to_mfn(_pte) (((_pte) & (PADDR_MASK&PAGE_MASK)) >> PAGE_SHIFT)
     3.8 +#define pte_to_mfn(_pte) (((_pte) & (PADDR_MASK&PAGE_MASK)) >> L1_PAGETABLE_SHIFT)
     3.9 +
    3.10 +#endif
    3.11 +
    3.12 +
    3.13 +
    3.14 +#ifdef __i386__
    3.15 +
    3.16 +#define L1_PAGETABLE_SHIFT      12
    3.17 +#define L2_PAGETABLE_SHIFT      22
    3.18 +
    3.19 +#define L1_PAGETABLE_ENTRIES    1024
    3.20 +#define L2_PAGETABLE_ENTRIES    1024
    3.21 +#endif
    3.22  
    3.23  /* Given a virtual address, get an entry offset into a page table. */
    3.24  #define l1_table_offset(_a) \
    3.25    (((_a) >> L1_PAGETABLE_SHIFT) & (L1_PAGETABLE_ENTRIES - 1))
    3.26  #define l2_table_offset(_a) \
    3.27    (((_a) >> L2_PAGETABLE_SHIFT) & (L2_PAGETABLE_ENTRIES - 1))
    3.28 +#ifdef __x86_64__
    3.29  #define l3_table_offset(_a) \
    3.30    (((_a) >> L3_PAGETABLE_SHIFT) & (L3_PAGETABLE_ENTRIES - 1))
    3.31  #define l4_table_offset(_a) \
    3.32 @@ -67,13 +81,16 @@
    3.33  #define _PAGE_PSE      0x080UL
    3.34  #define _PAGE_GLOBAL   0x100UL
    3.35  
    3.36 -#define PAGE_SHIFT      12
    3.37 -#define PAGE_SIZE       (1UL << PAGE_SHIFT)
    3.38 +#define L1_PROT (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED)
    3.39 +#define L2_PROT (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_USER)
    3.40 +
    3.41 +#define PAGE_SIZE       (1UL << L1_PAGETABLE_SHIFT)
    3.42 +#define PAGE_SHIFT      L1_PAGETABLE_SHIFT
    3.43  #define PAGE_MASK       (~(PAGE_SIZE-1))
    3.44  
    3.45 -#define PFN_UP(x)	(((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
    3.46 -#define PFN_DOWN(x)	((x) >> PAGE_SHIFT)
    3.47 -#define PFN_PHYS(x)	((x) << PAGE_SHIFT)
    3.48 +#define PFN_UP(x)	(((x) + PAGE_SIZE-1) >> L1_PAGETABLE_SHIFT)
    3.49 +#define PFN_DOWN(x)	((x) >> L1_PAGETABLE_SHIFT)
    3.50 +#define PFN_PHYS(x)	((x) << L1_PAGETABLE_SHIFT)
    3.51  
    3.52  /* to align the pointer to the (next) page boundary */
    3.53  #define PAGE_ALIGN(addr)        (((addr)+PAGE_SIZE-1)&PAGE_MASK)
    3.54 @@ -83,14 +100,14 @@ extern unsigned long *phys_to_machine_ma
    3.55  #define mfn_to_pfn(_mfn) (machine_to_phys_mapping[(_mfn)])
    3.56  static __inline__ unsigned long phys_to_machine(unsigned long phys)
    3.57  {
    3.58 -    unsigned long machine = pfn_to_mfn(phys >> PAGE_SHIFT);
    3.59 -    machine = (machine << PAGE_SHIFT) | (phys & ~PAGE_MASK);
    3.60 +    unsigned long machine = pfn_to_mfn(phys >> L1_PAGETABLE_SHIFT);
    3.61 +    machine = (machine << L1_PAGETABLE_SHIFT) | (phys & ~PAGE_MASK);
    3.62      return machine;
    3.63  }
    3.64  static __inline__ unsigned long machine_to_phys(unsigned long machine)
    3.65  {
    3.66 -    unsigned long phys = mfn_to_pfn(machine >> PAGE_SHIFT);
    3.67 -    phys = (phys << PAGE_SHIFT) | (machine & ~PAGE_MASK);
    3.68 +    unsigned long phys = mfn_to_pfn(machine >> L1_PAGETABLE_SHIFT);
    3.69 +    phys = (phys << L1_PAGETABLE_SHIFT) | (machine & ~PAGE_MASK);
    3.70      return phys;
    3.71  }
    3.72  
    3.73 @@ -105,7 +122,10 @@ static __inline__ unsigned long machine_
    3.74  #define __va to_virt
    3.75  #define __pa to_phys
    3.76  
    3.77 +#define virt_to_pfn(_virt)         (PFN_DOWN(to_phys(_virt)))
    3.78 +
    3.79  void init_mm(void);
    3.80  unsigned long alloc_pages(int order);
    3.81 +int is_mfn_mapped(unsigned long mfn);
    3.82  
    3.83  #endif /* _MM_H_ */
     4.1 --- a/extras/mini-os/kernel.c	Thu Aug 25 16:26:30 2005 +0000
     4.2 +++ b/extras/mini-os/kernel.c	Thu Aug 25 16:27:04 2005 +0000
     4.3 @@ -133,7 +133,7 @@ void start_kernel(start_info_t *si)
     4.4      for ( ; ; ) 
     4.5      {      
     4.6  //        HYPERVISOR_yield();
     4.7 -        block(1);
     4.8 +        block(100);
     4.9          i++;
    4.10      }
    4.11  }
     5.1 --- a/extras/mini-os/mm.c	Thu Aug 25 16:26:30 2005 +0000
     5.2 +++ b/extras/mini-os/mm.c	Thu Aug 25 16:27:04 2005 +0000
     5.3 @@ -5,9 +5,9 @@
     5.4   *
     5.5   *        File: mm.c
     5.6   *      Author: Rolf Neugebauer (neugebar@dcs.gla.ac.uk)
     5.7 - *     Changes: 
     5.8 + *     Changes: Grzegorz Milos
     5.9   *              
    5.10 - *        Date: Aug 2003
    5.11 + *        Date: Aug 2003, chages Aug 2005
    5.12   * 
    5.13   * Environment: Xen Minimal OS
    5.14   * Description: memory management related functions
    5.15 @@ -41,86 +41,18 @@
    5.16  #include <types.h>
    5.17  #include <lib.h>
    5.18  
    5.19 +
    5.20 +#ifdef MM_DEBUG
    5.21 +#define DEBUG(_f, _a...) \
    5.22 +    printk("MINI_OS(file=mm.c, line=%d) " _f "\n", __LINE__, ## _a)
    5.23 +#else
    5.24 +#define DEBUG(_f, _a...)    ((void)0)
    5.25 +#endif
    5.26 +
    5.27  unsigned long *phys_to_machine_mapping;
    5.28  extern char *stack;
    5.29  extern char _text, _etext, _edata, _end;
    5.30  
    5.31 -static void init_page_allocator(unsigned long min, unsigned long max);
    5.32 -
    5.33 -void init_mm(void)
    5.34 -{
    5.35 -
    5.36 -    unsigned long start_pfn, max_pfn, max_free_pfn;
    5.37 -
    5.38 -    unsigned long *pgd = (unsigned long *)start_info.pt_base;
    5.39 -
    5.40 -    printk("MM: Init\n");
    5.41 -
    5.42 -    printk("  _text:        %p\n", &_text);
    5.43 -    printk("  _etext:       %p\n", &_etext);
    5.44 -    printk("  _edata:       %p\n", &_edata);
    5.45 -    printk("  stack start:  %p\n", &stack);
    5.46 -    printk("  _end:         %p\n", &_end);
    5.47 -
    5.48 -    /* set up minimal memory infos */
    5.49 -    start_pfn = PFN_UP(to_phys(&_end));
    5.50 -    max_pfn = start_info.nr_pages;
    5.51 -
    5.52 -    printk("  start_pfn:    %lx\n", start_pfn);
    5.53 -    printk("  max_pfn:      %lx\n", max_pfn);
    5.54 -
    5.55 -    /*
    5.56 -     * we know where free tables start (start_pfn) and how many we 
    5.57 -     * have (max_pfn). 
    5.58 -     * 
    5.59 -     * Currently the hypervisor stores page tables it providesin the
    5.60 -     * high region of the this memory range.
    5.61 -     * 
    5.62 -     * next we work out how far down this goes (max_free_pfn)
    5.63 -     * 
    5.64 -     * XXX this assumes the hypervisor provided page tables to be in
    5.65 -     * the upper region of our initial memory. I don't know if this 
    5.66 -     * is always true.
    5.67 -     */
    5.68 -
    5.69 -    max_free_pfn = PFN_DOWN(to_phys(pgd));
    5.70 -#ifdef __i386__
    5.71 -    {
    5.72 -        unsigned long *pgd = (unsigned long *)start_info.pt_base;
    5.73 -        unsigned long  pte;
    5.74 -        int i;
    5.75 -        printk("  pgd(pa(pgd)): %lx(%lx)", (u_long)pgd, to_phys(pgd));
    5.76 -
    5.77 -        for ( i = 0; i < (HYPERVISOR_VIRT_START>>22); i++ )
    5.78 -        {
    5.79 -            unsigned long pgde = *pgd++;
    5.80 -            if ( !(pgde & 1) ) continue;
    5.81 -            pte = machine_to_phys(pgde & PAGE_MASK);
    5.82 -            printk("  PT(%x): %lx(%lx)", i, (u_long)to_virt(pte), pte);
    5.83 -            if (PFN_DOWN(pte) <= max_free_pfn) 
    5.84 -                max_free_pfn = PFN_DOWN(pte);
    5.85 -        }
    5.86 -    }
    5.87 -    max_free_pfn--;
    5.88 -    printk("  max_free_pfn: %lx\n", max_free_pfn);
    5.89 -
    5.90 -    /*
    5.91 -     * now we can initialise the page allocator
    5.92 -     */
    5.93 -    printk("MM: Initialise page allocator for %lx(%lx)-%lx(%lx)\n",
    5.94 -           (u_long)to_virt(PFN_PHYS(start_pfn)), PFN_PHYS(start_pfn), 
    5.95 -           (u_long)to_virt(PFN_PHYS(max_free_pfn)), PFN_PHYS(max_free_pfn));
    5.96 -    init_page_allocator(PFN_PHYS(start_pfn), PFN_PHYS(max_free_pfn));   
    5.97 -#endif
    5.98 -
    5.99 -
   5.100 -    /* Now initialise the physical->machine mapping table. */
   5.101 -
   5.102 -
   5.103 -    printk("MM: done\n");
   5.104 -
   5.105 -    
   5.106 -}
   5.107  
   5.108  /*********************
   5.109   * ALLOCATION BITMAP
   5.110 @@ -214,6 +146,59 @@ static chunk_head_t  free_tail[FREELIST_
   5.111  #define round_pgdown(_p)  ((_p)&PAGE_MASK)
   5.112  #define round_pgup(_p)    (((_p)+(PAGE_SIZE-1))&PAGE_MASK)
   5.113  
   5.114 +#ifdef MM_DEBUG
   5.115 +/*
   5.116 + * Prints allocation[0/1] for @nr_pages, starting at @start
   5.117 + * address (virtual).
   5.118 + */
   5.119 +static void print_allocation(void *start, int nr_pages)
   5.120 +{
   5.121 +    unsigned long pfn_start = virt_to_pfn(start);
   5.122 +    int count;
   5.123 +    for(count = 0; count < nr_pages; count++)
   5.124 +        if(allocated_in_map(pfn_start + count)) printk("1");
   5.125 +        else printk("0");
   5.126 +        
   5.127 +    printk("\n");        
   5.128 +}
   5.129 +
   5.130 +/*
   5.131 + * Prints chunks (making them with letters) for @nr_pages starting
   5.132 + * at @start (virtual).
   5.133 + */
   5.134 +static void print_chunks(void *start, int nr_pages)
   5.135 +{
   5.136 +    char chunks[1001], current='A';
   5.137 +    int order, count;
   5.138 +    chunk_head_t *head;
   5.139 +    unsigned long pfn_start = virt_to_pfn(start);
   5.140 +   
   5.141 +    memset(chunks, (int)'_', 1000);
   5.142 +    if(nr_pages > 1000) 
   5.143 +    {
   5.144 +        DEBUG("Can only pring 1000 pages. Increase buffer size.");
   5.145 +    }
   5.146 +    
   5.147 +    for(order=0; order < FREELIST_SIZE; order++)
   5.148 +    {
   5.149 +        head = free_head[order];
   5.150 +        while(!FREELIST_EMPTY(head))
   5.151 +        {
   5.152 +            for(count = 0; count < 1<< head->level; count++)
   5.153 +            {
   5.154 +                if(count + virt_to_pfn(head) - pfn_start < 1000)
   5.155 +                    chunks[count + virt_to_pfn(head) - pfn_start] = current;
   5.156 +            }
   5.157 +            head = head->next;
   5.158 +            current++;
   5.159 +        }
   5.160 +    }
   5.161 +    chunks[nr_pages] = '\0';
   5.162 +    printk("%s\n", chunks);
   5.163 +}
   5.164 +#endif
   5.165 +
   5.166 +
   5.167  
   5.168  /*
   5.169   * Initialise allocator, placing addresses [@min,@max] in free pool.
   5.170 @@ -328,3 +313,198 @@ unsigned long alloc_pages(int order)
   5.171      return 0;
   5.172  }
   5.173  
   5.174 +void free_pages(void *pointer, int order)
   5.175 +{
   5.176 +    chunk_head_t *freed_ch, *to_merge_ch;
   5.177 +    chunk_tail_t *freed_ct;
   5.178 +    unsigned long mask;
   5.179 +    
   5.180 +    /* First free the chunk */
   5.181 +    map_free(virt_to_pfn(pointer), 1 << order);
   5.182 +    
   5.183 +    /* Create free chunk */
   5.184 +    freed_ch = (chunk_head_t *)pointer;
   5.185 +    freed_ct = (chunk_tail_t *)((char *)pointer + (1<<(order + PAGE_SHIFT)))-1;
   5.186 +    
   5.187 +    /* Now, possibly we can conseal chunks together */
   5.188 +    while(order < FREELIST_SIZE)
   5.189 +    {
   5.190 +        mask = 1 << (order + PAGE_SHIFT);
   5.191 +        if((unsigned long)freed_ch & mask) 
   5.192 +        {
   5.193 +            to_merge_ch = (chunk_head_t *)((char *)freed_ch - mask);
   5.194 +            if(allocated_in_map(virt_to_pfn(to_merge_ch)) ||
   5.195 +                    to_merge_ch->level != order)
   5.196 +                break;
   5.197 +            
   5.198 +            /* Merge with predecessor */
   5.199 +            freed_ch = to_merge_ch;   
   5.200 +        }
   5.201 +        else 
   5.202 +        {
   5.203 +            to_merge_ch = (chunk_head_t *)((char *)freed_ch + mask);
   5.204 +            if(allocated_in_map(virt_to_pfn(to_merge_ch)) ||
   5.205 +                    to_merge_ch->level != order)
   5.206 +                break;
   5.207 +            
   5.208 +            /* Merge with successor */
   5.209 +            freed_ct = (chunk_tail_t *)((char *)to_merge_ch + mask);
   5.210 +        }
   5.211 +        
   5.212 +        /* We are commited to merging, unlink the chunk */
   5.213 +        *(to_merge_ch->pprev) = to_merge_ch->next;
   5.214 +        to_merge_ch->next->pprev = to_merge_ch->pprev;
   5.215 +        
   5.216 +        order++;
   5.217 +    }
   5.218 +
   5.219 +    /* Link the new chunk */
   5.220 +    freed_ch->level = order;
   5.221 +    freed_ch->next  = free_head[order];
   5.222 +    freed_ch->pprev = &free_head[order];
   5.223 +    freed_ct->level = order;
   5.224 +    
   5.225 +    freed_ch->next->pprev = &freed_ch->next;
   5.226 +    free_head[order] = freed_ch;   
   5.227 +   
   5.228 +}
   5.229 +void build_pagetable(unsigned long *start_pfn, unsigned long *max_pfn)
   5.230 +{
   5.231 +    unsigned long pfn_to_map, pt_frame;
   5.232 +    unsigned long mach_ptd, max_mach_ptd;
   5.233 +    int count;
   5.234 +    unsigned long mach_pte, virt_pte;
   5.235 +    unsigned long *ptd = (unsigned long *)start_info.pt_base;
   5.236 +    mmu_update_t mmu_updates[L1_PAGETABLE_ENTRIES + 1];
   5.237 +    struct mmuext_op pin_request;
   5.238 +    
   5.239 +    /* Firstly work out what is the first pfn that is not yet in page tables
   5.240 +       NB. Assuming that builder fills whole pt_frames (which it does at the
   5.241 +       moment)
   5.242 +     */  
   5.243 +    pfn_to_map = (start_info.nr_pt_frames - 1) * L1_PAGETABLE_ENTRIES;
   5.244 +    DEBUG("start_pfn=%ld, first pfn_to_map %ld, max_pfn=%ld", 
   5.245 +            *start_pfn, pfn_to_map, *max_pfn);
   5.246 +
   5.247 +    /* Machine address of page table directory */
   5.248 +    mach_ptd = phys_to_machine(to_phys(start_info.pt_base));
   5.249 +    mach_ptd += sizeof(void *) * 
   5.250 +        l2_table_offset((unsigned long)to_virt(PFN_PHYS(pfn_to_map)));
   5.251 +  
   5.252 +    max_mach_ptd = sizeof(void *) * 
   5.253 +        l2_table_offset((unsigned long)to_virt(PFN_PHYS(*max_pfn)));
   5.254 +    
   5.255 +    /* Check that we are not trying to access Xen region */
   5.256 +    if(max_mach_ptd > sizeof(void *) * l2_table_offset(HYPERVISOR_VIRT_START))
   5.257 +    {
   5.258 +        printk("WARNING: mini-os will not use all the memory supplied\n");
   5.259 +        max_mach_ptd = sizeof(void *) * l2_table_offset(HYPERVISOR_VIRT_START);
   5.260 +        *max_pfn = virt_to_pfn(HYPERVISOR_VIRT_START - PAGE_SIZE);
   5.261 +    }
   5.262 +    max_mach_ptd += phys_to_machine(to_phys(start_info.pt_base));
   5.263 +    DEBUG("Max_mach_ptd 0x%lx", max_mach_ptd); 
   5.264 +   
   5.265 +    pt_frame = *start_pfn;
   5.266 +    /* Should not happen - no empty, mapped pages */
   5.267 +    if(pt_frame >= pfn_to_map)
   5.268 +    {
   5.269 +        printk("ERROR: Not even a single empty, mapped page\n");
   5.270 +        *(int*)0=0;
   5.271 +    }
   5.272 +    
   5.273 +    while(mach_ptd < max_mach_ptd)
   5.274 +    {
   5.275 +        /* Correct protection needs to be set for the new page table frame */
   5.276 +        virt_pte = (unsigned long)to_virt(PFN_PHYS(pt_frame));
   5.277 +        mach_pte = ptd[l2_table_offset(virt_pte)] & ~(PAGE_SIZE-1);
   5.278 +        mach_pte += sizeof(void *) * l1_table_offset(virt_pte);
   5.279 +        DEBUG("New page table page: pfn=0x%lx, mfn=0x%lx, virt_pte=0x%lx, "
   5.280 +                "mach_pte=0x%lx", pt_frame, pfn_to_mfn(pt_frame), 
   5.281 +                virt_pte, mach_pte);
   5.282 +        
   5.283 +        /* Update the entry */
   5.284 +        mmu_updates[0].ptr = mach_pte;
   5.285 +        mmu_updates[0].val = pfn_to_mfn(pt_frame) << PAGE_SHIFT | 
   5.286 +                                                    (L1_PROT & ~_PAGE_RW);
   5.287 +        if(HYPERVISOR_mmu_update(mmu_updates, 1, NULL, DOMID_SELF) < 0)
   5.288 +        {
   5.289 +            printk("PTE for new page table page could not be updated\n");
   5.290 +            *(int*)0=0;
   5.291 +        }
   5.292 +        
   5.293 +        /* Pin the page to provide correct protection */
   5.294 +        pin_request.cmd = MMUEXT_PIN_L1_TABLE;
   5.295 +        pin_request.mfn = pfn_to_mfn(pt_frame);
   5.296 +        if(HYPERVISOR_mmuext_op(&pin_request, 1, NULL, DOMID_SELF) < 0)
   5.297 +        {
   5.298 +            printk("ERROR: pinning failed\n");
   5.299 +            *(int*)0=0;
   5.300 +        }
   5.301 +        
   5.302 +        /* Now fill the new page table page with entries.
   5.303 +           Update the page directory as well. */
   5.304 +        count = 0;
   5.305 +        mmu_updates[count].ptr = mach_ptd;
   5.306 +        mmu_updates[count].val = pfn_to_mfn(pt_frame) << PAGE_SHIFT |
   5.307 +                                                         L2_PROT;
   5.308 +        count++;
   5.309 +        mach_ptd += sizeof(void *);
   5.310 +        mach_pte = phys_to_machine(PFN_PHYS(pt_frame++));
   5.311 +        
   5.312 +        for(;count <= L1_PAGETABLE_ENTRIES && pfn_to_map <= *max_pfn; count++)
   5.313 +        {
   5.314 +            mmu_updates[count].ptr = mach_pte;
   5.315 +            mmu_updates[count].val = 
   5.316 +                pfn_to_mfn(pfn_to_map++) << PAGE_SHIFT | L1_PROT;
   5.317 +            if(count == 1) DEBUG("mach_pte 0x%lx", mach_pte);
   5.318 +            mach_pte += sizeof(void *);
   5.319 +        }
   5.320 +        if(HYPERVISOR_mmu_update(mmu_updates, count, NULL, DOMID_SELF) < 0) 
   5.321 +        {            
   5.322 +            printk("ERROR: mmu_update failed\n");
   5.323 +            *(int*)0=0;
   5.324 +        }
   5.325 +        (*start_pfn)++;
   5.326 +    }
   5.327 +
   5.328 +    *start_pfn = pt_frame;
   5.329 +}
   5.330 +
   5.331 +void init_mm(void)
   5.332 +{
   5.333 +
   5.334 +    unsigned long start_pfn, max_pfn;
   5.335 +
   5.336 +    printk("MM: Init\n");
   5.337 +
   5.338 +    printk("  _text:        %p\n", &_text);
   5.339 +    printk("  _etext:       %p\n", &_etext);
   5.340 +    printk("  _edata:       %p\n", &_edata);
   5.341 +    printk("  stack start:  %p\n", &stack);
   5.342 +    printk("  _end:         %p\n", &_end);
   5.343 +
   5.344 +    /* set up minimal memory infos */
   5.345 +    phys_to_machine_mapping = (unsigned long *)start_info.mfn_list;
   5.346 +   
   5.347 +    /* First page follows page table pages and 3 more pages (store page etc) */
   5.348 +    start_pfn = PFN_UP(__pa(start_info.pt_base)) + start_info.nr_pt_frames + 3;
   5.349 +    max_pfn = start_info.nr_pages;
   5.350 +
   5.351 +    printk("  start_pfn:    %lx\n", start_pfn);
   5.352 +    printk("  max_pfn:      %lx\n", max_pfn);
   5.353 +
   5.354 +
   5.355 +    build_pagetable(&start_pfn, &max_pfn);
   5.356 +    
   5.357 +#ifdef __i386__
   5.358 +    /*
   5.359 +     * now we can initialise the page allocator
   5.360 +     */
   5.361 +    printk("MM: Initialise page allocator for %lx(%lx)-%lx(%lx)\n",
   5.362 +           (u_long)to_virt(PFN_PHYS(start_pfn)), PFN_PHYS(start_pfn), 
   5.363 +           (u_long)to_virt(PFN_PHYS(max_pfn)), PFN_PHYS(max_pfn));
   5.364 +    init_page_allocator(PFN_PHYS(start_pfn), PFN_PHYS(max_pfn));   
   5.365 +#endif
   5.366 +
   5.367 +    printk("MM: done\n");
   5.368 +}