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
     1.1 --- a/extras/mini-os/include/hypervisor.h	Thu Aug 25 16:26:30 2005 +0000
     1.2 +++ b/extras/mini-os/include/hypervisor.h	Thu Aug 25 16:27:04 2005 +0000
     1.3 @@ -80,17 +80,43 @@ static __inline__ int HYPERVISOR_set_tra
     1.4  
     1.5  static __inline__ int HYPERVISOR_mmu_update(mmu_update_t *req, 
     1.6                                              int count, 
     1.7 -                                            int *success_count)
     1.8 +                                            int *success_count, 
     1.9 +                                            domid_t domid)
    1.10  {
    1.11      int ret;
    1.12 +    unsigned long ign1, ign2, ign3, ign4;
    1.13 +
    1.14      __asm__ __volatile__ (
    1.15          TRAP_INSTR
    1.16 -        : "=a" (ret) : "0" (__HYPERVISOR_mmu_update), 
    1.17 -        _a1 (req), _a2 (count), _a3 (success_count)  : "memory" );
    1.18 +        : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4)
    1.19 +        : "0" (__HYPERVISOR_mmu_update), "1" (req), "2" (count),
    1.20 +          "3" (success_count), "4" (domid)
    1.21 +        : "memory" );
    1.22  
    1.23      return ret;
    1.24  }
    1.25  
    1.26 +
    1.27 +static __inline__ int HYPERVISOR_mmuext_op(struct mmuext_op *op, 
    1.28 +                                           int count, 
    1.29 +                                           int *success_count, 
    1.30 +                                           domid_t domid)
    1.31 +{
    1.32 +    int ret;
    1.33 +    unsigned long ign1, ign2, ign3, ign4;
    1.34 +
    1.35 +    __asm__ __volatile__ (
    1.36 +        TRAP_INSTR
    1.37 +        : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4)
    1.38 +        : "0" (__HYPERVISOR_mmuext_op), "1" (op), "2" (count),
    1.39 +          "3" (success_count), "4" (domid)
    1.40 +        : "memory" );
    1.41 +
    1.42 +    return ret;
    1.43 +}
    1.44 +
    1.45 +
    1.46 +
    1.47  static __inline__ int HYPERVISOR_set_gdt(unsigned long *frame_list, int entries)
    1.48  {
    1.49      int ret;
     2.1 --- a/extras/mini-os/include/mm.h	Thu Aug 25 16:26:30 2005 +0000
     2.2 +++ b/extras/mini-os/include/mm.h	Thu Aug 25 16:27:04 2005 +0000
     2.3 @@ -43,13 +43,27 @@
     2.4  #define PADDR_MASK              ((1UL << PADDR_BITS)-1)
     2.5  #define VADDR_MASK              ((1UL << VADDR_BITS)-1)
     2.6  
     2.7 -#define pte_to_mfn(_pte) (((_pte) & (PADDR_MASK&PAGE_MASK)) >> PAGE_SHIFT)
     2.8 +#define pte_to_mfn(_pte) (((_pte) & (PADDR_MASK&PAGE_MASK)) >> L1_PAGETABLE_SHIFT)
     2.9 +
    2.10 +#endif
    2.11 +
    2.12 +
    2.13 +
    2.14 +#ifdef __i386__
    2.15 +
    2.16 +#define L1_PAGETABLE_SHIFT      12
    2.17 +#define L2_PAGETABLE_SHIFT      22
    2.18 +
    2.19 +#define L1_PAGETABLE_ENTRIES    1024
    2.20 +#define L2_PAGETABLE_ENTRIES    1024
    2.21 +#endif
    2.22  
    2.23  /* Given a virtual address, get an entry offset into a page table. */
    2.24  #define l1_table_offset(_a) \
    2.25    (((_a) >> L1_PAGETABLE_SHIFT) & (L1_PAGETABLE_ENTRIES - 1))
    2.26  #define l2_table_offset(_a) \
    2.27    (((_a) >> L2_PAGETABLE_SHIFT) & (L2_PAGETABLE_ENTRIES - 1))
    2.28 +#ifdef __x86_64__
    2.29  #define l3_table_offset(_a) \
    2.30    (((_a) >> L3_PAGETABLE_SHIFT) & (L3_PAGETABLE_ENTRIES - 1))
    2.31  #define l4_table_offset(_a) \
    2.32 @@ -67,13 +81,16 @@
    2.33  #define _PAGE_PSE      0x080UL
    2.34  #define _PAGE_GLOBAL   0x100UL
    2.35  
    2.36 -#define PAGE_SHIFT      12
    2.37 -#define PAGE_SIZE       (1UL << PAGE_SHIFT)
    2.38 +#define L1_PROT (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED)
    2.39 +#define L2_PROT (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_USER)
    2.40 +
    2.41 +#define PAGE_SIZE       (1UL << L1_PAGETABLE_SHIFT)
    2.42 +#define PAGE_SHIFT      L1_PAGETABLE_SHIFT
    2.43  #define PAGE_MASK       (~(PAGE_SIZE-1))
    2.44  
    2.45 -#define PFN_UP(x)	(((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
    2.46 -#define PFN_DOWN(x)	((x) >> PAGE_SHIFT)
    2.47 -#define PFN_PHYS(x)	((x) << PAGE_SHIFT)
    2.48 +#define PFN_UP(x)	(((x) + PAGE_SIZE-1) >> L1_PAGETABLE_SHIFT)
    2.49 +#define PFN_DOWN(x)	((x) >> L1_PAGETABLE_SHIFT)
    2.50 +#define PFN_PHYS(x)	((x) << L1_PAGETABLE_SHIFT)
    2.51  
    2.52  /* to align the pointer to the (next) page boundary */
    2.53  #define PAGE_ALIGN(addr)        (((addr)+PAGE_SIZE-1)&PAGE_MASK)
    2.54 @@ -83,14 +100,14 @@ extern unsigned long *phys_to_machine_ma
    2.55  #define mfn_to_pfn(_mfn) (machine_to_phys_mapping[(_mfn)])
    2.56  static __inline__ unsigned long phys_to_machine(unsigned long phys)
    2.57  {
    2.58 -    unsigned long machine = pfn_to_mfn(phys >> PAGE_SHIFT);
    2.59 -    machine = (machine << PAGE_SHIFT) | (phys & ~PAGE_MASK);
    2.60 +    unsigned long machine = pfn_to_mfn(phys >> L1_PAGETABLE_SHIFT);
    2.61 +    machine = (machine << L1_PAGETABLE_SHIFT) | (phys & ~PAGE_MASK);
    2.62      return machine;
    2.63  }
    2.64  static __inline__ unsigned long machine_to_phys(unsigned long machine)
    2.65  {
    2.66 -    unsigned long phys = mfn_to_pfn(machine >> PAGE_SHIFT);
    2.67 -    phys = (phys << PAGE_SHIFT) | (machine & ~PAGE_MASK);
    2.68 +    unsigned long phys = mfn_to_pfn(machine >> L1_PAGETABLE_SHIFT);
    2.69 +    phys = (phys << L1_PAGETABLE_SHIFT) | (machine & ~PAGE_MASK);
    2.70      return phys;
    2.71  }
    2.72  
    2.73 @@ -105,7 +122,10 @@ static __inline__ unsigned long machine_
    2.74  #define __va to_virt
    2.75  #define __pa to_phys
    2.76  
    2.77 +#define virt_to_pfn(_virt)         (PFN_DOWN(to_phys(_virt)))
    2.78 +
    2.79  void init_mm(void);
    2.80  unsigned long alloc_pages(int order);
    2.81 +int is_mfn_mapped(unsigned long mfn);
    2.82  
    2.83  #endif /* _MM_H_ */
     3.1 --- a/extras/mini-os/kernel.c	Thu Aug 25 16:26:30 2005 +0000
     3.2 +++ b/extras/mini-os/kernel.c	Thu Aug 25 16:27:04 2005 +0000
     3.3 @@ -133,7 +133,7 @@ void start_kernel(start_info_t *si)
     3.4      for ( ; ; ) 
     3.5      {      
     3.6  //        HYPERVISOR_yield();
     3.7 -        block(1);
     3.8 +        block(100);
     3.9          i++;
    3.10      }
    3.11  }
     4.1 --- a/extras/mini-os/mm.c	Thu Aug 25 16:26:30 2005 +0000
     4.2 +++ b/extras/mini-os/mm.c	Thu Aug 25 16:27:04 2005 +0000
     4.3 @@ -5,9 +5,9 @@
     4.4   *
     4.5   *        File: mm.c
     4.6   *      Author: Rolf Neugebauer (neugebar@dcs.gla.ac.uk)
     4.7 - *     Changes: 
     4.8 + *     Changes: Grzegorz Milos
     4.9   *              
    4.10 - *        Date: Aug 2003
    4.11 + *        Date: Aug 2003, chages Aug 2005
    4.12   * 
    4.13   * Environment: Xen Minimal OS
    4.14   * Description: memory management related functions
    4.15 @@ -41,86 +41,18 @@
    4.16  #include <types.h>
    4.17  #include <lib.h>
    4.18  
    4.19 +
    4.20 +#ifdef MM_DEBUG
    4.21 +#define DEBUG(_f, _a...) \
    4.22 +    printk("MINI_OS(file=mm.c, line=%d) " _f "\n", __LINE__, ## _a)
    4.23 +#else
    4.24 +#define DEBUG(_f, _a...)    ((void)0)
    4.25 +#endif
    4.26 +
    4.27  unsigned long *phys_to_machine_mapping;
    4.28  extern char *stack;
    4.29  extern char _text, _etext, _edata, _end;
    4.30  
    4.31 -static void init_page_allocator(unsigned long min, unsigned long max);
    4.32 -
    4.33 -void init_mm(void)
    4.34 -{
    4.35 -
    4.36 -    unsigned long start_pfn, max_pfn, max_free_pfn;
    4.37 -
    4.38 -    unsigned long *pgd = (unsigned long *)start_info.pt_base;
    4.39 -
    4.40 -    printk("MM: Init\n");
    4.41 -
    4.42 -    printk("  _text:        %p\n", &_text);
    4.43 -    printk("  _etext:       %p\n", &_etext);
    4.44 -    printk("  _edata:       %p\n", &_edata);
    4.45 -    printk("  stack start:  %p\n", &stack);
    4.46 -    printk("  _end:         %p\n", &_end);
    4.47 -
    4.48 -    /* set up minimal memory infos */
    4.49 -    start_pfn = PFN_UP(to_phys(&_end));
    4.50 -    max_pfn = start_info.nr_pages;
    4.51 -
    4.52 -    printk("  start_pfn:    %lx\n", start_pfn);
    4.53 -    printk("  max_pfn:      %lx\n", max_pfn);
    4.54 -
    4.55 -    /*
    4.56 -     * we know where free tables start (start_pfn) and how many we 
    4.57 -     * have (max_pfn). 
    4.58 -     * 
    4.59 -     * Currently the hypervisor stores page tables it providesin the
    4.60 -     * high region of the this memory range.
    4.61 -     * 
    4.62 -     * next we work out how far down this goes (max_free_pfn)
    4.63 -     * 
    4.64 -     * XXX this assumes the hypervisor provided page tables to be in
    4.65 -     * the upper region of our initial memory. I don't know if this 
    4.66 -     * is always true.
    4.67 -     */
    4.68 -
    4.69 -    max_free_pfn = PFN_DOWN(to_phys(pgd));
    4.70 -#ifdef __i386__
    4.71 -    {
    4.72 -        unsigned long *pgd = (unsigned long *)start_info.pt_base;
    4.73 -        unsigned long  pte;
    4.74 -        int i;
    4.75 -        printk("  pgd(pa(pgd)): %lx(%lx)", (u_long)pgd, to_phys(pgd));
    4.76 -
    4.77 -        for ( i = 0; i < (HYPERVISOR_VIRT_START>>22); i++ )
    4.78 -        {
    4.79 -            unsigned long pgde = *pgd++;
    4.80 -            if ( !(pgde & 1) ) continue;
    4.81 -            pte = machine_to_phys(pgde & PAGE_MASK);
    4.82 -            printk("  PT(%x): %lx(%lx)", i, (u_long)to_virt(pte), pte);
    4.83 -            if (PFN_DOWN(pte) <= max_free_pfn) 
    4.84 -                max_free_pfn = PFN_DOWN(pte);
    4.85 -        }
    4.86 -    }
    4.87 -    max_free_pfn--;
    4.88 -    printk("  max_free_pfn: %lx\n", max_free_pfn);
    4.89 -
    4.90 -    /*
    4.91 -     * now we can initialise the page allocator
    4.92 -     */
    4.93 -    printk("MM: Initialise page allocator for %lx(%lx)-%lx(%lx)\n",
    4.94 -           (u_long)to_virt(PFN_PHYS(start_pfn)), PFN_PHYS(start_pfn), 
    4.95 -           (u_long)to_virt(PFN_PHYS(max_free_pfn)), PFN_PHYS(max_free_pfn));
    4.96 -    init_page_allocator(PFN_PHYS(start_pfn), PFN_PHYS(max_free_pfn));   
    4.97 -#endif
    4.98 -
    4.99 -
   4.100 -    /* Now initialise the physical->machine mapping table. */
   4.101 -
   4.102 -
   4.103 -    printk("MM: done\n");
   4.104 -
   4.105 -    
   4.106 -}
   4.107  
   4.108  /*********************
   4.109   * ALLOCATION BITMAP
   4.110 @@ -214,6 +146,59 @@ static chunk_head_t  free_tail[FREELIST_
   4.111  #define round_pgdown(_p)  ((_p)&PAGE_MASK)
   4.112  #define round_pgup(_p)    (((_p)+(PAGE_SIZE-1))&PAGE_MASK)
   4.113  
   4.114 +#ifdef MM_DEBUG
   4.115 +/*
   4.116 + * Prints allocation[0/1] for @nr_pages, starting at @start
   4.117 + * address (virtual).
   4.118 + */
   4.119 +static void print_allocation(void *start, int nr_pages)
   4.120 +{
   4.121 +    unsigned long pfn_start = virt_to_pfn(start);
   4.122 +    int count;
   4.123 +    for(count = 0; count < nr_pages; count++)
   4.124 +        if(allocated_in_map(pfn_start + count)) printk("1");
   4.125 +        else printk("0");
   4.126 +        
   4.127 +    printk("\n");        
   4.128 +}
   4.129 +
   4.130 +/*
   4.131 + * Prints chunks (making them with letters) for @nr_pages starting
   4.132 + * at @start (virtual).
   4.133 + */
   4.134 +static void print_chunks(void *start, int nr_pages)
   4.135 +{
   4.136 +    char chunks[1001], current='A';
   4.137 +    int order, count;
   4.138 +    chunk_head_t *head;
   4.139 +    unsigned long pfn_start = virt_to_pfn(start);
   4.140 +   
   4.141 +    memset(chunks, (int)'_', 1000);
   4.142 +    if(nr_pages > 1000) 
   4.143 +    {
   4.144 +        DEBUG("Can only pring 1000 pages. Increase buffer size.");
   4.145 +    }
   4.146 +    
   4.147 +    for(order=0; order < FREELIST_SIZE; order++)
   4.148 +    {
   4.149 +        head = free_head[order];
   4.150 +        while(!FREELIST_EMPTY(head))
   4.151 +        {
   4.152 +            for(count = 0; count < 1<< head->level; count++)
   4.153 +            {
   4.154 +                if(count + virt_to_pfn(head) - pfn_start < 1000)
   4.155 +                    chunks[count + virt_to_pfn(head) - pfn_start] = current;
   4.156 +            }
   4.157 +            head = head->next;
   4.158 +            current++;
   4.159 +        }
   4.160 +    }
   4.161 +    chunks[nr_pages] = '\0';
   4.162 +    printk("%s\n", chunks);
   4.163 +}
   4.164 +#endif
   4.165 +
   4.166 +
   4.167  
   4.168  /*
   4.169   * Initialise allocator, placing addresses [@min,@max] in free pool.
   4.170 @@ -328,3 +313,198 @@ unsigned long alloc_pages(int order)
   4.171      return 0;
   4.172  }
   4.173  
   4.174 +void free_pages(void *pointer, int order)
   4.175 +{
   4.176 +    chunk_head_t *freed_ch, *to_merge_ch;
   4.177 +    chunk_tail_t *freed_ct;
   4.178 +    unsigned long mask;
   4.179 +    
   4.180 +    /* First free the chunk */
   4.181 +    map_free(virt_to_pfn(pointer), 1 << order);
   4.182 +    
   4.183 +    /* Create free chunk */
   4.184 +    freed_ch = (chunk_head_t *)pointer;
   4.185 +    freed_ct = (chunk_tail_t *)((char *)pointer + (1<<(order + PAGE_SHIFT)))-1;
   4.186 +    
   4.187 +    /* Now, possibly we can conseal chunks together */
   4.188 +    while(order < FREELIST_SIZE)
   4.189 +    {
   4.190 +        mask = 1 << (order + PAGE_SHIFT);
   4.191 +        if((unsigned long)freed_ch & mask) 
   4.192 +        {
   4.193 +            to_merge_ch = (chunk_head_t *)((char *)freed_ch - mask);
   4.194 +            if(allocated_in_map(virt_to_pfn(to_merge_ch)) ||
   4.195 +                    to_merge_ch->level != order)
   4.196 +                break;
   4.197 +            
   4.198 +            /* Merge with predecessor */
   4.199 +            freed_ch = to_merge_ch;   
   4.200 +        }
   4.201 +        else 
   4.202 +        {
   4.203 +            to_merge_ch = (chunk_head_t *)((char *)freed_ch + mask);
   4.204 +            if(allocated_in_map(virt_to_pfn(to_merge_ch)) ||
   4.205 +                    to_merge_ch->level != order)
   4.206 +                break;
   4.207 +            
   4.208 +            /* Merge with successor */
   4.209 +            freed_ct = (chunk_tail_t *)((char *)to_merge_ch + mask);
   4.210 +        }
   4.211 +        
   4.212 +        /* We are commited to merging, unlink the chunk */
   4.213 +        *(to_merge_ch->pprev) = to_merge_ch->next;
   4.214 +        to_merge_ch->next->pprev = to_merge_ch->pprev;
   4.215 +        
   4.216 +        order++;
   4.217 +    }
   4.218 +
   4.219 +    /* Link the new chunk */
   4.220 +    freed_ch->level = order;
   4.221 +    freed_ch->next  = free_head[order];
   4.222 +    freed_ch->pprev = &free_head[order];
   4.223 +    freed_ct->level = order;
   4.224 +    
   4.225 +    freed_ch->next->pprev = &freed_ch->next;
   4.226 +    free_head[order] = freed_ch;   
   4.227 +   
   4.228 +}
   4.229 +void build_pagetable(unsigned long *start_pfn, unsigned long *max_pfn)
   4.230 +{
   4.231 +    unsigned long pfn_to_map, pt_frame;
   4.232 +    unsigned long mach_ptd, max_mach_ptd;
   4.233 +    int count;
   4.234 +    unsigned long mach_pte, virt_pte;
   4.235 +    unsigned long *ptd = (unsigned long *)start_info.pt_base;
   4.236 +    mmu_update_t mmu_updates[L1_PAGETABLE_ENTRIES + 1];
   4.237 +    struct mmuext_op pin_request;
   4.238 +    
   4.239 +    /* Firstly work out what is the first pfn that is not yet in page tables
   4.240 +       NB. Assuming that builder fills whole pt_frames (which it does at the
   4.241 +       moment)
   4.242 +     */  
   4.243 +    pfn_to_map = (start_info.nr_pt_frames - 1) * L1_PAGETABLE_ENTRIES;
   4.244 +    DEBUG("start_pfn=%ld, first pfn_to_map %ld, max_pfn=%ld", 
   4.245 +            *start_pfn, pfn_to_map, *max_pfn);
   4.246 +
   4.247 +    /* Machine address of page table directory */
   4.248 +    mach_ptd = phys_to_machine(to_phys(start_info.pt_base));
   4.249 +    mach_ptd += sizeof(void *) * 
   4.250 +        l2_table_offset((unsigned long)to_virt(PFN_PHYS(pfn_to_map)));
   4.251 +  
   4.252 +    max_mach_ptd = sizeof(void *) * 
   4.253 +        l2_table_offset((unsigned long)to_virt(PFN_PHYS(*max_pfn)));
   4.254 +    
   4.255 +    /* Check that we are not trying to access Xen region */
   4.256 +    if(max_mach_ptd > sizeof(void *) * l2_table_offset(HYPERVISOR_VIRT_START))
   4.257 +    {
   4.258 +        printk("WARNING: mini-os will not use all the memory supplied\n");
   4.259 +        max_mach_ptd = sizeof(void *) * l2_table_offset(HYPERVISOR_VIRT_START);
   4.260 +        *max_pfn = virt_to_pfn(HYPERVISOR_VIRT_START - PAGE_SIZE);
   4.261 +    }
   4.262 +    max_mach_ptd += phys_to_machine(to_phys(start_info.pt_base));
   4.263 +    DEBUG("Max_mach_ptd 0x%lx", max_mach_ptd); 
   4.264 +   
   4.265 +    pt_frame = *start_pfn;
   4.266 +    /* Should not happen - no empty, mapped pages */
   4.267 +    if(pt_frame >= pfn_to_map)
   4.268 +    {
   4.269 +        printk("ERROR: Not even a single empty, mapped page\n");
   4.270 +        *(int*)0=0;
   4.271 +    }
   4.272 +    
   4.273 +    while(mach_ptd < max_mach_ptd)
   4.274 +    {
   4.275 +        /* Correct protection needs to be set for the new page table frame */
   4.276 +        virt_pte = (unsigned long)to_virt(PFN_PHYS(pt_frame));
   4.277 +        mach_pte = ptd[l2_table_offset(virt_pte)] & ~(PAGE_SIZE-1);
   4.278 +        mach_pte += sizeof(void *) * l1_table_offset(virt_pte);
   4.279 +        DEBUG("New page table page: pfn=0x%lx, mfn=0x%lx, virt_pte=0x%lx, "
   4.280 +                "mach_pte=0x%lx", pt_frame, pfn_to_mfn(pt_frame), 
   4.281 +                virt_pte, mach_pte);
   4.282 +        
   4.283 +        /* Update the entry */
   4.284 +        mmu_updates[0].ptr = mach_pte;
   4.285 +        mmu_updates[0].val = pfn_to_mfn(pt_frame) << PAGE_SHIFT | 
   4.286 +                                                    (L1_PROT & ~_PAGE_RW);
   4.287 +        if(HYPERVISOR_mmu_update(mmu_updates, 1, NULL, DOMID_SELF) < 0)
   4.288 +        {
   4.289 +            printk("PTE for new page table page could not be updated\n");
   4.290 +            *(int*)0=0;
   4.291 +        }
   4.292 +        
   4.293 +        /* Pin the page to provide correct protection */
   4.294 +        pin_request.cmd = MMUEXT_PIN_L1_TABLE;
   4.295 +        pin_request.mfn = pfn_to_mfn(pt_frame);
   4.296 +        if(HYPERVISOR_mmuext_op(&pin_request, 1, NULL, DOMID_SELF) < 0)
   4.297 +        {
   4.298 +            printk("ERROR: pinning failed\n");
   4.299 +            *(int*)0=0;
   4.300 +        }
   4.301 +        
   4.302 +        /* Now fill the new page table page with entries.
   4.303 +           Update the page directory as well. */
   4.304 +        count = 0;
   4.305 +        mmu_updates[count].ptr = mach_ptd;
   4.306 +        mmu_updates[count].val = pfn_to_mfn(pt_frame) << PAGE_SHIFT |
   4.307 +                                                         L2_PROT;
   4.308 +        count++;
   4.309 +        mach_ptd += sizeof(void *);
   4.310 +        mach_pte = phys_to_machine(PFN_PHYS(pt_frame++));
   4.311 +        
   4.312 +        for(;count <= L1_PAGETABLE_ENTRIES && pfn_to_map <= *max_pfn; count++)
   4.313 +        {
   4.314 +            mmu_updates[count].ptr = mach_pte;
   4.315 +            mmu_updates[count].val = 
   4.316 +                pfn_to_mfn(pfn_to_map++) << PAGE_SHIFT | L1_PROT;
   4.317 +            if(count == 1) DEBUG("mach_pte 0x%lx", mach_pte);
   4.318 +            mach_pte += sizeof(void *);
   4.319 +        }
   4.320 +        if(HYPERVISOR_mmu_update(mmu_updates, count, NULL, DOMID_SELF) < 0) 
   4.321 +        {            
   4.322 +            printk("ERROR: mmu_update failed\n");
   4.323 +            *(int*)0=0;
   4.324 +        }
   4.325 +        (*start_pfn)++;
   4.326 +    }
   4.327 +
   4.328 +    *start_pfn = pt_frame;
   4.329 +}
   4.330 +
   4.331 +void init_mm(void)
   4.332 +{
   4.333 +
   4.334 +    unsigned long start_pfn, max_pfn;
   4.335 +
   4.336 +    printk("MM: Init\n");
   4.337 +
   4.338 +    printk("  _text:        %p\n", &_text);
   4.339 +    printk("  _etext:       %p\n", &_etext);
   4.340 +    printk("  _edata:       %p\n", &_edata);
   4.341 +    printk("  stack start:  %p\n", &stack);
   4.342 +    printk("  _end:         %p\n", &_end);
   4.343 +
   4.344 +    /* set up minimal memory infos */
   4.345 +    phys_to_machine_mapping = (unsigned long *)start_info.mfn_list;
   4.346 +   
   4.347 +    /* First page follows page table pages and 3 more pages (store page etc) */
   4.348 +    start_pfn = PFN_UP(__pa(start_info.pt_base)) + start_info.nr_pt_frames + 3;
   4.349 +    max_pfn = start_info.nr_pages;
   4.350 +
   4.351 +    printk("  start_pfn:    %lx\n", start_pfn);
   4.352 +    printk("  max_pfn:      %lx\n", max_pfn);
   4.353 +
   4.354 +
   4.355 +    build_pagetable(&start_pfn, &max_pfn);
   4.356 +    
   4.357 +#ifdef __i386__
   4.358 +    /*
   4.359 +     * now we can initialise the page allocator
   4.360 +     */
   4.361 +    printk("MM: Initialise page allocator for %lx(%lx)-%lx(%lx)\n",
   4.362 +           (u_long)to_virt(PFN_PHYS(start_pfn)), PFN_PHYS(start_pfn), 
   4.363 +           (u_long)to_virt(PFN_PHYS(max_pfn)), PFN_PHYS(max_pfn));
   4.364 +    init_page_allocator(PFN_PHYS(start_pfn), PFN_PHYS(max_pfn));   
   4.365 +#endif
   4.366 +
   4.367 +    printk("MM: done\n");
   4.368 +}