Commit 0a962c0276f668a5c06948b83a8def0b8d596985
1 parent
d993e026
dirty flag changes
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1281 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
4 changed files
with
57 additions
and
23 deletions
cpu-all.h
| ... | ... | @@ -109,9 +109,11 @@ static inline void tswap64s(uint64_t *s) |
| 109 | 109 | #if TARGET_LONG_SIZE == 4 |
| 110 | 110 | #define tswapl(s) tswap32(s) |
| 111 | 111 | #define tswapls(s) tswap32s((uint32_t *)(s)) |
| 112 | +#define bswaptls(s) bswap32s(s) | |
| 112 | 113 | #else |
| 113 | 114 | #define tswapl(s) tswap64(s) |
| 114 | 115 | #define tswapls(s) tswap64s((uint64_t *)(s)) |
| 116 | +#define bswaptls(s) bswap64s(s) | |
| 115 | 117 | #endif |
| 116 | 118 | |
| 117 | 119 | /* NOTE: arm FPA is horrible as double 32 bit words are stored in big |
| ... | ... | @@ -733,18 +735,27 @@ void stl_phys(target_phys_addr_t addr, uint32_t val); |
| 733 | 735 | int cpu_memory_rw_debug(CPUState *env, target_ulong addr, |
| 734 | 736 | uint8_t *buf, int len, int is_write); |
| 735 | 737 | |
| 738 | +#define VGA_DIRTY_FLAG 0x01 | |
| 739 | + | |
| 736 | 740 | /* read dirty bit (return 0 or 1) */ |
| 737 | 741 | static inline int cpu_physical_memory_is_dirty(target_ulong addr) |
| 738 | 742 | { |
| 739 | - return phys_ram_dirty[addr >> TARGET_PAGE_BITS]; | |
| 743 | + return phys_ram_dirty[addr >> TARGET_PAGE_BITS] == 0xff; | |
| 744 | +} | |
| 745 | + | |
| 746 | +static inline int cpu_physical_memory_get_dirty(target_ulong addr, | |
| 747 | + int dirty_flags) | |
| 748 | +{ | |
| 749 | + return phys_ram_dirty[addr >> TARGET_PAGE_BITS] & dirty_flags; | |
| 740 | 750 | } |
| 741 | 751 | |
| 742 | 752 | static inline void cpu_physical_memory_set_dirty(target_ulong addr) |
| 743 | 753 | { |
| 744 | - phys_ram_dirty[addr >> TARGET_PAGE_BITS] = 1; | |
| 754 | + phys_ram_dirty[addr >> TARGET_PAGE_BITS] = 0xff; | |
| 745 | 755 | } |
| 746 | 756 | |
| 747 | -void cpu_physical_memory_reset_dirty(target_ulong start, target_ulong end); | |
| 757 | +void cpu_physical_memory_reset_dirty(target_ulong start, target_ulong end, | |
| 758 | + int dirty_flags); | |
| 748 | 759 | |
| 749 | 760 | void dump_exec_info(FILE *f, |
| 750 | 761 | int (*cpu_fprintf)(FILE *f, const char *fmt, ...)); | ... | ... |
exec.c
| ... | ... | @@ -110,7 +110,7 @@ unsigned long qemu_host_page_mask; |
| 110 | 110 | |
| 111 | 111 | /* XXX: for system emulation, it could just be an array */ |
| 112 | 112 | static PageDesc *l1_map[L1_SIZE]; |
| 113 | -static PhysPageDesc *l1_phys_map[L1_SIZE]; | |
| 113 | +PhysPageDesc **l1_phys_map; | |
| 114 | 114 | |
| 115 | 115 | #if !defined(CONFIG_USER_ONLY) |
| 116 | 116 | static VirtPageDesc *l1_virt_map[L1_SIZE]; |
| ... | ... | @@ -176,6 +176,8 @@ static void page_init(void) |
| 176 | 176 | #if !defined(CONFIG_USER_ONLY) |
| 177 | 177 | virt_valid_tag = 1; |
| 178 | 178 | #endif |
| 179 | + l1_phys_map = qemu_vmalloc(L1_SIZE * sizeof(PhysPageDesc *)); | |
| 180 | + memset(l1_phys_map, 0, L1_SIZE * sizeof(PhysPageDesc *)); | |
| 179 | 181 | } |
| 180 | 182 | |
| 181 | 183 | static inline PageDesc *page_find_alloc(unsigned int index) |
| ... | ... | @@ -211,7 +213,7 @@ static inline PhysPageDesc *phys_page_find_alloc(unsigned int index) |
| 211 | 213 | p = *lp; |
| 212 | 214 | if (!p) { |
| 213 | 215 | /* allocate if not found */ |
| 214 | - p = qemu_malloc(sizeof(PhysPageDesc) * L2_SIZE); | |
| 216 | + p = qemu_vmalloc(sizeof(PhysPageDesc) * L2_SIZE); | |
| 215 | 217 | memset(p, 0, sizeof(PhysPageDesc) * L2_SIZE); |
| 216 | 218 | *lp = p; |
| 217 | 219 | } |
| ... | ... | @@ -1305,6 +1307,11 @@ void tlb_flush(CPUState *env, int flush_global) |
| 1305 | 1307 | #if !defined(CONFIG_SOFTMMU) |
| 1306 | 1308 | munmap((void *)MMAP_AREA_START, MMAP_AREA_END - MMAP_AREA_START); |
| 1307 | 1309 | #endif |
| 1310 | +#ifdef USE_KQEMU | |
| 1311 | + if (env->kqemu_enabled) { | |
| 1312 | + kqemu_flush(env, flush_global); | |
| 1313 | + } | |
| 1314 | +#endif | |
| 1308 | 1315 | tlb_flush_count++; |
| 1309 | 1316 | } |
| 1310 | 1317 | |
| ... | ... | @@ -1362,6 +1369,11 @@ void tlb_flush_page(CPUState *env, target_ulong addr) |
| 1362 | 1369 | if (addr < MMAP_AREA_END) |
| 1363 | 1370 | munmap((void *)addr, TARGET_PAGE_SIZE); |
| 1364 | 1371 | #endif |
| 1372 | +#ifdef USE_KQEMU | |
| 1373 | + if (env->kqemu_enabled) { | |
| 1374 | + kqemu_flush_page(env, addr); | |
| 1375 | + } | |
| 1376 | +#endif | |
| 1365 | 1377 | } |
| 1366 | 1378 | |
| 1367 | 1379 | static inline void tlb_protect_code1(CPUTLBEntry *tlb_entry, target_ulong addr) |
| ... | ... | @@ -1426,11 +1438,13 @@ static inline void tlb_reset_dirty_range(CPUTLBEntry *tlb_entry, |
| 1426 | 1438 | } |
| 1427 | 1439 | } |
| 1428 | 1440 | |
| 1429 | -void cpu_physical_memory_reset_dirty(target_ulong start, target_ulong end) | |
| 1441 | +void cpu_physical_memory_reset_dirty(target_ulong start, target_ulong end, | |
| 1442 | + int dirty_flags) | |
| 1430 | 1443 | { |
| 1431 | 1444 | CPUState *env; |
| 1432 | 1445 | unsigned long length, start1; |
| 1433 | - int i; | |
| 1446 | + int i, mask, len; | |
| 1447 | + uint8_t *p; | |
| 1434 | 1448 | |
| 1435 | 1449 | start &= TARGET_PAGE_MASK; |
| 1436 | 1450 | end = TARGET_PAGE_ALIGN(end); |
| ... | ... | @@ -1438,7 +1452,11 @@ void cpu_physical_memory_reset_dirty(target_ulong start, target_ulong end) |
| 1438 | 1452 | length = end - start; |
| 1439 | 1453 | if (length == 0) |
| 1440 | 1454 | return; |
| 1441 | - memset(phys_ram_dirty + (start >> TARGET_PAGE_BITS), 0, length >> TARGET_PAGE_BITS); | |
| 1455 | + mask = ~dirty_flags; | |
| 1456 | + p = phys_ram_dirty + (start >> TARGET_PAGE_BITS); | |
| 1457 | + len = length >> TARGET_PAGE_BITS; | |
| 1458 | + for(i = 0; i < len; i++) | |
| 1459 | + p[i] &= mask; | |
| 1442 | 1460 | |
| 1443 | 1461 | env = cpu_single_env; |
| 1444 | 1462 | /* we modify the TLB cache so that the dirty bit will be set again |
| ... | ... | @@ -1497,7 +1515,7 @@ static inline void tlb_set_dirty(unsigned long addr, target_ulong vaddr) |
| 1497 | 1515 | CPUState *env = cpu_single_env; |
| 1498 | 1516 | int i; |
| 1499 | 1517 | |
| 1500 | - phys_ram_dirty[(addr - (unsigned long)phys_ram_base) >> TARGET_PAGE_BITS] = 1; | |
| 1518 | + phys_ram_dirty[(addr - (unsigned long)phys_ram_base) >> TARGET_PAGE_BITS] = 0xff; | |
| 1501 | 1519 | |
| 1502 | 1520 | addr &= TARGET_PAGE_MASK; |
| 1503 | 1521 | i = (vaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); |
| ... | ... | @@ -1669,7 +1687,7 @@ int page_unprotect(unsigned long addr, unsigned long pc, void *puc) |
| 1669 | 1687 | cpu_abort(cpu_single_env, "error mprotect addr=0x%lx prot=%d\n", |
| 1670 | 1688 | (unsigned long)addr, vp->prot); |
| 1671 | 1689 | /* set the dirty bit */ |
| 1672 | - phys_ram_dirty[vp->phys_addr >> TARGET_PAGE_BITS] = 1; | |
| 1690 | + phys_ram_dirty[vp->phys_addr >> TARGET_PAGE_BITS] = 0xff; | |
| 1673 | 1691 | /* flush the code inside */ |
| 1674 | 1692 | tb_invalidate_phys_page(vp->phys_addr, pc, puc); |
| 1675 | 1693 | return 1; |
| ... | ... | @@ -1887,7 +1905,7 @@ static void code_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val) |
| 1887 | 1905 | tb_invalidate_phys_page_fast(phys_addr, 1); |
| 1888 | 1906 | #endif |
| 1889 | 1907 | stb_p((uint8_t *)(long)addr, val); |
| 1890 | - phys_ram_dirty[phys_addr >> TARGET_PAGE_BITS] = 1; | |
| 1908 | + phys_ram_dirty[phys_addr >> TARGET_PAGE_BITS] = 0xff; | |
| 1891 | 1909 | } |
| 1892 | 1910 | |
| 1893 | 1911 | static void code_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val) |
| ... | ... | @@ -1899,7 +1917,7 @@ static void code_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val) |
| 1899 | 1917 | tb_invalidate_phys_page_fast(phys_addr, 2); |
| 1900 | 1918 | #endif |
| 1901 | 1919 | stw_p((uint8_t *)(long)addr, val); |
| 1902 | - phys_ram_dirty[phys_addr >> TARGET_PAGE_BITS] = 1; | |
| 1920 | + phys_ram_dirty[phys_addr >> TARGET_PAGE_BITS] = 0xff; | |
| 1903 | 1921 | } |
| 1904 | 1922 | |
| 1905 | 1923 | static void code_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val) |
| ... | ... | @@ -1911,7 +1929,7 @@ static void code_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val) |
| 1911 | 1929 | tb_invalidate_phys_page_fast(phys_addr, 4); |
| 1912 | 1930 | #endif |
| 1913 | 1931 | stl_p((uint8_t *)(long)addr, val); |
| 1914 | - phys_ram_dirty[phys_addr >> TARGET_PAGE_BITS] = 1; | |
| 1932 | + phys_ram_dirty[phys_addr >> TARGET_PAGE_BITS] = 0xff; | |
| 1915 | 1933 | } |
| 1916 | 1934 | |
| 1917 | 1935 | static CPUReadMemoryFunc *code_mem_read[3] = { |
| ... | ... | @@ -1959,7 +1977,7 @@ static void io_mem_init(void) |
| 1959 | 1977 | io_mem_nb = 5; |
| 1960 | 1978 | |
| 1961 | 1979 | /* alloc dirty bits array */ |
| 1962 | - phys_ram_dirty = qemu_malloc(phys_ram_size >> TARGET_PAGE_BITS); | |
| 1980 | + phys_ram_dirty = qemu_vmalloc(phys_ram_size >> TARGET_PAGE_BITS); | |
| 1963 | 1981 | } |
| 1964 | 1982 | |
| 1965 | 1983 | /* mem_read and mem_write are arrays of functions containing the |
| ... | ... | @@ -2098,7 +2116,7 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, |
| 2098 | 2116 | /* invalidate code */ |
| 2099 | 2117 | tb_invalidate_phys_page_range(addr1, addr1 + l, 0); |
| 2100 | 2118 | /* set dirty bit */ |
| 2101 | - phys_ram_dirty[addr1 >> TARGET_PAGE_BITS] = 1; | |
| 2119 | + phys_ram_dirty[addr1 >> TARGET_PAGE_BITS] = 0xff; | |
| 2102 | 2120 | } |
| 2103 | 2121 | } else { |
| 2104 | 2122 | if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM && |
| ... | ... | @@ -2219,7 +2237,7 @@ void stl_phys(target_phys_addr_t addr, uint32_t val) |
| 2219 | 2237 | /* invalidate code */ |
| 2220 | 2238 | tb_invalidate_phys_page_range(addr1, addr1 + 4, 0); |
| 2221 | 2239 | /* set dirty bit */ |
| 2222 | - phys_ram_dirty[addr1 >> TARGET_PAGE_BITS] = 1; | |
| 2240 | + phys_ram_dirty[addr1 >> TARGET_PAGE_BITS] = 0xff; | |
| 2223 | 2241 | } |
| 2224 | 2242 | } |
| 2225 | 2243 | ... | ... |
hw/tcx.c
| ... | ... | @@ -129,7 +129,7 @@ void tcx_update_display(void *opaque) |
| 129 | 129 | } |
| 130 | 130 | |
| 131 | 131 | for(y = 0; y < YSZ; y += 4, page += TARGET_PAGE_SIZE) { |
| 132 | - if (cpu_physical_memory_is_dirty(page)) { | |
| 132 | + if (cpu_physical_memory_get_dirty(page, VGA_DIRTY_FLAG)) { | |
| 133 | 133 | if (y_start < 0) |
| 134 | 134 | y_start = y; |
| 135 | 135 | if (page < page_min) |
| ... | ... | @@ -166,7 +166,8 @@ void tcx_update_display(void *opaque) |
| 166 | 166 | } |
| 167 | 167 | /* reset modified pages */ |
| 168 | 168 | if (page_max != -1) { |
| 169 | - cpu_physical_memory_reset_dirty(page_min, page_max + TARGET_PAGE_SIZE); | |
| 169 | + cpu_physical_memory_reset_dirty(page_min, page_max + TARGET_PAGE_SIZE, | |
| 170 | + VGA_DIRTY_FLAG); | |
| 170 | 171 | } |
| 171 | 172 | } |
| 172 | 173 | |
| ... | ... | @@ -216,7 +217,8 @@ static void tcx_reset(void *opaque) |
| 216 | 217 | memset(s->b, 0, 256); |
| 217 | 218 | s->r[255] = s->g[255] = s->b[255] = 255; |
| 218 | 219 | memset(s->vram, 0, MAXX*MAXY); |
| 219 | - cpu_physical_memory_reset_dirty(s->vram_offset, s->vram_offset + MAXX*MAXY); | |
| 220 | + cpu_physical_memory_reset_dirty(s->vram_offset, s->vram_offset + MAXX*MAXY, | |
| 221 | + VGA_DIRTY_FLAG); | |
| 220 | 222 | } |
| 221 | 223 | |
| 222 | 224 | void *tcx_init(DisplayState *ds, uint32_t addr, uint8_t *vram_base, | ... | ... |
hw/vga.c
| ... | ... | @@ -1454,11 +1454,13 @@ static void vga_draw_graphic(VGAState *s, int full_update) |
| 1454 | 1454 | } |
| 1455 | 1455 | page0 = s->vram_offset + (addr & TARGET_PAGE_MASK); |
| 1456 | 1456 | page1 = s->vram_offset + ((addr + bwidth - 1) & TARGET_PAGE_MASK); |
| 1457 | - update = full_update | cpu_physical_memory_is_dirty(page0) | | |
| 1458 | - cpu_physical_memory_is_dirty(page1); | |
| 1457 | + update = full_update | | |
| 1458 | + cpu_physical_memory_get_dirty(page0, VGA_DIRTY_FLAG) | | |
| 1459 | + cpu_physical_memory_get_dirty(page1, VGA_DIRTY_FLAG); | |
| 1459 | 1460 | if ((page1 - page0) > TARGET_PAGE_SIZE) { |
| 1460 | 1461 | /* if wide line, can use another page */ |
| 1461 | - update |= cpu_physical_memory_is_dirty(page0 + TARGET_PAGE_SIZE); | |
| 1462 | + update |= cpu_physical_memory_get_dirty(page0 + TARGET_PAGE_SIZE, | |
| 1463 | + VGA_DIRTY_FLAG); | |
| 1462 | 1464 | } |
| 1463 | 1465 | /* explicit invalidation for the hardware cursor */ |
| 1464 | 1466 | update |= (s->invalidated_y_table[y >> 5] >> (y & 0x1f)) & 1; |
| ... | ... | @@ -1501,7 +1503,8 @@ static void vga_draw_graphic(VGAState *s, int full_update) |
| 1501 | 1503 | } |
| 1502 | 1504 | /* reset modified pages */ |
| 1503 | 1505 | if (page_max != -1) { |
| 1504 | - cpu_physical_memory_reset_dirty(page_min, page_max + TARGET_PAGE_SIZE); | |
| 1506 | + cpu_physical_memory_reset_dirty(page_min, page_max + TARGET_PAGE_SIZE, | |
| 1507 | + VGA_DIRTY_FLAG); | |
| 1505 | 1508 | } |
| 1506 | 1509 | memset(s->invalidated_y_table, 0, ((height + 31) >> 5) * 4); |
| 1507 | 1510 | } | ... | ... |