Commit 0a962c0276f668a5c06948b83a8def0b8d596985

Authored by bellard
1 parent d993e026

dirty flag changes


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1281 c046a42c-6fe2-441c-8c8c-71466251a162
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, ...));
... ...
... ... @@ -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 }
... ...