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 | } | ... | ... |