Reworks memlayout (XCC)
authorBarret Rhoden <brho@cs.berkeley.edu>
Mon, 17 Jun 2013 06:20:50 +0000 (23:20 -0700)
committerBarret Rhoden <brho@cs.berkeley.edu>
Sat, 22 Jun 2013 17:29:31 +0000 (10:29 -0700)
Adds a memlayout for 64 bit x86, and reworks it slightly for the other
arches.  Everyone needs to specify UVPT and BRK_END, for instance.

Probably should reinstall your kernel headers and rebuild userspace.

kern/arch/riscv/ros/mmu.h
kern/arch/x86/entry32.S
kern/arch/x86/entry64.S
kern/arch/x86/kdebug.c
kern/arch/x86/pmap64.c
kern/arch/x86/ros/mmu32.h
kern/arch/x86/ros/mmu64.h
kern/include/ros/memlayout.h
kern/src/process.c

index 14ebc79..43a9c43 100644 (file)
@@ -153,4 +153,11 @@ typedef unsigned long pte_t;
 typedef unsigned long pde_t;
 #endif
 
 typedef unsigned long pde_t;
 #endif
 
+/* Same as VPT but read-only for users */
+#define UVPT           (ULIM - PTSIZE)
+
+/* Arbitrary boundary between the break and the start of
+ * memory returned by calls to mmap with addr = 0 */
+#define BRK_END 0x40000000
+
 #endif /* ROS_INC_ARCH_MMU_H */
 #endif /* ROS_INC_ARCH_MMU_H */
index 1e6544e..c537e64 100644 (file)
@@ -6,9 +6,6 @@
 #include <arch/trap.h>
 #include <ros/memlayout.h>
 
 #include <arch/trap.h>
 #include <ros/memlayout.h>
 
-# Shift Right Logical 
-#define SRL(val, shamt)                (((val) >> (shamt)) & ~(-1 << (32 - (shamt))))
-
 .set CODE_SEL,0x8              # index of code seg within mygdt
 .set DATA_SEL,0x10             # index of data seg within mygdt
 
 .set CODE_SEL,0x8              # index of code seg within mygdt
 .set DATA_SEL,0x10             # index of data seg within mygdt
 
@@ -107,18 +104,7 @@ boot_pdt:
 
 # From here down is linked for KERNBASE
 
 
 # From here down is linked for KERNBASE
 
-###################################################################    
-# See <inc/memlayout.h> for a complete description of these two symbols.
-###################################################################
 .data
 .data
-       .globl  vpt
-       .set    vpt, VPT
-       .globl  vpd
-       .set    vpd, (VPT + SRL(VPT, 10))
-
-###################################################################
-# boot stack
-###################################################################
        .p2align        PGSHIFT         # force page alignment
        .globl          bootstack
 bootstack:
        .p2align        PGSHIFT         # force page alignment
        .globl          bootstack
 bootstack:
index 031a0ef..e6add3f 100644 (file)
@@ -7,9 +7,6 @@
 #include <arch/x86.h>
 #include <ros/memlayout.h>
 
 #include <arch/x86.h>
 #include <ros/memlayout.h>
 
-# Shift Right Logical 
-#define SRL(val, shamt)                (((val) >> (shamt)) & ~(-1 << (32 - (shamt))))
-
 #define MULTIBOOT_PAGE_ALIGN  (1<<0)
 #define MULTIBOOT_MEMORY_INFO (1<<1)
 #define MULTIBOOT_HEADER_MAGIC (0x1BADB002)
 #define MULTIBOOT_PAGE_ALIGN  (1<<0)
 #define MULTIBOOT_MEMORY_INFO (1<<1)
 #define MULTIBOOT_HEADER_MAGIC (0x1BADB002)
@@ -154,14 +151,6 @@ boot_pml3_kernbase:
 
 # From here down is linked for KERNBASE
 .data
 
 # From here down is linked for KERNBASE
 .data
-       # TODO: do we need these in asm?
-       .globl  vpt
-       .quad   vpt
-       .set    vpt, VPT
-       .globl  vpd
-       .quad   vpd
-       .set    vpd, (VPT + SRL(VPT, 10))
-
        .p2align        PGSHIFT         # force page alignment
        .globl          bootstack
 bootstack:
        .p2align        PGSHIFT         # force page alignment
        .globl          bootstack
 bootstack:
index 7c4b1f7..cb11235 100644 (file)
@@ -163,6 +163,7 @@ debuginfo_eip(uintptr_t addr, eipdebuginfo_t *NONNULL info)
                /* TODO: short circuiting this, til our user space apps pack stab data
                 * the kernel knows about */
                return -1;
                /* TODO: short circuiting this, til our user space apps pack stab data
                 * the kernel knows about */
                return -1;
+               #if 0
                // The user-application linker script, user/user.ld,
                // puts information about the application's stabs (equivalent
                // to __STAB_BEGIN__, __STAB_END__, __STABSTR_BEGIN__, and
                // The user-application linker script, user/user.ld,
                // puts information about the application's stabs (equivalent
                // to __STAB_BEGIN__, __STAB_END__, __STABSTR_BEGIN__, and
@@ -181,6 +182,7 @@ debuginfo_eip(uintptr_t addr, eipdebuginfo_t *NONNULL info)
 
                // Make sure the STABS and string table memory is valid.
                // LAB 3: Your code here.
 
                // Make sure the STABS and string table memory is valid.
                // LAB 3: Your code here.
+               #endif
        }
 
        if (!stab_table_valid(stabstr, stabstr_end))
        }
 
        if (!stab_table_valid(stabstr, stabstr_end))
index c62fe72..27cd546 100644 (file)
@@ -123,10 +123,32 @@ boot_map_segment(pde_t *COUNT(NPDENTRIES) pgdir, uintptr_t la, size_t size, phys
 //
 // From UWLIM to ULIM, the user is allowed to read but not write.
 // Above ULIM the user cannot read (or write). 
 //
 // From UWLIM to ULIM, the user is allowed to read but not write.
 // Above ULIM the user cannot read (or write). 
-void
-vm_init(void)
+
+#define check_sym_va(sym, addr)                                                \
+({                                                                             \
+       if ((sym) != (addr))                                                       \
+               printk("Error: " #sym " is %p, should be " #addr "\n", sym);           \
+})
+
+void vm_init(void)
 {
 {
-// TODO: do this
+       /* Make sure our symbols are up to date (see arch/ros/mmu64.h) */
+       check_sym_va(KERN_LOAD_ADDR, 0xffffffffc0000000);
+       check_sym_va(LAPIC_BASE,     0xffffffffbffff000);
+       check_sym_va(IOAPIC_BASE,    0xffffffffbfffe000);
+       check_sym_va(VPT_TOP,        0xffffff0000000000);
+       check_sym_va(VPT,            0xfffffe8000000000);
+       check_sym_va(KERN_VMAP_TOP,  0xfffffe8000000000);
+       check_sym_va(KERNBASE,       0xffff800000000000);
+       check_sym_va(ULIM,           0x0000800000000000);
+       check_sym_va(UVPT,           0x00007f8000000000);
+       check_sym_va(UINFO,          0x00007f7fffe00000);
+       check_sym_va(UWLIM,          0x00007f7fffe00000);
+       check_sym_va(UDATA,          0x00007f7fffc00000);
+       check_sym_va(UGDATA,         0x00007f7fffbff000);
+       check_sym_va(UMAPTOP,        0x00007f7fffbff000);
+       check_sym_va(USTACKTOP,      0x00007f7fffbff000);
+       check_sym_va(BRK_END,        0x0000400000000000);
        return;
 
        pde_t* pgdir;
        return;
 
        pde_t* pgdir;
@@ -144,7 +166,7 @@ vm_init(void)
        lcr4(rcr4() | CR4_PGE);
 
        // set up mtrr's for core0.  other cores will do the same later
        lcr4(rcr4() | CR4_PGE);
 
        // set up mtrr's for core0.  other cores will do the same later
-       // XXX this will break c89
+// XXX this will break c89
        setup_default_mtrrs(0);
 
        /*
        setup_default_mtrrs(0);
 
        /*
@@ -664,11 +686,11 @@ int env_user_mem_walk(env_t* e, void* start, size_t len,
                uintptr_t pteno_end = (pdeno == pdeno_end - 1 && PTX(end) != 0 ?
                                      PTX(end) : NPTENTRIES );
                int ret;
                uintptr_t pteno_end = (pdeno == pdeno_end - 1 && PTX(end) != 0 ?
                                      PTX(end) : NPTENTRIES );
                int ret;
-               for (pteno = pteno_start; pteno < pteno_end; pteno++) {
-                       if (!PAGE_UNMAPPED(pt[pteno]))
-                               if((ret = callback(e, &pt[pteno], PGADDR(pdeno, pteno, 0), arg)))
-                                       return ret;
-               }
+//             for (pteno = pteno_start; pteno < pteno_end; pteno++) {
+//                     if (!PAGE_UNMAPPED(pt[pteno]))
+//                             if((ret = callback(e, &pt[pteno], PGADDR(pdeno, pteno, 0), arg)))
+//                                     return ret;
+//             }
        }
        return 0;
 }
        }
        return 0;
 }
index c359a79..81aeada 100644 (file)
@@ -53,7 +53,7 @@ typedef unsigned long pde_t;
  *                     |     Per-Process R/W Data     |                   |
  *    UDATA     ---->  +------------------------------+ 0x7f400000      --+
  *    UMAPTOP,         |    Global Shared R/W Data    | RW/RW  PGSIZE
  *                     |     Per-Process R/W Data     |                   |
  *    UDATA     ---->  +------------------------------+ 0x7f400000      --+
  *    UMAPTOP,         |    Global Shared R/W Data    | RW/RW  PGSIZE
- * UXSTACKTOP,UGDATA ->+------------------------------+ 0x7f3ff000
+ *      UGDATA  ---->  +------------------------------+ 0x7f3ff000
  *                     |     User Exception Stack     | RW/RW  PGSIZE
  *                     +------------------------------+ 0x7f3fe000
  *                     |       Empty Memory (*)       | --/--  PGSIZE
  *                     |     User Exception Stack     | RW/RW  PGSIZE
  *                     +------------------------------+ 0x7f3fe000
  *                     |       Empty Memory (*)       | --/--  PGSIZE
@@ -71,15 +71,10 @@ typedef unsigned long pde_t;
  *                     |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~|
  *                     |     Program Data & Heap      |
  *    UTEXT -------->  +------------------------------+ 0x00800000
  *                     |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~|
  *                     |     Program Data & Heap      |
  *    UTEXT -------->  +------------------------------+ 0x00800000
- *    PFTEMP ------->  |       Empty Memory (*)       |        PTSIZE
  *                     |                              |
  *                     |                              |
- *    UTEMP -------->  +------------------------------+ 0x00400000      --+
- *                     |       Empty Memory (*)       |                   |
- *                     | - - - - - - - - - - - - - - -|                   |
- *                     |  User STAB Data (optional)   |                 PTSIZE
- *    USTABDATA ---->  +------------------------------+ 0x00200000        |
- *                     |       Empty Memory (*)       |                   |
- *    0 ------------>  +------------------------------+                 --+
+ *                     |       Empty Memory (*)       |
+ *                     |                              |
+ *                     +------------------------------+ 0x00000000
  *
  * (*) Note: The kernel ensures that "Invalid Memory" (ULIM) is *never*
  *     mapped.  "Empty Memory" is normally unmapped, but user programs may
  *
  * (*) Note: The kernel ensures that "Invalid Memory" (ULIM) is *never*
  *     mapped.  "Empty Memory" is normally unmapped, but user programs may
@@ -112,6 +107,8 @@ typedef unsigned long pde_t;
  * which maps all the PTEs containing the page mappings for the entire
  * virtual address space into that 4 Meg region starting at VPT. */
 #define VPT                            (KERNBASE - PTSIZE)
  * which maps all the PTEs containing the page mappings for the entire
  * virtual address space into that 4 Meg region starting at VPT. */
 #define VPT                            (KERNBASE - PTSIZE)
+#define VPD (VPT + (VPT >> 10))
+#define vpd VPD
 #define LAPIC_BASE             (VPT - PGSIZE)
 #define IOAPIC_BASE            (LAPIC_BASE - PGSIZE)
 
 #define LAPIC_BASE             (VPT - PGSIZE)
 #define IOAPIC_BASE            (LAPIC_BASE - PGSIZE)
 
@@ -121,6 +118,13 @@ typedef unsigned long pde_t;
 
 #define ULIM            0x80000000
 
 
 #define ULIM            0x80000000
 
+/* Same as VPT but read-only for users */
+#define UVPT           (ULIM - PTSIZE)
+
+/* Arbitrary boundary between the break and the start of
+ * memory returned by calls to mmap with addr = 0 */
+#define BRK_END 0x40000000
+
 // Use this if needed in annotations
 #define IVY_KERNBASE (0xC000U << 16)
 
 // Use this if needed in annotations
 #define IVY_KERNBASE (0xC000U << 16)
 
@@ -143,11 +147,9 @@ typedef unsigned long pde_t;
 // page number field of address
 #define LA2PPN(la)     (((uintptr_t) (la)) >> PGSHIFT)
 #define PTE2PPN(pte)   LA2PPN(pte)
 // page number field of address
 #define LA2PPN(la)     (((uintptr_t) (la)) >> PGSHIFT)
 #define PTE2PPN(pte)   LA2PPN(pte)
-#define VPN(la)                PPN(la)         // used to index into vpt[]
 
 // page directory index
 #define PDX(la)                ((((uintptr_t) (la)) >> PDXSHIFT) & 0x3FF)
 
 // page directory index
 #define PDX(la)                ((((uintptr_t) (la)) >> PDXSHIFT) & 0x3FF)
-#define VPD(la)                PDX(la)         // used to index into vpd[]
 
 // page table index
 #define PTX(la)                ((((uintptr_t) (la)) >> PTXSHIFT) & 0x3FF)
 
 // page table index
 #define PTX(la)                ((((uintptr_t) (la)) >> PTXSHIFT) & 0x3FF)
index 857b2b0..1742f72 100644 (file)
@@ -11,210 +11,285 @@ typedef unsigned long pte_t;
 typedef unsigned long pde_t;
 #endif
 
 typedef unsigned long pde_t;
 #endif
 
-// TODO: 64 bit
-/* x86's 32 bit Virtual Memory Map.  Symbols are similar on other archs
+/* Virtual memory map:                                  Virt Addresses
+ *                                                      perms: kernel/user
  *
  *
- * Virtual memory map:                                Permissions
- *                                                    kernel/user
- *
- *    4 Gig -------->  +------------------------------+
+ *                     +------------------------------+ 0xffffffffffffffff -+
+ *                     |                              |                     |
+ *                     |   Mapped to lowmem, unused   | RW/--               |
+ *                     |                              |                     |
+ *  "end" symbol  -->  +------------------------------+        PML3_PTE_REACH
+ *                     |                              |                     |
+ *                     |  Kernel link/load location   |                     |
+ *                     |    (mapped to 0, physical)   |                     |
+ *                     |                              |                     |
+ * KERN_LOAD_ADDR -->  +------------------------------+ 0xffffffffc0000000 -+
+ *                     |                              |
+ *                     |          Local APIC          | RW/--  PGSIZE
+ *                     |                              |
+ *    LAPIC_BASE  -->  +------------------------------+ 0xffffffffbffff000
+ *                     |                              |
+ *                     |            IOAPIC            | RW/--  PGSIZE
+ *                     |                              |
+ *  IOAPIC_BASE,  -->  +------------------------------+ 0xffffffffbfffe000
+ *  KERN_DYN_TOP       |   Kernel Dynamic Mappings    |
+ *                     |              .               |
  *                     :              .               :
  *                     :              .               :
- *  KERN_LOAD_ADDR,    +------------------------------+ 0xffffffffc0000000
- *  KERN_VMAP_TOP      |                              |
  *                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ RW/--
  *                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ RW/--
+ *                     :                              :
+ *                     |          Unmapped            | --/--
+ *                     |                              |
+ *                     |  Kernel static linking limit |
+ *                     +------------------------------+ 0xffffffff80000000
+ *                     |                              |
+ *                     |                              |
+ *                     |                              |
+ *  VPT_TOP    ----->  +------------------------------+ 0xffffff0000000000 -+
+ *                     |                              |                     |
+ *                     |                              |                     |
+ *                     |  Cur. Page Table (Kern. RW)  | RW/--  P4ML_PTE_REACH
+ *                     |                              |                     |
+ *                     |                              |                     |
+ *    VPT,     ----->  +------------------------------+ 0xfffffe8000000000 -+
+ *  KERN_VMAP_TOP      |                              |
  *                     :              .               :
  *                     :              .               :
  *                     :              .               :
  *                     |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~| RW/--
  *                     |                              | RW/--
  *                     :              .               :
  *                     :              .               :
  *                     :              .               :
  *                     |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~| RW/--
  *                     |                              | RW/--
+ *                     |                              | RW/--
+ *                     |                              | RW/--
  *                     |   Remapped Physical Memory   | RW/--
  *                     |                              | RW/--
  *                     |   Remapped Physical Memory   | RW/--
  *                     |                              | RW/--
- *    KERNBASE ----->  +------------------------------+ 0xffff80000000
- *
- *
- *
- *                     |  Cur. Page Table (Kern. RW)  | RW/--  PTSIZE
- *    VPT          --> +------------------------------+ 0xbfc00000
- *                     |          Local APIC          | RW/--  PGSIZE
- *    LAPIC        --> +------------------------------+ 0xbfbff000
- *                     |            IOAPIC            | RW/--  PGSIZE
- *    IOAPIC,      --> +------------------------------+ 0xbfbfe000
- *  KERN_DYN_TOP       |   Kernel Dynamic Mappings    |
- *                     |              .               |
- *                     :              .               :
- *                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ RW/--
- *                     :                              :
- *                     |      Invalid Memory (*)      | --/--
- *    ULIM      ---->  +------------------------------+ 0x80000000      --+
- *                     |  Cur. Page Table (User R-)   | R-/R-  PTSIZE     |
- *    UVPT      ---->  +------------------------------+ 0x7fc00000      --+
- *                     | Unmapped (expandable region) |                   |
- *                     |                              | R-/R-            PTSIZE
- *                     |     Per-Process R/O Info     |                   |
- * UWLIM, UINFO ---->  +------------------------------+ 0x7f800000      --+
- *                     | Unmapped (expandable region) |                   |
- *                     |                              | RW/RW            PTSIZE
- *                     |     Per-Process R/W Data     |                   |
- *    UDATA     ---->  +------------------------------+ 0x7f400000      --+
- *    UMAPTOP,         |    Global Shared R/W Data    | RW/RW  PGSIZE
- * UXSTACKTOP,UGDATA ->+------------------------------+ 0x7f3ff000
- *                     |     User Exception Stack     | RW/RW  PGSIZE
- *                     +------------------------------+ 0x7f3fe000
- *                     |       Empty Memory (*)       | --/--  PGSIZE
- *    USTACKTOP  --->  +------------------------------+ 0x7f3fd000
- *                     |      Normal User Stack       | RW/RW  256*PGSIZE (1MB)
- *                     +------------------------------+ 0x7f2fd000
- *                     |       Empty Memory (*)       | --/--  PGSIZE
- *    USTACKBOT  --->  +------------------------------+ 0x7f2fc000
+ *                     |                              | RW/--
+ *                     |                              | RW/--
+ *    KERNBASE  ---->  +------------------------------+ 0xffff800000000000
+ *                     |                              |
+ *                     |                              |
+ *                     |                              |
+ *                     |   Non-canonical addresses    |
+ *                     |         (unusable)           |
+ *                     |                              |
+ *                     |                              |
+ * ULIM (not canon) -> +------------------------------+ 0x0000800000000000 -+
+ *                     +     Highest user address     + 0x00007fffffffffff  |
+ *                     |                              |                     |
+ *                     |  Cur. Page Table (User R-)   | R-/R-  PML4_PTE_REACH
+ *                     |                              |                     |
+ *    UVPT      ---->  +------------------------------+ 0x00007f8000000000 -+
+ *                     | Unmapped (expandable region) |                     |
+ *                     |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~|                     |
+ *                     |     Per-Process R/O Info     | R-/R-  PML2_PTE_REACH
+ *                     |         (procinfo)           |                     |
+ * UWLIM, UINFO ---->  +------------------------------+ 0x00007f7fffe00000 -+
+ *                     | Unmapped (expandable region) |                     |
+ *                     |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~|                     |
+ *                     |     Per-Process R/W Data     | RW/RW  PML2_PTE_REACH
+ *                     |         (procdata)           |                     |
+ *    UDATA     ---->  +------------------------------+ 0x00007f7fffc00000 -+
+ *                     |                              |
+ *                     |    Global Shared R/W Data    | RW/RW  PGSIZE
  *                     |                              |
  *                     |                              |
+ * UMAPTOP, UGDATA ->  +------------------------------+ 0x00007f7fffbff000
+ *    USTACKTOP        |                              |
+ *                     |      Normal User Stack       | RW/RW 256 * PGSIZE
  *                     |                              |
  *                     |                              |
- *                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *                     +------------------------------+ 0x00007f7fffbfb000
+ *                     |                              |
+ *                     |        Empty Memory          |
+ *                     |                              |
+ *                     .                              .
  *                     .                              .
  *                     .                              .
+ *    BRK_END   ---->  +------------------------------+ 0x0000400000000000
  *                     .                              .
  *                     .                              .
  *                     .                              .
  *                     .                              .
+ *                     |                              |
+ *                     |        Empty Memory          |
+ *                     |                              |
  *                     |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~|
  *                     |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~|
+ *                     |                              |
  *                     |     Program Data & Heap      |
  *                     |     Program Data & Heap      |
- *    UTEXT -------->  +------------------------------+ 0x00800000
- *    PFTEMP ------->  |       Empty Memory (*)       |        PTSIZE
  *                     |                              |
  *                     |                              |
- *    UTEMP -------->  +------------------------------+ 0x00400000      --+
- *                     |       Empty Memory (*)       |                   |
- *                     | - - - - - - - - - - - - - - -|                   |
- *                     |  User STAB Data (optional)   |                 PTSIZE
- *    USTABDATA ---->  +------------------------------+ 0x00200000        |
- *                     |       Empty Memory (*)       |                   |
- *    0 ------------>  +------------------------------+                 --+
- *
- * (*) Note: The kernel ensures that "Invalid Memory" (ULIM) is *never*
- *     mapped.  "Empty Memory" is normally unmapped, but user programs may
- *     map pages there if desired.  ROS user programs map pages temporarily
- *     at UTEMP.
+ *                     +------------------------------+ 0x0000000000400000
+ *                     |                              |
+ *                     |       Empty Memory (*)       |
+ *                     |                              |
+ *                     +------------------------------+ 0x0000000000000000
  */
 
  */
 
-
-// At IOPHYSMEM (640K) there is a 384K hole for I/O.  From the kernel,
-// IOPHYSMEM can be addressed at KERNBASE + IOPHYSMEM.  The hole ends
-// at physical address EXTPHYSMEM.
-#define IOPHYSMEM      0x0A0000
-#define VGAPHYSMEM     0x0A0000
-#define DEVPHYSMEM     0x0C0000
-#define BIOSPHYSMEM    0x0F0000
-#define EXTPHYSMEM     0x100000
-
-/* **************************************** */
-/* Kernel Virtual Memory Mapping  (not really an MMU thing) */
-
-#define KERNBASE        0xffff800000000000
+/* Physical Mapping symbols:
+ * At IOPHYSMEM (640K) there is a 384K hole for I/O.  From the kernel,
+ * IOPHYSMEM can be addressed at KERNBASE + IOPHYSMEM.  The hole ends
+ * at physical address EXTPHYSMEM. */
+#define IOPHYSMEM              0x0A0000
+#define VGAPHYSMEM             0x0A0000
+#define DEVPHYSMEM             0x0C0000
+#define BIOSPHYSMEM            0x0F0000
+#define EXTPHYSMEM             0x100000
+
+/* Kernel Virtual Memory Mapping */
+
+/* The kernel needs to be loaded in the top 2 GB of memory, since we compile it
+ * with -mcmodel=kernel (helps with relocations).  We're actually loading it in
+ * the top 1 GB. */
 #define KERN_LOAD_ADDR  0xffffffffc0000000
 #define KERN_LOAD_ADDR  0xffffffffc0000000
-/* Top of the kernel virtual mapping area (KERNBASE) */
-#define KERN_VMAP_TOP  KERN_LOAD_ADDR /* upper 2GB reserved */
-
 /* Static kernel mappings */
 /* Static kernel mappings */
-/* Virtual page table.  Entry PDX(VPT) in the PD contains a pointer to
- * the page directory itself, thereby turning the PD into a page table,
- * which maps all the PTEs containing the page mappings for the entire
- * virtual address space into that 4 Meg region starting at VPT. */
-#define VPT                            (KERN_LOAD_ADDR - PTSIZE)
-#define LAPIC_BASE             (VPT - PGSIZE)
+#define LAPIC_BASE             (KERN_LOAD_ADDR - PGSIZE)
 #define IOAPIC_BASE            (LAPIC_BASE - PGSIZE)
 #define IOAPIC_BASE            (LAPIC_BASE - PGSIZE)
-
 /* All arches must define this, which is the lower limit of their static
  * mappings, and where the dynamic mappings will start. */
 #define KERN_DYN_TOP   IOAPIC_BASE
 
 /* All arches must define this, which is the lower limit of their static
  * mappings, and where the dynamic mappings will start. */
 #define KERN_DYN_TOP   IOAPIC_BASE
 
-/* Highest user address: 0x00007fffffffffff: 1 zero, 47 ones, sign extended */
-#define ULIM            0x0000800000000000
+/* Virtual page table.  Every PML4 has a PTE at the slot (PML4(VPT))
+ * corresponding to VPT that points to that PML4's base.  In essence, the 512
+ * GB chunk of the VA space from VPT..VPT_TOP is a window into the paging
+ * structure.
+ *
+ * The VPT needs to be aligned on 39 bits.
+ *
+ * Ex: Say the VPT's entry in 9 bits is "9v".  If you construct a VA from:
+ * 9v9v9v9v000, the paging hardware will recurse 4 times, with the end result
+ * being the PML4.  That virtual address will map to the PML4 itself.
+ *
+ * If you want to see a specific PML3, figure out which entry it is in the
+ * PML4 (using PML3(va)), say 9 bits = "9X".  The VA 9v9v9v9X000 will map to
+ * that PML3. */
+#define VPT_TOP                        0xffffff0000000000
+#define VPT                            (VPT_TOP - PML4_PTE_REACH)
+/* Helper to return the current outer pgdir via the VPT mapping. */
+#define VPD (VPT + (VPT >> 9) + (VPT >> 18) + (VPT >> 27))
+#define vpd VPD
 
 
-// Use this if needed in annotations
-//#define IVY_KERNBASE (0xC000U << 16)
+/* Top of the kernel virtual mapping area (KERNBASE) */
+#define KERN_VMAP_TOP  (VPT)
+/* Base of the physical memory map. This maps from 0 physical to max_paddr */
+#define KERNBASE        0xffff800000000000
+
+/* Highest user address: 0x00007fffffffffff: 1 zero, 47 ones, sign extended.
+ * From here down to UWLIM is User Read-only */
+#define ULIM            0x0000800000000000
+/* Same as VPT but read-only for users */
+#define UVPT                   (ULIM - PML4_PTE_REACH)
+/* Arbitrary boundary between the break and the start of
+ * memory returned by calls to mmap with addr = 0 */
+#define BRK_END                        0x0000400000000000
 
 /* **************************************** */
 /* Page table constants, macros, etc */
 
 
 /* **************************************** */
 /* Page table constants, macros, etc */
 
-// A linear address 'la' has a three-part structure as follows:
-//
-// +--------10------+-------10-------+---------12----------+
-// | Page Directory |   Page Table   | Offset within Page  |
-// |      Index     |      Index     |                     |
-// +----------------+----------------+---------------------+
-//  \--- PDX(la) --/ \--- PTX(la) --/ \---- PGOFF(la) ----/
-//  \----------- PPN(la) -----------/
-//
-// The PDX, PTX, PGOFF, and PPN macros decompose linear addresses as shown.
-// To construct a linear address la from PDX(la), PTX(la), and PGOFF(la),
-// use PGADDR(PDX(la), PTX(la), PGOFF(la)).
-
-// page number field of address
-#define LA2PPN(la)     (((uintptr_t) (la)) >> PGSHIFT)
+/* A linear address 'la' has a five-part structure as follows:
+ *
+ * +-----9------+-----9------+-----9------+-----9------+---------12----------+
+ * | PML4 bits  | PML3 bits  | PML2 bits  | PML1 bits  |     Page offset     |
+ * |   offset   |   offset   |   offset   |   offset   |                     |
+ * +------------+------------+------------+------------+---------------------+
+ *  \ PML4(la) / \ PML3(la) / \ PML2(la) / \ PML1(la) / \---- PGOFF(la) ----/
+ *  \------------------ LA2PPN(la) -------------------/
+ *
+ * The PMLx, PGOFF, and LA2PPN macros decompose linear addresses as shown.
+ * To construct a linear address la from these, use:
+ * PGADDR(PML4(la), PML3(la), PML2(la), PML1(la), PGOFF(la)).
+ * Careful, that's arch- and bit-specific.
+ *
+ * I'd somewhat like it if we started counting from the outer-most PT, though
+ * amd coined the term PML4 for the outermost, instead of PML1.  Incidentally,
+ * they also don't use numbers other than PML4, sticking with names like PDP. */
+
+#define PML4_SHIFT             39
+#define PML3_SHIFT             30
+#define PML2_SHIFT             21
+#define PML1_SHIFT             12
+
+/* PTE reach is the amount of VM an entry can map, either as a jumbo or as
+ * further page tables.  I'd like to write these as shifts, but I can't please
+ * both the compiler and the assembler. */
+#define PML4_PTE_REACH (0x0000008000000000)    /* No jumbos available */
+#define PML3_PTE_REACH (0x0000000040000000)    /* 1 GB jumbos available */
+#define PML2_PTE_REACH (0x0000000000200000)    /* 2 MB jumbos available */
+#define PML1_PTE_REACH (0x0000000000001000)    /* aka, PGSIZE */
+
+/* Reach is the amount of VM a table can map, counting all of its entries.
+ * Note that a PML(n)_PTE is a PML(n-1) table. */
+#define PML3_REACH             (PML4_PTE_REACH)
+#define PML2_REACH             (PML3_PTE_REACH)
+#define PML1_REACH             (PML2_PTE_REACH)
+
+/* PMLx(la) gives the 9 bits specifying the la's entry in PML x */
+#define PML4(la)               (((uintptr_t)(la) >> PML4_SHIFT) & 0x1ff)
+#define PML3(la)               (((uintptr_t)(la) >> PML3_SHIFT) & 0x1ff)
+#define PML2(la)               (((uintptr_t)(la) >> PML2_SHIFT) & 0x1ff)
+#define PML1(la)               (((uintptr_t)(la) >> PML1_SHIFT) & 0x1ff)
+
+/* Common kernel helpers */
+#define PGSHIFT                        PML1_SHIFT
+#define PGSIZE                 PML1_PTE_REACH
+#define LA2PPN(la)             ((uintptr_t)(la) >> PGSHIFT)
 #define PTE2PPN(pte)   LA2PPN(pte)
 #define PTE2PPN(pte)   LA2PPN(pte)
-#define VPN(la)                PPN(la)         // used to index into vpt[]
-
-// page directory index
-#define PDX(la)                ((((uintptr_t) (la)) >> PDXSHIFT) & 0x3FF)
-#define VPD(la)                PDX(la)         // used to index into vpd[]
-
-// page table index
-#define PTX(la)                ((((uintptr_t) (la)) >> PTXSHIFT) & 0x3FF)
-
-// offset in page
-#define PGOFF(la)      (((uintptr_t) (la)) & 0xFFF)
-
-// offset in jumbo page
-#define JPGOFF(la)     (((uintptr_t) (la)) & 0x003FFFFF)
-
-// construct PTE from PPN and flags
-#define PTE(ppn, flags) ((ppn) << PTXSHIFT | PGOFF(flags))
-
-// construct linear address from indexes and offset
-#define PGADDR(d, t, o)        ((void*SNT) ((d) << PDXSHIFT | (t) << PTXSHIFT | (o)))
-
-// Page directory and page table constants.
-#define NPDENTRIES     1024            // page directory entries per page directory
-#define NPTENTRIES     1024            // page table entries per page table
-
-#define PTXSHIFT       12              // offset of PTX in a linear address
-#define PDXSHIFT       22              // offset of PDX in a linear address
-
-// Page table/directory entry flags.
-#define PTE_P          0x001   // Present
-#define PTE_W          0x002   // Writeable
-#define PTE_U          0x004   // User
-#define PTE_PWT                0x008   // Write-Through
-#define PTE_PCD                0x010   // Cache-Disable
-#define PTE_A          0x020   // Accessed
-#define PTE_D          0x040   // Dirty
-#define PTE_PS         0x080   // Page Size (only applies to PDEs)
-#define PTE_PAT                0x080   // PAT (only applies to second layer PTEs)
-#define PTE_G          0x100   // Global Page
-
-#define PTE_PERM       (PTE_W | PTE_U) // The permissions fields
-// commly used access modes
-#define PTE_KERN_RW    PTE_W           // Kernel Read/Write
-#define PTE_KERN_RO    0               // Kernel Read-Only
-#define PTE_USER_RW    (PTE_W | PTE_U) // Kernel/User Read/Write
-#define PTE_USER_RO    PTE_U           // Kernel/User Read-Only
-
-// The PTE_AVAIL bits aren't used by the kernel or interpreted by the
-// hardware, so user processes are allowed to set them arbitrarily.
-#define PTE_AVAIL      0xE00   // Available for software use
-
-// Only flags in PTE_USER may be used in system calls.
-#define PTE_USER       (PTE_AVAIL | PTE_P | PTE_W | PTE_U)
-
-// address in page table entry
-#define PTE_ADDR(pte)  ((physaddr_t) (pte) & ~0xFFF)
-
-#define PTSHIFT 22
-#define PTSIZE (1 << PTSHIFT)
-#define PGSHIFT 12
-#define PGSIZE (1 << PGSHIFT)
+#define PGOFF(la)              ((uintptr_t)(la) & (PGSIZE - 1))
+
+/* construct PTE from PPN and flags */
+#define PTE(ppn, flags) ((ppn) << PGSHIFT | PGOFF(flags))
+
+/* construct linear address from indexes and offset */
+#define PGADDR(p4, p3, p2, p1, o) ((void*)(((p4) << PML4_SHIFT) |              \
+                                           ((p3) << PML3_SHIFT) |              \
+                                           ((p2) << PML2_SHIFT) |              \
+                                           ((p1) << PML1_SHIFT) |(o)))
+
+/* These are used in older code, referring to the outer-most page table */
+#define PDX(la)                        PML4(la)
+#define NPDENTRIES             512
+/* This is used in places (procinfo) meaning "size of smallest jumbo page" */
+#define PTSIZE PML2_PTE_REACH
+
+
+/* TODO: not sure if we'll need these - limited to 64bit code */
+/* this only gives us the L1 PML */
+#define PTX(la)                ((((uintptr_t) (la)) >> 12) & 0x1ff)
+#define JPGOFF(la)     (((uintptr_t) (la)) & 0x001FFFFF)
+#define NPTENTRIES             512
 #define JPGSIZE PTSIZE
 
 #define JPGSIZE PTSIZE
 
-// we must guarantee that for any PTE, exactly one of the following is true
+
+/* Page table/directory entry flags. */
+
+/* Some things to be careful of:  Global and PAT only apply to the last PTE in
+ * a chain: so either a PTE in PML1, or a Jumbo PTE in PML2 or 3.  When PAT
+ * applies, which bit we use depends on whether we are jumbo or not.  For PML1,
+ * PAT is bit 8.  For jumbo PTEs (and only when they are for a jumbo page), we
+ * use bit 12. */
+#define PTE_P                  0x001   /* Present */
+#define PTE_W                  0x002   /* Writeable */
+#define PTE_U                  0x004   /* User */
+#define PTE_PWT                        0x008   /* Write-Through */
+#define PTE_PCD                        0x010   /* Cache-Disable */
+#define PTE_A                  0x020   /* Accessed */
+#define PTE_D                  0x040   /* Dirty */
+#define PTE_PS                 0x080   /* Page Size */
+#define PTE_PAT                        0x080   /* Page attribute table */
+#define PTE_G                  0x100   /* Global Page */
+#define PTE_JPAT               0x800   /* Jumbo PAT */
+
+/* Permissions fields and common access modes.  These should be read as 'just
+ * kernel or user too' and 'RO or RW'.  USER_RO means read-only for everyone. */
+#define PTE_PERM               (PTE_W | PTE_U)
+#define PTE_KERN_RW            PTE_W           // Kernel Read/Write
+#define PTE_KERN_RO            0               // Kernel Read-Only
+#define PTE_USER_RW            (PTE_W | PTE_U) // Kernel/User Read/Write
+#define PTE_USER_RO            PTE_U           // Kernel/User Read-Only
+
+/* The PTE/translation part of a PTE/virtual(linear) address.  It's used
+ * frequently to be the page address of a virtual address. */
+#define PTE_ADDR(pte)  ((physaddr_t) (pte) & ~(PGSIZE - 1))
+/* More meaningful macro, same as PTE_ADDR */
+#define PG_ADDR(la)    ((uintptr_t)(la) & ~(PGSIZE - 1))
+
+/* we must guarantee that for any PTE, exactly one of the following is true */
 #define PAGE_PRESENT(pte) ((pte) & PTE_P)
 #define PAGE_UNMAPPED(pte) ((pte) == 0)
 #define PAGE_PAGED_OUT(pte) (!PAGE_PRESENT(pte) && !PAGE_UNMAPPED(pte))
 
 #define PAGE_PRESENT(pte) ((pte) & PTE_P)
 #define PAGE_UNMAPPED(pte) ((pte) == 0)
 #define PAGE_PAGED_OUT(pte) (!PAGE_PRESENT(pte) && !PAGE_UNMAPPED(pte))
 
+
 /* **************************************** */
 /* Segmentation */
 // XXX 64b: these all need redone
 /* **************************************** */
 /* Segmentation */
 // XXX 64b: these all need redone
@@ -263,6 +338,7 @@ typedef unsigned long pde_t;
 
 #else  // not __ASSEMBLER__
 
 
 #else  // not __ASSEMBLER__
 
+/* TODO: consider removing this, if we're just using one asm GDT */
 // Segment Descriptors
 typedef struct Segdesc {
        unsigned sd_lim_15_0 : 16;  // Low bits of segment limit
 // Segment Descriptors
 typedef struct Segdesc {
        unsigned sd_lim_15_0 : 16;  // Low bits of segment limit
@@ -453,4 +529,5 @@ extern pseudodesc_t gdt_pd;
 
 #define SEG_COUNT      7               // Number of segments in the steady state
 #define LDT_SIZE       (8192 * sizeof(segdesc_t))
 
 #define SEG_COUNT      7               // Number of segments in the steady state
 #define LDT_SIZE       (8192 * sizeof(segdesc_t))
+
 #endif /* ROS_INC_ARCH_MMU64_H */
 #endif /* ROS_INC_ARCH_MMU64_H */
index 1b24a96..7ab50b6 100644 (file)
 #define KSTKSHIFT      (PGSHIFT)                       /* KSTKSIZE == PGSIZE */
 #define KSTKSIZE       (1 << KSTKSHIFT)        /* size of a static kernel stack */
 
 #define KSTKSHIFT      (PGSHIFT)                       /* KSTKSIZE == PGSIZE */
 #define KSTKSIZE       (1 << KSTKSHIFT)        /* size of a static kernel stack */
 
-/*
- * User read-only mappings! Anything below here til UWLIM are readonly to user.
- * They are global pages mapped in at env allocation time.
- */
-
-// Same as VPT but read-only for users
-#define UVPT           (ULIM - PTSIZE)
-
-/*
- * Top of user VM. User can manipulate VA from UWLIM-1 and down!
- */
-
-// Top of user-accessible VM
-#define UWLIM          (UVPT - PTSIZE)
-// Read-only, per-process shared info structures
-#define UINFO          UWLIM
-
-// Read-write, per-process shared page for sending asynchronous 
-// syscalls to the kernel
-#define UDATA    (UWLIM - PTSIZE)
-
-// Read-write, global page.  Shared by all processes.  Can't be trusted.
-#define UGDATA   (UDATA - PGSIZE)
-
-// Top of one-page user exception stack
-#define UXSTACKTOP     UGDATA
+/* Read-only, per-process shared info structures */
+#define UINFO                  (UVPT - PTSIZE)
+/* Top of user-writable VM */
+#define UWLIM                  UINFO
+/* Read-write, per-process shared info structures */
+#define UDATA                  (UWLIM - PTSIZE)
+/* Read-write, global page.  Shared by all processes. */
+#define UGDATA                 (UDATA - PGSIZE)
 /* Limit of what is mmap()/munmap()-able */
 /* Limit of what is mmap()/munmap()-able */
-#define UMAPTOP UXSTACKTOP
-// Next page left invalid to guard against exception stack overflow; then:
-// Top of normal user stack
-#define USTACKTOP      (UXSTACKTOP - 2*PGSIZE)
-// Maximum stack depth preallocated to 1MB
+#define UMAPTOP                        UGDATA
+/* Top of normal user stack */
+#define USTACKTOP              UMAPTOP
+/* Stack size of thread0, allocated by the kernel */
 #define USTACK_NUM_PAGES       256
 #define USTACK_NUM_PAGES       256
-// Next page left invalid to guard against stack overflow
-// Maximum bottom of normal user stack
-#define USTACKBOT      (USTACKTOP - (USTACK_NUM_PAGES+1)*PGSIZE)
-
-// Arbitrary boundary between the break and the start of
-// memory returned by calls to mmap with addr = 0
-#define BRK_END 0x40000000
-
-// Where user programs generally begin
-#define UTEXT          (2*PTSIZE)
-
-// Used for temporary page mappings.  Typed 'void*' for convenience
-#define UTEMP          ((void*) PTSIZE)
-// Used for temporary page mappings for the user page-fault handler
-// (should not conflict with other temporary page mappings)
-#define PFTEMP         (UTEMP + PTSIZE - PGSIZE)
-// The location of the user-level STABS data structure
-#define USTABDATA      (PTSIZE / 2)
-
-
-#ifndef __ASSEMBLER__
-
-/*
- * The page directory entry corresponding to the virtual address range
- * [VPT, VPT + PTSIZE) points to the page directory itself.  Thus, the page
- * directory is treated as a page table as well as a page directory.
- *
- * One result of treating the page directory as a page table is that all PTEs
- * can be accessed through a "virtual page table" at virtual address VPT (to
- * which vpt is set in entry.S).  The PTE for page number N is stored in
- * vpt[N].  (It's worth drawing a diagram of this!)
- *
- * A second consequence is that the contents of the current page directory
- * will always be available at virtual address (VPT + (VPT >> PGSHIFT)), to
- * which vpd is set in entry.S.
- */
-
-extern volatile pte_t *vpt; // VA of "virtual page table"
-extern volatile pde_t *vpd; // VA of current page directory
 
 
-#endif /* !__ASSEMBLER__ */
 #endif /* !ROS_INC_MEMLAYOUT_H */
 #endif /* !ROS_INC_MEMLAYOUT_H */
index d67b83a..753540b 100644 (file)
@@ -194,7 +194,7 @@ static void proc_init_procinfo(struct proc* p)
        p->procinfo->max_vcores = max_vcores(p);
        p->procinfo->tsc_freq = system_timing.tsc_freq;
        p->procinfo->timing_overhead = system_timing.timing_overhead;
        p->procinfo->max_vcores = max_vcores(p);
        p->procinfo->tsc_freq = system_timing.tsc_freq;
        p->procinfo->timing_overhead = system_timing.timing_overhead;
-       p->procinfo->heap_bottom = (void*)UTEXT;
+       p->procinfo->heap_bottom = 0;
        /* 0'ing the arguments.  Some higher function will need to set them */
        memset(p->procinfo->argp, 0, sizeof(p->procinfo->argp));
        memset(p->procinfo->argbuf, 0, sizeof(p->procinfo->argbuf));
        /* 0'ing the arguments.  Some higher function will need to set them */
        memset(p->procinfo->argp, 0, sizeof(p->procinfo->argp));
        memset(p->procinfo->argbuf, 0, sizeof(p->procinfo->argbuf));
@@ -270,11 +270,12 @@ error_t proc_alloc(struct proc **pp, struct proc *parent)
        p->state = PROC_CREATED; /* shouldn't go through state machine for init */
        p->env_flags = 0;
        p->env_entry = 0; // cheating.  this really gets set later
        p->state = PROC_CREATED; /* shouldn't go through state machine for init */
        p->env_flags = 0;
        p->env_entry = 0; // cheating.  this really gets set later
-       p->heap_top = (void*)UTEXT;     /* heap_bottom set in proc_init_procinfo */
+       p->heap_top = 0;
        spinlock_init(&p->mm_lock);
        TAILQ_INIT(&p->vm_regions); /* could init this in the slab */
        spinlock_init(&p->mm_lock);
        TAILQ_INIT(&p->vm_regions); /* could init this in the slab */
-       /* Initialize the vcore lists, we'll build the inactive list so that it includes
-        * all vcores when we initialize procinfo.  Do this before initing procinfo. */
+       /* Initialize the vcore lists, we'll build the inactive list so that it
+        * includes all vcores when we initialize procinfo.  Do this before initing
+        * procinfo. */
        TAILQ_INIT(&p->online_vcs);
        TAILQ_INIT(&p->bulk_preempted_vcs);
        TAILQ_INIT(&p->inactive_vcs);
        TAILQ_INIT(&p->online_vcs);
        TAILQ_INIT(&p->bulk_preempted_vcs);
        TAILQ_INIT(&p->inactive_vcs);