Commit 1ccde1cb942f77958776578939bbcfc4c9bdf362

Authored by bellard
1 parent ad081323

added generic physical memory dirty bit support


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@601 c046a42c-6fe2-441c-8c8c-71466251a162
cpu-all.h
... ... @@ -500,6 +500,7 @@ int cpu_inl(CPUState *env, int addr);
500 500 extern int phys_ram_size;
501 501 extern int phys_ram_fd;
502 502 extern uint8_t *phys_ram_base;
  503 +extern uint8_t *phys_ram_dirty;
503 504  
504 505 /* physical memory access */
505 506 #define IO_MEM_NB_ENTRIES 256
... ... @@ -509,9 +510,11 @@ extern uint8_t *phys_ram_base;
509 510 #define IO_MEM_RAM (0 << IO_MEM_SHIFT) /* hardcoded offset */
510 511 #define IO_MEM_ROM (1 << IO_MEM_SHIFT) /* hardcoded offset */
511 512 #define IO_MEM_UNASSIGNED (2 << IO_MEM_SHIFT)
512   -#define IO_MEM_CODE (3 << IO_MEM_SHIFT)
  513 +#define IO_MEM_CODE (3 << IO_MEM_SHIFT) /* used internally, never use directly */
  514 +#define IO_MEM_NOTDIRTY (4 << IO_MEM_SHIFT) /* used internally, never use directly */
513 515  
514   -typedef void CPUWriteMemoryFunc(uint32_t addr, uint32_t value);
  516 +/* NOTE: vaddr is only used internally. Never use it except if you know what you do */
  517 +typedef void CPUWriteMemoryFunc(uint32_t addr, uint32_t value, uint32_t vaddr);
515 518 typedef uint32_t CPUReadMemoryFunc(uint32_t addr);
516 519  
517 520 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,
525 528 int cpu_memory_rw_debug(CPUState *env,
526 529 uint8_t *buf, target_ulong addr, int len, int is_write);
527 530  
  531 +/* read dirty bit (return 0 or 1) */
  532 +static inline int cpu_physical_memory_is_dirty(target_ulong addr)
  533 +{
  534 + return phys_ram_dirty[addr >> TARGET_PAGE_BITS];
  535 +}
  536 +
  537 +static inline void cpu_physical_memory_set_dirty(target_ulong addr)
  538 +{
  539 + phys_ram_dirty[addr >> TARGET_PAGE_BITS] = 1;
  540 +}
  541 +
  542 +void cpu_physical_memory_reset_dirty(target_ulong start, target_ulong end);
  543 +
528 544 /* gdb stub API */
529 545 extern int gdbstub_fd;
530 546 CPUState *cpu_gdbstub_get_env(void *opaque);
... ...
exec-all.h
... ... @@ -530,6 +530,8 @@ static inline target_ulong get_phys_addr_code(CPUState *env, target_ulong addr)
530 530 }
531 531 #else
532 532 /* NOTE: this function can trigger an exception */
  533 +/* NOTE2: the returned address is not exactly the physical address: it
  534 + is the offset relative to phys_ram_base */
533 535 /* XXX: i386 target specific */
534 536 static inline target_ulong get_phys_addr_code(CPUState *env, target_ulong addr)
535 537 {
... ...
... ... @@ -59,6 +59,7 @@ uint8_t *code_gen_ptr;
59 59 int phys_ram_size;
60 60 int phys_ram_fd;
61 61 uint8_t *phys_ram_base;
  62 +uint8_t *phys_ram_dirty;
62 63  
63 64 typedef struct PageDesc {
64 65 /* 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)
162 163 #if !defined(CONFIG_USER_ONLY)
163 164 static void tlb_protect_code(CPUState *env, uint32_t addr);
164 165 static void tlb_unprotect_code(CPUState *env, uint32_t addr);
165   -static void tlb_unprotect_code_phys(CPUState *env, uint32_t phys_addr);
  166 +static void tlb_unprotect_code_phys(CPUState *env, uint32_t phys_addr, target_ulong vaddr);
166 167  
167 168 static inline VirtPageDesc *virt_page_find_alloc(unsigned int index)
168 169 {
... ... @@ -528,8 +529,11 @@ static void build_page_bitmap(PageDesc *p)
528 529  
529 530 /* invalidate all TBs which intersect with the target physical page
530 531 starting in range [start;end[. NOTE: start and end must refer to
531   - the same physical page */
532   -static void tb_invalidate_phys_page_range(target_ulong start, target_ulong end)
  532 + the same physical page. 'vaddr' is a virtual address referencing
  533 + the physical page of code. It is only used an a hint if there is no
  534 + code left. */
  535 +static void tb_invalidate_phys_page_range(target_ulong start, target_ulong end,
  536 + target_ulong vaddr)
533 537 {
534 538 int n;
535 539 PageDesc *p;
... ... @@ -571,13 +575,13 @@ static void tb_invalidate_phys_page_range(target_ulong start, target_ulong end)
571 575 /* if no code remaining, no need to continue to use slow writes */
572 576 if (!p->first_tb) {
573 577 invalidate_page_bitmap(p);
574   - tlb_unprotect_code_phys(cpu_single_env, start);
  578 + tlb_unprotect_code_phys(cpu_single_env, start, vaddr);
575 579 }
576 580 #endif
577 581 }
578 582  
579 583 /* len must be <= 8 and start must be a multiple of len */
580   -static inline void tb_invalidate_phys_page_fast(target_ulong start, int len)
  584 +static inline void tb_invalidate_phys_page_fast(target_ulong start, int len, target_ulong vaddr)
581 585 {
582 586 PageDesc *p;
583 587 int offset, b;
... ... @@ -592,7 +596,7 @@ static inline void tb_invalidate_phys_page_fast(target_ulong start, int len)
592 596 goto do_invalidate;
593 597 } else {
594 598 do_invalidate:
595   - tb_invalidate_phys_page_range(start, start + len);
  599 + tb_invalidate_phys_page_range(start, start + len, vaddr);
596 600 }
597 601 }
598 602  
... ... @@ -1088,8 +1092,7 @@ static inline void tlb_protect_code1(CPUTLBEntry *tlb_entry, uint32_t addr)
1088 1092 (TARGET_PAGE_MASK | TLB_INVALID_MASK)) &&
1089 1093 (tlb_entry->address & ~TARGET_PAGE_MASK) != IO_MEM_CODE &&
1090 1094 (tlb_entry->address & ~TARGET_PAGE_MASK) != IO_MEM_ROM) {
1091   - tlb_entry->address |= IO_MEM_CODE;
1092   - tlb_entry->addend -= (unsigned long)phys_ram_base;
  1095 + tlb_entry->address = (tlb_entry->address & TARGET_PAGE_MASK) | IO_MEM_CODE;
1093 1096 }
1094 1097 }
1095 1098  
... ... @@ -1116,8 +1119,7 @@ static inline void tlb_unprotect_code1(CPUTLBEntry *tlb_entry, uint32_t addr)
1116 1119 if (addr == (tlb_entry->address &
1117 1120 (TARGET_PAGE_MASK | TLB_INVALID_MASK)) &&
1118 1121 (tlb_entry->address & ~TARGET_PAGE_MASK) == IO_MEM_CODE) {
1119   - tlb_entry->address &= TARGET_PAGE_MASK;
1120   - tlb_entry->addend += (unsigned long)phys_ram_base;
  1122 + tlb_entry->address = (tlb_entry->address & TARGET_PAGE_MASK) | IO_MEM_NOTDIRTY;
1121 1123 }
1122 1124 }
1123 1125  
... ... @@ -1138,23 +1140,84 @@ static inline void tlb_unprotect_code2(CPUTLBEntry *tlb_entry,
1138 1140 {
1139 1141 if ((tlb_entry->address & ~TARGET_PAGE_MASK) == IO_MEM_CODE &&
1140 1142 ((tlb_entry->address & TARGET_PAGE_MASK) + tlb_entry->addend) == phys_addr) {
1141   - tlb_entry->address &= TARGET_PAGE_MASK;
1142   - tlb_entry->addend += (unsigned long)phys_ram_base;
  1143 + tlb_entry->address = (tlb_entry->address & TARGET_PAGE_MASK) | IO_MEM_NOTDIRTY;
1143 1144 }
1144 1145 }
1145 1146  
1146 1147 /* update the TLB so that writes in physical page 'phys_addr' are no longer
1147 1148 tested self modifying code */
1148   -/* XXX: find a way to improve it */
1149   -static void tlb_unprotect_code_phys(CPUState *env, uint32_t phys_addr)
  1149 +static void tlb_unprotect_code_phys(CPUState *env, uint32_t phys_addr, target_ulong vaddr)
1150 1150 {
1151 1151 int i;
1152 1152  
1153 1153 phys_addr &= TARGET_PAGE_MASK;
  1154 + phys_addr += (long)phys_ram_base;
  1155 + i = (vaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
  1156 + tlb_unprotect_code2(&env->tlb_write[0][i], phys_addr);
  1157 + tlb_unprotect_code2(&env->tlb_write[1][i], phys_addr);
  1158 +}
  1159 +
  1160 +static inline void tlb_reset_dirty_range(CPUTLBEntry *tlb_entry,
  1161 + unsigned long start, unsigned long length)
  1162 +{
  1163 + unsigned long addr;
  1164 + if ((tlb_entry->address & ~TARGET_PAGE_MASK) == IO_MEM_RAM) {
  1165 + addr = (tlb_entry->address & TARGET_PAGE_MASK) + tlb_entry->addend;
  1166 + if ((addr - start) < length) {
  1167 + tlb_entry->address = (tlb_entry->address & TARGET_PAGE_MASK) | IO_MEM_NOTDIRTY;
  1168 + }
  1169 + }
  1170 +}
  1171 +
  1172 +void cpu_physical_memory_reset_dirty(target_ulong start, target_ulong end)
  1173 +{
  1174 + CPUState *env;
  1175 + target_ulong length;
  1176 + int i;
  1177 +
  1178 + start &= TARGET_PAGE_MASK;
  1179 + end = TARGET_PAGE_ALIGN(end);
  1180 +
  1181 + length = end - start;
  1182 + if (length == 0)
  1183 + return;
  1184 + memset(phys_ram_dirty + (start >> TARGET_PAGE_BITS), 0, length >> TARGET_PAGE_BITS);
  1185 +
  1186 + env = cpu_single_env;
  1187 + /* we modify the TLB cache so that the dirty bit will be set again
  1188 + when accessing the range */
  1189 + start += (unsigned long)phys_ram_base;
1154 1190 for(i = 0; i < CPU_TLB_SIZE; i++)
1155   - tlb_unprotect_code2(&env->tlb_write[0][i], phys_addr);
  1191 + tlb_reset_dirty_range(&env->tlb_write[0][i], start, length);
1156 1192 for(i = 0; i < CPU_TLB_SIZE; i++)
1157   - tlb_unprotect_code2(&env->tlb_write[1][i], phys_addr);
  1193 + tlb_reset_dirty_range(&env->tlb_write[1][i], start, length);
  1194 +}
  1195 +
  1196 +static inline void tlb_set_dirty1(CPUTLBEntry *tlb_entry,
  1197 + unsigned long start)
  1198 +{
  1199 + unsigned long addr;
  1200 + if ((tlb_entry->address & ~TARGET_PAGE_MASK) == IO_MEM_NOTDIRTY) {
  1201 + addr = (tlb_entry->address & TARGET_PAGE_MASK) + tlb_entry->addend;
  1202 + if (addr == start) {
  1203 + tlb_entry->address = (tlb_entry->address & TARGET_PAGE_MASK) | IO_MEM_RAM;
  1204 + }
  1205 + }
  1206 +}
  1207 +
  1208 +/* update the TLB corresponding to virtual page vaddr and phys addr
  1209 + addr so that it is no longer dirty */
  1210 +static inline void tlb_set_dirty(unsigned long addr, target_ulong vaddr)
  1211 +{
  1212 + CPUState *env = cpu_single_env;
  1213 + int i;
  1214 +
  1215 + phys_ram_dirty[(addr - (unsigned long)phys_ram_base) >> TARGET_PAGE_BITS] = 1;
  1216 +
  1217 + addr &= TARGET_PAGE_MASK;
  1218 + i = (vaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
  1219 + tlb_set_dirty1(&env->tlb_write[0][i], addr);
  1220 + tlb_set_dirty1(&env->tlb_write[1][i], addr);
1158 1221 }
1159 1222  
1160 1223 /* 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,
1210 1273 if ((pd & ~TARGET_PAGE_MASK) == IO_MEM_ROM) {
1211 1274 /* ROM: access is ignored (same as unassigned) */
1212 1275 env->tlb_write[is_user][index].address = vaddr | IO_MEM_ROM;
1213   - env->tlb_write[is_user][index].addend = addend - (unsigned long)phys_ram_base;
  1276 + env->tlb_write[is_user][index].addend = addend;
1214 1277 } else if (first_tb) {
1215 1278 /* if code is present, we use a specific memory
1216 1279 handler. It works only for physical memory access */
1217 1280 env->tlb_write[is_user][index].address = vaddr | IO_MEM_CODE;
1218   - env->tlb_write[is_user][index].addend = addend - (unsigned long)phys_ram_base;
  1281 + env->tlb_write[is_user][index].addend = addend;
  1282 + } else if ((pd & ~TARGET_PAGE_MASK) == IO_MEM_RAM &&
  1283 + !cpu_physical_memory_is_dirty(pd)) {
  1284 + env->tlb_write[is_user][index].address = vaddr | IO_MEM_NOTDIRTY;
  1285 + env->tlb_write[is_user][index].addend = addend;
1219 1286 } else {
1220 1287 env->tlb_write[is_user][index].address = address;
1221 1288 env->tlb_write[is_user][index].addend = addend;
... ... @@ -1446,6 +1513,10 @@ void page_unprotect_range(uint8_t *data, unsigned long data_size)
1446 1513 }
1447 1514 }
1448 1515  
  1516 +static inline void tlb_set_dirty(unsigned long addr, target_ulong vaddr)
  1517 +{
  1518 +}
  1519 +
1449 1520 #endif /* defined(CONFIG_USER_ONLY) */
1450 1521  
1451 1522 /* register physical memory. 'size' must be a multiple of the target
... ... @@ -1471,7 +1542,7 @@ static uint32_t unassigned_mem_readb(uint32_t addr)
1471 1542 return 0;
1472 1543 }
1473 1544  
1474   -static void unassigned_mem_writeb(uint32_t addr, uint32_t val)
  1545 +static void unassigned_mem_writeb(uint32_t addr, uint32_t val, uint32_t vaddr)
1475 1546 {
1476 1547 }
1477 1548  
... ... @@ -1490,28 +1561,40 @@ static CPUWriteMemoryFunc *unassigned_mem_write[3] = {
1490 1561 /* self modifying code support in soft mmu mode : writing to a page
1491 1562 containing code comes to these functions */
1492 1563  
1493   -static void code_mem_writeb(uint32_t addr, uint32_t val)
  1564 +static void code_mem_writeb(uint32_t addr, uint32_t val, uint32_t vaddr)
1494 1565 {
  1566 + unsigned long phys_addr;
  1567 +
  1568 + phys_addr = addr - (long)phys_ram_base;
1495 1569 #if !defined(CONFIG_USER_ONLY)
1496   - tb_invalidate_phys_page_fast(addr, 1);
  1570 + tb_invalidate_phys_page_fast(phys_addr, 1, vaddr);
1497 1571 #endif
1498   - stb_raw(phys_ram_base + addr, val);
  1572 + stb_raw((uint8_t *)addr, val);
  1573 + phys_ram_dirty[phys_addr >> TARGET_PAGE_BITS] = 1;
1499 1574 }
1500 1575  
1501   -static void code_mem_writew(uint32_t addr, uint32_t val)
  1576 +static void code_mem_writew(uint32_t addr, uint32_t val, uint32_t vaddr)
1502 1577 {
  1578 + unsigned long phys_addr;
  1579 +
  1580 + phys_addr = addr - (long)phys_ram_base;
1503 1581 #if !defined(CONFIG_USER_ONLY)
1504   - tb_invalidate_phys_page_fast(addr, 2);
  1582 + tb_invalidate_phys_page_fast(phys_addr, 2, vaddr);
1505 1583 #endif
1506   - stw_raw(phys_ram_base + addr, val);
  1584 + stw_raw((uint8_t *)addr, val);
  1585 + phys_ram_dirty[phys_addr >> TARGET_PAGE_BITS] = 1;
1507 1586 }
1508 1587  
1509   -static void code_mem_writel(uint32_t addr, uint32_t val)
  1588 +static void code_mem_writel(uint32_t addr, uint32_t val, uint32_t vaddr)
1510 1589 {
  1590 + unsigned long phys_addr;
  1591 +
  1592 + phys_addr = addr - (long)phys_ram_base;
1511 1593 #if !defined(CONFIG_USER_ONLY)
1512   - tb_invalidate_phys_page_fast(addr, 4);
  1594 + tb_invalidate_phys_page_fast(phys_addr, 4, vaddr);
1513 1595 #endif
1514   - stl_raw(phys_ram_base + addr, val);
  1596 + stl_raw((uint8_t *)addr, val);
  1597 + phys_ram_dirty[phys_addr >> TARGET_PAGE_BITS] = 1;
1515 1598 }
1516 1599  
1517 1600 static CPUReadMemoryFunc *code_mem_read[3] = {
... ... @@ -1526,12 +1609,40 @@ static CPUWriteMemoryFunc *code_mem_write[3] = {
1526 1609 code_mem_writel,
1527 1610 };
1528 1611  
  1612 +static void notdirty_mem_writeb(uint32_t addr, uint32_t val, uint32_t vaddr)
  1613 +{
  1614 + stb_raw((uint8_t *)addr, val);
  1615 + tlb_set_dirty(addr, vaddr);
  1616 +}
  1617 +
  1618 +static void notdirty_mem_writew(uint32_t addr, uint32_t val, uint32_t vaddr)
  1619 +{
  1620 + stw_raw((uint8_t *)addr, val);
  1621 + tlb_set_dirty(addr, vaddr);
  1622 +}
  1623 +
  1624 +static void notdirty_mem_writel(uint32_t addr, uint32_t val, uint32_t vaddr)
  1625 +{
  1626 + stl_raw((uint8_t *)addr, val);
  1627 + tlb_set_dirty(addr, vaddr);
  1628 +}
  1629 +
  1630 +static CPUWriteMemoryFunc *notdirty_mem_write[3] = {
  1631 + notdirty_mem_writeb,
  1632 + notdirty_mem_writew,
  1633 + notdirty_mem_writel,
  1634 +};
  1635 +
1529 1636 static void io_mem_init(void)
1530 1637 {
1531 1638 cpu_register_io_memory(IO_MEM_ROM >> IO_MEM_SHIFT, code_mem_read, unassigned_mem_write);
1532 1639 cpu_register_io_memory(IO_MEM_UNASSIGNED >> IO_MEM_SHIFT, unassigned_mem_read, unassigned_mem_write);
1533 1640 cpu_register_io_memory(IO_MEM_CODE >> IO_MEM_SHIFT, code_mem_read, code_mem_write);
1534   - io_mem_nb = 4;
  1641 + cpu_register_io_memory(IO_MEM_NOTDIRTY >> IO_MEM_SHIFT, code_mem_read, notdirty_mem_write);
  1642 + io_mem_nb = 5;
  1643 +
  1644 + /* alloc dirty bits array */
  1645 + phys_ram_dirty = malloc(phys_ram_size >> TARGET_PAGE_BITS);
1535 1646 }
1536 1647  
1537 1648 /* 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,
1620 1731 if (l >= 4 && ((addr & 3) == 0)) {
1621 1732 /* 32 bit read access */
1622 1733 val = ldl_raw(buf);
1623   - io_mem_write[io_index][2](addr, val);
  1734 + io_mem_write[io_index][2](addr, val, 0);
1624 1735 l = 4;
1625 1736 } else if (l >= 2 && ((addr & 1) == 0)) {
1626 1737 /* 16 bit read access */
1627 1738 val = lduw_raw(buf);
1628   - io_mem_write[io_index][1](addr, val);
  1739 + io_mem_write[io_index][1](addr, val, 0);
1629 1740 l = 2;
1630 1741 } else {
1631 1742 /* 8 bit access */
1632 1743 val = ldub_raw(buf);
1633   - io_mem_write[io_index][0](addr, val);
  1744 + io_mem_write[io_index][0](addr, val, 0);
1634 1745 l = 1;
1635 1746 }
1636 1747 } else {
... ...
softmmu_template.h
... ... @@ -76,14 +76,14 @@ static inline void glue(io_write, SUFFIX)(unsigned long physaddr,
76 76  
77 77 index = (tlb_addr >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
78 78 #if SHIFT <= 2
79   - io_mem_write[index][SHIFT](physaddr, val);
  79 + io_mem_write[index][SHIFT](physaddr, val, tlb_addr);
80 80 #else
81 81 #ifdef TARGET_WORDS_BIGENDIAN
82   - io_mem_write[index][2](physaddr, val >> 32);
83   - io_mem_write[index][2](physaddr + 4, val);
  82 + io_mem_write[index][2](physaddr, val >> 32, tlb_addr);
  83 + io_mem_write[index][2](physaddr + 4, val, tlb_addr);
84 84 #else
85   - io_mem_write[index][2](physaddr, val);
86   - io_mem_write[index][2](physaddr + 4, val >> 32);
  85 + io_mem_write[index][2](physaddr, val, tlb_addr);
  86 + io_mem_write[index][2](physaddr + 4, val >> 32, tlb_addr);
87 87 #endif
88 88 #endif /* SHIFT > 2 */
89 89 }
... ...
... ... @@ -233,6 +233,7 @@ int nographic;
233 233 int term_inited;
234 234 int64_t ticks_per_sec;
235 235 int boot_device = 'c';
  236 +static int ram_size;
236 237  
237 238 /***********************************************************/
238 239 /* x86 io ports */
... ... @@ -610,7 +611,7 @@ void cmos_init(void)
610 611 cmos_data[REG_EQUIPMENT_BYTE] |= 0x04; /* PS/2 mouse installed */
611 612  
612 613 /* memory size */
613   - val = (phys_ram_size / 1024) - 1024;
  614 + val = (ram_size / 1024) - 1024;
614 615 if (val > 65535)
615 616 val = 65535;
616 617 cmos_data[0x17] = val;
... ... @@ -618,7 +619,7 @@ void cmos_init(void)
618 619 cmos_data[0x30] = val;
619 620 cmos_data[0x31] = val >> 8;
620 621  
621   - val = (phys_ram_size / 65536) - ((16 * 1024 * 1024) / 65536);
  622 + val = (ram_size / 65536) - ((16 * 1024 * 1024) / 65536);
622 623 if (val > 65535)
623 624 val = 65535;
624 625 cmos_data[0x34] = val;
... ... @@ -3312,7 +3313,7 @@ extern void __sigaction();
3312 3313 int main(int argc, char **argv)
3313 3314 {
3314 3315 int c, ret, initrd_size, i, use_gdbstub, gdbstub_port, long_index;
3315   - int snapshot, linux_boot, total_ram_size;
  3316 + int snapshot, linux_boot;
3316 3317 #if defined (TARGET_I386)
3317 3318 struct linux_params *params;
3318 3319 #endif
... ... @@ -3331,7 +3332,7 @@ int main(int argc, char **argv)
3331 3332 fd_filename[i] = NULL;
3332 3333 for(i = 0; i < MAX_DISKS; i++)
3333 3334 hd_filename[i] = NULL;
3334   - phys_ram_size = 32 * 1024 * 1024;
  3335 + ram_size = 32 * 1024 * 1024;
3335 3336 vga_ram_size = VGA_RAM_SIZE;
3336 3337 #if defined (TARGET_I386)
3337 3338 pstrcpy(network_script, sizeof(network_script), DEFAULT_NETWORK_SCRIPT);
... ... @@ -3425,10 +3426,10 @@ int main(int argc, char **argv)
3425 3426 help();
3426 3427 break;
3427 3428 case 'm':
3428   - phys_ram_size = atoi(optarg) * 1024 * 1024;
3429   - if (phys_ram_size <= 0)
  3429 + ram_size = atoi(optarg) * 1024 * 1024;
  3430 + if (ram_size <= 0)
3430 3431 help();
3431   - if (phys_ram_size > PHYS_RAM_MAX_SIZE) {
  3432 + if (ram_size > PHYS_RAM_MAX_SIZE) {
3432 3433 fprintf(stderr, "qemu: at most %d MB RAM can be simulated\n",
3433 3434 PHYS_RAM_MAX_SIZE / (1024 * 1024));
3434 3435 exit(1);
... ... @@ -3489,10 +3490,10 @@ int main(int argc, char **argv)
3489 3490 #endif
3490 3491  
3491 3492 /* init the memory */
3492   - total_ram_size = phys_ram_size + vga_ram_size;
  3493 + phys_ram_size = ram_size + vga_ram_size;
3493 3494  
3494 3495 #ifdef CONFIG_SOFTMMU
3495   - phys_ram_base = malloc(total_ram_size);
  3496 + phys_ram_base = memalign(TARGET_PAGE_SIZE, phys_ram_size);
3496 3497 if (!phys_ram_base) {
3497 3498 fprintf(stderr, "Could not allocate physical memory\n");
3498 3499 exit(1);
... ... @@ -3518,10 +3519,10 @@ int main(int argc, char **argv)
3518 3519 phys_ram_file);
3519 3520 exit(1);
3520 3521 }
3521   - ftruncate(phys_ram_fd, total_ram_size);
  3522 + ftruncate(phys_ram_fd, phys_ram_size);
3522 3523 unlink(phys_ram_file);
3523   - phys_ram_base = mmap(get_mmap_addr(total_ram_size),
3524   - total_ram_size,
  3524 + phys_ram_base = mmap(get_mmap_addr(phys_ram_size),
  3525 + phys_ram_size,
3525 3526 PROT_WRITE | PROT_READ, MAP_SHARED | MAP_FIXED,
3526 3527 phys_ram_fd, 0);
3527 3528 if (phys_ram_base == MAP_FAILED) {
... ... @@ -3551,7 +3552,7 @@ int main(int argc, char **argv)
3551 3552 init_ioports();
3552 3553  
3553 3554 /* allocate RAM */
3554   - cpu_register_physical_memory(0, phys_ram_size, 0);
  3555 + cpu_register_physical_memory(0, ram_size, 0);
3555 3556  
3556 3557 if (linux_boot) {
3557 3558 /* now we can load the kernel */
... ... @@ -3580,7 +3581,7 @@ int main(int argc, char **argv)
3580 3581 params->mount_root_rdonly = 0;
3581 3582 stw_raw(&params->cl_magic, 0xA33F);
3582 3583 stw_raw(&params->cl_offset, params->commandline - (uint8_t *)params);
3583   - stl_raw(&params->alt_mem_k, (phys_ram_size / 1024) - 1024);
  3584 + stl_raw(&params->alt_mem_k, (ram_size / 1024) - 1024);
3584 3585 pstrcat(params->commandline, sizeof(params->commandline), kernel_cmdline);
3585 3586 params->loader_type = 0x01;
3586 3587 if (initrd_size > 0) {
... ... @@ -3617,7 +3618,7 @@ int main(int argc, char **argv)
3617 3618 env->regs[R_ESI] = KERNEL_PARAMS_ADDR;
3618 3619 env->eflags = 0x2;
3619 3620 #elif defined (TARGET_PPC)
3620   - PPC_init_hw(env, phys_ram_size, KERNEL_LOAD_ADDR, ret,
  3621 + PPC_init_hw(env, ram_size, KERNEL_LOAD_ADDR, ret,
3621 3622 KERNEL_STACK_ADDR, boot_device);
3622 3623 #endif
3623 3624 } else {
... ... @@ -3669,7 +3670,7 @@ int main(int argc, char **argv)
3669 3670 /* init basic PC hardware */
3670 3671 register_ioport_write(0x80, 1, ioport80_write, 1);
3671 3672  
3672   - vga_initialize(ds, phys_ram_base + phys_ram_size, phys_ram_size,
  3673 + vga_initialize(ds, phys_ram_base + ram_size, ram_size,
3673 3674 vga_ram_size);
3674 3675 #if defined (TARGET_I386)
3675 3676 cmos_init();
... ...