ia64/xen-unstable

changeset 12543:a3c6479c87ef

[MINIOS] Refactored mm.c and sched.c. x86 arch specific code got moved to
arch/x86/mm.c and arch/x86/sched.c. Header files were also refactored:
arch specific code got moved to include/x86/arch_mm.h and
include/x86/sched_mm.h.

Signed-off-by: Dietmar Hahn <dietmar.hahn@fujitsu-siemens.com>
Signed-off-by: Grzegorz Milos <gm281@cam.ac.uk>
author kfraser@localhost.localdomain
date Wed Nov 22 10:11:36 2006 +0000 (2006-11-22)
parents 60b60f75a221
children 395aa5609e6d
files extras/mini-os/Makefile extras/mini-os/arch/x86/mm.c extras/mini-os/arch/x86/sched.c extras/mini-os/include/mm.h extras/mini-os/include/sched.h extras/mini-os/include/x86/arch_mm.h extras/mini-os/include/x86/arch_sched.h extras/mini-os/mm.c extras/mini-os/sched.c
line diff
     1.1 --- a/extras/mini-os/Makefile	Wed Nov 22 10:10:29 2006 +0000
     1.2 +++ b/extras/mini-os/Makefile	Wed Nov 22 10:11:36 2006 +0000
     1.3 @@ -55,9 +55,10 @@ EXTRA_SRC += arch/$(EXTRA_INC)
     1.4  endif
     1.5  
     1.6  ifeq ($(TARGET_ARCH),ia64)
     1.7 -CFLAGS += -mfixed-range=f12-f15,f32-f127
     1.8 -ASFLAGS += -x assembler-with-cpp -ansi -Wall
     1.9 -ASFLAGS += -mfixed-range=f12-f15,f32-f127
    1.10 +CFLAGS += -mfixed-range=f2-f5,f12-f15,f32-f127 -mconstant-gp
    1.11 +ASFLAGS += -x assembler-with-cpp -Wall
    1.12 +ASFLAGS += -mfixed-range=f2-f5,f12-f15,f32-f127 -fomit-frame-pointer
    1.13 +ASFLAGS += -fno-builtin -fno-common -fno-strict-aliasing -mconstant-gp
    1.14  ARCH_LINKS = IA64_LINKS		# Special link on ia64 needed
    1.15  define arch_links
    1.16  [ -e include/ia64/asm-xsi-offsets.h ] || ln -sf ../../../../xen/include/asm-ia64/asm-xsi-offsets.h include/ia64/asm-xsi-offsets.h
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/extras/mini-os/arch/x86/mm.c	Wed Nov 22 10:11:36 2006 +0000
     2.3 @@ -0,0 +1,428 @@
     2.4 +/* 
     2.5 + ****************************************************************************
     2.6 + * (C) 2003 - Rolf Neugebauer - Intel Research Cambridge
     2.7 + * (C) 2005 - Grzegorz Milos - Intel Research Cambridge
     2.8 + ****************************************************************************
     2.9 + *
    2.10 + *        File: mm.c
    2.11 + *      Author: Rolf Neugebauer (neugebar@dcs.gla.ac.uk)
    2.12 + *     Changes: Grzegorz Milos
    2.13 + *              
    2.14 + *        Date: Aug 2003, chages Aug 2005
    2.15 + * 
    2.16 + * Environment: Xen Minimal OS
    2.17 + * Description: memory management related functions
    2.18 + *              contains buddy page allocator from Xen.
    2.19 + *
    2.20 + ****************************************************************************
    2.21 + * Permission is hereby granted, free of charge, to any person obtaining a copy
    2.22 + * of this software and associated documentation files (the "Software"), to
    2.23 + * deal in the Software without restriction, including without limitation the
    2.24 + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
    2.25 + * sell copies of the Software, and to permit persons to whom the Software is
    2.26 + * furnished to do so, subject to the following conditions:
    2.27 + * 
    2.28 + * The above copyright notice and this permission notice shall be included in
    2.29 + * all copies or substantial portions of the Software.
    2.30 + * 
    2.31 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
    2.32 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
    2.33 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
    2.34 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
    2.35 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
    2.36 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
    2.37 + * DEALINGS IN THE SOFTWARE.
    2.38 + */
    2.39 +
    2.40 +#include <os.h>
    2.41 +#include <hypervisor.h>
    2.42 +#include <mm.h>
    2.43 +#include <types.h>
    2.44 +#include <lib.h>
    2.45 +#include <xmalloc.h>
    2.46 +
    2.47 +#ifdef MM_DEBUG
    2.48 +#define DEBUG(_f, _a...) \
    2.49 +    printk("MINI_OS(file=mm.c, line=%d) " _f "\n", __LINE__, ## _a)
    2.50 +#else
    2.51 +#define DEBUG(_f, _a...)    ((void)0)
    2.52 +#endif
    2.53 +
    2.54 +unsigned long *phys_to_machine_mapping;
    2.55 +extern char *stack;
    2.56 +extern void page_walk(unsigned long virt_addr);
    2.57 +
    2.58 +void new_pt_frame(unsigned long *pt_pfn, unsigned long prev_l_mfn, 
    2.59 +                                unsigned long offset, unsigned long level)
    2.60 +{   
    2.61 +    pgentry_t *tab = (pgentry_t *)start_info.pt_base;
    2.62 +    unsigned long pt_page = (unsigned long)pfn_to_virt(*pt_pfn); 
    2.63 +    unsigned long prot_e, prot_t, pincmd;
    2.64 +    mmu_update_t mmu_updates[1];
    2.65 +    struct mmuext_op pin_request;
    2.66 +    
    2.67 +    DEBUG("Allocating new L%d pt frame for pt_pfn=%lx, "
    2.68 +           "prev_l_mfn=%lx, offset=%lx", 
    2.69 +           level, *pt_pfn, prev_l_mfn, offset);
    2.70 +
    2.71 +    /* We need to clear the page, otherwise we might fail to map it
    2.72 +       as a page table page */
    2.73 +    memset((unsigned long*)pfn_to_virt(*pt_pfn), 0, PAGE_SIZE);  
    2.74 + 
    2.75 +    switch ( level )
    2.76 +    {
    2.77 +    case L1_FRAME:
    2.78 +         prot_e = L1_PROT;
    2.79 +         prot_t = L2_PROT;
    2.80 +         pincmd = MMUEXT_PIN_L1_TABLE;
    2.81 +         break;
    2.82 +#if defined(__x86_64__) || defined(CONFIG_X86_PAE)
    2.83 +    case L2_FRAME:
    2.84 +         prot_e = L2_PROT;
    2.85 +         prot_t = L3_PROT;
    2.86 +         pincmd = MMUEXT_PIN_L2_TABLE;
    2.87 +         break;
    2.88 +#endif
    2.89 +#if defined(__x86_64__)
    2.90 +    case L3_FRAME:
    2.91 +         prot_e = L3_PROT;
    2.92 +         prot_t = L4_PROT;
    2.93 +         pincmd = MMUEXT_PIN_L3_TABLE;
    2.94 +         break;
    2.95 +#endif
    2.96 +    default:
    2.97 +         printk("new_pt_frame() called with invalid level number %d\n", level);
    2.98 +         do_exit();
    2.99 +         break;
   2.100 +    }
   2.101 +
   2.102 +    /* Update the entry */
   2.103 +#if defined(__x86_64__)
   2.104 +    tab = pte_to_virt(tab[l4_table_offset(pt_page)]);
   2.105 +    tab = pte_to_virt(tab[l3_table_offset(pt_page)]);
   2.106 +#endif
   2.107 +#if defined(CONFIG_X86_PAE)
   2.108 +    tab = pte_to_virt(tab[l3_table_offset(pt_page)]);
   2.109 +#endif
   2.110 +
   2.111 +    mmu_updates[0].ptr = ((pgentry_t)tab[l2_table_offset(pt_page)] & PAGE_MASK) + 
   2.112 +                         sizeof(pgentry_t) * l1_table_offset(pt_page);
   2.113 +    mmu_updates[0].val = (pgentry_t)pfn_to_mfn(*pt_pfn) << PAGE_SHIFT | 
   2.114 +                         (prot_e & ~_PAGE_RW);
   2.115 +    if(HYPERVISOR_mmu_update(mmu_updates, 1, NULL, DOMID_SELF) < 0)
   2.116 +    {
   2.117 +         printk("PTE for new page table page could not be updated\n");
   2.118 +         do_exit();
   2.119 +    }
   2.120 +                        
   2.121 +    /* Pin the page to provide correct protection */
   2.122 +    pin_request.cmd = pincmd;
   2.123 +    pin_request.arg1.mfn = pfn_to_mfn(*pt_pfn);
   2.124 +    if(HYPERVISOR_mmuext_op(&pin_request, 1, NULL, DOMID_SELF) < 0)
   2.125 +    {
   2.126 +        printk("ERROR: pinning failed\n");
   2.127 +        do_exit();
   2.128 +    }
   2.129 +
   2.130 +    /* Now fill the new page table page with entries.
   2.131 +       Update the page directory as well. */
   2.132 +    mmu_updates[0].ptr = ((pgentry_t)prev_l_mfn << PAGE_SHIFT) + sizeof(pgentry_t) * offset;
   2.133 +    mmu_updates[0].val = (pgentry_t)pfn_to_mfn(*pt_pfn) << PAGE_SHIFT | prot_t;
   2.134 +    if(HYPERVISOR_mmu_update(mmu_updates, 1, NULL, DOMID_SELF) < 0) 
   2.135 +    {
   2.136 +       printk("ERROR: mmu_update failed\n");
   2.137 +       do_exit();
   2.138 +    }
   2.139 +
   2.140 +    *pt_pfn += 1;
   2.141 +}
   2.142 +
   2.143 +/* Checks if a pagetable frame is needed (if weren't allocated by Xen) */
   2.144 +static int need_pt_frame(unsigned long virt_address, int level)
   2.145 +{
   2.146 +    unsigned long hyp_virt_start = HYPERVISOR_VIRT_START;
   2.147 +#if defined(__x86_64__)
   2.148 +    unsigned long hyp_virt_end = HYPERVISOR_VIRT_END;
   2.149 +#else
   2.150 +    unsigned long hyp_virt_end = 0xffffffff;
   2.151 +#endif
   2.152 +
   2.153 +    /* In general frames will _not_ be needed if they were already
   2.154 +       allocated to map the hypervisor into our VA space */
   2.155 +#if defined(__x86_64__)
   2.156 +    if(level == L3_FRAME)
   2.157 +    {
   2.158 +        if(l4_table_offset(virt_address) >= 
   2.159 +           l4_table_offset(hyp_virt_start) &&
   2.160 +           l4_table_offset(virt_address) <= 
   2.161 +           l4_table_offset(hyp_virt_end))
   2.162 +            return 0;
   2.163 +        return 1;
   2.164 +    } else
   2.165 +#endif
   2.166 +
   2.167 +#if defined(__x86_64__) || defined(CONFIG_X86_PAE)
   2.168 +    if(level == L2_FRAME)
   2.169 +    {
   2.170 +#if defined(__x86_64__)
   2.171 +        if(l4_table_offset(virt_address) >= 
   2.172 +           l4_table_offset(hyp_virt_start) &&
   2.173 +           l4_table_offset(virt_address) <= 
   2.174 +           l4_table_offset(hyp_virt_end))
   2.175 +#endif
   2.176 +            if(l3_table_offset(virt_address) >= 
   2.177 +               l3_table_offset(hyp_virt_start) &&
   2.178 +               l3_table_offset(virt_address) <= 
   2.179 +               l3_table_offset(hyp_virt_end))
   2.180 +                return 0;
   2.181 +
   2.182 +        return 1;
   2.183 +    } else 
   2.184 +#endif /* defined(__x86_64__) || defined(CONFIG_X86_PAE) */
   2.185 +
   2.186 +    /* Always need l1 frames */
   2.187 +    if(level == L1_FRAME)
   2.188 +        return 1;
   2.189 +
   2.190 +    printk("ERROR: Unknown frame level %d, hypervisor %llx,%llx\n", 
   2.191 +        level, hyp_virt_start, hyp_virt_end);
   2.192 +    return -1;
   2.193 +}
   2.194 +
   2.195 +void build_pagetable(unsigned long *start_pfn, unsigned long *max_pfn)
   2.196 +{
   2.197 +    unsigned long start_address, end_address;
   2.198 +    unsigned long pfn_to_map, pt_pfn = *start_pfn;
   2.199 +    static mmu_update_t mmu_updates[L1_PAGETABLE_ENTRIES + 1];
   2.200 +    pgentry_t *tab = (pgentry_t *)start_info.pt_base, page;
   2.201 +    unsigned long mfn = pfn_to_mfn(virt_to_pfn(start_info.pt_base));
   2.202 +    unsigned long offset;
   2.203 +    int count = 0;
   2.204 +
   2.205 +    pfn_to_map = (start_info.nr_pt_frames - NOT_L1_FRAMES) * L1_PAGETABLE_ENTRIES;
   2.206 +
   2.207 +    if (*max_pfn >= virt_to_pfn(HYPERVISOR_VIRT_START))
   2.208 +    {
   2.209 +        printk("WARNING: Mini-OS trying to use Xen virtual space. "
   2.210 +               "Truncating memory from %dMB to ",
   2.211 +               ((unsigned long)pfn_to_virt(*max_pfn) - (unsigned long)&_text)>>20);
   2.212 +        *max_pfn = virt_to_pfn(HYPERVISOR_VIRT_START - PAGE_SIZE);
   2.213 +        printk("%dMB\n",
   2.214 +               ((unsigned long)pfn_to_virt(*max_pfn) - (unsigned long)&_text)>>20);
   2.215 +    }
   2.216 +
   2.217 +    start_address = (unsigned long)pfn_to_virt(pfn_to_map);
   2.218 +    end_address = (unsigned long)pfn_to_virt(*max_pfn);
   2.219 +
   2.220 +    /* We worked out the virtual memory range to map, now mapping loop */
   2.221 +    printk("Mapping memory range 0x%lx - 0x%lx\n", start_address, end_address);
   2.222 +
   2.223 +    while(start_address < end_address)
   2.224 +    {
   2.225 +        tab = (pgentry_t *)start_info.pt_base;
   2.226 +        mfn = pfn_to_mfn(virt_to_pfn(start_info.pt_base));
   2.227 +
   2.228 +#if defined(__x86_64__)
   2.229 +        offset = l4_table_offset(start_address);
   2.230 +        /* Need new L3 pt frame */
   2.231 +        if(!(start_address & L3_MASK)) 
   2.232 +            if(need_pt_frame(start_address, L3_FRAME)) 
   2.233 +                new_pt_frame(&pt_pfn, mfn, offset, L3_FRAME);
   2.234 +
   2.235 +        page = tab[offset];
   2.236 +        mfn = pte_to_mfn(page);
   2.237 +        tab = to_virt(mfn_to_pfn(mfn) << PAGE_SHIFT);
   2.238 +#endif
   2.239 +#if defined(__x86_64__) || defined(CONFIG_X86_PAE)
   2.240 +        offset = l3_table_offset(start_address);
   2.241 +        /* Need new L2 pt frame */
   2.242 +        if(!(start_address & L2_MASK))
   2.243 +            if(need_pt_frame(start_address, L2_FRAME))
   2.244 +                new_pt_frame(&pt_pfn, mfn, offset, L2_FRAME);
   2.245 +
   2.246 +        page = tab[offset];
   2.247 +        mfn = pte_to_mfn(page);
   2.248 +        tab = to_virt(mfn_to_pfn(mfn) << PAGE_SHIFT);
   2.249 +#endif
   2.250 +        offset = l2_table_offset(start_address);        
   2.251 +        /* Need new L1 pt frame */
   2.252 +        if(!(start_address & L1_MASK))
   2.253 +            if(need_pt_frame(start_address, L1_FRAME)) 
   2.254 +                new_pt_frame(&pt_pfn, mfn, offset, L1_FRAME);
   2.255 +
   2.256 +        page = tab[offset];
   2.257 +        mfn = pte_to_mfn(page);
   2.258 +        offset = l1_table_offset(start_address);
   2.259 +
   2.260 +        mmu_updates[count].ptr = ((pgentry_t)mfn << PAGE_SHIFT) + sizeof(pgentry_t) * offset;
   2.261 +        mmu_updates[count].val = (pgentry_t)pfn_to_mfn(pfn_to_map++) << PAGE_SHIFT | L1_PROT;
   2.262 +        count++;
   2.263 +        if (count == L1_PAGETABLE_ENTRIES || pfn_to_map == *max_pfn)
   2.264 +        {
   2.265 +            if(HYPERVISOR_mmu_update(mmu_updates, count, NULL, DOMID_SELF) < 0)
   2.266 +            {
   2.267 +                printk("PTE could not be updated\n");
   2.268 +                do_exit();
   2.269 +            }
   2.270 +            count = 0;
   2.271 +        }
   2.272 +        start_address += PAGE_SIZE;
   2.273 +    }
   2.274 +
   2.275 +    *start_pfn = pt_pfn;
   2.276 +}
   2.277 +
   2.278 +
   2.279 +void mem_test(unsigned long *start_add, unsigned long *end_add)
   2.280 +{
   2.281 +    unsigned long mask = 0x10000;
   2.282 +    unsigned long *pointer;
   2.283 +
   2.284 +    for(pointer = start_add; pointer < end_add; pointer++)
   2.285 +    {
   2.286 +        if(!(((unsigned long)pointer) & 0xfffff))
   2.287 +        {
   2.288 +            printk("Writing to %lx\n", pointer);
   2.289 +            page_walk((unsigned long)pointer);
   2.290 +        }
   2.291 +        *pointer = (unsigned long)pointer & ~mask;
   2.292 +    }
   2.293 +
   2.294 +    for(pointer = start_add; pointer < end_add; pointer++)
   2.295 +    {
   2.296 +        if(((unsigned long)pointer & ~mask) != *pointer)
   2.297 +            printk("Read error at 0x%lx. Read: 0x%lx, should read 0x%lx\n",
   2.298 +                (unsigned long)pointer, 
   2.299 +                *pointer, 
   2.300 +                ((unsigned long)pointer & ~mask));
   2.301 +    }
   2.302 +
   2.303 +}
   2.304 +
   2.305 +static pgentry_t *demand_map_pgt;
   2.306 +static void *demand_map_area_start;
   2.307 +
   2.308 +void arch_init_demand_mapping_area(unsigned long max_pfn)
   2.309 +{
   2.310 +    unsigned long mfn;
   2.311 +    pgentry_t *tab;
   2.312 +    unsigned long start_addr;
   2.313 +    unsigned long pt_pfn;
   2.314 +    unsigned offset;
   2.315 +
   2.316 +    /* Round up to four megs.  + 1024 rather than + 1023 since we want
   2.317 +       to be sure we don't end up in the same place we started. */
   2.318 +    max_pfn = (max_pfn + L1_PAGETABLE_ENTRIES) & ~(L1_PAGETABLE_ENTRIES - 1);
   2.319 +    if (max_pfn == 0 ||
   2.320 +            (unsigned long)pfn_to_virt(max_pfn + L1_PAGETABLE_ENTRIES) >=
   2.321 +            HYPERVISOR_VIRT_START) {
   2.322 +        printk("Too much memory; no room for demand map hole.\n");
   2.323 +        do_exit();
   2.324 +    }
   2.325 +
   2.326 +    demand_map_area_start = pfn_to_virt(max_pfn);
   2.327 +    printk("Demand map pfns start at %lx (%p).\n", max_pfn,
   2.328 +            demand_map_area_start);
   2.329 +    start_addr = (unsigned long)demand_map_area_start;
   2.330 +
   2.331 +    tab = (pgentry_t *)start_info.pt_base;
   2.332 +    mfn = virt_to_mfn(start_info.pt_base);
   2.333 +    pt_pfn = virt_to_pfn(alloc_page());
   2.334 +
   2.335 +#if defined(__x86_64__)
   2.336 +    offset = l4_table_offset(start_addr);
   2.337 +    if (!(tab[offset] & _PAGE_PRESENT)) {
   2.338 +        new_pt_frame(&pt_pfn, mfn, offset, L3_FRAME);
   2.339 +        pt_pfn = virt_to_pfn(alloc_page());
   2.340 +    }
   2.341 +    ASSERT(tab[offset] & _PAGE_PRESENT);
   2.342 +    mfn = pte_to_mfn(tab[offset]);
   2.343 +    tab = to_virt(mfn_to_pfn(mfn) << PAGE_SHIFT);
   2.344 +#endif
   2.345 +#if defined(__x86_64__) || defined(CONFIG_X86_PAE)
   2.346 +    offset = l3_table_offset(start_addr);
   2.347 +    if (!(tab[offset] & _PAGE_PRESENT)) {
   2.348 +        new_pt_frame(&pt_pfn, mfn, offset, L2_FRAME);
   2.349 +        pt_pfn = virt_to_pfn(alloc_page());
   2.350 +    }
   2.351 +    ASSERT(tab[offset] & _PAGE_PRESENT);
   2.352 +    mfn = pte_to_mfn(tab[offset]);
   2.353 +    tab = to_virt(mfn_to_pfn(mfn) << PAGE_SHIFT);
   2.354 +#endif
   2.355 +    offset = l2_table_offset(start_addr);
   2.356 +    if (tab[offset] & _PAGE_PRESENT) {
   2.357 +        printk("Demand map area already has a page table covering it?\n");
   2.358 +        BUG();
   2.359 +    }
   2.360 +    demand_map_pgt = pfn_to_virt(pt_pfn);
   2.361 +    new_pt_frame(&pt_pfn, mfn, offset, L1_FRAME);
   2.362 +    ASSERT(tab[offset] & _PAGE_PRESENT);
   2.363 +    printk("Initialised demand area.\n");
   2.364 +}
   2.365 +
   2.366 +void *map_frames(unsigned long *f, unsigned long n)
   2.367 +{
   2.368 +    unsigned long x;
   2.369 +    unsigned long y = 0;
   2.370 +    mmu_update_t mmu_updates[16];
   2.371 +    int rc;
   2.372 +
   2.373 +    if (n > 16) {
   2.374 +        printk("Tried to map too many (%ld) frames at once.\n", n);
   2.375 +        return NULL;
   2.376 +    }
   2.377 +
   2.378 +    /* Find a run of n contiguous frames */
   2.379 +    for (x = 0; x <= 1024 - n; x += y + 1) {
   2.380 +        for (y = 0; y < n; y++)
   2.381 +            if (demand_map_pgt[x+y] & _PAGE_PRESENT)
   2.382 +                break;
   2.383 +        if (y == n)
   2.384 +            break;
   2.385 +    }
   2.386 +    if (y != n) {
   2.387 +        printk("Failed to map %ld frames!\n", n);
   2.388 +        return NULL;
   2.389 +    }
   2.390 +
   2.391 +    /* Found it at x.  Map it in. */
   2.392 +    for (y = 0; y < n; y++) {
   2.393 +        mmu_updates[y].ptr = virt_to_mach(&demand_map_pgt[x + y]);
   2.394 +        mmu_updates[y].val = (f[y] << PAGE_SHIFT) | L1_PROT;
   2.395 +    }
   2.396 +
   2.397 +    rc = HYPERVISOR_mmu_update(mmu_updates, n, NULL, DOMID_SELF);
   2.398 +    if (rc < 0) {
   2.399 +        printk("Map %ld failed: %d.\n", n, rc);
   2.400 +        return NULL;
   2.401 +    } else {
   2.402 +        return (void *)(unsigned long)((unsigned long)demand_map_area_start +
   2.403 +                x * PAGE_SIZE);
   2.404 +    }
   2.405 +}
   2.406 +
   2.407 +void arch_init_mm(unsigned long* start_pfn_p, unsigned long* max_pfn_p)
   2.408 +{
   2.409 +
   2.410 +    unsigned long start_pfn, max_pfn;
   2.411 +
   2.412 +    printk("  _text:        %p\n", &_text);
   2.413 +    printk("  _etext:       %p\n", &_etext);
   2.414 +    printk("  _edata:       %p\n", &_edata);
   2.415 +    printk("  stack start:  %p\n", &stack);
   2.416 +    printk("  _end:         %p\n", &_end);
   2.417 +
   2.418 +    /* First page follows page table pages and 3 more pages (store page etc) */
   2.419 +    start_pfn = PFN_UP(to_phys(start_info.pt_base)) + 
   2.420 +                start_info.nr_pt_frames + 3;
   2.421 +    max_pfn = start_info.nr_pages;
   2.422 +   
   2.423 +    printk("  start_pfn:    %lx\n", start_pfn);
   2.424 +    printk("  max_pfn:      %lx\n", max_pfn);
   2.425 +
   2.426 +    build_pagetable(&start_pfn, &max_pfn);
   2.427 +
   2.428 +    *start_pfn_p = start_pfn;
   2.429 +    *max_pfn_p = max_pfn;
   2.430 +}
   2.431 +
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/extras/mini-os/arch/x86/sched.c	Wed Nov 22 10:11:36 2006 +0000
     3.3 @@ -0,0 +1,150 @@
     3.4 +/* 
     3.5 + ****************************************************************************
     3.6 + * (C) 2005 - Grzegorz Milos - Intel Research Cambridge
     3.7 + ****************************************************************************
     3.8 + *
     3.9 + *        File: sched.c
    3.10 + *      Author: Grzegorz Milos
    3.11 + *     Changes: Robert Kaiser
    3.12 + *              
    3.13 + *        Date: Aug 2005
    3.14 + * 
    3.15 + * Environment: Xen Minimal OS
    3.16 + * Description: simple scheduler for Mini-Os
    3.17 + *
    3.18 + * The scheduler is non-preemptive (cooperative), and schedules according 
    3.19 + * to Round Robin algorithm.
    3.20 + *
    3.21 + ****************************************************************************
    3.22 + * Permission is hereby granted, free of charge, to any person obtaining a copy
    3.23 + * of this software and associated documentation files (the "Software"), to
    3.24 + * deal in the Software without restriction, including without limitation the
    3.25 + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
    3.26 + * sell copies of the Software, and to permit persons to whom the Software is
    3.27 + * furnished to do so, subject to the following conditions:
    3.28 + * 
    3.29 + * The above copyright notice and this permission notice shall be included in
    3.30 + * all copies or substantial portions of the Software.
    3.31 + * 
    3.32 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
    3.33 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
    3.34 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
    3.35 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
    3.36 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
    3.37 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
    3.38 + * DEALINGS IN THE SOFTWARE.
    3.39 + */
    3.40 +
    3.41 +#include <os.h>
    3.42 +#include <hypervisor.h>
    3.43 +#include <time.h>
    3.44 +#include <mm.h>
    3.45 +#include <types.h>
    3.46 +#include <lib.h>
    3.47 +#include <xmalloc.h>
    3.48 +#include <list.h>
    3.49 +#include <sched.h>
    3.50 +#include <semaphore.h>
    3.51 +
    3.52 +
    3.53 +#ifdef SCHED_DEBUG
    3.54 +#define DEBUG(_f, _a...) \
    3.55 +    printk("MINI_OS(file=sched.c, line=%d) " _f "\n", __LINE__, ## _a)
    3.56 +#else
    3.57 +#define DEBUG(_f, _a...)    ((void)0)
    3.58 +#endif
    3.59 +
    3.60 +
    3.61 +void dump_stack(struct thread *thread)
    3.62 +{
    3.63 +    unsigned long *bottom = (unsigned long *)(thread->stack + 2*4*1024); 
    3.64 +    unsigned long *pointer = (unsigned long *)thread->sp;
    3.65 +    int count;
    3.66 +    if(thread == current)
    3.67 +    {
    3.68 +#ifdef __i386__    
    3.69 +        asm("movl %%esp,%0"
    3.70 +            : "=r"(pointer));
    3.71 +#else
    3.72 +        asm("movq %%rsp,%0"
    3.73 +            : "=r"(pointer));
    3.74 +#endif
    3.75 +    }
    3.76 +    printk("The stack for \"%s\"\n", thread->name);
    3.77 +    for(count = 0; count < 25 && pointer < bottom; count ++)
    3.78 +    {
    3.79 +        printk("[0x%lx] 0x%lx\n", pointer, *pointer);
    3.80 +        pointer++;
    3.81 +    }
    3.82 +    
    3.83 +    if(pointer < bottom) printk(" ... continues.\n");
    3.84 +}
    3.85 +
    3.86 +/* Gets run when a new thread is scheduled the first time ever, 
    3.87 +   defined in x86_[32/64].S */
    3.88 +extern void thread_starter(void);
    3.89 +
    3.90 +/* Pushes the specified value onto the stack of the specified thread */
    3.91 +static void stack_push(struct thread *thread, unsigned long value)
    3.92 +{
    3.93 +    thread->sp -= sizeof(unsigned long);
    3.94 +    *((unsigned long *)thread->sp) = value;
    3.95 +}
    3.96 +
    3.97 +struct thread* create_thread(char *name, void (*function)(void *), void *data)
    3.98 +{
    3.99 +    struct thread *thread;
   3.100 +    unsigned long flags;
   3.101 +    
   3.102 +    thread = xmalloc(struct thread);
   3.103 +    /* Allocate 2 pages for stack, stack will be 2pages aligned */
   3.104 +    thread->stack = (char *)alloc_pages(1);
   3.105 +    thread->name = name;
   3.106 +    printk("Thread \"%s\": pointer: 0x%lx, stack: 0x%lx\n", name, thread, 
   3.107 +            thread->stack);
   3.108 +    
   3.109 +    thread->sp = (unsigned long)thread->stack + 4096 * 2;
   3.110 +    /* Save pointer to the thread on the stack, used by current macro */
   3.111 +    *((unsigned long *)thread->stack) = (unsigned long)thread;
   3.112 +    
   3.113 +    stack_push(thread, (unsigned long) function);
   3.114 +    stack_push(thread, (unsigned long) data);
   3.115 +    thread->ip = (unsigned long) thread_starter;
   3.116 +     
   3.117 +    /* Not runable, not exited, not sleeping */
   3.118 +    thread->flags = 0;
   3.119 +    thread->wakeup_time = 0LL;
   3.120 +    set_runnable(thread);
   3.121 +    local_irq_save(flags);
   3.122 +    if(idle_thread != NULL) {
   3.123 +        list_add_tail(&thread->thread_list, &idle_thread->thread_list); 
   3.124 +    } else if(function != idle_thread_fn)
   3.125 +    {
   3.126 +        printk("BUG: Not allowed to create thread before initialising scheduler.\n");
   3.127 +        BUG();
   3.128 +    }
   3.129 +    local_irq_restore(flags);
   3.130 +    return thread;
   3.131 +}
   3.132 +
   3.133 +
   3.134 +void run_idle_thread(void)
   3.135 +{
   3.136 +    /* Switch stacks and run the thread */ 
   3.137 +#if defined(__i386__)
   3.138 +    __asm__ __volatile__("mov %0,%%esp\n\t"
   3.139 +                         "push %1\n\t" 
   3.140 +                         "ret"                                            
   3.141 +                         :"=m" (idle_thread->sp)
   3.142 +                         :"m" (idle_thread->ip));                          
   3.143 +#elif defined(__x86_64__)
   3.144 +    __asm__ __volatile__("mov %0,%%rsp\n\t"
   3.145 +                         "push %1\n\t" 
   3.146 +                         "ret"                                            
   3.147 +                         :"=m" (idle_thread->sp)
   3.148 +                         :"m" (idle_thread->ip));                                                    
   3.149 +#endif
   3.150 +}
   3.151 +
   3.152 +
   3.153 +
     4.1 --- a/extras/mini-os/include/mm.h	Wed Nov 22 10:10:29 2006 +0000
     4.2 +++ b/extras/mini-os/include/mm.h	Wed Nov 22 10:11:36 2006 +0000
     4.3 @@ -29,182 +29,15 @@
     4.4  #include <xen/arch-x86_32.h>
     4.5  #elif defined(__x86_64__)
     4.6  #include <xen/arch-x86_64.h>
     4.7 +#elif defined(__ia64__)
     4.8 +#include <xen/arch-ia64.h>
     4.9  #else
    4.10  #error "Unsupported architecture"
    4.11  #endif
    4.12  
    4.13  #include <lib.h>
    4.14 -
    4.15 -#define L1_FRAME                1
    4.16 -#define L2_FRAME                2
    4.17 -#define L3_FRAME                3
    4.18 -
    4.19 -#define L1_PAGETABLE_SHIFT      12
    4.20 -
    4.21 -#if defined(__i386__)
    4.22 -
    4.23 -#if !defined(CONFIG_X86_PAE)
    4.24 -
    4.25 -#define L2_PAGETABLE_SHIFT      22
    4.26 -
    4.27 -#define L1_PAGETABLE_ENTRIES    1024
    4.28 -#define L2_PAGETABLE_ENTRIES    1024
    4.29 -
    4.30 -#define PADDR_BITS              32
    4.31 -#define PADDR_MASK              (~0UL)
    4.32 -
    4.33 -#define NOT_L1_FRAMES           1
    4.34 -#define PRIpte "08lx"
    4.35 -typedef unsigned long pgentry_t;
    4.36 -
    4.37 -#else /* defined(CONFIG_X86_PAE) */
    4.38 -
    4.39 -#define L2_PAGETABLE_SHIFT      21
    4.40 -#define L3_PAGETABLE_SHIFT      30
    4.41 -
    4.42 -#define L1_PAGETABLE_ENTRIES    512
    4.43 -#define L2_PAGETABLE_ENTRIES    512
    4.44 -#define L3_PAGETABLE_ENTRIES    4
    4.45 -
    4.46 -#define PADDR_BITS              44
    4.47 -#define PADDR_MASK              ((1ULL << PADDR_BITS)-1)
    4.48 -
    4.49 -#define L2_MASK  ((1UL << L3_PAGETABLE_SHIFT) - 1)
    4.50 -
    4.51 -/*
    4.52 - * If starting from virtual address greater than 0xc0000000,
    4.53 - * this value will be 2 to account for final mid-level page
    4.54 - * directory which is always mapped in at this location.
    4.55 - */
    4.56 -#define NOT_L1_FRAMES           3
    4.57 -#define PRIpte "016llx"
    4.58 -typedef uint64_t pgentry_t;
    4.59 -
    4.60 -#endif /* !defined(CONFIG_X86_PAE) */
    4.61 -
    4.62 -#elif defined(__x86_64__)
    4.63 -
    4.64 -#define L2_PAGETABLE_SHIFT      21
    4.65 -#define L3_PAGETABLE_SHIFT      30
    4.66 -#define L4_PAGETABLE_SHIFT      39
    4.67 -
    4.68 -#define L1_PAGETABLE_ENTRIES    512
    4.69 -#define L2_PAGETABLE_ENTRIES    512
    4.70 -#define L3_PAGETABLE_ENTRIES    512
    4.71 -#define L4_PAGETABLE_ENTRIES    512
    4.72 -
    4.73 -/* These are page-table limitations. Current CPUs support only 40-bit phys. */
    4.74 -#define PADDR_BITS              52
    4.75 -#define VADDR_BITS              48
    4.76 -#define PADDR_MASK              ((1UL << PADDR_BITS)-1)
    4.77 -#define VADDR_MASK              ((1UL << VADDR_BITS)-1)
    4.78 -
    4.79 -#define L2_MASK  ((1UL << L3_PAGETABLE_SHIFT) - 1)
    4.80 -#define L3_MASK  ((1UL << L4_PAGETABLE_SHIFT) - 1)
    4.81 -
    4.82 -#define NOT_L1_FRAMES           3
    4.83 -#define PRIpte "016lx"
    4.84 -typedef unsigned long pgentry_t;
    4.85 -
    4.86 -#endif
    4.87 -
    4.88 -#define L1_MASK  ((1UL << L2_PAGETABLE_SHIFT) - 1)
    4.89 +#include <arch_mm.h>
    4.90  
    4.91 -/* Given a virtual address, get an entry offset into a page table. */
    4.92 -#define l1_table_offset(_a) \
    4.93 -  (((_a) >> L1_PAGETABLE_SHIFT) & (L1_PAGETABLE_ENTRIES - 1))
    4.94 -#define l2_table_offset(_a) \
    4.95 -  (((_a) >> L2_PAGETABLE_SHIFT) & (L2_PAGETABLE_ENTRIES - 1))
    4.96 -#if defined(__x86_64__) || defined(CONFIG_X86_PAE)
    4.97 -#define l3_table_offset(_a) \
    4.98 -  (((_a) >> L3_PAGETABLE_SHIFT) & (L3_PAGETABLE_ENTRIES - 1))
    4.99 -#endif
   4.100 -#if defined(__x86_64__)
   4.101 -#define l4_table_offset(_a) \
   4.102 -  (((_a) >> L4_PAGETABLE_SHIFT) & (L4_PAGETABLE_ENTRIES - 1))
   4.103 -#endif
   4.104 -
   4.105 -#define _PAGE_PRESENT  0x001UL
   4.106 -#define _PAGE_RW       0x002UL
   4.107 -#define _PAGE_USER     0x004UL
   4.108 -#define _PAGE_PWT      0x008UL
   4.109 -#define _PAGE_PCD      0x010UL
   4.110 -#define _PAGE_ACCESSED 0x020UL
   4.111 -#define _PAGE_DIRTY    0x040UL
   4.112 -#define _PAGE_PAT      0x080UL
   4.113 -#define _PAGE_PSE      0x080UL
   4.114 -#define _PAGE_GLOBAL   0x100UL
   4.115 -
   4.116 -#if defined(__i386__)
   4.117 -#define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED)
   4.118 -#define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY |_PAGE_USER)
   4.119 -#if defined(CONFIG_X86_PAE)
   4.120 -#define L3_PROT (_PAGE_PRESENT)
   4.121 -#endif /* CONFIG_X86_PAE */
   4.122 -#elif defined(__x86_64__)
   4.123 -#define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_USER)
   4.124 -#define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
   4.125 -#define L3_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
   4.126 -#define L4_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
   4.127 -#endif /* __i386__ || __x86_64__ */
   4.128 -
   4.129 -#ifndef CONFIG_X86_PAE
   4.130 -#define PAGE_SIZE       (1UL << L1_PAGETABLE_SHIFT)
   4.131 -#else
   4.132 -#define PAGE_SIZE       (1ULL << L1_PAGETABLE_SHIFT)
   4.133 -#endif
   4.134 -#define PAGE_SHIFT      L1_PAGETABLE_SHIFT
   4.135 -#define PAGE_MASK       (~(PAGE_SIZE-1))
   4.136 -
   4.137 -#define PFN_UP(x)	(((x) + PAGE_SIZE-1) >> L1_PAGETABLE_SHIFT)
   4.138 -#define PFN_DOWN(x)	((x) >> L1_PAGETABLE_SHIFT)
   4.139 -#define PFN_PHYS(x)	((x) << L1_PAGETABLE_SHIFT)
   4.140 -
   4.141 -/* to align the pointer to the (next) page boundary */
   4.142 -#define PAGE_ALIGN(addr)        (((addr)+PAGE_SIZE-1)&PAGE_MASK)
   4.143 -
   4.144 -/* Definitions for machine and pseudophysical addresses. */
   4.145 -#ifdef CONFIG_X86_PAE
   4.146 -typedef unsigned long long paddr_t;
   4.147 -typedef unsigned long long maddr_t;
   4.148 -#else
   4.149 -typedef unsigned long paddr_t;
   4.150 -typedef unsigned long maddr_t;
   4.151 -#endif
   4.152 -
   4.153 -extern unsigned long *phys_to_machine_mapping;
   4.154 -extern char _text, _etext, _edata, _end;
   4.155 -#define pfn_to_mfn(_pfn) (phys_to_machine_mapping[(_pfn)])
   4.156 -static __inline__ maddr_t phys_to_machine(paddr_t phys)
   4.157 -{
   4.158 -	maddr_t machine = pfn_to_mfn(phys >> PAGE_SHIFT);
   4.159 -	machine = (machine << PAGE_SHIFT) | (phys & ~PAGE_MASK);
   4.160 -	return machine;
   4.161 -}
   4.162 -
   4.163 -#define mfn_to_pfn(_mfn) (machine_to_phys_mapping[(_mfn)])
   4.164 -static __inline__ paddr_t machine_to_phys(maddr_t machine)
   4.165 -{
   4.166 -	paddr_t phys = mfn_to_pfn(machine >> PAGE_SHIFT);
   4.167 -	phys = (phys << PAGE_SHIFT) | (machine & ~PAGE_MASK);
   4.168 -	return phys;
   4.169 -}
   4.170 -
   4.171 -#define VIRT_START                 ((unsigned long)&_text)
   4.172 -
   4.173 -#define to_phys(x)                 ((unsigned long)(x)-VIRT_START)
   4.174 -#define to_virt(x)                 ((void *)((unsigned long)(x)+VIRT_START))
   4.175 -
   4.176 -#define virt_to_pfn(_virt)         (PFN_DOWN(to_phys(_virt)))
   4.177 -#define virt_to_mfn(_virt)         (pfn_to_mfn(virt_to_pfn(_virt)))
   4.178 -#define mach_to_virt(_mach)        (to_virt(machine_to_phys(_mach)))
   4.179 -#define virt_to_mach(_virt)        (phys_to_machine(to_phys(_virt)))
   4.180 -#define mfn_to_virt(_mfn)          (to_virt(mfn_to_pfn(_mfn) << PAGE_SHIFT))
   4.181 -#define pfn_to_virt(_pfn)          (to_virt((_pfn) << PAGE_SHIFT))
   4.182 -
   4.183 -/* Pagetable walking. */
   4.184 -#define pte_to_mfn(_pte)           (((_pte) & (PADDR_MASK&PAGE_MASK)) >> L1_PAGETABLE_SHIFT)
   4.185 -#define pte_to_virt(_pte)          to_virt(mfn_to_pfn(pte_to_mfn(_pte)) << PAGE_SHIFT)
   4.186  
   4.187  void init_mm(void);
   4.188  unsigned long alloc_pages(int order);
   4.189 @@ -220,6 +53,8 @@ static __inline__ int get_order(unsigned
   4.190      return order;
   4.191  }
   4.192  
   4.193 +void arch_init_demand_mapping_area(unsigned long max_pfn);
   4.194 +void arch_init_mm(unsigned long* start_pfn_p, unsigned long* max_pfn_p);
   4.195  
   4.196  void *map_frames(unsigned long *f, unsigned long n);
   4.197  
     5.1 --- a/extras/mini-os/include/sched.h	Wed Nov 22 10:10:29 2006 +0000
     5.2 +++ b/extras/mini-os/include/sched.h	Wed Nov 22 10:11:36 2006 +0000
     5.3 @@ -3,36 +3,40 @@
     5.4  
     5.5  #include <list.h>
     5.6  #include <time.h>
     5.7 +#include <arch_sched.h>
     5.8  
     5.9  struct thread
    5.10  {
    5.11      char *name;
    5.12      char *stack;
    5.13 +#if !defined(__ia64__)
    5.14      unsigned long sp;  /* Stack pointer */
    5.15      unsigned long ip;  /* Instruction pointer */
    5.16 +#else /* !defined(__ia64__) */
    5.17 +    thread_regs_t regs;
    5.18 +#endif /* !defined(__ia64__) */
    5.19      struct list_head thread_list;
    5.20      u32 flags;
    5.21      s_time_t wakeup_time;
    5.22  };
    5.23  
    5.24 +extern struct thread *idle_thread;
    5.25 +void idle_thread_fn(void *unused);
    5.26  
    5.27 +#define RUNNABLE_FLAG   0x00000001
    5.28 +
    5.29 +#define is_runnable(_thread)    (_thread->flags & RUNNABLE_FLAG)
    5.30 +#define set_runnable(_thread)   (_thread->flags |= RUNNABLE_FLAG)
    5.31 +#define clear_runnable(_thread) (_thread->flags &= ~RUNNABLE_FLAG)
    5.32 +
    5.33 +#define switch_threads(prev, next) arch_switch_threads(prev, next)
    5.34 + 
    5.35  
    5.36  void init_sched(void);
    5.37  void run_idle_thread(void);
    5.38  struct thread* create_thread(char *name, void (*function)(void *), void *data);
    5.39  void schedule(void);
    5.40  
    5.41 -static inline struct thread* get_current(void)
    5.42 -{
    5.43 -    struct thread **current;
    5.44 -#ifdef __i386__    
    5.45 -    __asm__("andl %%esp,%0; ":"=r" (current) : "r" (~8191UL));
    5.46 -#else
    5.47 -    __asm__("andq %%rsp,%0; ":"=r" (current) : "r" (~8191UL));
    5.48 -#endif 
    5.49 -    return *current;
    5.50 -}
    5.51 -          
    5.52  #define current get_current()
    5.53  
    5.54  
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/extras/mini-os/include/x86/arch_mm.h	Wed Nov 22 10:11:36 2006 +0000
     6.3 @@ -0,0 +1,209 @@
     6.4 +/* -*-  Mode:C; c-basic-offset:4; tab-width:4 -*-
     6.5 + *
     6.6 + * (C) 2003 - Rolf Neugebauer - Intel Research Cambridge
     6.7 + * Copyright (c) 2005, Keir A Fraser
     6.8 + *
     6.9 + * Permission is hereby granted, free of charge, to any person obtaining a copy
    6.10 + * of this software and associated documentation files (the "Software"), to
    6.11 + * deal in the Software without restriction, including without limitation the
    6.12 + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
    6.13 + * sell copies of the Software, and to permit persons to whom the Software is
    6.14 + * furnished to do so, subject to the following conditions:
    6.15 + * 
    6.16 + * The above copyright notice and this permission notice shall be included in
    6.17 + * all copies or substantial portions of the Software.
    6.18 + * 
    6.19 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
    6.20 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
    6.21 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
    6.22 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
    6.23 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
    6.24 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
    6.25 + * DEALINGS IN THE SOFTWARE.
    6.26 + */
    6.27 +
    6.28 +#ifndef _ARCH_MM_H_
    6.29 +#define _ARCH_MM_H_
    6.30 +
    6.31 +#if defined(__i386__)
    6.32 +#include <xen/arch-x86_32.h>
    6.33 +#elif defined(__x86_64__)
    6.34 +#include <xen/arch-x86_64.h>
    6.35 +#else
    6.36 +#error "Unsupported architecture"
    6.37 +#endif
    6.38 +
    6.39 +#define L1_FRAME                1
    6.40 +#define L2_FRAME                2
    6.41 +#define L3_FRAME                3
    6.42 +
    6.43 +#define L1_PAGETABLE_SHIFT      12
    6.44 +
    6.45 +#if defined(__i386__)
    6.46 +
    6.47 +#if !defined(CONFIG_X86_PAE)
    6.48 +
    6.49 +#define L2_PAGETABLE_SHIFT      22
    6.50 +
    6.51 +#define L1_PAGETABLE_ENTRIES    1024
    6.52 +#define L2_PAGETABLE_ENTRIES    1024
    6.53 +
    6.54 +#define PADDR_BITS              32
    6.55 +#define PADDR_MASK              (~0UL)
    6.56 +
    6.57 +#define NOT_L1_FRAMES           1
    6.58 +#define PRIpte "08lx"
    6.59 +typedef unsigned long pgentry_t;
    6.60 +
    6.61 +#else /* defined(CONFIG_X86_PAE) */
    6.62 +
    6.63 +#define L2_PAGETABLE_SHIFT      21
    6.64 +#define L3_PAGETABLE_SHIFT      30
    6.65 +
    6.66 +#define L1_PAGETABLE_ENTRIES    512
    6.67 +#define L2_PAGETABLE_ENTRIES    512
    6.68 +#define L3_PAGETABLE_ENTRIES    4
    6.69 +
    6.70 +#define PADDR_BITS              44
    6.71 +#define PADDR_MASK              ((1ULL << PADDR_BITS)-1)
    6.72 +
    6.73 +#define L2_MASK  ((1UL << L3_PAGETABLE_SHIFT) - 1)
    6.74 +
    6.75 +/*
    6.76 + * If starting from virtual address greater than 0xc0000000,
    6.77 + * this value will be 2 to account for final mid-level page
    6.78 + * directory which is always mapped in at this location.
    6.79 + */
    6.80 +#define NOT_L1_FRAMES           3
    6.81 +#define PRIpte "016llx"
    6.82 +typedef uint64_t pgentry_t;
    6.83 +
    6.84 +#endif /* !defined(CONFIG_X86_PAE) */
    6.85 +
    6.86 +#elif defined(__x86_64__)
    6.87 +
    6.88 +#define L2_PAGETABLE_SHIFT      21
    6.89 +#define L3_PAGETABLE_SHIFT      30
    6.90 +#define L4_PAGETABLE_SHIFT      39
    6.91 +
    6.92 +#define L1_PAGETABLE_ENTRIES    512
    6.93 +#define L2_PAGETABLE_ENTRIES    512
    6.94 +#define L3_PAGETABLE_ENTRIES    512
    6.95 +#define L4_PAGETABLE_ENTRIES    512
    6.96 +
    6.97 +/* These are page-table limitations. Current CPUs support only 40-bit phys. */
    6.98 +#define PADDR_BITS              52
    6.99 +#define VADDR_BITS              48
   6.100 +#define PADDR_MASK              ((1UL << PADDR_BITS)-1)
   6.101 +#define VADDR_MASK              ((1UL << VADDR_BITS)-1)
   6.102 +
   6.103 +#define L2_MASK  ((1UL << L3_PAGETABLE_SHIFT) - 1)
   6.104 +#define L3_MASK  ((1UL << L4_PAGETABLE_SHIFT) - 1)
   6.105 +
   6.106 +#define NOT_L1_FRAMES           3
   6.107 +#define PRIpte "016lx"
   6.108 +typedef unsigned long pgentry_t;
   6.109 +
   6.110 +#endif
   6.111 +
   6.112 +#define L1_MASK  ((1UL << L2_PAGETABLE_SHIFT) - 1)
   6.113 +
   6.114 +/* Given a virtual address, get an entry offset into a page table. */
   6.115 +#define l1_table_offset(_a) \
   6.116 +  (((_a) >> L1_PAGETABLE_SHIFT) & (L1_PAGETABLE_ENTRIES - 1))
   6.117 +#define l2_table_offset(_a) \
   6.118 +  (((_a) >> L2_PAGETABLE_SHIFT) & (L2_PAGETABLE_ENTRIES - 1))
   6.119 +#if defined(__x86_64__) || defined(CONFIG_X86_PAE)
   6.120 +#define l3_table_offset(_a) \
   6.121 +  (((_a) >> L3_PAGETABLE_SHIFT) & (L3_PAGETABLE_ENTRIES - 1))
   6.122 +#endif
   6.123 +#if defined(__x86_64__)
   6.124 +#define l4_table_offset(_a) \
   6.125 +  (((_a) >> L4_PAGETABLE_SHIFT) & (L4_PAGETABLE_ENTRIES - 1))
   6.126 +#endif
   6.127 +
   6.128 +#define _PAGE_PRESENT  0x001UL
   6.129 +#define _PAGE_RW       0x002UL
   6.130 +#define _PAGE_USER     0x004UL
   6.131 +#define _PAGE_PWT      0x008UL
   6.132 +#define _PAGE_PCD      0x010UL
   6.133 +#define _PAGE_ACCESSED 0x020UL
   6.134 +#define _PAGE_DIRTY    0x040UL
   6.135 +#define _PAGE_PAT      0x080UL
   6.136 +#define _PAGE_PSE      0x080UL
   6.137 +#define _PAGE_GLOBAL   0x100UL
   6.138 +
   6.139 +#if defined(__i386__)
   6.140 +#define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED)
   6.141 +#define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY |_PAGE_USER)
   6.142 +#if defined(CONFIG_X86_PAE)
   6.143 +#define L3_PROT (_PAGE_PRESENT)
   6.144 +#endif /* CONFIG_X86_PAE */
   6.145 +#elif defined(__x86_64__)
   6.146 +#define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_USER)
   6.147 +#define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
   6.148 +#define L3_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
   6.149 +#define L4_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
   6.150 +#endif /* __i386__ || __x86_64__ */
   6.151 +
   6.152 +#ifndef CONFIG_X86_PAE
   6.153 +#define PAGE_SIZE       (1UL << L1_PAGETABLE_SHIFT)
   6.154 +#else
   6.155 +#define PAGE_SIZE       (1ULL << L1_PAGETABLE_SHIFT)
   6.156 +#endif
   6.157 +#define PAGE_SHIFT      L1_PAGETABLE_SHIFT
   6.158 +#define PAGE_MASK       (~(PAGE_SIZE-1))
   6.159 +
   6.160 +#define PFN_UP(x)	(((x) + PAGE_SIZE-1) >> L1_PAGETABLE_SHIFT)
   6.161 +#define PFN_DOWN(x)	((x) >> L1_PAGETABLE_SHIFT)
   6.162 +#define PFN_PHYS(x)	((x) << L1_PAGETABLE_SHIFT)
   6.163 +#define PHYS_PFN(x)	((x) >> L1_PAGETABLE_SHIFT)
   6.164 +
   6.165 +/* to align the pointer to the (next) page boundary */
   6.166 +#define PAGE_ALIGN(addr)        (((addr)+PAGE_SIZE-1)&PAGE_MASK)
   6.167 +
   6.168 +/* Definitions for machine and pseudophysical addresses. */
   6.169 +#ifdef CONFIG_X86_PAE
   6.170 +typedef unsigned long long paddr_t;
   6.171 +typedef unsigned long long maddr_t;
   6.172 +#else
   6.173 +typedef unsigned long paddr_t;
   6.174 +typedef unsigned long maddr_t;
   6.175 +#endif
   6.176 +
   6.177 +extern unsigned long *phys_to_machine_mapping;
   6.178 +extern char _text, _etext, _edata, _end;
   6.179 +#define pfn_to_mfn(_pfn) (phys_to_machine_mapping[(_pfn)])
   6.180 +static __inline__ maddr_t phys_to_machine(paddr_t phys)
   6.181 +{
   6.182 +	maddr_t machine = pfn_to_mfn(phys >> PAGE_SHIFT);
   6.183 +	machine = (machine << PAGE_SHIFT) | (phys & ~PAGE_MASK);
   6.184 +	return machine;
   6.185 +}
   6.186 +
   6.187 +#define mfn_to_pfn(_mfn) (machine_to_phys_mapping[(_mfn)])
   6.188 +static __inline__ paddr_t machine_to_phys(maddr_t machine)
   6.189 +{
   6.190 +	paddr_t phys = mfn_to_pfn(machine >> PAGE_SHIFT);
   6.191 +	phys = (phys << PAGE_SHIFT) | (machine & ~PAGE_MASK);
   6.192 +	return phys;
   6.193 +}
   6.194 +
   6.195 +#define VIRT_START                 ((unsigned long)&_text)
   6.196 +
   6.197 +#define to_phys(x)                 ((unsigned long)(x)-VIRT_START)
   6.198 +#define to_virt(x)                 ((void *)((unsigned long)(x)+VIRT_START))
   6.199 +
   6.200 +#define virt_to_pfn(_virt)         (PFN_DOWN(to_phys(_virt)))
   6.201 +#define virt_to_mfn(_virt)         (pfn_to_mfn(virt_to_pfn(_virt)))
   6.202 +#define mach_to_virt(_mach)        (to_virt(machine_to_phys(_mach)))
   6.203 +#define virt_to_mach(_virt)        (phys_to_machine(to_phys(_virt)))
   6.204 +#define mfn_to_virt(_mfn)          (to_virt(mfn_to_pfn(_mfn) << PAGE_SHIFT))
   6.205 +#define pfn_to_virt(_pfn)          (to_virt((_pfn) << PAGE_SHIFT))
   6.206 +
   6.207 +/* Pagetable walking. */
   6.208 +#define pte_to_mfn(_pte)           (((_pte) & (PADDR_MASK&PAGE_MASK)) >> L1_PAGETABLE_SHIFT)
   6.209 +#define pte_to_virt(_pte)          to_virt(mfn_to_pfn(pte_to_mfn(_pte)) << PAGE_SHIFT)
   6.210 +
   6.211 +
   6.212 +#endif /* _ARCH_MM_H_ */
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/extras/mini-os/include/x86/arch_sched.h	Wed Nov 22 10:11:36 2006 +0000
     7.3 @@ -0,0 +1,58 @@
     7.4 +
     7.5 +#ifndef __ARCH_SCHED_H__
     7.6 +#define __ARCH_SCHED_H__
     7.7 +
     7.8 +
     7.9 +static inline struct thread* get_current(void)
    7.10 +{
    7.11 +    struct thread **current;
    7.12 +#ifdef __i386__    
    7.13 +    __asm__("andl %%esp,%0; ":"=r" (current) : "r" (~8191UL));
    7.14 +#else
    7.15 +    __asm__("andq %%rsp,%0; ":"=r" (current) : "r" (~8191UL));
    7.16 +#endif 
    7.17 +    return *current;
    7.18 +}
    7.19 +
    7.20 +#ifdef __i386__
    7.21 +#define arch_switch_threads(prev, next) do {                            \
    7.22 +    unsigned long esi,edi;                                              \
    7.23 +    __asm__ __volatile__("pushfl\n\t"                                   \
    7.24 +                         "pushl %%ebp\n\t"                              \
    7.25 +                         "movl %%esp,%0\n\t"         /* save ESP */     \
    7.26 +                         "movl %4,%%esp\n\t"        /* restore ESP */   \
    7.27 +                         "movl $1f,%1\n\t"          /* save EIP */      \
    7.28 +                         "pushl %5\n\t"             /* restore EIP */   \
    7.29 +                         "ret\n\t"                                      \
    7.30 +                         "1:\t"                                         \
    7.31 +                         "popl %%ebp\n\t"                               \
    7.32 +                         "popfl"                                        \
    7.33 +                         :"=m" (prev->sp),"=m" (prev->ip),            \
    7.34 +                          "=S" (esi),"=D" (edi)             \
    7.35 +                         :"m" (next->sp),"m" (next->ip),              \
    7.36 +                          "2" (prev), "d" (next));                      \
    7.37 +} while (0)
    7.38 +#elif __x86_64__
    7.39 +#define arch_switch_threads(prev, next) do {                                 \
    7.40 +    unsigned long rsi,rdi;                                              \
    7.41 +    __asm__ __volatile__("pushfq\n\t"                                   \
    7.42 +                         "pushq %%rbp\n\t"                              \
    7.43 +                         "movq %%rsp,%0\n\t"         /* save RSP */     \
    7.44 +                         "movq %4,%%rsp\n\t"        /* restore RSP */   \
    7.45 +                         "movq $1f,%1\n\t"          /* save RIP */      \
    7.46 +                         "pushq %5\n\t"             /* restore RIP */   \
    7.47 +                         "ret\n\t"                                      \
    7.48 +                         "1:\t"                                         \
    7.49 +                         "popq %%rbp\n\t"                               \
    7.50 +                         "popfq"                                        \
    7.51 +                         :"=m" (prev->sp),"=m" (prev->ip),            \
    7.52 +                          "=S" (rsi),"=D" (rdi)             \
    7.53 +                         :"m" (next->sp),"m" (next->ip),              \
    7.54 +                          "2" (prev), "d" (next));                      \
    7.55 +} while (0)
    7.56 +#endif
    7.57 +
    7.58 +
    7.59 +
    7.60 +          
    7.61 +#endif /* __ARCH_SCHED_H__ */
     8.1 --- a/extras/mini-os/mm.c	Wed Nov 22 10:10:29 2006 +0000
     8.2 +++ b/extras/mini-os/mm.c	Wed Nov 22 10:11:36 2006 +0000
     8.3 @@ -48,10 +48,6 @@
     8.4  #define DEBUG(_f, _a...)    ((void)0)
     8.5  #endif
     8.6  
     8.7 -unsigned long *phys_to_machine_mapping;
     8.8 -extern char *stack;
     8.9 -extern void page_walk(unsigned long virt_addr);
    8.10 -
    8.11  /*********************
    8.12   * ALLOCATION BITMAP
    8.13   *  One bit per page of memory. Bit set => page is allocated.
    8.14 @@ -226,11 +222,11 @@ static void init_page_allocator(unsigned
    8.15      /* All allocated by default. */
    8.16      memset(alloc_bitmap, ~0, bitmap_size);
    8.17      /* Free up the memory we've been given to play with. */
    8.18 -    map_free(min>>PAGE_SHIFT, range>>PAGE_SHIFT);
    8.19 +    map_free(PHYS_PFN(min), range>>PAGE_SHIFT);
    8.20  
    8.21      /* The buddy lists are addressed in high memory. */
    8.22 -    min += VIRT_START;
    8.23 -    max += VIRT_START;
    8.24 +    min = (unsigned long) to_virt(min);
    8.25 +    max = (unsigned long) to_virt(max);
    8.26  
    8.27      while ( range != 0 )
    8.28      {
    8.29 @@ -297,7 +293,7 @@ unsigned long alloc_pages(int order)
    8.30          free_head[i] = spare_ch;
    8.31      }
    8.32      
    8.33 -    map_alloc(to_phys(alloc_ch)>>PAGE_SHIFT, 1<<order);
    8.34 +    map_alloc(PHYS_PFN(to_phys(alloc_ch)), 1<<order);
    8.35  
    8.36      return((unsigned long)alloc_ch);
    8.37  
    8.38 @@ -365,350 +361,6 @@ void free_pages(void *pointer, int order
    8.39  }
    8.40  
    8.41  
    8.42 -void new_pt_frame(unsigned long *pt_pfn, unsigned long prev_l_mfn, 
    8.43 -                                unsigned long offset, unsigned long level)
    8.44 -{   
    8.45 -    pgentry_t *tab = (pgentry_t *)start_info.pt_base;
    8.46 -    unsigned long pt_page = (unsigned long)pfn_to_virt(*pt_pfn); 
    8.47 -    unsigned long prot_e, prot_t, pincmd;
    8.48 -    mmu_update_t mmu_updates[1];
    8.49 -    struct mmuext_op pin_request;
    8.50 -    
    8.51 -    DEBUG("Allocating new L%d pt frame for pt_pfn=%lx, "
    8.52 -           "prev_l_mfn=%lx, offset=%lx", 
    8.53 -           level, *pt_pfn, prev_l_mfn, offset);
    8.54 -
    8.55 -    /* We need to clear the page, otherwise we might fail to map it
    8.56 -       as a page table page */
    8.57 -    memset((unsigned long*)pfn_to_virt(*pt_pfn), 0, PAGE_SIZE);  
    8.58 - 
    8.59 -    switch ( level )
    8.60 -    {
    8.61 -    case L1_FRAME:
    8.62 -         prot_e = L1_PROT;
    8.63 -         prot_t = L2_PROT;
    8.64 -         pincmd = MMUEXT_PIN_L1_TABLE;
    8.65 -         break;
    8.66 -#if defined(__x86_64__) || defined(CONFIG_X86_PAE)
    8.67 -    case L2_FRAME:
    8.68 -         prot_e = L2_PROT;
    8.69 -         prot_t = L3_PROT;
    8.70 -         pincmd = MMUEXT_PIN_L2_TABLE;
    8.71 -         break;
    8.72 -#endif
    8.73 -#if defined(__x86_64__)
    8.74 -    case L3_FRAME:
    8.75 -         prot_e = L3_PROT;
    8.76 -         prot_t = L4_PROT;
    8.77 -         pincmd = MMUEXT_PIN_L3_TABLE;
    8.78 -         break;
    8.79 -#endif
    8.80 -    default:
    8.81 -         printk("new_pt_frame() called with invalid level number %d\n", level);
    8.82 -         do_exit();
    8.83 -         break;
    8.84 -    }
    8.85 -    /* Update the entry */
    8.86 -#if defined(__x86_64__)
    8.87 -    tab = pte_to_virt(tab[l4_table_offset(pt_page)]);
    8.88 -    tab = pte_to_virt(tab[l3_table_offset(pt_page)]);
    8.89 -#endif
    8.90 -#if defined(CONFIG_X86_PAE)
    8.91 -    tab = pte_to_virt(tab[l3_table_offset(pt_page)]);
    8.92 -#endif
    8.93 -
    8.94 -    mmu_updates[0].ptr = ((pgentry_t)tab[l2_table_offset(pt_page)] & PAGE_MASK) + 
    8.95 -                         sizeof(pgentry_t) * l1_table_offset(pt_page);
    8.96 -    mmu_updates[0].val = (pgentry_t)pfn_to_mfn(*pt_pfn) << PAGE_SHIFT | 
    8.97 -                         (prot_e & ~_PAGE_RW);
    8.98 -    if(HYPERVISOR_mmu_update(mmu_updates, 1, NULL, DOMID_SELF) < 0)
    8.99 -    {
   8.100 -         printk("PTE for new page table page could not be updated\n");
   8.101 -         do_exit();
   8.102 -    }
   8.103 -                        
   8.104 -    /* Pin the page to provide correct protection */
   8.105 -    pin_request.cmd = pincmd;
   8.106 -    pin_request.arg1.mfn = pfn_to_mfn(*pt_pfn);
   8.107 -    if(HYPERVISOR_mmuext_op(&pin_request, 1, NULL, DOMID_SELF) < 0)
   8.108 -    {
   8.109 -        printk("ERROR: pinning failed\n");
   8.110 -        do_exit();
   8.111 -    }
   8.112 -
   8.113 -    /* Now fill the new page table page with entries.
   8.114 -       Update the page directory as well. */
   8.115 -    mmu_updates[0].ptr = ((pgentry_t)prev_l_mfn << PAGE_SHIFT) + sizeof(pgentry_t) * offset;
   8.116 -    mmu_updates[0].val = (pgentry_t)pfn_to_mfn(*pt_pfn) << PAGE_SHIFT | prot_t;
   8.117 -    if(HYPERVISOR_mmu_update(mmu_updates, 1, NULL, DOMID_SELF) < 0) 
   8.118 -    {
   8.119 -       printk("ERROR: mmu_update failed\n");
   8.120 -       do_exit();
   8.121 -    }
   8.122 -    *pt_pfn += 1;
   8.123 -}
   8.124 -
   8.125 -/* Checks if a pagetable frame is needed (if weren't allocated by Xen) */
   8.126 -static int need_pt_frame(unsigned long virt_address, int level)
   8.127 -{
   8.128 -    unsigned long hyp_virt_start = HYPERVISOR_VIRT_START;
   8.129 -#if defined(__x86_64__)
   8.130 -    unsigned long hyp_virt_end = HYPERVISOR_VIRT_END;
   8.131 -#else
   8.132 -    unsigned long hyp_virt_end = 0xffffffff;
   8.133 -#endif
   8.134 -
   8.135 -    /* In general frames will _not_ be needed if they were already
   8.136 -       allocated to map the hypervisor into our VA space */
   8.137 -#if defined(__x86_64__)
   8.138 -    if(level == L3_FRAME)
   8.139 -    {
   8.140 -        if(l4_table_offset(virt_address) >= 
   8.141 -           l4_table_offset(hyp_virt_start) &&
   8.142 -           l4_table_offset(virt_address) <= 
   8.143 -           l4_table_offset(hyp_virt_end))
   8.144 -            return 0;
   8.145 -        return 1;
   8.146 -    } else
   8.147 -#endif
   8.148 -
   8.149 -#if defined(__x86_64__) || defined(CONFIG_X86_PAE)
   8.150 -    if(level == L2_FRAME)
   8.151 -    {
   8.152 -#if defined(__x86_64__)
   8.153 -        if(l4_table_offset(virt_address) >= 
   8.154 -           l4_table_offset(hyp_virt_start) &&
   8.155 -           l4_table_offset(virt_address) <= 
   8.156 -           l4_table_offset(hyp_virt_end))
   8.157 -#endif
   8.158 -            if(l3_table_offset(virt_address) >= 
   8.159 -               l3_table_offset(hyp_virt_start) &&
   8.160 -               l3_table_offset(virt_address) <= 
   8.161 -               l3_table_offset(hyp_virt_end))
   8.162 -                return 0;
   8.163 -
   8.164 -        return 1;
   8.165 -    } else 
   8.166 -#endif /* defined(__x86_64__) || defined(CONFIG_X86_PAE) */
   8.167 -
   8.168 -    /* Always need l1 frames */
   8.169 -    if(level == L1_FRAME)
   8.170 -        return 1;
   8.171 -
   8.172 -    printk("ERROR: Unknown frame level %d, hypervisor %llx,%llx\n", 
   8.173 -        level, hyp_virt_start, hyp_virt_end);
   8.174 -    return -1;
   8.175 -}
   8.176 -
   8.177 -void build_pagetable(unsigned long *start_pfn, unsigned long *max_pfn)
   8.178 -{
   8.179 -    unsigned long start_address, end_address;
   8.180 -    unsigned long pfn_to_map, pt_pfn = *start_pfn;
   8.181 -    static mmu_update_t mmu_updates[L1_PAGETABLE_ENTRIES + 1];
   8.182 -    pgentry_t *tab = (pgentry_t *)start_info.pt_base, page;
   8.183 -    unsigned long mfn = pfn_to_mfn(virt_to_pfn(start_info.pt_base));
   8.184 -    unsigned long offset;
   8.185 -    int count = 0;
   8.186 -
   8.187 -    pfn_to_map = (start_info.nr_pt_frames - NOT_L1_FRAMES) * L1_PAGETABLE_ENTRIES;
   8.188 -
   8.189 -    if (*max_pfn >= virt_to_pfn(HYPERVISOR_VIRT_START))
   8.190 -    {
   8.191 -        printk("WARNING: Mini-OS trying to use Xen virtual space. "
   8.192 -               "Truncating memory from %dMB to ",
   8.193 -               ((unsigned long)pfn_to_virt(*max_pfn) - (unsigned long)&_text)>>20);
   8.194 -        *max_pfn = virt_to_pfn(HYPERVISOR_VIRT_START - PAGE_SIZE);
   8.195 -        printk("%dMB\n",
   8.196 -               ((unsigned long)pfn_to_virt(*max_pfn) - (unsigned long)&_text)>>20);
   8.197 -    }
   8.198 -
   8.199 -    start_address = (unsigned long)pfn_to_virt(pfn_to_map);
   8.200 -    end_address = (unsigned long)pfn_to_virt(*max_pfn);
   8.201 -
   8.202 -    /* We worked out the virtual memory range to map, now mapping loop */
   8.203 -    printk("Mapping memory range 0x%lx - 0x%lx\n", start_address, end_address);
   8.204 -
   8.205 -    while(start_address < end_address)
   8.206 -    {
   8.207 -        tab = (pgentry_t *)start_info.pt_base;
   8.208 -        mfn = pfn_to_mfn(virt_to_pfn(start_info.pt_base));
   8.209 -
   8.210 -#if defined(__x86_64__)
   8.211 -        offset = l4_table_offset(start_address);
   8.212 -        /* Need new L3 pt frame */
   8.213 -        if(!(start_address & L3_MASK)) 
   8.214 -            if(need_pt_frame(start_address, L3_FRAME)) 
   8.215 -                new_pt_frame(&pt_pfn, mfn, offset, L3_FRAME);
   8.216 -
   8.217 -        page = tab[offset];
   8.218 -        mfn = pte_to_mfn(page);
   8.219 -        tab = to_virt(mfn_to_pfn(mfn) << PAGE_SHIFT);
   8.220 -#endif
   8.221 -#if defined(__x86_64__) || defined(CONFIG_X86_PAE)
   8.222 -        offset = l3_table_offset(start_address);
   8.223 -        /* Need new L2 pt frame */
   8.224 -        if(!(start_address & L2_MASK))
   8.225 -            if(need_pt_frame(start_address, L2_FRAME))
   8.226 -                new_pt_frame(&pt_pfn, mfn, offset, L2_FRAME);
   8.227 -
   8.228 -        page = tab[offset];
   8.229 -        mfn = pte_to_mfn(page);
   8.230 -        tab = to_virt(mfn_to_pfn(mfn) << PAGE_SHIFT);
   8.231 -#endif
   8.232 -        offset = l2_table_offset(start_address);        
   8.233 -        /* Need new L1 pt frame */
   8.234 -        if(!(start_address & L1_MASK))
   8.235 -            if(need_pt_frame(start_address, L1_FRAME)) 
   8.236 -                new_pt_frame(&pt_pfn, mfn, offset, L1_FRAME);
   8.237 -
   8.238 -        page = tab[offset];
   8.239 -        mfn = pte_to_mfn(page);
   8.240 -        offset = l1_table_offset(start_address);
   8.241 -
   8.242 -        mmu_updates[count].ptr = ((pgentry_t)mfn << PAGE_SHIFT) + sizeof(pgentry_t) * offset;
   8.243 -        mmu_updates[count].val = (pgentry_t)pfn_to_mfn(pfn_to_map++) << PAGE_SHIFT | L1_PROT;
   8.244 -        count++;
   8.245 -        if (count == L1_PAGETABLE_ENTRIES || pfn_to_map == *max_pfn)
   8.246 -        {
   8.247 -            if(HYPERVISOR_mmu_update(mmu_updates, count, NULL, DOMID_SELF) < 0)
   8.248 -            {
   8.249 -                printk("PTE could not be updated\n");
   8.250 -                do_exit();
   8.251 -            }
   8.252 -            count = 0;
   8.253 -        }
   8.254 -        start_address += PAGE_SIZE;
   8.255 -    }
   8.256 -    *start_pfn = pt_pfn;
   8.257 -}
   8.258 -
   8.259 -
   8.260 -void mem_test(unsigned long *start_add, unsigned long *end_add)
   8.261 -{
   8.262 -    unsigned long mask = 0x10000;
   8.263 -    unsigned long *pointer;
   8.264 -
   8.265 -    for(pointer = start_add; pointer < end_add; pointer++)
   8.266 -    {
   8.267 -        if(!(((unsigned long)pointer) & 0xfffff))
   8.268 -        {
   8.269 -            printk("Writing to %lx\n", pointer);
   8.270 -            page_walk((unsigned long)pointer);
   8.271 -        }
   8.272 -        *pointer = (unsigned long)pointer & ~mask;
   8.273 -    }
   8.274 -
   8.275 -    for(pointer = start_add; pointer < end_add; pointer++)
   8.276 -    {
   8.277 -        if(((unsigned long)pointer & ~mask) != *pointer)
   8.278 -            printk("Read error at 0x%lx. Read: 0x%lx, should read 0x%lx\n",
   8.279 -                (unsigned long)pointer, 
   8.280 -                *pointer, 
   8.281 -                ((unsigned long)pointer & ~mask));
   8.282 -    }
   8.283 -
   8.284 -}
   8.285 -
   8.286 -static pgentry_t *demand_map_pgt;
   8.287 -static void *demand_map_area_start;
   8.288 -
   8.289 -static void init_demand_mapping_area(unsigned long max_pfn)
   8.290 -{
   8.291 -    unsigned long mfn;
   8.292 -    pgentry_t *tab;
   8.293 -    unsigned long start_addr;
   8.294 -    unsigned long pt_pfn;
   8.295 -    unsigned offset;
   8.296 -
   8.297 -    /* Round up to four megs.  + 1024 rather than + 1023 since we want
   8.298 -       to be sure we don't end up in the same place we started. */
   8.299 -    max_pfn = (max_pfn + L1_PAGETABLE_ENTRIES) & ~(L1_PAGETABLE_ENTRIES - 1);
   8.300 -    if (max_pfn == 0 ||
   8.301 -            (unsigned long)pfn_to_virt(max_pfn + L1_PAGETABLE_ENTRIES) >=
   8.302 -            HYPERVISOR_VIRT_START) {
   8.303 -        printk("Too much memory; no room for demand map hole.\n");
   8.304 -        do_exit();
   8.305 -    }
   8.306 -
   8.307 -    demand_map_area_start = pfn_to_virt(max_pfn);
   8.308 -    printk("Demand map pfns start at %lx (%p).\n", max_pfn,
   8.309 -            demand_map_area_start);
   8.310 -    start_addr = (unsigned long)demand_map_area_start;
   8.311 -
   8.312 -    tab = (pgentry_t *)start_info.pt_base;
   8.313 -    mfn = virt_to_mfn(start_info.pt_base);
   8.314 -    pt_pfn = virt_to_pfn(alloc_page());
   8.315 -
   8.316 -#if defined(__x86_64__)
   8.317 -    offset = l4_table_offset(start_addr);
   8.318 -    if (!(tab[offset] & _PAGE_PRESENT)) {
   8.319 -        new_pt_frame(&pt_pfn, mfn, offset, L3_FRAME);
   8.320 -        pt_pfn = virt_to_pfn(alloc_page());
   8.321 -    }
   8.322 -    ASSERT(tab[offset] & _PAGE_PRESENT);
   8.323 -    mfn = pte_to_mfn(tab[offset]);
   8.324 -    tab = to_virt(mfn_to_pfn(mfn) << PAGE_SHIFT);
   8.325 -#endif
   8.326 -#if defined(__x86_64__) || defined(CONFIG_X86_PAE)
   8.327 -    offset = l3_table_offset(start_addr);
   8.328 -    if (!(tab[offset] & _PAGE_PRESENT)) {
   8.329 -        new_pt_frame(&pt_pfn, mfn, offset, L2_FRAME);
   8.330 -        pt_pfn = virt_to_pfn(alloc_page());
   8.331 -    }
   8.332 -    ASSERT(tab[offset] & _PAGE_PRESENT);
   8.333 -    mfn = pte_to_mfn(tab[offset]);
   8.334 -    tab = to_virt(mfn_to_pfn(mfn) << PAGE_SHIFT);
   8.335 -#endif
   8.336 -    offset = l2_table_offset(start_addr);
   8.337 -    if (tab[offset] & _PAGE_PRESENT) {
   8.338 -        printk("Demand map area already has a page table covering it?\n");
   8.339 -        BUG();
   8.340 -    }
   8.341 -    demand_map_pgt = pfn_to_virt(pt_pfn);
   8.342 -    new_pt_frame(&pt_pfn, mfn, offset, L1_FRAME);
   8.343 -    ASSERT(tab[offset] & _PAGE_PRESENT);
   8.344 -}
   8.345 -
   8.346 -void *map_frames(unsigned long *f, unsigned long n)
   8.347 -{
   8.348 -    unsigned long x;
   8.349 -    unsigned long y = 0;
   8.350 -    mmu_update_t mmu_updates[16];
   8.351 -    int rc;
   8.352 -
   8.353 -    if (n > 16) {
   8.354 -        printk("Tried to map too many (%ld) frames at once.\n", n);
   8.355 -        return NULL;
   8.356 -    }
   8.357 -
   8.358 -    /* Find a run of n contiguous frames */
   8.359 -    for (x = 0; x <= 1024 - n; x += y + 1) {
   8.360 -        for (y = 0; y < n; y++)
   8.361 -            if (demand_map_pgt[x+y] & _PAGE_PRESENT)
   8.362 -                break;
   8.363 -        if (y == n)
   8.364 -            break;
   8.365 -    }
   8.366 -    if (y != n) {
   8.367 -        printk("Failed to map %ld frames!\n", n);
   8.368 -        return NULL;
   8.369 -    }
   8.370 -
   8.371 -    /* Found it at x.  Map it in. */
   8.372 -    for (y = 0; y < n; y++) {
   8.373 -        mmu_updates[y].ptr = virt_to_mach(&demand_map_pgt[x + y]);
   8.374 -        mmu_updates[y].val = (f[y] << PAGE_SHIFT) | L1_PROT;
   8.375 -    }
   8.376 -
   8.377 -    rc = HYPERVISOR_mmu_update(mmu_updates, n, NULL, DOMID_SELF);
   8.378 -    if (rc < 0) {
   8.379 -        printk("Map %ld failed: %d.\n", n, rc);
   8.380 -        return NULL;
   8.381 -    } else {
   8.382 -        return (void *)(unsigned long)((unsigned long)demand_map_area_start +
   8.383 -                x * PAGE_SIZE);
   8.384 -    }
   8.385 -}
   8.386  
   8.387  void init_mm(void)
   8.388  {
   8.389 @@ -717,22 +369,7 @@ void init_mm(void)
   8.390  
   8.391      printk("MM: Init\n");
   8.392  
   8.393 -    printk("  _text:        %p\n", &_text);
   8.394 -    printk("  _etext:       %p\n", &_etext);
   8.395 -    printk("  _edata:       %p\n", &_edata);
   8.396 -    printk("  stack start:  %p\n", &stack);
   8.397 -    printk("  _end:         %p\n", &_end);
   8.398 -
   8.399 -    /* First page follows page table pages and 3 more pages (store page etc) */
   8.400 -    start_pfn = PFN_UP(to_phys(start_info.pt_base)) + 
   8.401 -                start_info.nr_pt_frames + 3;
   8.402 -    max_pfn = start_info.nr_pages;
   8.403 -   
   8.404 -    printk("  start_pfn:    %lx\n", start_pfn);
   8.405 -    printk("  max_pfn:      %lx\n", max_pfn);
   8.406 -
   8.407 -    build_pagetable(&start_pfn, &max_pfn);
   8.408 -
   8.409 +    arch_init_mm(&start_pfn, &max_pfn);
   8.410      /*
   8.411       * now we can initialise the page allocator
   8.412       */
   8.413 @@ -742,8 +379,7 @@ void init_mm(void)
   8.414      init_page_allocator(PFN_PHYS(start_pfn), PFN_PHYS(max_pfn));
   8.415      printk("MM: done\n");
   8.416  
   8.417 -    init_demand_mapping_area(max_pfn);
   8.418 -    printk("Initialised demand area.\n");
   8.419 +    arch_init_demand_mapping_area(max_pfn);
   8.420  }
   8.421  
   8.422  void sanity_check(void)
     9.1 --- a/extras/mini-os/sched.c	Wed Nov 22 10:10:29 2006 +0000
     9.2 +++ b/extras/mini-os/sched.c	Wed Nov 22 10:11:36 2006 +0000
     9.3 @@ -54,82 +54,9 @@
     9.4  #define DEBUG(_f, _a...)    ((void)0)
     9.5  #endif
     9.6  
     9.7 -
     9.8 -#define RUNNABLE_FLAG   0x00000001
     9.9 -
    9.10 -#define is_runnable(_thread)    (_thread->flags & RUNNABLE_FLAG)
    9.11 -#define set_runnable(_thread)   (_thread->flags |= RUNNABLE_FLAG)
    9.12 -#define clear_runnable(_thread) (_thread->flags &= ~RUNNABLE_FLAG)
    9.13 -
    9.14 -
    9.15  struct thread *idle_thread = NULL;
    9.16  LIST_HEAD(exited_threads);
    9.17  
    9.18 -void idle_thread_fn(void *unused);
    9.19 -
    9.20 -void dump_stack(struct thread *thread)
    9.21 -{
    9.22 -    unsigned long *bottom = (unsigned long *)(thread->stack + 2*4*1024); 
    9.23 -    unsigned long *pointer = (unsigned long *)thread->sp;
    9.24 -    int count;
    9.25 -    if(thread == current)
    9.26 -    {
    9.27 -#ifdef __i386__    
    9.28 -        asm("movl %%esp,%0"
    9.29 -            : "=r"(pointer));
    9.30 -#else
    9.31 -        asm("movq %%rsp,%0"
    9.32 -            : "=r"(pointer));
    9.33 -#endif
    9.34 -    }
    9.35 -    printk("The stack for \"%s\"\n", thread->name);
    9.36 -    for(count = 0; count < 25 && pointer < bottom; count ++)
    9.37 -    {
    9.38 -        printk("[0x%lx] 0x%lx\n", pointer, *pointer);
    9.39 -        pointer++;
    9.40 -    }
    9.41 -    
    9.42 -    if(pointer < bottom) printk(" ... continues.\n");
    9.43 -}
    9.44 -
    9.45 -#ifdef __i386__
    9.46 -#define switch_threads(prev, next) do {                                 \
    9.47 -    unsigned long esi,edi;                                              \
    9.48 -    __asm__ __volatile__("pushfl\n\t"                                   \
    9.49 -                         "pushl %%ebp\n\t"                              \
    9.50 -                         "movl %%esp,%0\n\t"         /* save ESP */     \
    9.51 -                         "movl %4,%%esp\n\t"        /* restore ESP */   \
    9.52 -                         "movl $1f,%1\n\t"          /* save EIP */      \
    9.53 -                         "pushl %5\n\t"             /* restore EIP */   \
    9.54 -                         "ret\n\t"                                      \
    9.55 -                         "1:\t"                                         \
    9.56 -                         "popl %%ebp\n\t"                               \
    9.57 -                         "popfl"                                        \
    9.58 -                         :"=m" (prev->sp),"=m" (prev->ip),            \
    9.59 -                          "=S" (esi),"=D" (edi)             \
    9.60 -                         :"m" (next->sp),"m" (next->ip),              \
    9.61 -                          "2" (prev), "d" (next));                      \
    9.62 -} while (0)
    9.63 -#elif __x86_64__
    9.64 -#define switch_threads(prev, next) do {                                 \
    9.65 -    unsigned long rsi,rdi;                                              \
    9.66 -    __asm__ __volatile__("pushfq\n\t"                                   \
    9.67 -                         "pushq %%rbp\n\t"                              \
    9.68 -                         "movq %%rsp,%0\n\t"         /* save RSP */     \
    9.69 -                         "movq %4,%%rsp\n\t"        /* restore RSP */   \
    9.70 -                         "movq $1f,%1\n\t"          /* save RIP */      \
    9.71 -                         "pushq %5\n\t"             /* restore RIP */   \
    9.72 -                         "ret\n\t"                                      \
    9.73 -                         "1:\t"                                         \
    9.74 -                         "popq %%rbp\n\t"                               \
    9.75 -                         "popfq"                                        \
    9.76 -                         :"=m" (prev->sp),"=m" (prev->ip),            \
    9.77 -                          "=S" (rsi),"=D" (rdi)             \
    9.78 -                         :"m" (next->sp),"m" (next->ip),              \
    9.79 -                          "2" (prev), "d" (next));                      \
    9.80 -} while (0)
    9.81 -#endif
    9.82 -
    9.83  void inline print_runqueue(void)
    9.84  {
    9.85      struct list_head *it;
    9.86 @@ -250,50 +177,6 @@ void exit_thread(void)
    9.87      schedule();
    9.88  }
    9.89  
    9.90 -/* Pushes the specified value onto the stack of the specified thread */
    9.91 -static void stack_push(struct thread *thread, unsigned long value)
    9.92 -{
    9.93 -    thread->sp -= sizeof(unsigned long);
    9.94 -    *((unsigned long *)thread->sp) = value;
    9.95 -}
    9.96 -
    9.97 -struct thread* create_thread(char *name, void (*function)(void *), void *data)
    9.98 -{
    9.99 -    struct thread *thread;
   9.100 -    unsigned long flags;
   9.101 -    
   9.102 -    thread = xmalloc(struct thread);
   9.103 -    /* Allocate 2 pages for stack, stack will be 2pages aligned */
   9.104 -    thread->stack = (char *)alloc_pages(1);
   9.105 -    thread->name = name;
   9.106 -    printk("Thread \"%s\": pointer: 0x%lx, stack: 0x%lx\n", name, thread, 
   9.107 -            thread->stack);
   9.108 -    
   9.109 -    thread->sp = (unsigned long)thread->stack + 4096 * 2;
   9.110 -    /* Save pointer to the thread on the stack, used by current macro */
   9.111 -    *((unsigned long *)thread->stack) = (unsigned long)thread;
   9.112 -    
   9.113 -    stack_push(thread, (unsigned long) function);
   9.114 -    stack_push(thread, (unsigned long) data);
   9.115 -    thread->ip = (unsigned long) thread_starter;
   9.116 -     
   9.117 -    /* Not runable, not exited, not sleeping */
   9.118 -    thread->flags = 0;
   9.119 -    thread->wakeup_time = 0LL;
   9.120 -    set_runnable(thread);
   9.121 -    local_irq_save(flags);
   9.122 -    if(idle_thread != NULL) {
   9.123 -        list_add_tail(&thread->thread_list, &idle_thread->thread_list); 
   9.124 -    } else if(function != idle_thread_fn)
   9.125 -    {
   9.126 -        printk("BUG: Not allowed to create thread before initialising scheduler.\n");
   9.127 -        BUG();
   9.128 -    }
   9.129 -    local_irq_restore(flags);
   9.130 -    return thread;
   9.131 -}
   9.132 -
   9.133 -
   9.134  void block(struct thread *thread)
   9.135  {
   9.136      thread->wakeup_time = 0LL;
   9.137 @@ -327,26 +210,6 @@ void idle_thread_fn(void *unused)
   9.138      }
   9.139  }
   9.140  
   9.141 -void run_idle_thread(void)
   9.142 -{
   9.143 -    /* Switch stacks and run the thread */ 
   9.144 -#if defined(__i386__)
   9.145 -    __asm__ __volatile__("mov %0,%%esp\n\t"
   9.146 -                         "push %1\n\t" 
   9.147 -                         "ret"                                            
   9.148 -                         :"=m" (idle_thread->sp)
   9.149 -                         :"m" (idle_thread->ip));                          
   9.150 -#elif defined(__x86_64__)
   9.151 -    __asm__ __volatile__("mov %0,%%rsp\n\t"
   9.152 -                         "push %1\n\t" 
   9.153 -                         "ret"                                            
   9.154 -                         :"=m" (idle_thread->sp)
   9.155 -                         :"m" (idle_thread->ip));                                                    
   9.156 -#endif
   9.157 -}
   9.158 -
   9.159 -
   9.160 -
   9.161  DECLARE_MUTEX(mutex);
   9.162  
   9.163  void th_f1(void *data)