KVM supports more than 2GB of memory for x86_64 hosts. The following patch fixes a number of type related issues where int's were being used when they shouldn't have been. It also introduces CMOS support so the BIOS can build the appropriate e820 tables.
For v2 of this patch, I've moved ram_addr_t to cpu-all.h and switched ram_size to be a ram_addr_t. I've also removed the memory limit check for x86_64 (provided kqemu isn't enabled) and enabled the use of a 'M' or 'G' suffix for the -m option. I've also tried to do a more thorough job of updating the code to use the proper types. This patch also includes support for setting up > 2GB of memory for TARGET_I386. KVM works quite happily with 5GB of ram but I suspect there are still some uint32_t's in the non-KVM does not work when using more than 3GB of RAM. Since v2, I got rid of an improper declaration of ram_size by moving it from sysemu.h to cpu-all.h. I also added some code to handle wrap around in the '-m' option. I also eliminated the unnecessary change to TARGET_PAGE_SIZE. diff --git a/cpu-all.h b/cpu-all.h index 7a7e655..cb03072 100644 --- a/cpu-all.h +++ b/cpu-all.h @@ -800,12 +800,16 @@ int cpu_inw(CPUState *env, int addr); int cpu_inl(CPUState *env, int addr); #endif +/* address in the RAM (different from a physical address) */ +typedef unsigned long ram_addr_t; + /* memory API */ -extern int phys_ram_size; +extern ram_addr_t phys_ram_size; extern int phys_ram_fd; extern uint8_t *phys_ram_base; extern uint8_t *phys_ram_dirty; +extern ram_addr_t ram_size; /* physical memory access */ #define TLB_INVALID_MASK (1 << 3) @@ -830,7 +834,7 @@ void cpu_register_physical_memory(target_phys_addr_t start_addr, unsigned long size, unsigned long phys_offset); uint32_t cpu_get_physical_page_desc(target_phys_addr_t addr); -ram_addr_t qemu_ram_alloc(unsigned int size); +ram_addr_t qemu_ram_alloc(unsigned long size); void qemu_ram_free(ram_addr_t addr); int cpu_register_io_memory(int io_index, CPUReadMemoryFunc **mem_read, diff --git a/cpu-defs.h b/cpu-defs.h index 6979c11..60ac4c6 100644 --- a/cpu-defs.h +++ b/cpu-defs.h @@ -76,9 +76,6 @@ typedef uint64_t target_phys_addr_t; #error TARGET_PHYS_ADDR_BITS undefined #endif -/* address in the RAM (different from a physical address) */ -typedef unsigned long ram_addr_t; - #define HOST_LONG_SIZE (HOST_LONG_BITS / 8) #define EXCP_INTERRUPT 0x10000 /* async interruption */ diff --git a/exec.c b/exec.c index e9a5918..1e6ac97 100644 --- a/exec.c +++ b/exec.c @@ -73,6 +73,8 @@ #define TARGET_VIRT_ADDR_SPACE_BITS 42 #elif defined(TARGET_PPC64) #define TARGET_PHYS_ADDR_SPACE_BITS 42 +#elif defined(TARGET_X86_64) && !defined(USE_KQEMU) +#define TARGET_PHYS_ADDR_SPACE_BITS 42 #else /* Note: for compatibility with kqemu, we use 32 bits for x86_64 */ #define TARGET_PHYS_ADDR_SPACE_BITS 32 @@ -87,7 +89,7 @@ spinlock_t tb_lock = SPIN_LOCK_UNLOCKED; uint8_t code_gen_buffer[CODE_GEN_BUFFER_SIZE] __attribute__((aligned (32))); uint8_t *code_gen_ptr; -int phys_ram_size; +ram_addr_t phys_ram_size; int phys_ram_fd; uint8_t *phys_ram_base; uint8_t *phys_ram_dirty; @@ -112,7 +114,7 @@ typedef struct PageDesc { typedef struct PhysPageDesc { /* offset in host memory of the page + io_index in the low 12 bits */ - uint32_t phys_offset; + ram_addr_t phys_offset; } PhysPageDesc; #define L2_BITS 10 @@ -1980,7 +1982,7 @@ static inline void tlb_set_dirty(CPUState *env, static int subpage_register (subpage_t *mmio, uint32_t start, uint32_t end, int memory); -static void *subpage_init (target_phys_addr_t base, uint32_t *phys, +static void *subpage_init (target_phys_addr_t base, ram_addr_t *phys, int orig_memory); #define CHECK_SUBPAGE(addr, start_addr, start_addr2, end_addr, end_addr2, \ need_subpage) \ @@ -2084,12 +2086,12 @@ uint32_t cpu_get_physical_page_desc(target_phys_addr_t addr) } /* XXX: better than nothing */ -ram_addr_t qemu_ram_alloc(unsigned int size) +ram_addr_t qemu_ram_alloc(unsigned long size) { ram_addr_t addr; if ((phys_ram_alloc_offset + size) >= phys_ram_size) { - fprintf(stderr, "Not enough memory (requested_size = %u, max memory = %d)\n", - size, phys_ram_size); + fprintf(stderr, "Not enough memory (requested_size = %lu, max memory = %" PRIu64 ")\n", + size, (uint64_t)phys_ram_size); abort(); } addr = phys_ram_alloc_offset; @@ -2432,7 +2434,7 @@ static int subpage_register (subpage_t *mmio, uint32_t start, uint32_t end, return 0; } -static void *subpage_init (target_phys_addr_t base, uint32_t *phys, +static void *subpage_init (target_phys_addr_t base, ram_addr_t *phys, int orig_memory) { subpage_t *mmio; diff --git a/hw/an5206.c b/hw/an5206.c index 52be63b..7037218 100644 --- a/hw/an5206.c +++ b/hw/an5206.c @@ -30,7 +30,7 @@ void DMA_run (void) /* Board init. */ -static void an5206_init(int ram_size, int vga_ram_size, +static void an5206_init(ram_addr_t ram_size, int vga_ram_size, const char *boot_device, DisplayState *ds, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model) diff --git a/hw/boards.h b/hw/boards.h index 26a9c63..547598e 100644 --- a/hw/boards.h +++ b/hw/boards.h @@ -3,7 +3,7 @@ #ifndef HW_BOARDS_H #define HW_BOARDS_H -typedef void QEMUMachineInitFunc(int ram_size, int vga_ram_size, +typedef void QEMUMachineInitFunc(ram_addr_t ram_size, int vga_ram_size, const char *boot_device, DisplayState *ds, const char *kernel_filename, const char *kernel_cmdline, diff --git a/hw/dummy_m68k.c b/hw/dummy_m68k.c index 705d304..1641d56 100644 --- a/hw/dummy_m68k.c +++ b/hw/dummy_m68k.c @@ -14,7 +14,7 @@ /* Board init. */ -static void dummy_m68k_init(int ram_size, int vga_ram_size, +static void dummy_m68k_init(ram_addr_t ram_size, int vga_ram_size, const char *boot_device, DisplayState *ds, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model) diff --git a/hw/etraxfs.c b/hw/etraxfs.c index dfef962..1934478 100644 --- a/hw/etraxfs.c +++ b/hw/etraxfs.c @@ -109,7 +109,7 @@ static void dummy_cpu_set_irq(void *opaque, int irq, int level) } static -void bareetraxfs_init (int ram_size, int vga_ram_size, +void bareetraxfs_init (ram_addr_t ram_size, int vga_ram_size, const char *boot_device, DisplayState *ds, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model) diff --git a/hw/gumstix.c b/hw/gumstix.c index 2cf52f9..28be8d7 100644 --- a/hw/gumstix.c +++ b/hw/gumstix.c @@ -41,7 +41,7 @@ static const int sector_len = 128 * 1024; -static void connex_init(int ram_size, int vga_ram_size, +static void connex_init(ram_addr_t ram_size, int vga_ram_size, const char *boot_device, DisplayState *ds, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model) @@ -81,7 +81,7 @@ static void connex_init(int ram_size, int vga_ram_size, pxa2xx_gpio_in_get(cpu->gpio)[36]); } -static void verdex_init(int ram_size, int vga_ram_size, +static void verdex_init(ram_addr_t ram_size, int vga_ram_size, const char *boot_device, DisplayState *ds, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model) diff --git a/hw/integratorcp.c b/hw/integratorcp.c index 549cc25..33ae9fb 100644 --- a/hw/integratorcp.c +++ b/hw/integratorcp.c @@ -469,7 +469,7 @@ static void icp_control_init(uint32_t base) /* Board init. */ -static void integratorcp_init(int ram_size, int vga_ram_size, +static void integratorcp_init(ram_addr_t ram_size, int vga_ram_size, const char *boot_device, DisplayState *ds, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model) diff --git a/hw/mainstone.c b/hw/mainstone.c index 5856791..15f2465 100644 --- a/hw/mainstone.c +++ b/hw/mainstone.c @@ -59,7 +59,7 @@ static struct keymap map[0xE0] = { enum mainstone_model_e { mainstone }; -static void mainstone_common_init(int ram_size, int vga_ram_size, +static void mainstone_common_init(ram_addr_t ram_size, int vga_ram_size, DisplayState *ds, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model, enum mainstone_model_e model, int arm_id) @@ -125,7 +125,7 @@ static void mainstone_common_init(int ram_size, int vga_ram_size, initrd_filename, arm_id, PXA2XX_SDRAM_BASE); } -static void mainstone_init(int ram_size, int vga_ram_size, +static void mainstone_init(ram_addr_t ram_size, int vga_ram_size, const char *boot_device, DisplayState *ds, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model) diff --git a/hw/mcf5208.c b/hw/mcf5208.c index d7e7dcf..5c05bf0 100644 --- a/hw/mcf5208.c +++ b/hw/mcf5208.c @@ -202,7 +202,7 @@ static void mcf5208_sys_init(qemu_irq *pic) } } -static void mcf5208evb_init(int ram_size, int vga_ram_size, +static void mcf5208evb_init(ram_addr_t ram_size, int vga_ram_size, const char *boot_device, DisplayState *ds, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model) diff --git a/hw/mips_malta.c b/hw/mips_malta.c index 1ab5940..f3ce4ee 100644 --- a/hw/mips_malta.c +++ b/hw/mips_malta.c @@ -763,7 +763,7 @@ static void main_cpu_reset(void *opaque) } static -void mips_malta_init (int ram_size, int vga_ram_size, +void mips_malta_init (ram_addr_t ram_size, int vga_ram_size, const char *boot_device, DisplayState *ds, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model) diff --git a/hw/mips_mipssim.c b/hw/mips_mipssim.c index fe75314..56bb0da 100644 --- a/hw/mips_mipssim.c +++ b/hw/mips_mipssim.c @@ -106,7 +106,7 @@ static void main_cpu_reset(void *opaque) } static void -mips_mipssim_init (int ram_size, int vga_ram_size, +mips_mipssim_init (ram_addr_t ram_size, int vga_ram_size, const char *boot_device, DisplayState *ds, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model) diff --git a/hw/mips_pica61.c b/hw/mips_pica61.c index dfbc2f0..e971faf 100644 --- a/hw/mips_pica61.c +++ b/hw/mips_pica61.c @@ -63,7 +63,7 @@ static void main_cpu_reset(void *opaque) } static -void mips_pica61_init (int ram_size, int vga_ram_size, +void mips_pica61_init (ram_addr_t ram_size, int vga_ram_size, const char *boot_device, DisplayState *ds, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model) diff --git a/hw/mips_r4k.c b/hw/mips_r4k.c index 63bd158..d723f4b 100644 --- a/hw/mips_r4k.c +++ b/hw/mips_r4k.c @@ -145,7 +145,7 @@ static void main_cpu_reset(void *opaque) } static -void mips_r4k_init (int ram_size, int vga_ram_size, +void mips_r4k_init (ram_addr_t ram_size, int vga_ram_size, const char *boot_device, DisplayState *ds, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model) diff --git a/hw/palm.c b/hw/palm.c index 9400ea7..d1f5129 100644 --- a/hw/palm.c +++ b/hw/palm.c @@ -183,7 +183,7 @@ static void palmte_gpio_setup(struct omap_mpu_state_s *cpu) qemu_irq_raise(omap_mpuio_in_get(cpu->mpuio)[11]); } -static void palmte_init(int ram_size, int vga_ram_size, +static void palmte_init(ram_addr_t ram_size, int vga_ram_size, const char *boot_device, DisplayState *ds, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model) diff --git a/hw/pc.c b/hw/pc.c index b3885e8..d609baa 100644 --- a/hw/pc.c +++ b/hw/pc.c @@ -181,7 +181,8 @@ static int boot_device2nibble(char boot_device) } /* hd_table must contain 4 block drivers */ -static void cmos_init(int ram_size, const char *boot_device, BlockDriverState **hd_table) +static void cmos_init(ram_addr_t ram_size, ram_addr_t above_4g_mem_size, + const char *boot_device, BlockDriverState **hd_table) { RTCState *s = rtc_state; int nbds, bds[3] = { 0, }; @@ -204,6 +205,12 @@ static void cmos_init(int ram_size, const char *boot_device, BlockDriverState ** rtc_set_memory(s, 0x30, val); rtc_set_memory(s, 0x31, val >> 8); + if (above_4g_mem_size) { + rtc_set_memory(s, 0x5b, (unsigned int)above_4g_mem_size >> 16); + rtc_set_memory(s, 0x5c, (unsigned int)above_4g_mem_size >> 24); + rtc_set_memory(s, 0x5d, (uint64_t)above_4g_mem_size >> 32); + } + if (ram_size > (16 * 1024 * 1024)) val = (ram_size / 65536) - ((16 * 1024 * 1024) / 65536); else @@ -697,7 +704,7 @@ static void pc_init_ne2k_isa(NICInfo *nd, qemu_irq *pic) } /* PC hardware initialisation */ -static void pc_init1(int ram_size, int vga_ram_size, +static void pc_init1(ram_addr_t ram_size, int vga_ram_size, const char *boot_device, DisplayState *ds, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, @@ -706,6 +713,7 @@ static void pc_init1(int ram_size, int vga_ram_size, char buf[1024]; int ret, linux_boot, i; ram_addr_t ram_addr, vga_ram_addr, bios_offset, vga_bios_offset; + ram_addr_t below_4g_mem_size, above_4g_mem_size = 0; int bios_size, isa_bios_size, vga_bios_size; PCIBus *pci_bus; int piix3_devfn = -1; @@ -717,6 +725,17 @@ static void pc_init1(int ram_size, int vga_ram_size, BlockDriverState *hd[MAX_IDE_BUS * MAX_IDE_DEVS]; BlockDriverState *fd[MAX_FD]; + if (ram_size >= 0xe0000000 ) { + above_4g_mem_size = ram_size - 0xe0000000; + below_4g_mem_size = 0xe0000000; + + /* we need to cover the 4G memory hole, since this memory is never + * touched, it shouldn't result in greater memory usage */ + ram_size += 0x20000000; + } else { + below_4g_mem_size = ram_size; + } + linux_boot = (kernel_filename != NULL); /* init CPUs */ @@ -750,7 +769,13 @@ static void pc_init1(int ram_size, int vga_ram_size, /* allocate RAM */ ram_addr = qemu_ram_alloc(ram_size); - cpu_register_physical_memory(0, ram_size, ram_addr); + cpu_register_physical_memory(0, below_4g_mem_size, ram_addr); + + /* above 4giga memory allocation */ + if (above_4g_mem_size > 0) { + cpu_register_physical_memory(0x100000000ULL, above_4g_mem_size, + ram_addr + 0x100000000ULL); + } /* allocate VGA RAM */ vga_ram_addr = qemu_ram_alloc(vga_ram_size); @@ -970,7 +995,7 @@ static void pc_init1(int ram_size, int vga_ram_size, } floppy_controller = fdctrl_init(i8259[6], 2, 0, 0x3f0, fd); - cmos_init(ram_size, boot_device, hd); + cmos_init(below_4g_mem_size, above_4g_mem_size, boot_device, hd); if (pci_enabled && usb_enabled) { usb_uhci_piix3_init(pci_bus, piix3_devfn + 2); @@ -1010,7 +1035,7 @@ static void pc_init1(int ram_size, int vga_ram_size, } } -static void pc_init_pci(int ram_size, int vga_ram_size, +static void pc_init_pci(ram_addr_t ram_size, int vga_ram_size, const char *boot_device, DisplayState *ds, const char *kernel_filename, const char *kernel_cmdline, @@ -1022,7 +1047,7 @@ static void pc_init_pci(int ram_size, int vga_ram_size, initrd_filename, 1, cpu_model); } -static void pc_init_isa(int ram_size, int vga_ram_size, +static void pc_init_isa(ram_addr_t ram_size, int vga_ram_size, const char *boot_device, DisplayState *ds, const char *kernel_filename, const char *kernel_cmdline, diff --git a/hw/ppc405_boards.c b/hw/ppc405_boards.c index b96a188..4eb402e 100644 --- a/hw/ppc405_boards.c +++ b/hw/ppc405_boards.c @@ -177,7 +177,7 @@ static void ref405ep_fpga_init (uint32_t base) } } -static void ref405ep_init (int ram_size, int vga_ram_size, +static void ref405ep_init (ram_addr_t ram_size, int vga_ram_size, const char *boot_device, DisplayState *ds, const char *kernel_filename, const char *kernel_cmdline, @@ -504,7 +504,7 @@ static void taihu_cpld_init (uint32_t base) } } -static void taihu_405ep_init(int ram_size, int vga_ram_size, +static void taihu_405ep_init(ram_addr_t ram_size, int vga_ram_size, const char *boot_device, DisplayState *ds, const char *kernel_filename, const char *kernel_cmdline, diff --git a/hw/ppc_chrp.c b/hw/ppc_chrp.c index 4437a10..991eb8d 100644 --- a/hw/ppc_chrp.c +++ b/hw/ppc_chrp.c @@ -57,7 +57,7 @@ static CPUReadMemoryFunc *unin_read[] = { }; /* PowerPC Mac99 hardware initialisation */ -static void ppc_core99_init (int ram_size, int vga_ram_size, +static void ppc_core99_init (ram_addr_t ram_size, int vga_ram_size, const char *boot_device, DisplayState *ds, const char *kernel_filename, const char *kernel_cmdline, diff --git a/hw/ppc_oldworld.c b/hw/ppc_oldworld.c index 6b4f202..92beeeb 100644 --- a/hw/ppc_oldworld.c +++ b/hw/ppc_oldworld.c @@ -103,7 +103,7 @@ static int vga_osi_call (CPUState *env) return 1; /* osi_call handled */ } -static void ppc_heathrow_init (int ram_size, int vga_ram_size, +static void ppc_heathrow_init (ram_addr_t ram_size, int vga_ram_size, const char *boot_device, DisplayState *ds, const char *kernel_filename, const char *kernel_cmdline, diff --git a/hw/ppc_prep.c b/hw/ppc_prep.c index c42688e..779a283 100644 --- a/hw/ppc_prep.c +++ b/hw/ppc_prep.c @@ -535,7 +535,7 @@ CPUReadMemoryFunc *PPC_prep_io_read[] = { #define NVRAM_SIZE 0x2000 /* PowerPC PREP hardware initialisation */ -static void ppc_prep_init (int ram_size, int vga_ram_size, +static void ppc_prep_init (ram_addr_t ram_size, int vga_ram_size, const char *boot_device, DisplayState *ds, const char *kernel_filename, const char *kernel_cmdline, diff --git a/hw/r2d.c b/hw/r2d.c index b6cc31c..1ea763b 100644 --- a/hw/r2d.c +++ b/hw/r2d.c @@ -30,7 +30,7 @@ #define SDRAM_BASE 0x0c000000 /* Physical location of SDRAM: Area 3 */ #define SDRAM_SIZE 0x04000000 -static void r2d_init(int ram_size, int vga_ram_size, +static void r2d_init(ram_addr_t ram_size, int vga_ram_size, const char *boot_device, DisplayState * ds, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model) diff --git a/hw/realview.c b/hw/realview.c index 29579d8..5c62650 100644 --- a/hw/realview.c +++ b/hw/realview.c @@ -18,7 +18,7 @@ /* Board init. */ -static void realview_init(int ram_size, int vga_ram_size, +static void realview_init(ram_addr_t ram_size, int vga_ram_size, const char *boot_device, DisplayState *ds, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model) diff --git a/hw/shix.c b/hw/shix.c index 533b159..241e076 100644 --- a/hw/shix.c +++ b/hw/shix.c @@ -65,7 +65,7 @@ void vga_screen_dump(const char *filename) /* XXXXX */ } -static void shix_init(int ram_size, int vga_ram_size, +static void shix_init(ram_addr_t ram_size, int vga_ram_size, const char *boot_device, DisplayState * ds, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model) diff --git a/hw/spitz.c b/hw/spitz.c index 159c633..0d4e955 100644 --- a/hw/spitz.c +++ b/hw/spitz.c @@ -1180,7 +1180,7 @@ static void sl_bootparam_write(uint32_t ptr) /* Board init. */ enum spitz_model_e { spitz, akita, borzoi, terrier }; -static void spitz_common_init(int ram_size, int vga_ram_size, +static void spitz_common_init(ram_addr_t ram_size, int vga_ram_size, DisplayState *ds, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model, enum spitz_model_e model, int arm_id) @@ -1237,7 +1237,7 @@ static void spitz_common_init(int ram_size, int vga_ram_size, sl_bootparam_write(SL_PXA_PARAM_BASE - PXA2XX_SDRAM_BASE); } -static void spitz_init(int ram_size, int vga_ram_size, +static void spitz_init(ram_addr_t ram_size, int vga_ram_size, const char *boot_device, DisplayState *ds, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model) @@ -1246,7 +1246,7 @@ static void spitz_init(int ram_size, int vga_ram_size, kernel_cmdline, initrd_filename, cpu_model, spitz, 0x2c9); } -static void borzoi_init(int ram_size, int vga_ram_size, +static void borzoi_init(ram_addr_t ram_size, int vga_ram_size, const char *boot_device, DisplayState *ds, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model) @@ -1255,7 +1255,7 @@ static void borzoi_init(int ram_size, int vga_ram_size, kernel_cmdline, initrd_filename, cpu_model, borzoi, 0x33f); } -static void akita_init(int ram_size, int vga_ram_size, +static void akita_init(ram_addr_t ram_size, int vga_ram_size, const char *boot_device, DisplayState *ds, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model) @@ -1264,7 +1264,7 @@ static void akita_init(int ram_size, int vga_ram_size, kernel_cmdline, initrd_filename, cpu_model, akita, 0x2e8); } -static void terrier_init(int ram_size, int vga_ram_size, +static void terrier_init(ram_addr_t ram_size, int vga_ram_size, const char *boot_device, DisplayState *ds, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model) diff --git a/hw/stellaris.c b/hw/stellaris.c index 2fb927b..9af65b8 100644 --- a/hw/stellaris.c +++ b/hw/stellaris.c @@ -1169,7 +1169,7 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model, } /* FIXME: Figure out how to generate these from stellaris_boards. */ -static void lm3s811evb_init(int ram_size, int vga_ram_size, +static void lm3s811evb_init(ram_addr_t ram_size, int vga_ram_size, const char *boot_device, DisplayState *ds, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model) @@ -1177,7 +1177,7 @@ static void lm3s811evb_init(int ram_size, int vga_ram_size, stellaris_init(kernel_filename, cpu_model, ds, &stellaris_boards[0]); } -static void lm3s6965evb_init(int ram_size, int vga_ram_size, +static void lm3s6965evb_init(ram_addr_t ram_size, int vga_ram_size, const char *boot_device, DisplayState *ds, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model) diff --git a/hw/sun4m.c b/hw/sun4m.c index 8b3c49d..6733431 100644 --- a/hw/sun4m.c +++ b/hw/sun4m.c @@ -888,7 +888,7 @@ static const struct hwdef hwdefs[] = { }; /* SPARCstation 5 hardware initialisation */ -static void ss5_init(int RAM_size, int vga_ram_size, +static void ss5_init(ram_addr_t RAM_size, int vga_ram_size, const char *boot_device, DisplayState *ds, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model) @@ -898,7 +898,7 @@ static void ss5_init(int RAM_size, int vga_ram_size, } /* SPARCstation 10 hardware initialisation */ -static void ss10_init(int RAM_size, int vga_ram_size, +static void ss10_init(ram_addr_t RAM_size, int vga_ram_size, const char *boot_device, DisplayState *ds, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model) @@ -908,7 +908,7 @@ static void ss10_init(int RAM_size, int vga_ram_size, } /* SPARCserver 600MP hardware initialisation */ -static void ss600mp_init(int RAM_size, int vga_ram_size, +static void ss600mp_init(ram_addr_t RAM_size, int vga_ram_size, const char *boot_device, DisplayState *ds, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model) @@ -918,7 +918,7 @@ static void ss600mp_init(int RAM_size, int vga_ram_size, } /* SPARCstation 20 hardware initialisation */ -static void ss20_init(int RAM_size, int vga_ram_size, +static void ss20_init(ram_addr_t RAM_size, int vga_ram_size, const char *boot_device, DisplayState *ds, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model) @@ -928,7 +928,7 @@ static void ss20_init(int RAM_size, int vga_ram_size, } /* SPARCstation 2 hardware initialisation */ -static void ss2_init(int RAM_size, int vga_ram_size, +static void ss2_init(ram_addr_t RAM_size, int vga_ram_size, const char *boot_device, DisplayState *ds, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model) @@ -1177,7 +1177,7 @@ static void sun4d_hw_init(const struct sun4d_hwdef *hwdef, int RAM_size, } /* SPARCserver 1000 hardware initialisation */ -static void ss1000_init(int RAM_size, int vga_ram_size, +static void ss1000_init(ram_addr_t RAM_size, int vga_ram_size, const char *boot_device, DisplayState *ds, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model) @@ -1187,7 +1187,7 @@ static void ss1000_init(int RAM_size, int vga_ram_size, } /* SPARCcenter 2000 hardware initialisation */ -static void ss2000_init(int RAM_size, int vga_ram_size, +static void ss2000_init(ram_addr_t RAM_size, int vga_ram_size, const char *boot_device, DisplayState *ds, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model) diff --git a/hw/sun4u.c b/hw/sun4u.c index 183f64a..d99110b 100644 --- a/hw/sun4u.c +++ b/hw/sun4u.c @@ -227,7 +227,7 @@ static const int parallel_irq[MAX_PARALLEL_PORTS] = { 7, 7, 7 }; static fdctrl_t *floppy_controller; /* Sun4u hardware initialisation */ -static void sun4u_init(int ram_size, int vga_ram_size, +static void sun4u_init(ram_addr_t ram_size, int vga_ram_size, const char *boot_devices, DisplayState *ds, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model) diff --git a/hw/versatilepb.c b/hw/versatilepb.c index da6e4ec..06e183b 100644 --- a/hw/versatilepb.c +++ b/hw/versatilepb.c @@ -157,7 +157,7 @@ static qemu_irq *vpb_sic_init(uint32_t base, qemu_irq *parent, int irq) peripherans and expansion busses. For now we emulate a subset of the PB peripherals and just change the board ID. */ -static void versatile_init(int ram_size, int vga_ram_size, +static void versatile_init(ram_addr_t ram_size, int vga_ram_size, const char *boot_device, DisplayState *ds, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model, @@ -287,7 +287,7 @@ static void versatile_init(int ram_size, int vga_ram_size, initrd_filename, board_id, 0x0); } -static void vpb_init(int ram_size, int vga_ram_size, +static void vpb_init(ram_addr_t ram_size, int vga_ram_size, const char *boot_device, DisplayState *ds, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model) @@ -298,7 +298,7 @@ static void vpb_init(int ram_size, int vga_ram_size, initrd_filename, cpu_model, 0x183); } -static void vab_init(int ram_size, int vga_ram_size, +static void vab_init(ram_addr_t ram_size, int vga_ram_size, const char *boot_device, DisplayState *ds, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model) diff --git a/osdep.c b/osdep.c index f824bc1..aa26fec 100644 --- a/osdep.c +++ b/osdep.c @@ -113,7 +113,6 @@ static void *kqemu_vmalloc(size_t size) int64_t free_space; int ram_mb; - extern int ram_size; free_space = (int64_t)stfs.f_bavail * stfs.f_bsize; if ((ram_size + 8192 * 1024) >= free_space) { ram_mb = (ram_size / (1024 * 1024)); diff --git a/qemu-doc.texi b/qemu-doc.texi index f9924d2..ba82a49 100644 --- a/qemu-doc.texi +++ b/qemu-doc.texi @@ -321,7 +321,9 @@ Disable boot signature checking for floppy disks in Bochs BIOS. It may be needed to boot from old floppy disks. @item -m @var{megs} -Set virtual RAM size to @var{megs} megabytes. Default is 128 MiB. +Set virtual RAM size to @var{megs} megabytes. Default is 128 MiB. Optionally, +a suffix of ``M'' or ``G'' can be used to signify a value in megabytes or +gigabytes respectively. @item -smp @var{n} Simulate an SMP system with @var{n} CPUs. On the PC target, up to 255 diff --git a/sysemu.h b/sysemu.h index 29377bf..66837a6 100644 --- a/sysemu.h +++ b/sysemu.h @@ -1,5 +1,6 @@ #ifndef SYSEMU_H #define SYSEMU_H + /* Misc. things related to the system emulator. */ /* vl.c */ @@ -69,7 +70,6 @@ int tap_win32_init(VLANState *vlan, const char *ifname); /* SLIRP */ void do_info_slirp(void); -extern int ram_size; extern int bios_size; extern int rtc_utc; extern int rtc_start_date; diff --git a/vl.c b/vl.c index deff149..f37bc7a 100644 --- a/vl.c +++ b/vl.c @@ -142,8 +142,6 @@ int inet_aton(const char *cp, struct in_addr *ia); //#define DEBUG_UNUSED_IOPORT //#define DEBUG_IOPORT -#define PHYS_RAM_MAX_SIZE (2047 * 1024 * 1024) - #ifdef TARGET_PPC #define DEFAULT_RAM_SIZE 144 #else @@ -174,7 +172,7 @@ static DisplayState display_state; int nographic; const char* keyboard_layout = NULL; int64_t ticks_per_sec; -int ram_size; +ram_addr_t ram_size; int pit_min_timer_count = 0; int nb_nics; NICInfo nd_table[MAX_NICS]; @@ -6828,7 +6826,8 @@ static int ram_get_page(QEMUFile *f, uint8_t *buf, int len) static int ram_load_v1(QEMUFile *f, void *opaque) { - int i, ret; + int ret; + ram_addr_t i; if (qemu_get_be32(f) != phys_ram_size) return -EINVAL; @@ -6964,7 +6963,7 @@ static void ram_decompress_close(RamDecompressState *s) static void ram_save(QEMUFile *f, void *opaque) { - int i; + ram_addr_t i; RamCompressState s1, *s = &s1; uint8_t buf[10]; @@ -7009,7 +7008,7 @@ static int ram_load(QEMUFile *f, void *opaque, int version_id) { RamDecompressState s1, *s = &s1; uint8_t buf[10]; - int i; + ram_addr_t i; if (version_id == 1) return ram_load_v1(f, opaque); @@ -7026,7 +7025,7 @@ static int ram_load(QEMUFile *f, void *opaque, int version_id) } if (buf[0] == 0) { if (ram_decompress_buf(s, phys_ram_base + i, BDRV_HASH_BLOCK_SIZE) < 0) { - fprintf(stderr, "Error while reading ram block address=0x%08x", i); + fprintf(stderr, "Error while reading ram block address=0x%08" PRIx64, (uint64_t)i); goto error; } } else @@ -8456,16 +8455,39 @@ int main(int argc, char **argv) case QEMU_OPTION_h: help(0); break; - case QEMU_OPTION_m: - ram_size = atoi(optarg) * 1024 * 1024; - if (ram_size <= 0) - help(1); - if (ram_size > PHYS_RAM_MAX_SIZE) { - fprintf(stderr, "qemu: at most %d MB RAM can be simulated\n", - PHYS_RAM_MAX_SIZE / (1024 * 1024)); + case QEMU_OPTION_m: { + uint64_t value; + char *ptr; + + value = strtoul(optarg, &ptr, 10); + switch (*ptr) { + case 0: case 'M': case 'm': + value <<= 20; + break; + case 'G': case 'g': + value <<= 30; + break; + default: + fprintf(stderr, "qemu: invalid ram size: %s\n", optarg); + exit(1); + } + + if (value != (uint64_t)(ram_addr_t)value) { + fprintf(stderr, "qemu: ram size too large\n"); + exit(1); + } + + /* On 32-bit hosts, QEMU is limited by virtual address space */ + if (ram_size > (2047 << 20) +#ifndef USE_KQEMU + && HOST_LONG_BITS == 32 +#endif + ) { + fprintf(stderr, "qemu: at most 2047 MB RAM can be simulated\n"); exit(1); } break; + } case QEMU_OPTION_d: { int mask; @@ -8866,6 +8888,13 @@ int main(int argc, char **argv) /* init the memory */ phys_ram_size = ram_size + vga_ram_size + MAX_BIOS_SIZE; +#if defined(TARGET_I386) + /* Extra ram for 4G memory hole */ + if (ram_size > 0xe0000000) { + phys_ram_size += 0x20000000; + } +#endif + phys_ram_base = qemu_vmalloc(phys_ram_size); if (!phys_ram_base) { fprintf(stderr, "Could not allocate physical memory\n");