diff options
-rw-r--r-- | cpu-all.h | 17 | ||||
-rw-r--r-- | exec.c | 44 | ||||
-rw-r--r-- | hw/tcx.c | 8 | ||||
-rw-r--r-- | hw/vga.c | 11 |
4 files changed, 57 insertions, 23 deletions
@@ -109,9 +109,11 @@ static inline void tswap64s(uint64_t *s) #if TARGET_LONG_SIZE == 4 #define tswapl(s) tswap32(s) #define tswapls(s) tswap32s((uint32_t *)(s)) +#define bswaptls(s) bswap32s(s) #else #define tswapl(s) tswap64(s) #define tswapls(s) tswap64s((uint64_t *)(s)) +#define bswaptls(s) bswap64s(s) #endif /* 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, uint8_t *buf, int len, int is_write); +#define VGA_DIRTY_FLAG 0x01 + /* read dirty bit (return 0 or 1) */ 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) { - 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, int (*cpu_fprintf)(FILE *f, const char *fmt, ...)); @@ -110,7 +110,7 @@ unsigned long qemu_host_page_mask; /* XXX: for system emulation, it could just be an array */ static PageDesc *l1_map[L1_SIZE]; -static PhysPageDesc *l1_phys_map[L1_SIZE]; +PhysPageDesc **l1_phys_map; #if !defined(CONFIG_USER_ONLY) static VirtPageDesc *l1_virt_map[L1_SIZE]; @@ -176,6 +176,8 @@ static void page_init(void) #if !defined(CONFIG_USER_ONLY) virt_valid_tag = 1; #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) @@ -211,7 +213,7 @@ static inline PhysPageDesc *phys_page_find_alloc(unsigned int index) p = *lp; if (!p) { /* 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); *lp = p; } @@ -1305,6 +1307,11 @@ void tlb_flush(CPUState *env, int flush_global) #if !defined(CONFIG_SOFTMMU) 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 tlb_flush_count++; } @@ -1362,6 +1369,11 @@ void tlb_flush_page(CPUState *env, target_ulong addr) if (addr < MMAP_AREA_END) munmap((void *)addr, TARGET_PAGE_SIZE); #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) @@ -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; unsigned long length, start1; - int i; + int i, mask, len; + uint8_t *p; start &= TARGET_PAGE_MASK; end = TARGET_PAGE_ALIGN(end); @@ -1438,7 +1452,11 @@ void cpu_physical_memory_reset_dirty(target_ulong start, target_ulong end) length = end - start; if (length == 0) 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; /* 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; 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; 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", (unsigned long)addr, vp->prot); /* 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 */ tb_invalidate_phys_page(vp->phys_addr, pc, puc); 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); #endif 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) @@ -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); #endif 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) @@ -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); #endif 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] = { @@ -1959,7 +1977,7 @@ static void io_mem_init(void) io_mem_nb = 5; /* 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 @@ -2098,7 +2116,7 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, /* invalidate code */ tb_invalidate_phys_page_range(addr1, addr1 + l, 0); /* set dirty bit */ - phys_ram_dirty[addr1 >> TARGET_PAGE_BITS] = 1; + phys_ram_dirty[addr1 >> TARGET_PAGE_BITS] = 0xff; } } else { 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 */ tb_invalidate_phys_page_range(addr1, addr1 + 4, 0); /* set dirty bit */ - phys_ram_dirty[addr1 >> TARGET_PAGE_BITS] = 1; + phys_ram_dirty[addr1 >> TARGET_PAGE_BITS] = 0xff; } } @@ -129,7 +129,7 @@ void tcx_update_display(void *opaque) } 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) y_start = y; if (page < page_min) @@ -166,7 +166,8 @@ void tcx_update_display(void *opaque) } /* reset modified pages */ 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); s->r[255] = s->g[255] = s->b[255] = 255; 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, @@ -1454,11 +1454,13 @@ static void vga_draw_graphic(VGAState *s, int full_update) } page0 = s->vram_offset + (addr & TARGET_PAGE_MASK); page1 = s->vram_offset + ((addr + bwidth - 1) & TARGET_PAGE_MASK); - update = full_update | cpu_physical_memory_is_dirty(page0) | - cpu_physical_memory_is_dirty(page1); + update = full_update | + 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 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 */ 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 */ 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); } |