| 110 |
|
|
| 111 |
/* XXX: for system emulation, it could just be an array */ |
/* XXX: for system emulation, it could just be an array */ |
| 112 |
static PageDesc *l1_map[L1_SIZE]; |
static PageDesc *l1_map[L1_SIZE]; |
| 113 |
static PhysPageDesc *l1_phys_map[L1_SIZE]; |
PhysPageDesc **l1_phys_map; |
| 114 |
|
|
| 115 |
#if !defined(CONFIG_USER_ONLY) |
#if !defined(CONFIG_USER_ONLY) |
| 116 |
static VirtPageDesc *l1_virt_map[L1_SIZE]; |
static VirtPageDesc *l1_virt_map[L1_SIZE]; |
| 176 |
#if !defined(CONFIG_USER_ONLY) |
#if !defined(CONFIG_USER_ONLY) |
| 177 |
virt_valid_tag = 1; |
virt_valid_tag = 1; |
| 178 |
#endif |
#endif |
| 179 |
|
l1_phys_map = qemu_vmalloc(L1_SIZE * sizeof(PhysPageDesc *)); |
| 180 |
|
memset(l1_phys_map, 0, L1_SIZE * sizeof(PhysPageDesc *)); |
| 181 |
} |
} |
| 182 |
|
|
| 183 |
static inline PageDesc *page_find_alloc(unsigned int index) |
static inline PageDesc *page_find_alloc(unsigned int index) |
| 213 |
p = *lp; |
p = *lp; |
| 214 |
if (!p) { |
if (!p) { |
| 215 |
/* allocate if not found */ |
/* allocate if not found */ |
| 216 |
p = qemu_malloc(sizeof(PhysPageDesc) * L2_SIZE); |
p = qemu_vmalloc(sizeof(PhysPageDesc) * L2_SIZE); |
| 217 |
memset(p, 0, sizeof(PhysPageDesc) * L2_SIZE); |
memset(p, 0, sizeof(PhysPageDesc) * L2_SIZE); |
| 218 |
*lp = p; |
*lp = p; |
| 219 |
} |
} |
| 1307 |
#if !defined(CONFIG_SOFTMMU) |
#if !defined(CONFIG_SOFTMMU) |
| 1308 |
munmap((void *)MMAP_AREA_START, MMAP_AREA_END - MMAP_AREA_START); |
munmap((void *)MMAP_AREA_START, MMAP_AREA_END - MMAP_AREA_START); |
| 1309 |
#endif |
#endif |
| 1310 |
|
#ifdef USE_KQEMU |
| 1311 |
|
if (env->kqemu_enabled) { |
| 1312 |
|
kqemu_flush(env, flush_global); |
| 1313 |
|
} |
| 1314 |
|
#endif |
| 1315 |
tlb_flush_count++; |
tlb_flush_count++; |
| 1316 |
} |
} |
| 1317 |
|
|
| 1369 |
if (addr < MMAP_AREA_END) |
if (addr < MMAP_AREA_END) |
| 1370 |
munmap((void *)addr, TARGET_PAGE_SIZE); |
munmap((void *)addr, TARGET_PAGE_SIZE); |
| 1371 |
#endif |
#endif |
| 1372 |
|
#ifdef USE_KQEMU |
| 1373 |
|
if (env->kqemu_enabled) { |
| 1374 |
|
kqemu_flush_page(env, addr); |
| 1375 |
|
} |
| 1376 |
|
#endif |
| 1377 |
} |
} |
| 1378 |
|
|
| 1379 |
static inline void tlb_protect_code1(CPUTLBEntry *tlb_entry, target_ulong addr) |
static inline void tlb_protect_code1(CPUTLBEntry *tlb_entry, target_ulong addr) |
| 1438 |
} |
} |
| 1439 |
} |
} |
| 1440 |
|
|
| 1441 |
void cpu_physical_memory_reset_dirty(target_ulong start, target_ulong end) |
void cpu_physical_memory_reset_dirty(target_ulong start, target_ulong end, |
| 1442 |
|
int dirty_flags) |
| 1443 |
{ |
{ |
| 1444 |
CPUState *env; |
CPUState *env; |
| 1445 |
unsigned long length, start1; |
unsigned long length, start1; |
| 1446 |
int i; |
int i, mask, len; |
| 1447 |
|
uint8_t *p; |
| 1448 |
|
|
| 1449 |
start &= TARGET_PAGE_MASK; |
start &= TARGET_PAGE_MASK; |
| 1450 |
end = TARGET_PAGE_ALIGN(end); |
end = TARGET_PAGE_ALIGN(end); |
| 1452 |
length = end - start; |
length = end - start; |
| 1453 |
if (length == 0) |
if (length == 0) |
| 1454 |
return; |
return; |
| 1455 |
memset(phys_ram_dirty + (start >> TARGET_PAGE_BITS), 0, length >> TARGET_PAGE_BITS); |
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; |
| 1460 |
|
|
| 1461 |
env = cpu_single_env; |
env = cpu_single_env; |
| 1462 |
/* 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 |
| 1515 |
CPUState *env = cpu_single_env; |
CPUState *env = cpu_single_env; |
| 1516 |
int i; |
int i; |
| 1517 |
|
|
| 1518 |
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; |
| 1519 |
|
|
| 1520 |
addr &= TARGET_PAGE_MASK; |
addr &= TARGET_PAGE_MASK; |
| 1521 |
i = (vaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); |
i = (vaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); |
| 1687 |
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", |
| 1688 |
(unsigned long)addr, vp->prot); |
(unsigned long)addr, vp->prot); |
| 1689 |
/* set the dirty bit */ |
/* set the dirty bit */ |
| 1690 |
phys_ram_dirty[vp->phys_addr >> TARGET_PAGE_BITS] = 1; |
phys_ram_dirty[vp->phys_addr >> TARGET_PAGE_BITS] = 0xff; |
| 1691 |
/* flush the code inside */ |
/* flush the code inside */ |
| 1692 |
tb_invalidate_phys_page(vp->phys_addr, pc, puc); |
tb_invalidate_phys_page(vp->phys_addr, pc, puc); |
| 1693 |
return 1; |
return 1; |
| 1905 |
tb_invalidate_phys_page_fast(phys_addr, 1); |
tb_invalidate_phys_page_fast(phys_addr, 1); |
| 1906 |
#endif |
#endif |
| 1907 |
stb_p((uint8_t *)(long)addr, val); |
stb_p((uint8_t *)(long)addr, val); |
| 1908 |
phys_ram_dirty[phys_addr >> TARGET_PAGE_BITS] = 1; |
phys_ram_dirty[phys_addr >> TARGET_PAGE_BITS] = 0xff; |
| 1909 |
} |
} |
| 1910 |
|
|
| 1911 |
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) |
| 1917 |
tb_invalidate_phys_page_fast(phys_addr, 2); |
tb_invalidate_phys_page_fast(phys_addr, 2); |
| 1918 |
#endif |
#endif |
| 1919 |
stw_p((uint8_t *)(long)addr, val); |
stw_p((uint8_t *)(long)addr, val); |
| 1920 |
phys_ram_dirty[phys_addr >> TARGET_PAGE_BITS] = 1; |
phys_ram_dirty[phys_addr >> TARGET_PAGE_BITS] = 0xff; |
| 1921 |
} |
} |
| 1922 |
|
|
| 1923 |
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) |
| 1929 |
tb_invalidate_phys_page_fast(phys_addr, 4); |
tb_invalidate_phys_page_fast(phys_addr, 4); |
| 1930 |
#endif |
#endif |
| 1931 |
stl_p((uint8_t *)(long)addr, val); |
stl_p((uint8_t *)(long)addr, val); |
| 1932 |
phys_ram_dirty[phys_addr >> TARGET_PAGE_BITS] = 1; |
phys_ram_dirty[phys_addr >> TARGET_PAGE_BITS] = 0xff; |
| 1933 |
} |
} |
| 1934 |
|
|
| 1935 |
static CPUReadMemoryFunc *code_mem_read[3] = { |
static CPUReadMemoryFunc *code_mem_read[3] = { |
| 1977 |
io_mem_nb = 5; |
io_mem_nb = 5; |
| 1978 |
|
|
| 1979 |
/* alloc dirty bits array */ |
/* alloc dirty bits array */ |
| 1980 |
phys_ram_dirty = qemu_malloc(phys_ram_size >> TARGET_PAGE_BITS); |
phys_ram_dirty = qemu_vmalloc(phys_ram_size >> TARGET_PAGE_BITS); |
| 1981 |
} |
} |
| 1982 |
|
|
| 1983 |
/* mem_read and mem_write are arrays of functions containing the |
/* mem_read and mem_write are arrays of functions containing the |
| 2116 |
/* invalidate code */ |
/* invalidate code */ |
| 2117 |
tb_invalidate_phys_page_range(addr1, addr1 + l, 0); |
tb_invalidate_phys_page_range(addr1, addr1 + l, 0); |
| 2118 |
/* set dirty bit */ |
/* set dirty bit */ |
| 2119 |
phys_ram_dirty[addr1 >> TARGET_PAGE_BITS] = 1; |
phys_ram_dirty[addr1 >> TARGET_PAGE_BITS] = 0xff; |
| 2120 |
} |
} |
| 2121 |
} else { |
} else { |
| 2122 |
if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM && |
if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM && |
| 2237 |
/* invalidate code */ |
/* invalidate code */ |
| 2238 |
tb_invalidate_phys_page_range(addr1, addr1 + 4, 0); |
tb_invalidate_phys_page_range(addr1, addr1 + 4, 0); |
| 2239 |
/* set dirty bit */ |
/* set dirty bit */ |
| 2240 |
phys_ram_dirty[addr1 >> TARGET_PAGE_BITS] = 1; |
phys_ram_dirty[addr1 >> TARGET_PAGE_BITS] = 0xff; |
| 2241 |
} |
} |
| 2242 |
} |
} |
| 2243 |
|
|