added generic physical memory dirty bit support
authorbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>
Fri, 6 Feb 2004 19:46:14 +0000 (19:46 +0000)
committerbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>
Fri, 6 Feb 2004 19:46:14 +0000 (19:46 +0000)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@601 c046a42c-6fe2-441c-8c8c-71466251a162

cpu-all.h
exec-all.h
exec.c
softmmu_template.h
vl.c

index 1cf35ea..a01818a 100644 (file)
--- a/cpu-all.h
+++ b/cpu-all.h
@@ -500,6 +500,7 @@ int cpu_inl(CPUState *env, int addr);
 extern int phys_ram_size;
 extern int phys_ram_fd;
 extern uint8_t *phys_ram_base;
+extern uint8_t *phys_ram_dirty;
 
 /* physical memory access */
 #define IO_MEM_NB_ENTRIES  256
@@ -509,9 +510,11 @@ extern uint8_t *phys_ram_base;
 #define IO_MEM_RAM         (0 << IO_MEM_SHIFT) /* hardcoded offset */
 #define IO_MEM_ROM         (1 << IO_MEM_SHIFT) /* hardcoded offset */
 #define IO_MEM_UNASSIGNED  (2 << IO_MEM_SHIFT)
-#define IO_MEM_CODE        (3 << IO_MEM_SHIFT)
+#define IO_MEM_CODE        (3 << IO_MEM_SHIFT) /* used internally, never use directly */
+#define IO_MEM_NOTDIRTY    (4 << IO_MEM_SHIFT) /* used internally, never use directly */
 
-typedef void CPUWriteMemoryFunc(uint32_t addr, uint32_t value);
+/* NOTE: vaddr is only used internally. Never use it except if you know what you do */
+typedef void CPUWriteMemoryFunc(uint32_t addr, uint32_t value, uint32_t vaddr);
 typedef uint32_t CPUReadMemoryFunc(uint32_t addr);
 
 void cpu_register_physical_memory(unsigned long start_addr, unsigned long size,
@@ -525,6 +528,19 @@ void cpu_physical_memory_rw(CPUState *env, uint8_t *buf, target_ulong addr,
 int cpu_memory_rw_debug(CPUState *env, 
                         uint8_t *buf, target_ulong addr, int len, int is_write);
 
+/* read dirty bit (return 0 or 1) */
+static inline int cpu_physical_memory_is_dirty(target_ulong addr)
+{
+    return phys_ram_dirty[addr >> TARGET_PAGE_BITS];
+}
+
+static inline void cpu_physical_memory_set_dirty(target_ulong addr)
+{
+    phys_ram_dirty[addr >> TARGET_PAGE_BITS] = 1;
+}
+
+void cpu_physical_memory_reset_dirty(target_ulong start, target_ulong end);
+
 /* gdb stub API */
 extern int gdbstub_fd;
 CPUState *cpu_gdbstub_get_env(void *opaque);
index 407e963..500818b 100644 (file)
@@ -530,6 +530,8 @@ static inline target_ulong get_phys_addr_code(CPUState *env, target_ulong addr)
 }
 #else
 /* NOTE: this function can trigger an exception */
+/* NOTE2: the returned address is not exactly the physical address: it
+   is the offset relative to phys_ram_base */
 /* XXX: i386 target specific */
 static inline target_ulong get_phys_addr_code(CPUState *env, target_ulong addr)
 {
diff --git a/exec.c b/exec.c
index 4bf87e3..20a3795 100644 (file)
--- a/exec.c
+++ b/exec.c
@@ -59,6 +59,7 @@ uint8_t *code_gen_ptr;
 int phys_ram_size;
 int phys_ram_fd;
 uint8_t *phys_ram_base;
+uint8_t *phys_ram_dirty;
 
 typedef struct PageDesc {
     /* offset in memory of the page + io_index in the low 12 bits */
@@ -162,7 +163,7 @@ static inline PageDesc *page_find(unsigned int index)
 #if !defined(CONFIG_USER_ONLY)
 static void tlb_protect_code(CPUState *env, uint32_t addr);
 static void tlb_unprotect_code(CPUState *env, uint32_t addr);
-static void tlb_unprotect_code_phys(CPUState *env, uint32_t phys_addr);
+static void tlb_unprotect_code_phys(CPUState *env, uint32_t phys_addr, target_ulong vaddr);
 
 static inline VirtPageDesc *virt_page_find_alloc(unsigned int index)
 {
@@ -528,8 +529,11 @@ static void build_page_bitmap(PageDesc *p)
 
 /* invalidate all TBs which intersect with the target physical page
    starting in range [start;end[. NOTE: start and end must refer to
-   the same physical page */
-static void tb_invalidate_phys_page_range(target_ulong start, target_ulong end)
+   the same physical page. 'vaddr' is a virtual address referencing
+   the physical page of code. It is only used an a hint if there is no
+   code left. */
+static void tb_invalidate_phys_page_range(target_ulong start, target_ulong end, 
+                                          target_ulong vaddr)
 {
     int n;
     PageDesc *p;
@@ -571,13 +575,13 @@ static void tb_invalidate_phys_page_range(target_ulong start, target_ulong end)
     /* if no code remaining, no need to continue to use slow writes */
     if (!p->first_tb) {
         invalidate_page_bitmap(p);
-        tlb_unprotect_code_phys(cpu_single_env, start);
+        tlb_unprotect_code_phys(cpu_single_env, start, vaddr);
     }
 #endif
 }
 
 /* len must be <= 8 and start must be a multiple of len */
-static inline void tb_invalidate_phys_page_fast(target_ulong start, int len)
+static inline void tb_invalidate_phys_page_fast(target_ulong start, int len, target_ulong vaddr)
 {
     PageDesc *p;
     int offset, b;
@@ -592,7 +596,7 @@ static inline void tb_invalidate_phys_page_fast(target_ulong start, int len)
             goto do_invalidate;
     } else {
     do_invalidate:
-        tb_invalidate_phys_page_range(start, start + len);
+        tb_invalidate_phys_page_range(start, start + len, vaddr);
     }
 }
 
@@ -1088,8 +1092,7 @@ static inline void tlb_protect_code1(CPUTLBEntry *tlb_entry, uint32_t addr)
                  (TARGET_PAGE_MASK | TLB_INVALID_MASK)) &&
         (tlb_entry->address & ~TARGET_PAGE_MASK) != IO_MEM_CODE &&
         (tlb_entry->address & ~TARGET_PAGE_MASK) != IO_MEM_ROM) {
-        tlb_entry->address |= IO_MEM_CODE;
-        tlb_entry->addend -= (unsigned long)phys_ram_base;
+        tlb_entry->address = (tlb_entry->address & TARGET_PAGE_MASK) | IO_MEM_CODE;
     }
 }
 
@@ -1116,8 +1119,7 @@ static inline void tlb_unprotect_code1(CPUTLBEntry *tlb_entry, uint32_t addr)
     if (addr == (tlb_entry->address & 
                  (TARGET_PAGE_MASK | TLB_INVALID_MASK)) &&
         (tlb_entry->address & ~TARGET_PAGE_MASK) == IO_MEM_CODE) {
-        tlb_entry->address &= TARGET_PAGE_MASK;
-        tlb_entry->addend += (unsigned long)phys_ram_base;
+        tlb_entry->address = (tlb_entry->address & TARGET_PAGE_MASK) | IO_MEM_NOTDIRTY;
     }
 }
 
@@ -1138,23 +1140,84 @@ static inline void tlb_unprotect_code2(CPUTLBEntry *tlb_entry,
 {
     if ((tlb_entry->address & ~TARGET_PAGE_MASK) == IO_MEM_CODE &&
         ((tlb_entry->address & TARGET_PAGE_MASK) + tlb_entry->addend) == phys_addr) {
-        tlb_entry->address &= TARGET_PAGE_MASK;
-        tlb_entry->addend += (unsigned long)phys_ram_base;
+        tlb_entry->address = (tlb_entry->address & TARGET_PAGE_MASK) | IO_MEM_NOTDIRTY;
     }
 }
 
 /* update the TLB so that writes in physical page 'phys_addr' are no longer
    tested self modifying code */
-/* XXX: find a way to improve it */
-static void tlb_unprotect_code_phys(CPUState *env, uint32_t phys_addr)
+static void tlb_unprotect_code_phys(CPUState *env, uint32_t phys_addr, target_ulong vaddr)
 {
     int i;
 
     phys_addr &= TARGET_PAGE_MASK;
+    phys_addr += (long)phys_ram_base;
+    i = (vaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
+    tlb_unprotect_code2(&env->tlb_write[0][i], phys_addr);
+    tlb_unprotect_code2(&env->tlb_write[1][i], phys_addr);
+}
+
+static inline void tlb_reset_dirty_range(CPUTLBEntry *tlb_entry, 
+                                         unsigned long start, unsigned long length)
+{
+    unsigned long addr;
+    if ((tlb_entry->address & ~TARGET_PAGE_MASK) == IO_MEM_RAM) {
+        addr = (tlb_entry->address & TARGET_PAGE_MASK) + tlb_entry->addend;
+        if ((addr - start) < length) {
+            tlb_entry->address = (tlb_entry->address & TARGET_PAGE_MASK) | IO_MEM_NOTDIRTY;
+        }
+    }
+}
+
+void cpu_physical_memory_reset_dirty(target_ulong start, target_ulong end)
+{
+    CPUState *env;
+    target_ulong length;
+    int i;
+
+    start &= TARGET_PAGE_MASK;
+    end = TARGET_PAGE_ALIGN(end);
+
+    length = end - start;
+    if (length == 0)
+        return;
+    memset(phys_ram_dirty + (start >> TARGET_PAGE_BITS), 0, length >> TARGET_PAGE_BITS);
+
+    env = cpu_single_env;
+    /* we modify the TLB cache so that the dirty bit will be set again
+       when accessing the range */
+    start += (unsigned long)phys_ram_base;
     for(i = 0; i < CPU_TLB_SIZE; i++)
-        tlb_unprotect_code2(&env->tlb_write[0][i], phys_addr);
+        tlb_reset_dirty_range(&env->tlb_write[0][i], start, length);
     for(i = 0; i < CPU_TLB_SIZE; i++)
-        tlb_unprotect_code2(&env->tlb_write[1][i], phys_addr);
+        tlb_reset_dirty_range(&env->tlb_write[1][i], start, length);
+}
+
+static inline void tlb_set_dirty1(CPUTLBEntry *tlb_entry, 
+                                    unsigned long start)
+{
+    unsigned long addr;
+    if ((tlb_entry->address & ~TARGET_PAGE_MASK) == IO_MEM_NOTDIRTY) {
+        addr = (tlb_entry->address & TARGET_PAGE_MASK) + tlb_entry->addend;
+        if (addr == start) {
+            tlb_entry->address = (tlb_entry->address & TARGET_PAGE_MASK) | IO_MEM_RAM;
+        }
+    }
+}
+
+/* update the TLB corresponding to virtual page vaddr and phys addr
+   addr so that it is no longer dirty */
+static inline void tlb_set_dirty(unsigned long addr, target_ulong vaddr)
+{
+    CPUState *env = cpu_single_env;
+    int i;
+
+    phys_ram_dirty[(addr - (unsigned long)phys_ram_base) >> TARGET_PAGE_BITS] = 1;
+
+    addr &= TARGET_PAGE_MASK;
+    i = (vaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
+    tlb_set_dirty1(&env->tlb_write[0][i], addr);
+    tlb_set_dirty1(&env->tlb_write[1][i], addr);
 }
 
 /* add a new TLB entry. At most one entry for a given virtual
@@ -1210,12 +1273,16 @@ int tlb_set_page(CPUState *env, uint32_t vaddr, uint32_t paddr, int prot,
             if ((pd & ~TARGET_PAGE_MASK) == IO_MEM_ROM) {
                 /* ROM: access is ignored (same as unassigned) */
                 env->tlb_write[is_user][index].address = vaddr | IO_MEM_ROM;
-                env->tlb_write[is_user][index].addend = addend - (unsigned long)phys_ram_base;
+                env->tlb_write[is_user][index].addend = addend;
             } else if (first_tb) {
                 /* if code is present, we use a specific memory
                    handler. It works only for physical memory access */
                 env->tlb_write[is_user][index].address = vaddr | IO_MEM_CODE;
-                env->tlb_write[is_user][index].addend = addend - (unsigned long)phys_ram_base;
+                env->tlb_write[is_user][index].addend = addend;
+            } else if ((pd & ~TARGET_PAGE_MASK) == IO_MEM_RAM && 
+                       !cpu_physical_memory_is_dirty(pd)) {
+                env->tlb_write[is_user][index].address = vaddr | IO_MEM_NOTDIRTY;
+                env->tlb_write[is_user][index].addend = addend;
             } else {
                 env->tlb_write[is_user][index].address = address;
                 env->tlb_write[is_user][index].addend = addend;
@@ -1446,6 +1513,10 @@ void page_unprotect_range(uint8_t *data, unsigned long data_size)
     }
 }
 
+static inline void tlb_set_dirty(unsigned long addr, target_ulong vaddr)
+{
+}
+
 #endif /* defined(CONFIG_USER_ONLY) */
 
 /* register physical memory. 'size' must be a multiple of the target
@@ -1471,7 +1542,7 @@ static uint32_t unassigned_mem_readb(uint32_t addr)
     return 0;
 }
 
-static void unassigned_mem_writeb(uint32_t addr, uint32_t val)
+static void unassigned_mem_writeb(uint32_t addr, uint32_t val, uint32_t vaddr)
 {
 }
 
@@ -1490,28 +1561,40 @@ static CPUWriteMemoryFunc *unassigned_mem_write[3] = {
 /* self modifying code support in soft mmu mode : writing to a page
    containing code comes to these functions */
 
-static void code_mem_writeb(uint32_t addr, uint32_t val)
+static void code_mem_writeb(uint32_t addr, uint32_t val, uint32_t vaddr)
 {
+    unsigned long phys_addr;
+
+    phys_addr = addr - (long)phys_ram_base;
 #if !defined(CONFIG_USER_ONLY)
-    tb_invalidate_phys_page_fast(addr, 1);
+    tb_invalidate_phys_page_fast(phys_addr, 1, vaddr);
 #endif
-    stb_raw(phys_ram_base + addr, val);
+    stb_raw((uint8_t *)addr, val);
+    phys_ram_dirty[phys_addr >> TARGET_PAGE_BITS] = 1;
 }
 
-static void code_mem_writew(uint32_t addr, uint32_t val)
+static void code_mem_writew(uint32_t addr, uint32_t val, uint32_t vaddr)
 {
+    unsigned long phys_addr;
+
+    phys_addr = addr - (long)phys_ram_base;
 #if !defined(CONFIG_USER_ONLY)
-    tb_invalidate_phys_page_fast(addr, 2);
+    tb_invalidate_phys_page_fast(phys_addr, 2, vaddr);
 #endif
-    stw_raw(phys_ram_base + addr, val);
+    stw_raw((uint8_t *)addr, val);
+    phys_ram_dirty[phys_addr >> TARGET_PAGE_BITS] = 1;
 }
 
-static void code_mem_writel(uint32_t addr, uint32_t val)
+static void code_mem_writel(uint32_t addr, uint32_t val, uint32_t vaddr)
 {
+    unsigned long phys_addr;
+
+    phys_addr = addr - (long)phys_ram_base;
 #if !defined(CONFIG_USER_ONLY)
-    tb_invalidate_phys_page_fast(addr, 4);
+    tb_invalidate_phys_page_fast(phys_addr, 4, vaddr);
 #endif
-    stl_raw(phys_ram_base + addr, val);
+    stl_raw((uint8_t *)addr, val);
+    phys_ram_dirty[phys_addr >> TARGET_PAGE_BITS] = 1;
 }
 
 static CPUReadMemoryFunc *code_mem_read[3] = {
@@ -1526,12 +1609,40 @@ static CPUWriteMemoryFunc *code_mem_write[3] = {
     code_mem_writel,
 };
 
+static void notdirty_mem_writeb(uint32_t addr, uint32_t val, uint32_t vaddr)
+{
+    stb_raw((uint8_t *)addr, val);
+    tlb_set_dirty(addr, vaddr);
+}
+
+static void notdirty_mem_writew(uint32_t addr, uint32_t val, uint32_t vaddr)
+{
+    stw_raw((uint8_t *)addr, val);
+    tlb_set_dirty(addr, vaddr);
+}
+
+static void notdirty_mem_writel(uint32_t addr, uint32_t val, uint32_t vaddr)
+{
+    stl_raw((uint8_t *)addr, val);
+    tlb_set_dirty(addr, vaddr);
+}
+
+static CPUWriteMemoryFunc *notdirty_mem_write[3] = {
+    notdirty_mem_writeb,
+    notdirty_mem_writew,
+    notdirty_mem_writel,
+};
+
 static void io_mem_init(void)
 {
     cpu_register_io_memory(IO_MEM_ROM >> IO_MEM_SHIFT, code_mem_read, unassigned_mem_write);
     cpu_register_io_memory(IO_MEM_UNASSIGNED >> IO_MEM_SHIFT, unassigned_mem_read, unassigned_mem_write);
     cpu_register_io_memory(IO_MEM_CODE >> IO_MEM_SHIFT, code_mem_read, code_mem_write);
-    io_mem_nb = 4;
+    cpu_register_io_memory(IO_MEM_NOTDIRTY >> IO_MEM_SHIFT, code_mem_read, notdirty_mem_write);
+    io_mem_nb = 5;
+
+    /* alloc dirty bits array */
+    phys_ram_dirty = malloc(phys_ram_size >> TARGET_PAGE_BITS);
 }
 
 /* mem_read and mem_write are arrays of functions containing the
@@ -1620,17 +1731,17 @@ void cpu_physical_memory_rw(CPUState *env, uint8_t *buf, target_ulong addr,
                 if (l >= 4 && ((addr & 3) == 0)) {
                     /* 32 bit read access */
                     val = ldl_raw(buf);
-                    io_mem_write[io_index][2](addr, val);
+                    io_mem_write[io_index][2](addr, val, 0);
                     l = 4;
                 } else if (l >= 2 && ((addr & 1) == 0)) {
                     /* 16 bit read access */
                     val = lduw_raw(buf);
-                    io_mem_write[io_index][1](addr, val);
+                    io_mem_write[io_index][1](addr, val, 0);
                     l = 2;
                 } else {
                     /* 8 bit access */
                     val = ldub_raw(buf);
-                    io_mem_write[io_index][0](addr, val);
+                    io_mem_write[io_index][0](addr, val, 0);
                     l = 1;
                 }
             } else {
index 2d3db62..2203c5a 100644 (file)
@@ -76,14 +76,14 @@ static inline void glue(io_write, SUFFIX)(unsigned long physaddr,
 
     index = (tlb_addr >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
 #if SHIFT <= 2
-    io_mem_write[index][SHIFT](physaddr, val);
+    io_mem_write[index][SHIFT](physaddr, val, tlb_addr);
 #else
 #ifdef TARGET_WORDS_BIGENDIAN
-    io_mem_write[index][2](physaddr, val >> 32);
-    io_mem_write[index][2](physaddr + 4, val);
+    io_mem_write[index][2](physaddr, val >> 32, tlb_addr);
+    io_mem_write[index][2](physaddr + 4, val, tlb_addr);
 #else
-    io_mem_write[index][2](physaddr, val);
-    io_mem_write[index][2](physaddr + 4, val >> 32);
+    io_mem_write[index][2](physaddr, val, tlb_addr);
+    io_mem_write[index][2](physaddr + 4, val >> 32, tlb_addr);
 #endif
 #endif /* SHIFT > 2 */
 }
diff --git a/vl.c b/vl.c
index 0ebfa74..0c1f839 100644 (file)
--- a/vl.c
+++ b/vl.c
@@ -233,6 +233,7 @@ int nographic;
 int term_inited;
 int64_t ticks_per_sec;
 int boot_device = 'c';
+static int ram_size;
 
 /***********************************************************/
 /* x86 io ports */
@@ -610,7 +611,7 @@ void cmos_init(void)
     cmos_data[REG_EQUIPMENT_BYTE] |= 0x04; /* PS/2 mouse installed */
 
     /* memory size */
-    val = (phys_ram_size / 1024) - 1024;
+    val = (ram_size / 1024) - 1024;
     if (val > 65535)
         val = 65535;
     cmos_data[0x17] = val;
@@ -618,7 +619,7 @@ void cmos_init(void)
     cmos_data[0x30] = val;
     cmos_data[0x31] = val >> 8;
 
-    val = (phys_ram_size / 65536) - ((16 * 1024 * 1024) / 65536);
+    val = (ram_size / 65536) - ((16 * 1024 * 1024) / 65536);
     if (val > 65535)
         val = 65535;
     cmos_data[0x34] = val;
@@ -3312,7 +3313,7 @@ extern void __sigaction();
 int main(int argc, char **argv)
 {
     int c, ret, initrd_size, i, use_gdbstub, gdbstub_port, long_index;
-    int snapshot, linux_boot, total_ram_size;
+    int snapshot, linux_boot;
 #if defined (TARGET_I386)
     struct linux_params *params;
 #endif
@@ -3331,7 +3332,7 @@ int main(int argc, char **argv)
         fd_filename[i] = NULL;
     for(i = 0; i < MAX_DISKS; i++)
         hd_filename[i] = NULL;
-    phys_ram_size = 32 * 1024 * 1024;
+    ram_size = 32 * 1024 * 1024;
     vga_ram_size = VGA_RAM_SIZE;
 #if defined (TARGET_I386)
     pstrcpy(network_script, sizeof(network_script), DEFAULT_NETWORK_SCRIPT);
@@ -3425,10 +3426,10 @@ int main(int argc, char **argv)
             help();
             break;
         case 'm':
-            phys_ram_size = atoi(optarg) * 1024 * 1024;
-            if (phys_ram_size <= 0)
+            ram_size = atoi(optarg) * 1024 * 1024;
+            if (ram_size <= 0)
                 help();
-            if (phys_ram_size > PHYS_RAM_MAX_SIZE) {
+            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));
                 exit(1);
@@ -3489,10 +3490,10 @@ int main(int argc, char **argv)
 #endif
 
     /* init the memory */
-    total_ram_size = phys_ram_size + vga_ram_size;
+    phys_ram_size = ram_size + vga_ram_size;
 
 #ifdef CONFIG_SOFTMMU
-    phys_ram_base = malloc(total_ram_size);
+    phys_ram_base = memalign(TARGET_PAGE_SIZE, phys_ram_size);
     if (!phys_ram_base) {
         fprintf(stderr, "Could not allocate physical memory\n");
         exit(1);
@@ -3518,10 +3519,10 @@ int main(int argc, char **argv)
                     phys_ram_file);
             exit(1);
         }
-        ftruncate(phys_ram_fd, total_ram_size);
+        ftruncate(phys_ram_fd, phys_ram_size);
         unlink(phys_ram_file);
-        phys_ram_base = mmap(get_mmap_addr(total_ram_size), 
-                             total_ram_size, 
+        phys_ram_base = mmap(get_mmap_addr(phys_ram_size), 
+                             phys_ram_size, 
                              PROT_WRITE | PROT_READ, MAP_SHARED | MAP_FIXED, 
                              phys_ram_fd, 0);
         if (phys_ram_base == MAP_FAILED) {
@@ -3551,7 +3552,7 @@ int main(int argc, char **argv)
     init_ioports();
 
     /* allocate RAM */
-    cpu_register_physical_memory(0, phys_ram_size, 0);
+    cpu_register_physical_memory(0, ram_size, 0);
 
     if (linux_boot) {
         /* now we can load the kernel */
@@ -3580,7 +3581,7 @@ int main(int argc, char **argv)
         params->mount_root_rdonly = 0;
         stw_raw(&params->cl_magic, 0xA33F);
         stw_raw(&params->cl_offset, params->commandline - (uint8_t *)params);
-        stl_raw(&params->alt_mem_k, (phys_ram_size / 1024) - 1024);
+        stl_raw(&params->alt_mem_k, (ram_size / 1024) - 1024);
         pstrcat(params->commandline, sizeof(params->commandline), kernel_cmdline);
         params->loader_type = 0x01;
         if (initrd_size > 0) {
@@ -3617,7 +3618,7 @@ int main(int argc, char **argv)
         env->regs[R_ESI] = KERNEL_PARAMS_ADDR;
         env->eflags = 0x2;
 #elif defined (TARGET_PPC)
-        PPC_init_hw(env, phys_ram_size, KERNEL_LOAD_ADDR, ret,
+        PPC_init_hw(env, ram_size, KERNEL_LOAD_ADDR, ret,
                     KERNEL_STACK_ADDR, boot_device);
 #endif
     } else {
@@ -3669,7 +3670,7 @@ int main(int argc, char **argv)
     /* init basic PC hardware */
     register_ioport_write(0x80, 1, ioport80_write, 1);
 
-    vga_initialize(ds, phys_ram_base + phys_ram_size, phys_ram_size, 
+    vga_initialize(ds, phys_ram_base + ram_size, ram_size, 
              vga_ram_size);
 #if defined (TARGET_I386)
     cmos_init();