From: Jack Lange Date: Thu, 19 Feb 2009 23:52:20 +0000 (-0600) Subject: added configurable memory sizes X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?p=palacios.git;a=commitdiff_plain;h=debabd511ff9dc2d0e6cd608045ac44295fe7319 added configurable memory sizes --- diff --git a/palacios/include/palacios/vm_guest.h b/palacios/include/palacios/vm_guest.h index 64b5a71..d7fcdeb 100644 --- a/palacios/include/palacios/vm_guest.h +++ b/palacios/include/palacios/vm_guest.h @@ -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; diff --git a/palacios/src/devices/nvram.c b/palacios/src/devices/nvram.c index 5d433bb..a8bfc53 100644 --- a/palacios/src/devices/nvram.c +++ b/palacios/src/devices/nvram.c @@ -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); diff --git a/palacios/src/palacios/vmm_config.c b/palacios/src/palacios/vmm_config.c index 5e0defc..32e3862 100644 --- a/palacios/src/palacios/vmm_config.c +++ b/palacios/src/palacios/vmm_config.c @@ -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);