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 |
|
|