http://ando-ruo.blogspot.hk/2012/11/qemu-cpumemoryrwdebug-normal-version.html
we have two version of memory access manipulation. latter is normal (fast) version which takes CPUState env to get physical address and check whether it is valided or not. if the address is not valid, cpu_get_phys_page_debug returns -1.
exec.c
4642 | phys_addr = cpu_get_phys_page_debug(env, page);
4643 | /* if no physical page mapped, return an error */
4644 | if (phys_addr == -1)
4645 | return -1;
exec.c
3853 |/* physical memory access (slow version, mainly for debug) */
3854 |#if defined(CONFIG_USER_ONLY)
3855 |int cpu_memory_rw_debug(CPUState *env, target_ulong addr,
3856 | uint8_t *buf, int len, int is_write)
3857 |{
4632 |/* virtual memory access for debug (includes writing to ROM) */
4633 |int cpu_memory_rw_debug(CPUState *env, target_ulong addr,
4634 | uint8_t *buf, int len, int is_write)
4635 |{
4636 | int l;
4637 | target_phys_addr_t phys_addr;
4638 | target_ulong page;
4639 |
4640 | while (len > 0) {
4641 | page = addr & TARGET_PAGE_MASK;
4642 | phys_addr = cpu_get_phys_page_debug(env, page);
4643 | /* if no physical page mapped, return an error */
4644 | if (phys_addr == -1)
4645 | return -1;
4646 | l = (page + TARGET_PAGE_SIZE) - addr;
4647 | if (l > len)
4648 | l = len;
4649 | phys_addr += (addr & ~TARGET_PAGE_MASK);
4650 | if (is_write)
4651 | cpu_physical_memory_write_rom(phys_addr, buf, l);
4652 | else
4653 | cpu_physical_memory_rw(phys_addr, buf, l, is_write);
4654 | len -= l;
4655 | buf += l;
4656 | addr += l;
4657 | }
4658 | return 0;
4659 |}
TARGET_PAGE_MASK and TARGET_PAGE_SIZE is a macro which is used to obtain the length of buffer from taking argument of page. these two macros are generic to all CPUs, defined in cpu-all.h
cpu-all.h
286 |/* page related stuff */
287 |
288 |#define TARGET_PAGE_SIZE (1 << TARGET_PAGE_BITS)
289 |#define TARGET_PAGE_MASK ~(TARGET_PAGE_SIZE - 1)
290 |#define TARGET_PAGE_ALIGN(addr) (((addr) + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK)
TARGET_PAGE_BITS is hard-coded in i386 to 12.
i386/cpu.h
934 |/* used to debug */
935 |#define X86_DUMP_FPU 0x0001 /* dump FPU state too */
936 |#define X86_DUMP_CCOP 0x0002 /* dump qemu flag cache */
937 |
938 |#define TARGET_PAGE_BITS 12
eventually this routine invoked either cpu_physical_memory_write_rom or cpu_physical_memory_rw.
4650 | if (is_write)
4651 | cpu_physical_memory_write_rom(phys_addr, buf, l);
4652 | else
4653 | cpu_physical_memory_rw(phys_addr, buf, l, is_write);