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 configurable memory sizes
Jack Lange [Thu, 19 Feb 2009 23:52:20 +0000 (17:52 -0600)]
palacios/include/palacios/vm_guest.h
palacios/src/devices/nvram.c
palacios/src/palacios/vmm_config.c

index 64b5a71..d7fcdeb 100644 (file)
@@ -119,7 +119,7 @@ struct guest_info {
 
   uint_t cpl;
 
-  addr_t mem_size; // Probably in bytes for now....
+  addr_t mem_size; // In bytes for now
   v3_shdw_map_t mem_map;
 
 
index 5d433bb..a8bfc53 100644 (file)
@@ -79,7 +79,6 @@ typedef enum {NVRAM_READY, NVRAM_REG_POSTED} nvram_state_t;
 #define NVRAM_REG_AMI_BIG_MEMORY_HIGH     0x35
 #define NVRAM_REG_AMI_BIG_MEMORY_LOW      0x34
 
-
 #define NVRAM_REG_CSUM_HIGH               0x2e
 #define NVRAM_REG_CSUM_LOW                0x2f
 #define NVRAM_REG_IBM_CENTURY_BYTE        0x32  
@@ -427,7 +426,51 @@ static int handle_timer_event(struct guest_info * info,
   return 0;
 }
 
-static int set_nvram_defaults(struct vm_device * dev) {
+
+
+static void set_memory_size(struct nvram_internal * nvram, addr_t bytes) {
+  // 1. Conventional Mem: 0-640k in K
+  // 2. Extended Mem: 0-16MB in K
+  // 3. Big Mem: 0-4G in 64K
+
+  if (bytes > 640 * 1024) {
+    nvram->mem_state[NVRAM_REG_BASE_MEMORY_HIGH] = 0x02;
+    nvram->mem_state[NVRAM_REG_BASE_MEMORY_LOW] = 0x80;
+  } else {
+    uint16_t memk = bytes * 1024;
+    nvram->mem_state[NVRAM_REG_BASE_MEMORY_HIGH] = (memk >> 8) & 0x00ff;
+    nvram->mem_state[NVRAM_REG_BASE_MEMORY_LOW] = memk & 0x00ff;
+
+    return;
+  }
+
+  if (bytes > (16 * 1024 * 1024)) {
+    // Set extended memory to 15 MB
+    nvram->mem_state[NVRAM_REG_EXT_MEMORY_HIGH] = 0x3C;
+    nvram->mem_state[NVRAM_REG_EXT_MEMORY_LOW] = 0x00;
+    nvram->mem_state[NVRAM_REG_EXT_MEMORY_2ND_HIGH]= 0x3C;
+    nvram->mem_state[NVRAM_REG_EXT_MEMORY_2ND_LOW]= 0x00;
+  } else {
+    uint16_t memk = bytes * 1024;
+    nvram->mem_state[NVRAM_REG_EXT_MEMORY_HIGH] = (memk >> 8) & 0x00ff;
+    nvram->mem_state[NVRAM_REG_EXT_MEMORY_LOW] = memk & 0x00ff;
+    nvram->mem_state[NVRAM_REG_EXT_MEMORY_2ND_HIGH]= (memk >> 8) & 0x00ff;
+    nvram->mem_state[NVRAM_REG_EXT_MEMORY_2ND_LOW]= memk & 0x00ff;
+
+    return;
+  }
+
+  {
+    // Set the extended memory beyond 16 MB in 64k chunks
+    uint16_t mem_chunks = bytes * (1024 / 64);
+    nvram->mem_state[NVRAM_REG_AMI_BIG_MEMORY_HIGH] = (mem_chunks >> 8) & 0x00ff;
+    nvram->mem_state[NVRAM_REG_AMI_BIG_MEMORY_LOW] = mem_chunks & 0x00ff;
+  }
+
+  return;
+}
+
+static int init_nvram_state(struct vm_device * dev) {
   struct guest_info * info = dev->vm;
   struct nvram_internal * nvram_state = (struct nvram_internal *)dev->private_data;
   
@@ -438,6 +481,9 @@ static int set_nvram_defaults(struct vm_device * dev) {
   PrintError("TODO: Set the nvram memory register to reflect info->mem_size (%p)\n", (void *)(info->mem_size));
   
 
+  memset(nvram_state->mem_state, 0, NVRAM_REG_MAX);
+
+
   //
   // 2 1.44 MB floppy drives
   //
@@ -461,30 +507,13 @@ static int set_nvram_defaults(struct vm_device * dev) {
   // For new boot sequence style, do cd, hd, floppy
   nvram_state->mem_state[NVRAM_REG_BOOTSEQ_NEW_FIRST] = 0x23;
   nvram_state->mem_state[NVRAM_REG_BOOTSEQ_NEW_SECOND] = 0x10;
-
+  
+  
   // Set equipment byte to note 2 floppies, vga display, keyboard,math,floppy
   nvram_state->mem_state[NVRAM_REG_EQUIPMENT_BYTE] = 0x4f;
-  //nvram_state->mem_state[NVRAM_REG_EQUIPMENT_BYTE] = 0xf;
-
-  // Set conventional memory to 640K
-  nvram_state->mem_state[NVRAM_REG_BASE_MEMORY_HIGH] = 0x02;
-  nvram_state->mem_state[NVRAM_REG_BASE_MEMORY_LOW] = 0x80;
-
-  // Set extended memory to 15 MB
-  nvram_state->mem_state[NVRAM_REG_EXT_MEMORY_HIGH] = 0x3C;
-  nvram_state->mem_state[NVRAM_REG_EXT_MEMORY_LOW] = 0x00;
-  nvram_state->mem_state[NVRAM_REG_EXT_MEMORY_2ND_HIGH]= 0x3C;
-  nvram_state->mem_state[NVRAM_REG_EXT_MEMORY_2ND_LOW]= 0x00;
-
-  // Set the extended memory beyond 16 MB to 128-16 MB
-  nvram_state->mem_state[NVRAM_REG_AMI_BIG_MEMORY_HIGH] = 0x7;
-  nvram_state->mem_state[NVRAM_REG_AMI_BIG_MEMORY_LOW] = 0x00;
-
-  //nvram_state->mem_state[NVRAM_REG_AMI_BIG_MEMORY_HIGH]= 0x00;
-  //nvram_state->mem_state[NVRAM_REG_AMI_BIG_MEMORY_LOW]= 0x00;
-
+  // nvram_state->mem_state[NVRAM_REG_EQUIPMENT_BYTE] = 0xf;
   
+
   // This is the harddisk type.... Set accordingly...
   nvram_state->mem_state[NVRAM_IBM_HD_DATA] = 0x20;
 
@@ -520,18 +549,19 @@ static int set_nvram_defaults(struct vm_device * dev) {
   nvram_state->us = 0;
   nvram_state->pus = 0;
 
+  set_memory_size(nvram_state, dev->vm->mem_size);
+
+  nvram_state->dev_state = NVRAM_READY;
+  nvram_state->thereg = 0;
+
   return 0;
 }
 
 
+
+
 static int nvram_reset_device(struct vm_device * dev) {
-  struct nvram_internal * data = (struct nvram_internal *) dev->private_data;
-  
-  PrintDebug("nvram: reset device\n");
-  data->dev_state = NVRAM_READY;
-  data->thereg = 0;
-  
+
   return 0;
 }
 
@@ -601,19 +631,9 @@ static int nvram_write_data_port(ushort_t port,
 
 
 static int nvram_init_device(struct vm_device * dev) {
-
-  struct nvram_internal * data = (struct nvram_internal *)dev->private_data;
-
   PrintDebug("nvram: init_device\n");
 
-  memset(data->mem_state, 0, NVRAM_REG_MAX);
-
-  // Would read state here
-  set_nvram_defaults(dev);
-  
-
-
-  nvram_reset_device(dev);
+  init_nvram_state(dev);
 
   // hook ports
   v3_dev_hook_io(dev, NVRAM_REG_PORT, NULL, &nvram_write_reg_port);
index 5e0defc..32e3862 100644 (file)
@@ -47,8 +47,6 @@
 #define USE_GENERIC 1
 
 
-#define ROMBIOS_START 0x000f0000
-#define VGABIOS_START 0x000c0000
 
 
 
@@ -100,11 +98,14 @@ int v3_config_guest(struct guest_info * info, struct v3_vm_config * config_ptr)
   info->cpu_mode = REAL;
   info->mem_mode = PHYSICAL_MEM;
 
-  // Amount of ram the Guest will have
-  info->mem_size = config_ptr->mem_size;
+  // Amount of ram the Guest will have, rounded to a 4K page boundary
+  info->mem_size = config_ptr->mem_size & ~(addr_t)0xfff;
 
   // Configure the memory map for the guest
-  setup_memory_map(info, config_ptr);
+  if (setup_memory_map(info, config_ptr) == -1) {
+    PrintError("Setting up guest memory map failed...\n");
+    return -1;
+  }
 
   // Configure the devices for the guest
   setup_devices(info, config_ptr);
@@ -134,77 +135,106 @@ int v3_config_guest(struct guest_info * info, struct v3_vm_config * config_ptr)
  * We need to make sure the memory map extends to cover it
  */
 static int setup_memory_map(struct guest_info * info, struct v3_vm_config * config_ptr) {
+  addr_t mem_pages = info->mem_size >> 12;
 
-  /* layout rombios */
-  {
-    uint_t num_pages = (config_ptr->rombios_size + PAGE_SIZE - 1) / PAGE_SIZE;
-    void * guest_mem =  V3_AllocPages(num_pages);
+  PrintDebug("Setting up memory map (memory size=%dMB)\n", (uint_t)(info->mem_size / (1024 * 1024)));
 
-    PrintDebug("Layout Region %d bytes\n", config_ptr->rombios_size);
-    memcpy(V3_VAddr(guest_mem), config_ptr->rombios, config_ptr->rombios_size);
-
-    v3_add_shadow_mem(info, ROMBIOS_START, ROMBIOS_START + (num_pages * PAGE_SIZE) - 1, (addr_t)guest_mem);
-    
-    PrintDebug("Adding Shadow Region (0x%p-0x%p) -> 0x%p\n", 
-              (void *)ROMBIOS_START, 
-              (void *)ROMBIOS_START + (num_pages * PAGE_SIZE), 
-              (void *)guest_mem);
+  // Fill up to the 640K hole
+  if (mem_pages >= 160) {
+    if (v3_add_shadow_mem(info, 0x0, 0xa0000, (addr_t)V3_AllocPages(160)) == -1) {
+      PrintError("Could not map full conventional memory\n");
+      return -1;
+    }
+  } else {
+    // Less than 640k of memory
+    if (v3_add_shadow_mem(info, 0x0, (mem_pages * PAGE_SIZE), (addr_t)V3_AllocPages(mem_pages)) == -1) {
+      PrintError("Could not map subset of conventional memory\n");
+      return -1;
+    };
   }
 
 
+#define VGABIOS_START 0x000c0000
+#define ROMBIOS_START 0x000f0000
+
+  // VGA frame buffer
+  if (1) {
+    if (v3_add_shadow_mem(info, 0xa0000, 0xc0000, 0xa0000) == -1) {
+      PrintError("Could not map VGA framebuffer\n");
+      return -1;
+    }
+  } else {
+    v3_hook_write_mem(info, 0xa0000, 0xc0000, 0xa0000,  passthrough_mem_write, NULL);
+  }  
+
+
   /* layout vgabios */
   {
     uint_t num_pages = (config_ptr->vgabios_size + PAGE_SIZE - 1) / PAGE_SIZE;
     void * guest_mem =  V3_AllocPages(num_pages);
+    addr_t vgabios_end = VGABIOS_START + (num_pages * PAGE_SIZE);
 
     PrintDebug("Layout Region %d bytes\n", config_ptr->vgabios_size);
     memcpy(V3_VAddr(guest_mem), config_ptr->vgabios, config_ptr->vgabios_size);
 
-    v3_add_shadow_mem(info, VGABIOS_START, VGABIOS_START + (num_pages * PAGE_SIZE) - 1, (addr_t)guest_mem);
-    
+    if (v3_add_shadow_mem(info, VGABIOS_START, vgabios_end, (addr_t)guest_mem) == -1) {
+      PrintError("Could not map VGABIOS\n");
+      return -1;
+    }
+
     PrintDebug("Adding Shadow Region (0x%p-0x%p) -> 0x%p\n", 
               (void *)VGABIOS_START, 
-              (void *)VGABIOS_START + (num_pages * PAGE_SIZE), 
+              (void *)vgabios_end, 
               (void *)guest_mem);
-  }
 
-      //     
-  v3_add_shadow_mem(info, 0x0, 0x9ffff, (addr_t)V3_AllocPages(160));
-  
-  if (1) {
-    v3_add_shadow_mem(info, 0xa0000, 0xbffff, 0xa0000); 
-  } else {
-    v3_hook_write_mem(info, 0xa0000, 0xbffff, 0xa0000,  passthrough_mem_write, NULL);
-  }  
-  
-  // TEMP
-  //add_shadow_region_passthrough(info, 0xc0000, 0xc8000, 0xc0000);
-  
-  if (1) {
-    v3_add_shadow_mem(info, 0xc7000, 0xc8000, (addr_t)V3_AllocPages(1));
-    if (v3_add_shadow_mem(info, 0xc8000, 0xf0000, (addr_t)V3_AllocPages(40)) == -1) {
-      PrintDebug("Error adding shadow region\n");
+
+    // Fill in the space between the VGABIOS and the ROMBIOS
+    // We'll just back this to shadow memory for now....
+    if (v3_add_shadow_mem(info, vgabios_end, ROMBIOS_START, 
+                         (addr_t)V3_AllocPages((ROMBIOS_START - vgabios_end) / PAGE_SIZE)) == -1) {
+      PrintError("Could not map VGABIOS->ROMBIOS gap\n");
+      return -1;
     }
-  } else {
-    v3_add_shadow_mem(info, 0xc0000, 0xc8000, 0xc0000);
-    v3_add_shadow_mem(info, 0xc8000, 0xf0000, 0xc8000);
   }
-  
-  
-  if (1) {
-    v3_add_shadow_mem(info, 0x100000, 0x1000000, (addr_t)V3_AllocPages(4096));
-  } else {
-    /* MEMORY HOOK TEST */
-    v3_add_shadow_mem(info, 0x100000, 0xa00000, (addr_t)V3_AllocPages(2304));
-    v3_hook_write_mem(info, 0xa00000, 0xa01000, (addr_t)V3_AllocPages(1), passthrough_mem_write, NULL); 
-    v3_add_shadow_mem(info, 0xa01000, 0x1000000, (addr_t)V3_AllocPages(1791));
+
+  /* layout rombios */
+  {
+    uint_t num_pages = (config_ptr->rombios_size + PAGE_SIZE - 1) / PAGE_SIZE;
+    void * guest_mem =  V3_AllocPages(num_pages);
+    addr_t rombios_end = ROMBIOS_START + (num_pages * PAGE_SIZE);
+
+    PrintDebug("Layout Region %d bytes\n", config_ptr->rombios_size);
+    memcpy(V3_VAddr(guest_mem), config_ptr->rombios, config_ptr->rombios_size);
+
+    if (v3_add_shadow_mem(info, ROMBIOS_START, rombios_end, (addr_t)guest_mem) == -1) {
+      PrintError("Could not map ROMBIOS\n");
+      return -1;
+    }
+    
+    PrintDebug("Adding Shadow Region (0x%p-0x%p) -> 0x%p\n", 
+              (void *)ROMBIOS_START, 
+              (void *)rombios_end, 
+              (void *)guest_mem);
+
+    if (rombios_end != 0x100000) {
+      PrintError("ROMBIOS must reach the 1MB barrier....\n");
+      return -1;
+    }
   }
 
-  v3_add_shadow_mem(info, 0x1000000, 0x8000000, (addr_t)V3_AllocPages(32768));
-  // test - give linux accesss to PCI space - PAD
-  //v3_add_shadow_mem(info, 0xc0000000,0xffffffff,0xc0000000);
-  
+
+
+  // Fill in the extended memory map....
+  {
+    int num_ext_pages = mem_pages - (0x100000 / PAGE_SIZE);
+
+    if (num_ext_pages > 0) {
+      if (v3_add_shadow_mem(info, 0x100000, info->mem_size, (addr_t)V3_AllocPages(num_ext_pages)) == -1) {
+       PrintError("Could not allocate extended shadow memory\n");
+       return -1;
+      }
+    }
+  }
   
   print_shadow_map(info);