Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


added testing
Jack Lange [Mon, 15 Sep 2008 20:14:27 +0000 (20:14 +0000)]
misc/test_vm/build/Makefile
misc/test_vm/include/geekos/paging.h
misc/test_vm/src/geekos/io.c
misc/test_vm/src/geekos/lowlevel.asm
misc/test_vm/src/geekos/main.c
misc/test_vm/src/geekos/paging.c

index 381ef25..df39370 100644 (file)
@@ -1,6 +1,6 @@
 # Makefile for GeekOS kernel, userspace, and tools
 # Copyright (c) 2004,2005 David H. Hovemeyer <daveho@cs.umd.edu>
-# $Revision: 1.1 $
+# $Revision: 1.2 $
 
 # This is free software.  You are permitted to use,
 # redistribute, and modify it as specified in the file "COPYING".
@@ -29,7 +29,6 @@
 #
 # The setup code needs to copy it up to this address and jump there
 #
-#KERNEL_BASE_ADDR := $(shell perl -e 'print sprintf("0x%x",$(TOP_OF_MEM)-4096*3-$(MAX_VMM));')
 KERNEL_BASE_ADDR := 0x100000
 
 # Kernel entry point function
@@ -123,10 +122,11 @@ COMMON_C_OBJS := $(COMMON_C_SRCS:%.c=common/%.o)
 
 # Uncomment if cross compiling
 #TARGET_CC_PREFIX := i386-elf-
+TARGET_CC_PREFIX :=  $(PROJECT_ROOT)/../devtools/i386/bin/i386-elf-
 
 # Target C compiler.  gcc 2.95.2 or later should work.
 TARGET_CC := $(TARGET_CC_PREFIX)gcc
-#TARGET_CC := $(TARGET_CC_PREFIX)gcc34 -m32
+
 
 # Host C compiler.  This is used to compile programs to execute on
 # the host platform, not the target (x86) platform.  On x86/ELF
@@ -241,6 +241,10 @@ pxe:       fd.img
 vm:    geekos/kernel.bin
        cp geekos/kernel.bin ../../vmm-hack1/build/vm_kernel
 
+guest_img: fd.img
+       cp fd.img guest.img
+       $(PAD) guest.img 1474560
+
 geekos/test: geekos/test.o
        $(CC) geekos/test.o -o geekos/test
 
index 1810f0b..11b7531 100644 (file)
@@ -2,7 +2,7 @@
  * Paging (virtual memory) support
  * Copyright (c) 2003, Jeffrey K. Hollingsworth <hollings@cs.umd.edu>
  * Copyright (c) 2003,2004 David H. Hovemeyer <daveho@cs.umd.edu>
- * $Revision: 1.1 $
+ * $Revision: 1.2 $
  * 
  * This is free software.  You are permitted to use,
  * redistribute, and modify it as specified in the file "COPYING".
@@ -97,6 +97,7 @@ extern void Flush_TLB(void);
 extern void Set_PDBR(pde_t *pageDir);
 extern pde_t *Get_PDBR(void);
 extern void Enable_Paging(pde_t *pageDir);
+extern void Invalidate_PG(void * addr);
 
 /*
  * Return the address that caused a page fault.
@@ -128,4 +129,6 @@ void Write_To_Paging_File(void *paddr, ulong_t vaddr, int pagefileIndex);
 void Read_From_Paging_File(void *paddr, ulong_t vaddr, int pagefileIndex);
 
 
+void VM_Test(struct Boot_Info *bootInfo, uint_t num_test_pages);
+
 #endif
index 3132733..70b9f50 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * x86 port IO routines
  * Copyright (c) 2001, David H. Hovemeyer <daveho@cs.umd.edu>
- * $Revision: 1.1 $
+ * $Revision: 1.2 $
  * 
  * This is free software.  You are permitted to use,
  * redistribute, and modify it as specified in the file "COPYING".
@@ -21,11 +21,14 @@ void Out_Byte(ushort_t port, uchar_t value)
     );
 }
 
+extern uchar_t InByteLL(ushort_t port);
+
 /*
  * Read a byte from an I/O port.
  */
 uchar_t In_Byte(ushort_t port)
 {
+  /*
     uchar_t value;
 
     __asm__ __volatile__ (
@@ -35,6 +38,9 @@ uchar_t In_Byte(ushort_t port)
     );
 
     return value;
+  */
+
+  return InByteLL(port);
 }
 
 /*
index 63f93c2..cae49a8 100644 (file)
@@ -2,7 +2,7 @@
 ; Low level interrupt/thread handling code for GeekOS.
 ; Copyright (c) 2001,2003,2004 David H. Hovemeyer <daveho@cs.umd.edu>
 ; Copyright (c) 2003, Jeffrey K. Hollingsworth <hollings@cs.umd.edu>
-; $Revision: 1.1 $
+; $Revision: 1.2 $
 
 ; This is free software.  You are permitted to use,
 ; redistribute, and modify it as specified in the file "COPYING".
@@ -143,6 +143,9 @@ EXPORT Load_LDTR
 EXPORT g_entryPointTableStart
 EXPORT g_entryPointTableEnd
 
+
+EXPORT InByteLL
+
 ; Thread context switch function.
 EXPORT Switch_To_Thread
 
@@ -161,6 +164,7 @@ EXPORT Enable_Paging
 EXPORT Set_PDBR
 EXPORT Get_PDBR
 EXPORT Flush_TLB
+EXPORT Invalidate_PG
 
 ; CPUID functions
 EXPORT cpuid_ecx
@@ -270,6 +274,15 @@ Flush_TLB:
 
 
 ;
+; Invalidate Page - removes a page from the TLB
+;
+align 8
+Invalidate_PG:
+       mov     eax, [esp+4]
+       invlpg  [eax]
+       ret
+
+;
 ; cpuid_ecx - return the ecx register from cpuid
 ;
 align 8
@@ -352,6 +365,28 @@ Proc_test:
        ret
 
 
+
+align 8
+InByteLL:
+       push    ebp
+       mov     ebp, esp
+       push    ecx
+       push    ebx
+       push    edx
+
+       rdtsc
+       mov     ebx, eax
+       mov     ecx, edx
+       mov     dx, [ebp + 8]
+
+       in      al, dx
+
+       pop     edx
+       pop     ebx
+       pop     ecx
+       pop     ebp
+       ret
+
 ; Common interrupt handling code.
 ; Save registers, call C handler function,
 ; possibly choose a new thread to run, restore
@@ -518,6 +553,7 @@ Get_EBP:
 
 
 
+
 ; ----------------------------------------------------------------------
 ; Generate interrupt-specific entry points for all interrupts.
 ; We also define symbols to indicate the extend of the table
index 80283a4..9d48319 100644 (file)
@@ -3,7 +3,7 @@
  * Copyright (c) 2001,2003,2004 David H. Hovemeyer <daveho@cs.umd.edu>
  * Copyright (c) 2003, Jeffrey K. Hollingsworth <hollings@cs.umd.edu>
  * Copyright (c) 2004, Iulian Neamtiu <neamtiu@cs.umd.edu>
- * $Revision: 1.1 $
+ * $Revision: 1.2 $
  * 
  * This is free software.  You are permitted to use,
  * redistribute, and modify it as specified in the file "COPYING".
@@ -53,6 +53,10 @@ extern uint_t Get_ESP();
 extern uint_t Get_EBP();
 
 
+
+extern void Invalidate_PG(void * addr);
+
+
 int foo=42;
 
 #define SPEAKER_PORT 0x61
@@ -247,7 +251,7 @@ void Main(struct Boot_Info* bootInfo)
   Init_Interrupts();
   Init_Scheduler();
   Init_Traps();
-  Init_Timer();
+  //  Init_Timer();
   Init_Keyboard();
   Init_VM(bootInfo);
   Init_Paging();
@@ -282,6 +286,20 @@ void Main(struct Boot_Info* bootInfo)
 
   SerialPrintLevel(1000,"Next: setup GDT\n");
 
+  {
+    int i = 0;
+    for (i = 0; i < 1024; i++) {
+      uint_t * addr = (uint_t *)0xa00000;
+      uint_t foo = *addr;
+
+      SerialPrint("Read From 0x%x=%d\n", (uint_t)addr, foo);
+    }
+
+  }
+  //  Invalidate_PG((void *)0x2000);
+
+  //  VM_Test(bootInfo, 32);  
+  //VM_Test(bootInfo, 1536);
 
   while(1);
   
index b2837dc..d82f785 100644 (file)
@@ -2,7 +2,7 @@
  * Paging (virtual memory) support
  * Copyright (c) 2003, Jeffrey K. Hollingsworth <hollings@cs.umd.edu>
  * Copyright (c) 2003,2004 David H. Hovemeyer <daveho@cs.umd.edu>
- * $Revision: 1.1 $
+ * $Revision: 1.2 $
  * 
  * This is free software.  You are permitted to use,
  * redistribute, and modify it as specified in the file "COPYING".
@@ -45,11 +45,15 @@ int debugFaults = 0;
 
 void SerialPrintPD(pde_t *pde)
 {
-  int i;
+  uint_t i;
 
   SerialPrint("Page Directory at %p:\n",pde);
-  for (i=0;i<NUM_PAGE_DIR_ENTRIES && pde[i].present;i++) { 
-    SerialPrintPDE((void*)(PAGE_SIZE*NUM_PAGE_TABLE_ENTRIES*i),&(pde[i]));
+  for (i = 0; i < NUM_PAGE_DIR_ENTRIES; i++) { 
+    if (pde[i].present) {
+      if ((i * PAGE_SIZE * 1024) > 0x40000000) {
+       SerialPrintPDE((void*)(PAGE_SIZE*NUM_PAGE_TABLE_ENTRIES*i),&(pde[i]));
+      }
+    }
   }
 }
 
@@ -58,8 +62,10 @@ void SerialPrintPT(void *starting_address, pte_t *pte)
   int i;
 
   SerialPrint("Page Table at %p:\n",pte);
-  for (i=0;i<NUM_PAGE_TABLE_ENTRIES && pte[i].present;i++) { 
-    SerialPrintPTE(starting_address + PAGE_SIZE*i,&(pte[i]));
+  for (i=0;i<NUM_PAGE_TABLE_ENTRIES;i++) { 
+    if (pte[i].present) {
+      SerialPrintPTE(starting_address + PAGE_SIZE*i,&(pte[i]));
+    }
   }
 }
 
@@ -95,13 +101,17 @@ void SerialPrintPTE(void *virtual_address, pte_t *pte)
 
 void SerialDumpPageTables(pde_t *pde)
 {
-  int i;
+  uint_t i;
   
   SerialPrint("Dumping the pages starting with the pde page at %p\n",pde);
 
-  for (i=0;i<NUM_PAGE_DIR_ENTRIES && pde[i].present;i++) { 
-    SerialPrintPDE((void*)(PAGE_SIZE*NUM_PAGE_TABLE_ENTRIES*i),&(pde[i]));
-    SerialPrintPT((void*)(PAGE_SIZE*NUM_PAGE_TABLE_ENTRIES*i),(void*)(pde[i].pageTableBaseAddr<<PAGE_POWER));
+  for (i = 0; i < NUM_PAGE_DIR_ENTRIES; i++) { 
+    if (pde[i].present) {
+      if ((i * PAGE_SIZE * 1024) >= 0x40000000) {
+       SerialPrintPDE((void *)(PAGE_SIZE * NUM_PAGE_TABLE_ENTRIES * i), &(pde[i]));
+       SerialPrintPT((void *)(PAGE_SIZE * NUM_PAGE_TABLE_ENTRIES * i), (void *)(pde[i].pageTableBaseAddr << PAGE_POWER));
+      }
+    }
   }
 }
     
@@ -264,6 +274,8 @@ void Init_VM(struct Boot_Info *bootInfo)
       }
     }
   }
+
+
   SerialPrintLevel(100,"Done creating 1<->1 initial page tables\n");
   SerialPrintLevel(100,"Now installing page fault handler\n");
   //  SerialDumpPageTables(pd);
@@ -275,6 +287,146 @@ void Init_VM(struct Boot_Info *bootInfo)
 }
 
 
+
+/* How we test...
+ * 1 <-> 1 mapping of physical memory, 
+ * We assume that physical memory << 1G
+ * we setup the test so that 1G+ is mapped in a testable order
+ * then go through and ensure that all the paging operations work...
+ * The static mapping sits at 1G
+ * The tests are run at 2G
+
+ */
+
+void VM_Test(struct Boot_Info *bootInfo, uint_t num_test_pages) {
+  int i,j;
+
+  pde_t * pd;
+  //pde_t *pde;
+  //  pte_t *pte;
+
+  PrintBoth("Running Paging Test\n");
+
+  pd = Get_PDBR();
+
+
+  void * one_gig = (void *)0x40000000;
+  void * two_gig = (void *)0x80000000;
+
+  /* Set up the 1 GIG static map */
+  ulong_t pde_offset = (((ulong_t)one_gig / PAGE_SIZE) / 1024);    
+  for (i = 0; i < num_test_pages; i += 1024) {
+    pde_t * pde = &(pd[pde_offset + (i / 1024)]);
+    pte_t * pte = (pte_t *)Alloc_Page();
+    memset(pte, 0, PAGE_SIZE);
+
+    pde->present = 1;
+    pde->flags= VM_READ | VM_WRITE | VM_EXEC | VM_USER;
+    pde->pageTableBaseAddr = PAGE_ALLIGNED_ADDR(pte);
+
+    for (j = 0; (j + i) < num_test_pages ; j++) {
+      pte[j].present = 1;
+      pte[j].flags = VM_READ | VM_WRITE | VM_EXEC | VM_USER;
+      pte[j].pageBaseAddr = PAGE_ALLIGNED_ADDR(Alloc_Page());
+    }
+  }
+
+  PrintBoth("Setup VM Test static map\n");
+
+
+  /* Setup the Two Gig test area */
+  /* First is just a incrmental mirroring of the 1G area */
+
+  pde_offset = (((ulong_t)two_gig / PAGE_SIZE) / 1024);  
+  
+  for (i = 0; i < num_test_pages; i += 1024) {
+    pde_t * pde = &(pd[pde_offset + (i / 1024)]);
+    pte_t * pte = (pte_t *)Alloc_Page();
+    memset(pte, 0, PAGE_SIZE);
+
+    pde->present = 1;
+    pde->flags= VM_READ | VM_WRITE | VM_EXEC | VM_USER;
+    pde->pageTableBaseAddr = PAGE_ALLIGNED_ADDR(pte);
+
+    for (j = 0; (j + i) < num_test_pages; j++) {
+      pte_t * static_pte = LookupPage(one_gig + (PAGE_SIZE * (j+i)));
+      pte[j].present = 1;
+      pte[j].flags = VM_READ | VM_WRITE | VM_EXEC | VM_USER;
+      pte[j].pageBaseAddr = static_pte->pageBaseAddr;
+    }
+  }
+
+  PrintBoth("Setup initial test area\n");
+
+  PrintBoth("Loading CR3\n");
+  Set_PDBR(pd);
+
+  SerialDumpPageTables(pd);
+
+  PrintBoth("Writing to Test Area\n");
+
+  /* Write data to each page in the 2G test area */
+  uint_t * test_ptr = (uint_t *)two_gig;
+  for (i = 0; i < num_test_pages; i++) {
+
+    SerialPrint("Writing %d to %p\n", i, test_ptr);
+    *test_ptr = (uint_t)i;
+    test_ptr += PAGE_SIZE / 4;
+  }
+
+
+  PrintBoth("Reversing Page Mapping\n");
+  
+  /* Reverse 2G test area mapping */
+  
+  pde_offset = (((ulong_t)two_gig / PAGE_SIZE) / 1024);
+
+  for (i = 0; i < num_test_pages; i += 1024) {
+    pde_t * pde = &(pd[pde_offset + (i / 1024)]);
+    pte_t * pte = (pte_t *)(pde->pageTableBaseAddr << 12);
+
+    for (j = 0; (j + i) < num_test_pages ; j++) {
+      pte_t * static_pte = LookupPage(one_gig + (PAGE_SIZE * (num_test_pages - (j+i) - 1)));
+      pte[j].pageBaseAddr = static_pte->pageBaseAddr;
+    } 
+  }
+
+
+  Set_PDBR(pd);
+  
+  PrintBoth("Page Mapping Reversed\n");
+  SerialDumpPageTables(pd);
+
+
+  PrintBoth("Page Consistency Check\n");
+
+  test_ptr = (uint_t *)two_gig;
+  for (i = 0; i < num_test_pages; i++) {
+    if ((*test_ptr) != num_test_pages - (i+1)) {
+      PrintBoth("Consistency Error: (Test Value=%d; Actual Value=%d)\n", (num_test_pages - i), (*test_ptr));
+      while(1);
+    }
+    test_ptr += PAGE_SIZE / 4;
+  }
+
+  PrintBoth("Test Sucessful\n");
+
+
+  PrintBoth("Invalidation Test\n");
+
+
+  Invalidate_PG(two_gig);
+
+  uint_t foo = 0;
+
+  foo = *(uint_t *)two_gig;
+  *(uint_t *)((char *)two_gig + 4) = foo;
+
+
+  PrintBoth("Invalidation Test Successful\n");
+}
+
+
 //
 pte_t *LookupPage(void *vaddr)
 {