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,9 +109,11 @@ static inline void tswap64s(uint64_t *s)
109 #if TARGET_LONG_SIZE == 4 109 #if TARGET_LONG_SIZE == 4
110 #define tswapl(s) tswap32(s) 110 #define tswapl(s) tswap32(s)
111 #define tswapls(s) tswap32s((uint32_t *)(s)) 111 #define tswapls(s) tswap32s((uint32_t *)(s))
  112 +#define bswaptls(s) bswap32s(s)
112 #else 113 #else
113 #define tswapl(s) tswap64(s) 114 #define tswapl(s) tswap64(s)
114 #define tswapls(s) tswap64s((uint64_t *)(s)) 115 #define tswapls(s) tswap64s((uint64_t *)(s))
  116 +#define bswaptls(s) bswap64s(s)
115 #endif 117 #endif
116 118
117 /* NOTE: arm FPA is horrible as double 32 bit words are stored in big 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,18 +735,27 @@ void stl_phys(target_phys_addr_t addr, uint32_t val);
733 int cpu_memory_rw_debug(CPUState *env, target_ulong addr, 735 int cpu_memory_rw_debug(CPUState *env, target_ulong addr,
734 uint8_t *buf, int len, int is_write); 736 uint8_t *buf, int len, int is_write);
735 737
  738 +#define VGA_DIRTY_FLAG 0x01
  739 +
736 /* read dirty bit (return 0 or 1) */ 740 /* read dirty bit (return 0 or 1) */
737 static inline int cpu_physical_memory_is_dirty(target_ulong addr) 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 static inline void cpu_physical_memory_set_dirty(target_ulong addr) 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 void dump_exec_info(FILE *f, 760 void dump_exec_info(FILE *f,
750 int (*cpu_fprintf)(FILE *f, const char *fmt, ...)); 761 int (*cpu_fprintf)(FILE *f, const char *fmt, ...));
@@ -110,7 +110,7 @@ unsigned long qemu_host_page_mask; @@ -110,7 +110,7 @@ unsigned long qemu_host_page_mask;
110 110
111 /* XXX: for system emulation, it could just be an array */ 111 /* XXX: for system emulation, it could just be an array */
112 static PageDesc *l1_map[L1_SIZE]; 112 static PageDesc *l1_map[L1_SIZE];
113 -static PhysPageDesc *l1_phys_map[L1_SIZE]; 113 +PhysPageDesc **l1_phys_map;
114 114
115 #if !defined(CONFIG_USER_ONLY) 115 #if !defined(CONFIG_USER_ONLY)
116 static VirtPageDesc *l1_virt_map[L1_SIZE]; 116 static VirtPageDesc *l1_virt_map[L1_SIZE];
@@ -176,6 +176,8 @@ static void page_init(void) @@ -176,6 +176,8 @@ static void page_init(void)
176 #if !defined(CONFIG_USER_ONLY) 176 #if !defined(CONFIG_USER_ONLY)
177 virt_valid_tag = 1; 177 virt_valid_tag = 1;
178 #endif 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 static inline PageDesc *page_find_alloc(unsigned int index) 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,7 +213,7 @@ static inline PhysPageDesc *phys_page_find_alloc(unsigned int index)
211 p = *lp; 213 p = *lp;
212 if (!p) { 214 if (!p) {
213 /* allocate if not found */ 215 /* allocate if not found */
214 - p = qemu_malloc(sizeof(PhysPageDesc) * L2_SIZE); 216 + p = qemu_vmalloc(sizeof(PhysPageDesc) * L2_SIZE);
215 memset(p, 0, sizeof(PhysPageDesc) * L2_SIZE); 217 memset(p, 0, sizeof(PhysPageDesc) * L2_SIZE);
216 *lp = p; 218 *lp = p;
217 } 219 }
@@ -1305,6 +1307,11 @@ void tlb_flush(CPUState *env, int flush_global) @@ -1305,6 +1307,11 @@ void tlb_flush(CPUState *env, int flush_global)
1305 #if !defined(CONFIG_SOFTMMU) 1307 #if !defined(CONFIG_SOFTMMU)
1306 munmap((void *)MMAP_AREA_START, MMAP_AREA_END - MMAP_AREA_START); 1308 munmap((void *)MMAP_AREA_START, MMAP_AREA_END - MMAP_AREA_START);
1307 #endif 1309 #endif
  1310 +#ifdef USE_KQEMU
  1311 + if (env->kqemu_enabled) {
  1312 + kqemu_flush(env, flush_global);
  1313 + }
  1314 +#endif
1308 tlb_flush_count++; 1315 tlb_flush_count++;
1309 } 1316 }
1310 1317
@@ -1362,6 +1369,11 @@ void tlb_flush_page(CPUState *env, target_ulong addr) @@ -1362,6 +1369,11 @@ void tlb_flush_page(CPUState *env, target_ulong addr)
1362 if (addr < MMAP_AREA_END) 1369 if (addr < MMAP_AREA_END)
1363 munmap((void *)addr, TARGET_PAGE_SIZE); 1370 munmap((void *)addr, TARGET_PAGE_SIZE);
1364 #endif 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 static inline void tlb_protect_code1(CPUTLBEntry *tlb_entry, target_ulong addr) 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,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 CPUState *env; 1444 CPUState *env;
1432 unsigned long length, start1; 1445 unsigned long length, start1;
1433 - int i; 1446 + int i, mask, len;
  1447 + uint8_t *p;
1434 1448
1435 start &= TARGET_PAGE_MASK; 1449 start &= TARGET_PAGE_MASK;
1436 end = TARGET_PAGE_ALIGN(end); 1450 end = TARGET_PAGE_ALIGN(end);
@@ -1438,7 +1452,11 @@ void cpu_physical_memory_reset_dirty(target_ulong start, target_ulong end) @@ -1438,7 +1452,11 @@ void cpu_physical_memory_reset_dirty(target_ulong start, target_ulong end)
1438 length = end - start; 1452 length = end - start;
1439 if (length == 0) 1453 if (length == 0)
1440 return; 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 env = cpu_single_env; 1461 env = cpu_single_env;
1444 /* we modify the TLB cache so that the dirty bit will be set again 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,7 +1515,7 @@ static inline void tlb_set_dirty(unsigned long addr, target_ulong vaddr)
1497 CPUState *env = cpu_single_env; 1515 CPUState *env = cpu_single_env;
1498 int i; 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 addr &= TARGET_PAGE_MASK; 1520 addr &= TARGET_PAGE_MASK;
1503 i = (vaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); 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,7 +1687,7 @@ int page_unprotect(unsigned long addr, unsigned long pc, void *puc)
1669 cpu_abort(cpu_single_env, "error mprotect addr=0x%lx prot=%d\n", 1687 cpu_abort(cpu_single_env, "error mprotect addr=0x%lx prot=%d\n",
1670 (unsigned long)addr, vp->prot); 1688 (unsigned long)addr, vp->prot);
1671 /* set the dirty bit */ 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 /* flush the code inside */ 1691 /* flush the code inside */
1674 tb_invalidate_phys_page(vp->phys_addr, pc, puc); 1692 tb_invalidate_phys_page(vp->phys_addr, pc, puc);
1675 return 1; 1693 return 1;
@@ -1887,7 +1905,7 @@ static void code_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val) @@ -1887,7 +1905,7 @@ static void code_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
1887 tb_invalidate_phys_page_fast(phys_addr, 1); 1905 tb_invalidate_phys_page_fast(phys_addr, 1);
1888 #endif 1906 #endif
1889 stb_p((uint8_t *)(long)addr, val); 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 static void code_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val) 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,7 +1917,7 @@ static void code_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
1899 tb_invalidate_phys_page_fast(phys_addr, 2); 1917 tb_invalidate_phys_page_fast(phys_addr, 2);
1900 #endif 1918 #endif
1901 stw_p((uint8_t *)(long)addr, val); 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 static void code_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val) 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,7 +1929,7 @@ static void code_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
1911 tb_invalidate_phys_page_fast(phys_addr, 4); 1929 tb_invalidate_phys_page_fast(phys_addr, 4);
1912 #endif 1930 #endif
1913 stl_p((uint8_t *)(long)addr, val); 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 static CPUReadMemoryFunc *code_mem_read[3] = { 1935 static CPUReadMemoryFunc *code_mem_read[3] = {
@@ -1959,7 +1977,7 @@ static void io_mem_init(void) @@ -1959,7 +1977,7 @@ static void io_mem_init(void)
1959 io_mem_nb = 5; 1977 io_mem_nb = 5;
1960 1978
1961 /* alloc dirty bits array */ 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 /* mem_read and mem_write are arrays of functions containing the 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,7 +2116,7 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
2098 /* invalidate code */ 2116 /* invalidate code */
2099 tb_invalidate_phys_page_range(addr1, addr1 + l, 0); 2117 tb_invalidate_phys_page_range(addr1, addr1 + l, 0);
2100 /* set dirty bit */ 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 } else { 2121 } else {
2104 if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM && 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,7 +2237,7 @@ void stl_phys(target_phys_addr_t addr, uint32_t val)
2219 /* invalidate code */ 2237 /* invalidate code */
2220 tb_invalidate_phys_page_range(addr1, addr1 + 4, 0); 2238 tb_invalidate_phys_page_range(addr1, addr1 + 4, 0);
2221 /* set dirty bit */ 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,7 +129,7 @@ void tcx_update_display(void *opaque)
129 } 129 }
130 130
131 for(y = 0; y < YSZ; y += 4, page += TARGET_PAGE_SIZE) { 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 if (y_start < 0) 133 if (y_start < 0)
134 y_start = y; 134 y_start = y;
135 if (page < page_min) 135 if (page < page_min)
@@ -166,7 +166,8 @@ void tcx_update_display(void *opaque) @@ -166,7 +166,8 @@ void tcx_update_display(void *opaque)
166 } 166 }
167 /* reset modified pages */ 167 /* reset modified pages */
168 if (page_max != -1) { 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,7 +217,8 @@ static void tcx_reset(void *opaque)
216 memset(s->b, 0, 256); 217 memset(s->b, 0, 256);
217 s->r[255] = s->g[255] = s->b[255] = 255; 218 s->r[255] = s->g[255] = s->b[255] = 255;
218 memset(s->vram, 0, MAXX*MAXY); 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 void *tcx_init(DisplayState *ds, uint32_t addr, uint8_t *vram_base, 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,11 +1454,13 @@ static void vga_draw_graphic(VGAState *s, int full_update)
1454 } 1454 }
1455 page0 = s->vram_offset + (addr & TARGET_PAGE_MASK); 1455 page0 = s->vram_offset + (addr & TARGET_PAGE_MASK);
1456 page1 = s->vram_offset + ((addr + bwidth - 1) & TARGET_PAGE_MASK); 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 if ((page1 - page0) > TARGET_PAGE_SIZE) { 1460 if ((page1 - page0) > TARGET_PAGE_SIZE) {
1460 /* if wide line, can use another page */ 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 /* explicit invalidation for the hardware cursor */ 1465 /* explicit invalidation for the hardware cursor */
1464 update |= (s->invalidated_y_table[y >> 5] >> (y & 0x1f)) & 1; 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,7 +1503,8 @@ static void vga_draw_graphic(VGAState *s, int full_update)
1501 } 1503 }
1502 /* reset modified pages */ 1504 /* reset modified pages */
1503 if (page_max != -1) { 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 memset(s->invalidated_y_table, 0, ((height + 31) >> 5) * 4); 1509 memset(s->invalidated_y_table, 0, ((height + 31) >> 5) * 4);
1507 } 1510 }