From c99599784e950169d85bf1e4446e7dbfb1a40f59 Mon Sep 17 00:00:00 2001
From: Robert Morris <rtm@nephron.lcs.mit.edu>
Date: Thu, 5 Aug 2010 16:00:59 -0400
Subject: [PATCH] remove some unused vm #defines fix corner cases with
 alignment when mapping kernel ELF file

---
 defs.h |  2 --
 mmu.h  | 30 ++++-------------------------
 proc.c |  2 +-
 vm.c   | 60 ++++++++++++++++++++++------------------------------------
 4 files changed, 28 insertions(+), 66 deletions(-)

diff --git a/defs.h b/defs.h
index 6a19244..4a63154 100644
--- a/defs.h
+++ b/defs.h
@@ -156,8 +156,6 @@ void            pminit(void);
 void            ksegment(void);
 void            kvmalloc(void);
 void            vminit(void);
-void            printstack(void);
-void            printpgdir(pde_t *);
 pde_t*          setupkvm(void);
 char*           uva2ka(pde_t*, char*);
 int             allocuvm(pde_t*, char*, uint);
diff --git a/mmu.h b/mmu.h
index e3ea46f..76a6f1b 100644
--- a/mmu.h
+++ b/mmu.h
@@ -85,32 +85,20 @@ struct segdesc {
 // | 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 PPN(la)		(((uint) (la)) >> PTXSHIFT)
-#define VPN(la)		PPN(la)		// used to index into vpt[]
+//  \--- PDX(la) --/ \--- PTX(la) --/ 
 
 // page directory index
 #define PDX(la)		((((uint) (la)) >> PDXSHIFT) & 0x3FF)
-#define VPD(la)		PDX(la)		// used to index into vpd[]
 
 // page table index
 #define PTX(la)		((((uint) (la)) >> PTXSHIFT) & 0x3FF)
 
-// offset in page
-#define PGOFF(la)	(((uint) (la)) & 0xFFF)
-
 // construct linear address from indexes and offset
 #define PGADDR(d, t, o)	((uint) ((d) << PDXSHIFT | (t) << PTXSHIFT | (o)))
 
-// mapping from physical addresses to virtual addresses is the identity one
-// (really linear addresses, but we map linear to physical also directly)
+// turn a kernel linear address into a physical address.
+// all of the kernel data structures have linear and
+// physical addresses that are equal.
 #define PADDR(a)       ((uint) a)
 
 // Page directory and page table constants.
@@ -120,9 +108,6 @@ struct segdesc {
 #define PGSIZE		4096		// bytes mapped by a page
 #define PGSHIFT		12		// log2(PGSIZE)
 
-#define PTSIZE		(PGSIZE*NPTENTRIES) // bytes mapped by a page directory entry
-#define PTSHIFT		22		// log2(PTSIZE)
-
 #define PTXSHIFT	12		// offset of PTX in a linear address
 #define PDXSHIFT	22		// offset of PDX in a linear address
 
@@ -140,13 +125,6 @@ struct segdesc {
 #define PTE_PS		0x080	// Page Size
 #define PTE_MBZ		0x180	// Bits must be zero
 
-// 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 or page directory entry
 #define PTE_ADDR(pte)	((uint) (pte) & ~0xFFF)
 
diff --git a/proc.c b/proc.c
index c1faec6..dd6f27e 100644
--- a/proc.c
+++ b/proc.c
@@ -414,9 +414,9 @@ wait(void)
         // Found one.
         pid = p->pid;
         kfree(p->kstack, KSTACKSIZE);
+	p->kstack = 0;
 	freevm(p->pgdir);
         p->state = UNUSED;
-	p->kstack = 0;
         p->pid = 0;
         p->parent = 0;
         p->name[0] = 0;
diff --git a/vm.c b/vm.c
index 6689b82..c94e9a3 100644
--- a/vm.c
+++ b/vm.c
@@ -33,27 +33,6 @@ static uint kernend;
 static uint freesz;
 pde_t *kpgdir;         // One kernel page table for scheduler procs
 
-void
-printpgdir(pde_t *pgdir)
-{
-  uint i;
-  uint j;
-
-  cprintf("printpgdir 0x%x\n", pgdir);
-  for (i = 0; i < NPDENTRIES; i++) {
-    if (pgdir[i] != 0 && i < 100) {
-      cprintf("pgdir %d, v=0x%x\n", i, pgdir[i]);
-      pte_t *pgtab = (pte_t*) PTE_ADDR(pgdir[i]);
-      for (j = 0; j < NPTENTRIES; j++) {
-	if (pgtab[j] != 0)
-	  cprintf("pgtab %d, v=0x%x, addr=0x%x\n", j, PGADDR(i, j, 0), 
-		PTE_ADDR(pgtab[j]));
-      }
-    }
-  }
-  cprintf("printpgdir done\n", pgdir);
-}
-
 // return the address of the PTE in page table pgdir
 // that corresponds to linear address va.  if create!=0,
 // create any required page table pages.
@@ -84,19 +63,25 @@ walkpgdir(pde_t *pgdir, const void *va, int create)
 }
 
 // create PTEs for linear addresses starting at la that refer to
-// physical addresses starting at pa. 
+// physical addresses starting at pa. la and size might not
+// be page-aligned.
 static int
 mappages(pde_t *pgdir, void *la, uint size, uint pa, int perm)
 {
-  uint i;
-  pte_t *pte;
-
-  for (i = 0; i < size; i += PGSIZE) {
-    if (!(pte = walkpgdir(pgdir, (void*)(la + i), 1)))
+  char *first = PGROUNDDOWN(la);
+  char *last = PGROUNDDOWN(la + size - 1);
+  char *a = first;
+  while(1){
+    pte_t *pte = walkpgdir(pgdir, a, 1);
+    if(pte == 0)
       return 0;
     if(*pte & PTE_P)
       panic("remap");
-    *pte = (pa + i) | perm | PTE_P;
+    *pte = pa | perm | PTE_P;
+    if(a == last)
+      break;
+    a += PGSIZE;
+    pa += PGSIZE;
   }
   return 1;
 }
@@ -160,10 +145,10 @@ setupkvm(void)
   // Map IO space from 640K to 1Mbyte
   if (!mappages(pgdir, (void *)USERTOP, 0x60000, USERTOP, PTE_W))
     return 0;
-  // Map kernel text from kern text addr read-only
+  // Map kernel text read-only
   if (!mappages(pgdir, (void *) kerntext, kerntsz, kerntext, 0))
     return 0;
-  // Map kernel data form kern data addr R/W
+  // Map kernel data read/write
   if (!mappages(pgdir, (void *) kerndata, kerndsz, kerndata, PTE_W))
     return 0;
   // Map dynamically-allocated memory read/write (kernel stacks, user mem)
@@ -194,10 +179,10 @@ allocuvm(pde_t *pgdir, char *addr, uint sz)
 {
   if (addr + sz >= (char*)USERTOP)
     return 0;
-  char *start = PGROUNDDOWN(addr);
+  char *first = PGROUNDDOWN(addr);
   char *last = PGROUNDDOWN(addr + sz - 1);
   char *a;
-  for(a = start; a <= last; a += PGSIZE){
+  for(a = first; a <= last; a += PGSIZE){
     pte_t *pte = walkpgdir(pgdir, a, 0);
     if(pte == 0 || (*pte & PTE_P) == 0){
       char *mem = kalloc(PGSIZE);
@@ -212,6 +197,8 @@ allocuvm(pde_t *pgdir, char *addr, uint sz)
   return 1;
 }
 
+// free a page table and all the physical memory pages
+// in the user part.
 void
 freevm(pde_t *pgdir)
 {
@@ -227,9 +214,8 @@ freevm(pde_t *pgdir)
 	if (pgtab[j] != 0) {
 	  uint pa = PTE_ADDR(pgtab[j]);
 	  uint va = PGADDR(i, j, 0);
-	  if (va >= USERTOP)   // done with user part?
-	    break;
-	  kfree((void *) pa, PGSIZE);
+	  if (va < USERTOP)   // user memory
+            kfree((void *) pa, PGSIZE);
 	  pgtab[j] = 0;
 	}
       }
@@ -314,8 +300,8 @@ pminit(void)
   kernend = ((uint)end + PGSIZE) & ~(PGSIZE-1);
   kerntext = ph[0].va;
   kerndata = ph[1].va;
-  kerntsz = kerndata - kerntext;
-  kerndsz = kernend - kerndata;
+  kerntsz = ph[0].memsz;
+  kerndsz = ph[1].memsz;
   freesz = PHYSTOP - kernend;
 
   cprintf("kerntext@0x%x(sz=0x%x), kerndata@0x%x(sz=0x%x), kernend 0x%x freesz = 0x%x\n",