dirty flag changes

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1281 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
bellard 2005-02-10 22:00:27 +00:00
parent d993e0260b
commit 0a962c0276
4 changed files with 57 additions and 23 deletions

View File

@ -109,9 +109,11 @@ static inline void tswap64s(uint64_t *s)
#if TARGET_LONG_SIZE == 4 #if TARGET_LONG_SIZE == 4
#define tswapl(s) tswap32(s) #define tswapl(s) tswap32(s)
#define tswapls(s) tswap32s((uint32_t *)(s)) #define tswapls(s) tswap32s((uint32_t *)(s))
#define bswaptls(s) bswap32s(s)
#else #else
#define tswapl(s) tswap64(s) #define tswapl(s) tswap64(s)
#define tswapls(s) tswap64s((uint64_t *)(s)) #define tswapls(s) tswap64s((uint64_t *)(s))
#define bswaptls(s) bswap64s(s)
#endif #endif
/* NOTE: arm FPA is horrible as double 32 bit words are stored in big /* 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);
int cpu_memory_rw_debug(CPUState *env, target_ulong addr, int cpu_memory_rw_debug(CPUState *env, target_ulong addr,
uint8_t *buf, int len, int is_write); uint8_t *buf, int len, int is_write);
#define VGA_DIRTY_FLAG 0x01
/* read dirty bit (return 0 or 1) */ /* read dirty bit (return 0 or 1) */
static inline int cpu_physical_memory_is_dirty(target_ulong addr) static inline int cpu_physical_memory_is_dirty(target_ulong addr)
{ {
return phys_ram_dirty[addr >> TARGET_PAGE_BITS]; return phys_ram_dirty[addr >> TARGET_PAGE_BITS] == 0xff;
}
static inline int cpu_physical_memory_get_dirty(target_ulong addr,
int dirty_flags)
{
return phys_ram_dirty[addr >> TARGET_PAGE_BITS] & dirty_flags;
} }
static inline void cpu_physical_memory_set_dirty(target_ulong addr) static inline void cpu_physical_memory_set_dirty(target_ulong addr)
{ {
phys_ram_dirty[addr >> TARGET_PAGE_BITS] = 1; phys_ram_dirty[addr >> TARGET_PAGE_BITS] = 0xff;
} }
void cpu_physical_memory_reset_dirty(target_ulong start, target_ulong end); void cpu_physical_memory_reset_dirty(target_ulong start, target_ulong end,
int dirty_flags);
void dump_exec_info(FILE *f, void dump_exec_info(FILE *f,
int (*cpu_fprintf)(FILE *f, const char *fmt, ...)); int (*cpu_fprintf)(FILE *f, const char *fmt, ...));

44
exec.c
View File

@ -110,7 +110,7 @@ unsigned long qemu_host_page_mask;
/* XXX: for system emulation, it could just be an array */ /* XXX: for system emulation, it could just be an array */
static PageDesc *l1_map[L1_SIZE]; static PageDesc *l1_map[L1_SIZE];
static PhysPageDesc *l1_phys_map[L1_SIZE]; PhysPageDesc **l1_phys_map;
#if !defined(CONFIG_USER_ONLY) #if !defined(CONFIG_USER_ONLY)
static VirtPageDesc *l1_virt_map[L1_SIZE]; static VirtPageDesc *l1_virt_map[L1_SIZE];
@ -176,6 +176,8 @@ static void page_init(void)
#if !defined(CONFIG_USER_ONLY) #if !defined(CONFIG_USER_ONLY)
virt_valid_tag = 1; virt_valid_tag = 1;
#endif #endif
l1_phys_map = qemu_vmalloc(L1_SIZE * sizeof(PhysPageDesc *));
memset(l1_phys_map, 0, L1_SIZE * sizeof(PhysPageDesc *));
} }
static inline PageDesc *page_find_alloc(unsigned int index) static inline PageDesc *page_find_alloc(unsigned int index)
@ -211,7 +213,7 @@ static inline PhysPageDesc *phys_page_find_alloc(unsigned int index)
p = *lp; p = *lp;
if (!p) { if (!p) {
/* allocate if not found */ /* allocate if not found */
p = qemu_malloc(sizeof(PhysPageDesc) * L2_SIZE); p = qemu_vmalloc(sizeof(PhysPageDesc) * L2_SIZE);
memset(p, 0, sizeof(PhysPageDesc) * L2_SIZE); memset(p, 0, sizeof(PhysPageDesc) * L2_SIZE);
*lp = p; *lp = p;
} }
@ -1304,6 +1306,11 @@ void tlb_flush(CPUState *env, int flush_global)
#if !defined(CONFIG_SOFTMMU) #if !defined(CONFIG_SOFTMMU)
munmap((void *)MMAP_AREA_START, MMAP_AREA_END - MMAP_AREA_START); munmap((void *)MMAP_AREA_START, MMAP_AREA_END - MMAP_AREA_START);
#endif
#ifdef USE_KQEMU
if (env->kqemu_enabled) {
kqemu_flush(env, flush_global);
}
#endif #endif
tlb_flush_count++; tlb_flush_count++;
} }
@ -1362,6 +1369,11 @@ void tlb_flush_page(CPUState *env, target_ulong addr)
if (addr < MMAP_AREA_END) if (addr < MMAP_AREA_END)
munmap((void *)addr, TARGET_PAGE_SIZE); munmap((void *)addr, TARGET_PAGE_SIZE);
#endif #endif
#ifdef USE_KQEMU
if (env->kqemu_enabled) {
kqemu_flush_page(env, addr);
}
#endif
} }
static inline void tlb_protect_code1(CPUTLBEntry *tlb_entry, target_ulong addr) 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,
} }
} }
void cpu_physical_memory_reset_dirty(target_ulong start, target_ulong end) void cpu_physical_memory_reset_dirty(target_ulong start, target_ulong end,
int dirty_flags)
{ {
CPUState *env; CPUState *env;
unsigned long length, start1; unsigned long length, start1;
int i; int i, mask, len;
uint8_t *p;
start &= TARGET_PAGE_MASK; start &= TARGET_PAGE_MASK;
end = TARGET_PAGE_ALIGN(end); end = TARGET_PAGE_ALIGN(end);
@ -1438,7 +1452,11 @@ void cpu_physical_memory_reset_dirty(target_ulong start, target_ulong end)
length = end - start; length = end - start;
if (length == 0) if (length == 0)
return; return;
memset(phys_ram_dirty + (start >> TARGET_PAGE_BITS), 0, length >> TARGET_PAGE_BITS); mask = ~dirty_flags;
p = phys_ram_dirty + (start >> TARGET_PAGE_BITS);
len = length >> TARGET_PAGE_BITS;
for(i = 0; i < len; i++)
p[i] &= mask;
env = cpu_single_env; env = cpu_single_env;
/* we modify the TLB cache so that the dirty bit will be set again /* 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)
CPUState *env = cpu_single_env; CPUState *env = cpu_single_env;
int i; int i;
phys_ram_dirty[(addr - (unsigned long)phys_ram_base) >> TARGET_PAGE_BITS] = 1; phys_ram_dirty[(addr - (unsigned long)phys_ram_base) >> TARGET_PAGE_BITS] = 0xff;
addr &= TARGET_PAGE_MASK; addr &= TARGET_PAGE_MASK;
i = (vaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); i = (vaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
@ -1669,7 +1687,7 @@ int page_unprotect(unsigned long addr, unsigned long pc, void *puc)
cpu_abort(cpu_single_env, "error mprotect addr=0x%lx prot=%d\n", cpu_abort(cpu_single_env, "error mprotect addr=0x%lx prot=%d\n",
(unsigned long)addr, vp->prot); (unsigned long)addr, vp->prot);
/* set the dirty bit */ /* set the dirty bit */
phys_ram_dirty[vp->phys_addr >> TARGET_PAGE_BITS] = 1; phys_ram_dirty[vp->phys_addr >> TARGET_PAGE_BITS] = 0xff;
/* flush the code inside */ /* flush the code inside */
tb_invalidate_phys_page(vp->phys_addr, pc, puc); tb_invalidate_phys_page(vp->phys_addr, pc, puc);
return 1; return 1;
@ -1887,7 +1905,7 @@ static void code_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
tb_invalidate_phys_page_fast(phys_addr, 1); tb_invalidate_phys_page_fast(phys_addr, 1);
#endif #endif
stb_p((uint8_t *)(long)addr, val); stb_p((uint8_t *)(long)addr, val);
phys_ram_dirty[phys_addr >> TARGET_PAGE_BITS] = 1; phys_ram_dirty[phys_addr >> TARGET_PAGE_BITS] = 0xff;
} }
static void code_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val) 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)
tb_invalidate_phys_page_fast(phys_addr, 2); tb_invalidate_phys_page_fast(phys_addr, 2);
#endif #endif
stw_p((uint8_t *)(long)addr, val); stw_p((uint8_t *)(long)addr, val);
phys_ram_dirty[phys_addr >> TARGET_PAGE_BITS] = 1; phys_ram_dirty[phys_addr >> TARGET_PAGE_BITS] = 0xff;
} }
static void code_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val) 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)
tb_invalidate_phys_page_fast(phys_addr, 4); tb_invalidate_phys_page_fast(phys_addr, 4);
#endif #endif
stl_p((uint8_t *)(long)addr, val); stl_p((uint8_t *)(long)addr, val);
phys_ram_dirty[phys_addr >> TARGET_PAGE_BITS] = 1; phys_ram_dirty[phys_addr >> TARGET_PAGE_BITS] = 0xff;
} }
static CPUReadMemoryFunc *code_mem_read[3] = { static CPUReadMemoryFunc *code_mem_read[3] = {
@ -1959,7 +1977,7 @@ static void io_mem_init(void)
io_mem_nb = 5; io_mem_nb = 5;
/* alloc dirty bits array */ /* alloc dirty bits array */
phys_ram_dirty = qemu_malloc(phys_ram_size >> TARGET_PAGE_BITS); phys_ram_dirty = qemu_vmalloc(phys_ram_size >> TARGET_PAGE_BITS);
} }
/* mem_read and mem_write are arrays of functions containing the /* 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,
/* invalidate code */ /* invalidate code */
tb_invalidate_phys_page_range(addr1, addr1 + l, 0); tb_invalidate_phys_page_range(addr1, addr1 + l, 0);
/* set dirty bit */ /* set dirty bit */
phys_ram_dirty[addr1 >> TARGET_PAGE_BITS] = 1; phys_ram_dirty[addr1 >> TARGET_PAGE_BITS] = 0xff;
} }
} else { } else {
if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM && if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM &&
@ -2219,7 +2237,7 @@ void stl_phys(target_phys_addr_t addr, uint32_t val)
/* invalidate code */ /* invalidate code */
tb_invalidate_phys_page_range(addr1, addr1 + 4, 0); tb_invalidate_phys_page_range(addr1, addr1 + 4, 0);
/* set dirty bit */ /* set dirty bit */
phys_ram_dirty[addr1 >> TARGET_PAGE_BITS] = 1; phys_ram_dirty[addr1 >> TARGET_PAGE_BITS] = 0xff;
} }
} }

View File

@ -129,7 +129,7 @@ void tcx_update_display(void *opaque)
} }
for(y = 0; y < YSZ; y += 4, page += TARGET_PAGE_SIZE) { for(y = 0; y < YSZ; y += 4, page += TARGET_PAGE_SIZE) {
if (cpu_physical_memory_is_dirty(page)) { if (cpu_physical_memory_get_dirty(page, VGA_DIRTY_FLAG)) {
if (y_start < 0) if (y_start < 0)
y_start = y; y_start = y;
if (page < page_min) if (page < page_min)
@ -166,7 +166,8 @@ void tcx_update_display(void *opaque)
} }
/* reset modified pages */ /* reset modified pages */
if (page_max != -1) { if (page_max != -1) {
cpu_physical_memory_reset_dirty(page_min, page_max + TARGET_PAGE_SIZE); cpu_physical_memory_reset_dirty(page_min, page_max + TARGET_PAGE_SIZE,
VGA_DIRTY_FLAG);
} }
} }
@ -216,7 +217,8 @@ static void tcx_reset(void *opaque)
memset(s->b, 0, 256); memset(s->b, 0, 256);
s->r[255] = s->g[255] = s->b[255] = 255; s->r[255] = s->g[255] = s->b[255] = 255;
memset(s->vram, 0, MAXX*MAXY); memset(s->vram, 0, MAXX*MAXY);
cpu_physical_memory_reset_dirty(s->vram_offset, s->vram_offset + MAXX*MAXY); cpu_physical_memory_reset_dirty(s->vram_offset, s->vram_offset + MAXX*MAXY,
VGA_DIRTY_FLAG);
} }
void *tcx_init(DisplayState *ds, uint32_t addr, uint8_t *vram_base, void *tcx_init(DisplayState *ds, uint32_t addr, uint8_t *vram_base,

View File

@ -1454,11 +1454,13 @@ static void vga_draw_graphic(VGAState *s, int full_update)
} }
page0 = s->vram_offset + (addr & TARGET_PAGE_MASK); page0 = s->vram_offset + (addr & TARGET_PAGE_MASK);
page1 = s->vram_offset + ((addr + bwidth - 1) & TARGET_PAGE_MASK); page1 = s->vram_offset + ((addr + bwidth - 1) & TARGET_PAGE_MASK);
update = full_update | cpu_physical_memory_is_dirty(page0) | update = full_update |
cpu_physical_memory_is_dirty(page1); cpu_physical_memory_get_dirty(page0, VGA_DIRTY_FLAG) |
cpu_physical_memory_get_dirty(page1, VGA_DIRTY_FLAG);
if ((page1 - page0) > TARGET_PAGE_SIZE) { if ((page1 - page0) > TARGET_PAGE_SIZE) {
/* if wide line, can use another page */ /* if wide line, can use another page */
update |= cpu_physical_memory_is_dirty(page0 + TARGET_PAGE_SIZE); update |= cpu_physical_memory_get_dirty(page0 + TARGET_PAGE_SIZE,
VGA_DIRTY_FLAG);
} }
/* explicit invalidation for the hardware cursor */ /* explicit invalidation for the hardware cursor */
update |= (s->invalidated_y_table[y >> 5] >> (y & 0x1f)) & 1; update |= (s->invalidated_y_table[y >> 5] >> (y & 0x1f)) & 1;
@ -1501,7 +1503,8 @@ static void vga_draw_graphic(VGAState *s, int full_update)
} }
/* reset modified pages */ /* reset modified pages */
if (page_max != -1) { if (page_max != -1) {
cpu_physical_memory_reset_dirty(page_min, page_max + TARGET_PAGE_SIZE); cpu_physical_memory_reset_dirty(page_min, page_max + TARGET_PAGE_SIZE,
VGA_DIRTY_FLAG);
} }
memset(s->invalidated_y_table, 0, ((height + 31) >> 5) * 4); memset(s->invalidated_y_table, 0, ((height + 31) >> 5) * 4);
} }