Convert IO_MEM_{RAM,ROM,UNASSIGNED,NOTDIRTY} to MemoryRegions

Convert the fixed-address IO_MEM_RAM, IO_MEM_ROM, IO_MEM_UNASSIGNED,
and IO_MEM_NOTDIRTY io handlers to MemoryRegions.  These aren't real
regions, since they are never added to the memory hierarchy, but they
allow reuse of the dispatch functionality.

Signed-off-by: Avi Kivity <avi@redhat.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
This commit is contained in:
Avi Kivity 2012-01-02 00:32:15 +02:00
parent d39e822265
commit 0e0df1e24d
4 changed files with 106 additions and 154 deletions

View File

@ -109,10 +109,10 @@ void cpu_physical_memory_write_rom(target_phys_addr_t addr,
#define IO_MEM_SHIFT 3 #define IO_MEM_SHIFT 3
#define IO_MEM_RAM (0 << IO_MEM_SHIFT) /* hardcoded offset */ extern struct MemoryRegion io_mem_ram;
#define IO_MEM_ROM (1 << IO_MEM_SHIFT) /* hardcoded offset */ extern struct MemoryRegion io_mem_rom;
#define IO_MEM_UNASSIGNED (2 << IO_MEM_SHIFT) extern struct MemoryRegion io_mem_unassigned;
#define IO_MEM_NOTDIRTY (3 << IO_MEM_SHIFT) extern struct MemoryRegion io_mem_notdirty;
#define IO_MEM_SUBPAGE_RAM (4 << IO_MEM_SHIFT) #define IO_MEM_SUBPAGE_RAM (4 << IO_MEM_SHIFT)
/* Acts like a ROM when read and like a device when written. */ /* Acts like a ROM when read and like a device when written. */

234
exec.c
View File

@ -118,6 +118,8 @@ RAMList ram_list = { .blocks = QLIST_HEAD_INITIALIZER(ram_list.blocks) };
static MemoryRegion *system_memory; static MemoryRegion *system_memory;
static MemoryRegion *system_io; static MemoryRegion *system_io;
MemoryRegion io_mem_ram, io_mem_rom, io_mem_unassigned, io_mem_notdirty;
#endif #endif
CPUState *first_cpu; CPUState *first_cpu;
@ -430,7 +432,7 @@ static PhysPageDesc *phys_page_find_alloc(target_phys_addr_t index, int alloc)
*lp = pd = g_malloc(sizeof(PhysPageDesc) * L2_SIZE); *lp = pd = g_malloc(sizeof(PhysPageDesc) * L2_SIZE);
for (i = 0; i < L2_SIZE; i++) { for (i = 0; i < L2_SIZE; i++) {
pd[i].phys_offset = IO_MEM_UNASSIGNED; pd[i].phys_offset = io_mem_unassigned.ram_addr;
pd[i].region_offset = (first_index + i) << TARGET_PAGE_BITS; pd[i].region_offset = (first_index + i) << TARGET_PAGE_BITS;
} }
} }
@ -446,7 +448,7 @@ static inline PhysPageDesc phys_page_find(target_phys_addr_t index)
return *p; return *p;
} else { } else {
return (PhysPageDesc) { return (PhysPageDesc) {
.phys_offset = IO_MEM_UNASSIGNED, .phys_offset = io_mem_unassigned.ram_addr,
.region_offset = index << TARGET_PAGE_BITS, .region_offset = index << TARGET_PAGE_BITS,
}; };
} }
@ -1965,7 +1967,7 @@ static inline void tlb_reset_dirty_range(CPUTLBEntry *tlb_entry,
unsigned long start, unsigned long length) unsigned long start, unsigned long length)
{ {
unsigned long addr; unsigned long addr;
if ((tlb_entry->addr_write & ~TARGET_PAGE_MASK) == IO_MEM_RAM) { if ((tlb_entry->addr_write & ~TARGET_PAGE_MASK) == io_mem_ram.ram_addr) {
addr = (tlb_entry->addr_write & TARGET_PAGE_MASK) + tlb_entry->addend; addr = (tlb_entry->addr_write & TARGET_PAGE_MASK) + tlb_entry->addend;
if ((addr - start) < length) { if ((addr - start) < length) {
tlb_entry->addr_write = (tlb_entry->addr_write & TARGET_PAGE_MASK) | TLB_NOTDIRTY; tlb_entry->addr_write = (tlb_entry->addr_write & TARGET_PAGE_MASK) | TLB_NOTDIRTY;
@ -2021,7 +2023,7 @@ static inline void tlb_update_dirty(CPUTLBEntry *tlb_entry)
ram_addr_t ram_addr; ram_addr_t ram_addr;
void *p; void *p;
if ((tlb_entry->addr_write & ~TARGET_PAGE_MASK) == IO_MEM_RAM) { if ((tlb_entry->addr_write & ~TARGET_PAGE_MASK) == io_mem_ram.ram_addr) {
p = (void *)(unsigned long)((tlb_entry->addr_write & TARGET_PAGE_MASK) p = (void *)(unsigned long)((tlb_entry->addr_write & TARGET_PAGE_MASK)
+ tlb_entry->addend); + tlb_entry->addend);
ram_addr = qemu_ram_addr_from_host_nofail(p); ram_addr = qemu_ram_addr_from_host_nofail(p);
@ -2087,7 +2089,7 @@ static void tlb_add_large_page(CPUState *env, target_ulong vaddr,
static bool is_ram_rom(ram_addr_t pd) static bool is_ram_rom(ram_addr_t pd)
{ {
pd &= ~TARGET_PAGE_MASK; pd &= ~TARGET_PAGE_MASK;
return pd == IO_MEM_RAM || pd == IO_MEM_ROM; return pd == io_mem_ram.ram_addr || pd == io_mem_rom.ram_addr;
} }
static bool is_ram_rom_romd(ram_addr_t pd) static bool is_ram_rom_romd(ram_addr_t pd)
@ -2133,10 +2135,10 @@ void tlb_set_page(CPUState *env, target_ulong vaddr,
if (is_ram_rom(pd)) { if (is_ram_rom(pd)) {
/* Normal RAM. */ /* Normal RAM. */
iotlb = pd & TARGET_PAGE_MASK; iotlb = pd & TARGET_PAGE_MASK;
if ((pd & ~TARGET_PAGE_MASK) == IO_MEM_RAM) if ((pd & ~TARGET_PAGE_MASK) == io_mem_ram.ram_addr)
iotlb |= IO_MEM_NOTDIRTY; iotlb |= io_mem_notdirty.ram_addr;
else else
iotlb |= IO_MEM_ROM; iotlb |= io_mem_rom.ram_addr;
} else { } else {
/* IO handlers are currently passed a physical address. /* IO handlers are currently passed a physical address.
It would be nice to pass an offset from the base address It would be nice to pass an offset from the base address
@ -2178,11 +2180,11 @@ void tlb_set_page(CPUState *env, target_ulong vaddr,
te->addr_code = -1; te->addr_code = -1;
} }
if (prot & PAGE_WRITE) { if (prot & PAGE_WRITE) {
if ((pd & ~TARGET_PAGE_MASK) == IO_MEM_ROM || if ((pd & ~TARGET_PAGE_MASK) == io_mem_rom.ram_addr ||
(pd & IO_MEM_ROMD)) { (pd & IO_MEM_ROMD)) {
/* Write access calls the I/O callback. */ /* Write access calls the I/O callback. */
te->addr_write = address | TLB_MMIO; te->addr_write = address | TLB_MMIO;
} else if ((pd & ~TARGET_PAGE_MASK) == IO_MEM_RAM && } else if ((pd & ~TARGET_PAGE_MASK) == io_mem_ram.ram_addr &&
!cpu_physical_memory_is_dirty(pd)) { !cpu_physical_memory_is_dirty(pd)) {
te->addr_write = address | TLB_NOTDIRTY; te->addr_write = address | TLB_NOTDIRTY;
} else { } else {
@ -2522,7 +2524,7 @@ void cpu_register_physical_memory_log(target_phys_addr_t start_addr,
assert(size); assert(size);
if (phys_offset == IO_MEM_UNASSIGNED) { if (phys_offset == io_mem_unassigned.ram_addr) {
region_offset = start_addr; region_offset = start_addr;
} }
region_offset &= TARGET_PAGE_MASK; region_offset &= TARGET_PAGE_MASK;
@ -2532,7 +2534,7 @@ void cpu_register_physical_memory_log(target_phys_addr_t start_addr,
addr = start_addr; addr = start_addr;
do { do {
p = phys_page_find_alloc(addr >> TARGET_PAGE_BITS, 0); p = phys_page_find_alloc(addr >> TARGET_PAGE_BITS, 0);
if (p && p->phys_offset != IO_MEM_UNASSIGNED) { if (p && p->phys_offset != io_mem_unassigned.ram_addr) {
ram_addr_t orig_memory = p->phys_offset; ram_addr_t orig_memory = p->phys_offset;
target_phys_addr_t start_addr2, end_addr2; target_phys_addr_t start_addr2, end_addr2;
int need_subpage = 0; int need_subpage = 0;
@ -2572,7 +2574,8 @@ void cpu_register_physical_memory_log(target_phys_addr_t start_addr,
if (need_subpage) { if (need_subpage) {
subpage = subpage_init((addr & TARGET_PAGE_MASK), subpage = subpage_init((addr & TARGET_PAGE_MASK),
&p->phys_offset, IO_MEM_UNASSIGNED, &p->phys_offset,
io_mem_unassigned.ram_addr,
addr & TARGET_PAGE_MASK); addr & TARGET_PAGE_MASK);
subpage_register(subpage, start_addr2, end_addr2, subpage_register(subpage, start_addr2, end_addr2,
phys_offset, region_offset); phys_offset, region_offset);
@ -3102,93 +3105,83 @@ ram_addr_t qemu_ram_addr_from_host_nofail(void *ptr)
return ram_addr; return ram_addr;
} }
static uint32_t unassigned_mem_readb(void *opaque, target_phys_addr_t addr) static uint64_t unassigned_mem_read(void *opaque, target_phys_addr_t addr,
unsigned size)
{ {
#ifdef DEBUG_UNASSIGNED #ifdef DEBUG_UNASSIGNED
printf("Unassigned mem read " TARGET_FMT_plx "\n", addr); printf("Unassigned mem read " TARGET_FMT_plx "\n", addr);
#endif #endif
#if defined(TARGET_ALPHA) || defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE) #if defined(TARGET_ALPHA) || defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE)
cpu_unassigned_access(cpu_single_env, addr, 0, 0, 0, 1); cpu_unassigned_access(cpu_single_env, addr, 0, 0, 0, size);
#endif #endif
return 0; return 0;
} }
static uint32_t unassigned_mem_readw(void *opaque, target_phys_addr_t addr) static void unassigned_mem_write(void *opaque, target_phys_addr_t addr,
uint64_t val, unsigned size)
{ {
#ifdef DEBUG_UNASSIGNED #ifdef DEBUG_UNASSIGNED
printf("Unassigned mem read " TARGET_FMT_plx "\n", addr); printf("Unassigned mem write " TARGET_FMT_plx " = 0x%"PRIx64"\n", addr, val);
#endif #endif
#if defined(TARGET_ALPHA) || defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE) #if defined(TARGET_ALPHA) || defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE)
cpu_unassigned_access(cpu_single_env, addr, 0, 0, 0, 2); cpu_unassigned_access(cpu_single_env, addr, 1, 0, 0, size);
#endif
return 0;
}
static uint32_t unassigned_mem_readl(void *opaque, target_phys_addr_t addr)
{
#ifdef DEBUG_UNASSIGNED
printf("Unassigned mem read " TARGET_FMT_plx "\n", addr);
#endif
#if defined(TARGET_ALPHA) || defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE)
cpu_unassigned_access(cpu_single_env, addr, 0, 0, 0, 4);
#endif
return 0;
}
static void unassigned_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
{
#ifdef DEBUG_UNASSIGNED
printf("Unassigned mem write " TARGET_FMT_plx " = 0x%x\n", addr, val);
#endif
#if defined(TARGET_ALPHA) || defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE)
cpu_unassigned_access(cpu_single_env, addr, 1, 0, 0, 1);
#endif #endif
} }
static void unassigned_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val) static const MemoryRegionOps unassigned_mem_ops = {
{ .read = unassigned_mem_read,
#ifdef DEBUG_UNASSIGNED .write = unassigned_mem_write,
printf("Unassigned mem write " TARGET_FMT_plx " = 0x%x\n", addr, val); .endianness = DEVICE_NATIVE_ENDIAN,
#endif
#if defined(TARGET_ALPHA) || defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE)
cpu_unassigned_access(cpu_single_env, addr, 1, 0, 0, 2);
#endif
}
static void unassigned_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
{
#ifdef DEBUG_UNASSIGNED
printf("Unassigned mem write " TARGET_FMT_plx " = 0x%x\n", addr, val);
#endif
#if defined(TARGET_ALPHA) || defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE)
cpu_unassigned_access(cpu_single_env, addr, 1, 0, 0, 4);
#endif
}
static CPUReadMemoryFunc * const unassigned_mem_read[3] = {
unassigned_mem_readb,
unassigned_mem_readw,
unassigned_mem_readl,
}; };
static CPUWriteMemoryFunc * const unassigned_mem_write[3] = { static uint64_t error_mem_read(void *opaque, target_phys_addr_t addr,
unassigned_mem_writeb, unsigned size)
unassigned_mem_writew, {
unassigned_mem_writel, abort();
}
static void error_mem_write(void *opaque, target_phys_addr_t addr,
uint64_t value, unsigned size)
{
abort();
}
static const MemoryRegionOps error_mem_ops = {
.read = error_mem_read,
.write = error_mem_write,
.endianness = DEVICE_NATIVE_ENDIAN,
}; };
static void notdirty_mem_writeb(void *opaque, target_phys_addr_t ram_addr, static const MemoryRegionOps rom_mem_ops = {
uint32_t val) .read = error_mem_read,
.write = unassigned_mem_write,
.endianness = DEVICE_NATIVE_ENDIAN,
};
static void notdirty_mem_write(void *opaque, target_phys_addr_t ram_addr,
uint64_t val, unsigned size)
{ {
int dirty_flags; int dirty_flags;
dirty_flags = cpu_physical_memory_get_dirty_flags(ram_addr); dirty_flags = cpu_physical_memory_get_dirty_flags(ram_addr);
if (!(dirty_flags & CODE_DIRTY_FLAG)) { if (!(dirty_flags & CODE_DIRTY_FLAG)) {
#if !defined(CONFIG_USER_ONLY) #if !defined(CONFIG_USER_ONLY)
tb_invalidate_phys_page_fast(ram_addr, 1); tb_invalidate_phys_page_fast(ram_addr, size);
dirty_flags = cpu_physical_memory_get_dirty_flags(ram_addr); dirty_flags = cpu_physical_memory_get_dirty_flags(ram_addr);
#endif #endif
} }
stb_p(qemu_get_ram_ptr(ram_addr), val); switch (size) {
case 1:
stb_p(qemu_get_ram_ptr(ram_addr), val);
break;
case 2:
stw_p(qemu_get_ram_ptr(ram_addr), val);
break;
case 4:
stl_p(qemu_get_ram_ptr(ram_addr), val);
break;
default:
abort();
}
dirty_flags |= (0xff & ~CODE_DIRTY_FLAG); dirty_flags |= (0xff & ~CODE_DIRTY_FLAG);
cpu_physical_memory_set_dirty_flags(ram_addr, dirty_flags); cpu_physical_memory_set_dirty_flags(ram_addr, dirty_flags);
/* we remove the notdirty callback only if the code has been /* we remove the notdirty callback only if the code has been
@ -3197,56 +3190,10 @@ static void notdirty_mem_writeb(void *opaque, target_phys_addr_t ram_addr,
tlb_set_dirty(cpu_single_env, cpu_single_env->mem_io_vaddr); tlb_set_dirty(cpu_single_env, cpu_single_env->mem_io_vaddr);
} }
static void notdirty_mem_writew(void *opaque, target_phys_addr_t ram_addr, static const MemoryRegionOps notdirty_mem_ops = {
uint32_t val) .read = error_mem_read,
{ .write = notdirty_mem_write,
int dirty_flags; .endianness = DEVICE_NATIVE_ENDIAN,
dirty_flags = cpu_physical_memory_get_dirty_flags(ram_addr);
if (!(dirty_flags & CODE_DIRTY_FLAG)) {
#if !defined(CONFIG_USER_ONLY)
tb_invalidate_phys_page_fast(ram_addr, 2);
dirty_flags = cpu_physical_memory_get_dirty_flags(ram_addr);
#endif
}
stw_p(qemu_get_ram_ptr(ram_addr), val);
dirty_flags |= (0xff & ~CODE_DIRTY_FLAG);
cpu_physical_memory_set_dirty_flags(ram_addr, dirty_flags);
/* we remove the notdirty callback only if the code has been
flushed */
if (dirty_flags == 0xff)
tlb_set_dirty(cpu_single_env, cpu_single_env->mem_io_vaddr);
}
static void notdirty_mem_writel(void *opaque, target_phys_addr_t ram_addr,
uint32_t val)
{
int dirty_flags;
dirty_flags = cpu_physical_memory_get_dirty_flags(ram_addr);
if (!(dirty_flags & CODE_DIRTY_FLAG)) {
#if !defined(CONFIG_USER_ONLY)
tb_invalidate_phys_page_fast(ram_addr, 4);
dirty_flags = cpu_physical_memory_get_dirty_flags(ram_addr);
#endif
}
stl_p(qemu_get_ram_ptr(ram_addr), val);
dirty_flags |= (0xff & ~CODE_DIRTY_FLAG);
cpu_physical_memory_set_dirty_flags(ram_addr, dirty_flags);
/* we remove the notdirty callback only if the code has been
flushed */
if (dirty_flags == 0xff)
tlb_set_dirty(cpu_single_env, cpu_single_env->mem_io_vaddr);
}
static CPUReadMemoryFunc * const error_mem_read[3] = {
NULL, /* never used */
NULL, /* never used */
NULL, /* never used */
};
static CPUWriteMemoryFunc * const notdirty_mem_write[3] = {
notdirty_mem_writeb,
notdirty_mem_writew,
notdirty_mem_writel,
}; };
/* Generate a debug exception if a watchpoint has been hit. */ /* Generate a debug exception if a watchpoint has been hit. */
@ -3492,7 +3439,7 @@ static int subpage_register (subpage_t *mmio, uint32_t start, uint32_t end,
printf("%s: %p start %08x end %08x idx %08x eidx %08x mem %ld\n", __func__, printf("%s: %p start %08x end %08x idx %08x eidx %08x mem %ld\n", __func__,
mmio, start, end, idx, eidx, memory); mmio, start, end, idx, eidx, memory);
#endif #endif
if ((memory & ~TARGET_PAGE_MASK) == IO_MEM_RAM) { if ((memory & ~TARGET_PAGE_MASK) == io_mem_ram.ram_addr) {
memory = IO_MEM_SUBPAGE_RAM; memory = IO_MEM_SUBPAGE_RAM;
} }
memory = (memory >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1); memory = (memory >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
@ -3563,12 +3510,12 @@ static int cpu_register_io_memory_fixed(int io_index,
} }
for (i = 0; i < 3; ++i) { for (i = 0; i < 3; ++i) {
_io_mem_read[io_index][i] assert(mem_read[i]);
= (mem_read[i] ? mem_read[i] : unassigned_mem_read[i]); _io_mem_read[io_index][i] = mem_read[i];
} }
for (i = 0; i < 3; ++i) { for (i = 0; i < 3; ++i) {
_io_mem_write[io_index][i] assert(mem_write[i]);
= (mem_write[i] ? mem_write[i] : unassigned_mem_write[i]); _io_mem_write[io_index][i] = mem_write[i];
} }
io_mem_opaque[io_index] = opaque; io_mem_opaque[io_index] = opaque;
@ -3588,8 +3535,8 @@ void cpu_unregister_io_memory(int io_table_address)
int io_index = io_table_address >> IO_MEM_SHIFT; int io_index = io_table_address >> IO_MEM_SHIFT;
for (i=0;i < 3; i++) { for (i=0;i < 3; i++) {
_io_mem_read[io_index][i] = unassigned_mem_read[i]; _io_mem_read[io_index][i] = NULL;
_io_mem_write[io_index][i] = unassigned_mem_write[i]; _io_mem_write[io_index][i] = NULL;
} }
io_mem_opaque[io_index] = NULL; io_mem_opaque[io_index] = NULL;
io_mem_used[io_index] = 0; io_mem_used[io_index] = 0;
@ -3599,12 +3546,14 @@ static void io_mem_init(void)
{ {
int i; int i;
cpu_register_io_memory_fixed(IO_MEM_ROM, error_mem_read, /* Must be first: */
unassigned_mem_write, NULL); memory_region_init_io(&io_mem_ram, &error_mem_ops, NULL, "ram", UINT64_MAX);
cpu_register_io_memory_fixed(IO_MEM_UNASSIGNED, unassigned_mem_read, assert(io_mem_ram.ram_addr == 0);
unassigned_mem_write, NULL); memory_region_init_io(&io_mem_rom, &rom_mem_ops, NULL, "rom", UINT64_MAX);
cpu_register_io_memory_fixed(IO_MEM_NOTDIRTY, error_mem_read, memory_region_init_io(&io_mem_unassigned, &unassigned_mem_ops, NULL,
notdirty_mem_write, NULL); "unassigned", UINT64_MAX);
memory_region_init_io(&io_mem_notdirty, &notdirty_mem_ops, NULL,
"notdirty", UINT64_MAX);
cpu_register_io_memory_fixed(IO_MEM_SUBPAGE_RAM, subpage_ram_read, cpu_register_io_memory_fixed(IO_MEM_SUBPAGE_RAM, subpage_ram_read,
subpage_ram_write, NULL); subpage_ram_write, NULL);
for (i=0; i<5; i++) for (i=0; i<5; i++)
@ -3698,7 +3647,7 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
pd = p.phys_offset; pd = p.phys_offset;
if (is_write) { if (is_write) {
if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM) { if ((pd & ~TARGET_PAGE_MASK) != io_mem_ram.ram_addr) {
target_phys_addr_t addr1; target_phys_addr_t addr1;
io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1); io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
addr1 = (addr & ~TARGET_PAGE_MASK) + p.region_offset; addr1 = (addr & ~TARGET_PAGE_MASK) + p.region_offset;
@ -3879,7 +3828,7 @@ void *cpu_physical_memory_map(target_phys_addr_t addr,
p = phys_page_find(page >> TARGET_PAGE_BITS); p = phys_page_find(page >> TARGET_PAGE_BITS);
pd = p.phys_offset; pd = p.phys_offset;
if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM) { if ((pd & ~TARGET_PAGE_MASK) != io_mem_ram.ram_addr) {
if (todo || bounce.buffer) { if (todo || bounce.buffer) {
break; break;
} }
@ -4150,7 +4099,7 @@ void stl_phys_notdirty(target_phys_addr_t addr, uint32_t val)
p = phys_page_find(addr >> TARGET_PAGE_BITS); p = phys_page_find(addr >> TARGET_PAGE_BITS);
pd = p.phys_offset; pd = p.phys_offset;
if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM) { if ((pd & ~TARGET_PAGE_MASK) != io_mem_ram.ram_addr) {
io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1); io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
addr = (addr & ~TARGET_PAGE_MASK) + p.region_offset; addr = (addr & ~TARGET_PAGE_MASK) + p.region_offset;
io_mem_write(io_index, addr, val, 4); io_mem_write(io_index, addr, val, 4);
@ -4181,7 +4130,7 @@ void stq_phys_notdirty(target_phys_addr_t addr, uint64_t val)
p = phys_page_find(addr >> TARGET_PAGE_BITS); p = phys_page_find(addr >> TARGET_PAGE_BITS);
pd = p.phys_offset; pd = p.phys_offset;
if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM) { if ((pd & ~TARGET_PAGE_MASK) != io_mem_ram.ram_addr) {
io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1); io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
addr = (addr & ~TARGET_PAGE_MASK) + p.region_offset; addr = (addr & ~TARGET_PAGE_MASK) + p.region_offset;
#ifdef TARGET_WORDS_BIGENDIAN #ifdef TARGET_WORDS_BIGENDIAN
@ -4210,7 +4159,7 @@ static inline void stl_phys_internal(target_phys_addr_t addr, uint32_t val,
p = phys_page_find(addr >> TARGET_PAGE_BITS); p = phys_page_find(addr >> TARGET_PAGE_BITS);
pd = p.phys_offset; pd = p.phys_offset;
if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM) { if ((pd & ~TARGET_PAGE_MASK) != io_mem_ram.ram_addr) {
io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1); io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
addr = (addr & ~TARGET_PAGE_MASK) + p.region_offset; addr = (addr & ~TARGET_PAGE_MASK) + p.region_offset;
#if defined(TARGET_WORDS_BIGENDIAN) #if defined(TARGET_WORDS_BIGENDIAN)
@ -4283,7 +4232,7 @@ static inline void stw_phys_internal(target_phys_addr_t addr, uint32_t val,
p = phys_page_find(addr >> TARGET_PAGE_BITS); p = phys_page_find(addr >> TARGET_PAGE_BITS);
pd = p.phys_offset; pd = p.phys_offset;
if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM) { if ((pd & ~TARGET_PAGE_MASK) != io_mem_ram.ram_addr) {
io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1); io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
addr = (addr & ~TARGET_PAGE_MASK) + p.region_offset; addr = (addr & ~TARGET_PAGE_MASK) + p.region_offset;
#if defined(TARGET_WORDS_BIGENDIAN) #if defined(TARGET_WORDS_BIGENDIAN)
@ -4514,7 +4463,8 @@ tb_page_addr_t get_page_addr_code(CPUState *env1, target_ulong addr)
ldub_code(addr); ldub_code(addr);
} }
pd = env1->tlb_table[mmu_idx][page_index].addr_code & ~TARGET_PAGE_MASK; pd = env1->tlb_table[mmu_idx][page_index].addr_code & ~TARGET_PAGE_MASK;
if (pd != IO_MEM_RAM && pd != IO_MEM_ROM && !(pd & IO_MEM_ROMD)) { if (pd != io_mem_ram.ram_addr && pd != io_mem_rom.ram_addr
&& !(pd & IO_MEM_ROMD)) {
#if defined(TARGET_ALPHA) || defined(TARGET_MIPS) || defined(TARGET_SPARC) #if defined(TARGET_ALPHA) || defined(TARGET_MIPS) || defined(TARGET_SPARC)
cpu_unassigned_access(env1, addr, 0, 1, 0, 4); cpu_unassigned_access(env1, addr, 0, 1, 0, 4);
#else #else

View File

@ -312,8 +312,7 @@ static void as_memory_range_add(AddressSpace *as, FlatRange *fr)
/* cpu_register_physical_memory_log() wants region_offset for /* cpu_register_physical_memory_log() wants region_offset for
* mmio, but prefers offseting phys_offset for RAM. Humour it. * mmio, but prefers offseting phys_offset for RAM. Humour it.
*/ */
if ((phys_offset & ~TARGET_PAGE_MASK) == IO_MEM_RAM if (memory_region_is_ram(fr->mr)) {
|| (phys_offset & ~TARGET_PAGE_MASK) == IO_MEM_ROM) {
phys_offset += region_offset; phys_offset += region_offset;
region_offset = 0; region_offset = 0;
} }
@ -323,7 +322,7 @@ static void as_memory_range_add(AddressSpace *as, FlatRange *fr)
} }
if (fr->readonly) { if (fr->readonly) {
phys_offset |= IO_MEM_ROM; phys_offset |= io_mem_rom.ram_addr;
} }
cpu_register_physical_memory_log(int128_get64(fr->addr.start), cpu_register_physical_memory_log(int128_get64(fr->addr.start),
@ -337,7 +336,7 @@ static void as_memory_range_del(AddressSpace *as, FlatRange *fr)
{ {
cpu_register_physical_memory(int128_get64(fr->addr.start), cpu_register_physical_memory(int128_get64(fr->addr.start),
int128_get64(fr->addr.size), int128_get64(fr->addr.size),
IO_MEM_UNASSIGNED); io_mem_unassigned.ram_addr);
} }
static void as_memory_log_start(AddressSpace *as, FlatRange *fr) static void as_memory_log_start(AddressSpace *as, FlatRange *fr)

View File

@ -22,6 +22,7 @@
* License along with this library; if not, see <http://www.gnu.org/licenses/>. * License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/ */
#include "qemu-timer.h" #include "qemu-timer.h"
#include "memory.h"
#define DATA_SIZE (1 << SHIFT) #define DATA_SIZE (1 << SHIFT)
@ -65,8 +66,9 @@ static inline DATA_TYPE glue(io_read, SUFFIX)(target_phys_addr_t physaddr,
index = (physaddr >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1); index = (physaddr >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
physaddr = (physaddr & TARGET_PAGE_MASK) + addr; physaddr = (physaddr & TARGET_PAGE_MASK) + addr;
env->mem_io_pc = (unsigned long)retaddr; env->mem_io_pc = (unsigned long)retaddr;
if (index != IO_MEM_RAM && index != IO_MEM_ROM if (index != io_mem_ram.ram_addr && index != io_mem_rom.ram_addr
&& index != IO_MEM_UNASSIGNED && index != IO_MEM_NOTDIRTY && index != io_mem_unassigned.ram_addr
&& index != io_mem_notdirty.ram_addr
&& !can_do_io(env)) { && !can_do_io(env)) {
cpu_io_recompile(env, retaddr); cpu_io_recompile(env, retaddr);
} }
@ -208,8 +210,9 @@ static inline void glue(io_write, SUFFIX)(target_phys_addr_t physaddr,
int index; int index;
index = (physaddr >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1); index = (physaddr >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
physaddr = (physaddr & TARGET_PAGE_MASK) + addr; physaddr = (physaddr & TARGET_PAGE_MASK) + addr;
if (index != IO_MEM_RAM && index != IO_MEM_ROM if (index != io_mem_ram.ram_addr && index != io_mem_rom.ram_addr
&& index != IO_MEM_UNASSIGNED && index != IO_MEM_NOTDIRTY && index != io_mem_unassigned.ram_addr
&& index != io_mem_notdirty.ram_addr
&& !can_do_io(env)) { && !can_do_io(env)) {
cpu_io_recompile(env, retaddr); cpu_io_recompile(env, retaddr);
} }