diff --git a/cpu-common.h b/cpu-common.h index ffb0a44e13a70ac5df4e62e73f4dcb8769428eed..0f3a68235fc3591d0b3e6286264fe45d44ec67e2 100644 --- a/cpu-common.h +++ b/cpu-common.h @@ -114,9 +114,6 @@ extern struct MemoryRegion io_mem_rom; extern struct MemoryRegion io_mem_unassigned; extern struct MemoryRegion io_mem_notdirty; -/* Acts like a ROM when read and like a device when written. */ -#define IO_MEM_ROMD (1) - #endif #endif /* !CPU_COMMON_H */ diff --git a/exec.c b/exec.c index d5b82aabba5ad28017a38bad9d91d6bc3ca4a7c1..8916825688ab48634ee5c4d71bbcf9056c250521 100644 --- a/exec.c +++ b/exec.c @@ -2091,9 +2091,18 @@ static bool is_ram_rom(ram_addr_t pd) return pd == io_mem_ram.ram_addr || pd == io_mem_rom.ram_addr; } +static bool is_romd(ram_addr_t pd) +{ + MemoryRegion *mr; + + pd &= ~TARGET_PAGE_MASK; + mr = io_mem_region[pd >> IO_MEM_SHIFT]; + return mr->rom_device && mr->readable; +} + static bool is_ram_rom_romd(ram_addr_t pd) { - return is_ram_rom(pd) || (pd & IO_MEM_ROMD); + return is_ram_rom(pd) || is_romd(pd); } /* Add a new TLB entry. At most one entry for a given virtual address @@ -2179,8 +2188,7 @@ void tlb_set_page(CPUState *env, target_ulong vaddr, te->addr_code = -1; } if (prot & PAGE_WRITE) { - if ((pd & ~TARGET_PAGE_MASK) == io_mem_rom.ram_addr || - (pd & IO_MEM_ROMD)) { + if ((pd & ~TARGET_PAGE_MASK) == io_mem_rom.ram_addr || is_romd(pd)) { /* Write access calls the I/O callback. */ te->addr_write = address | TLB_MMIO; } else if ((pd & ~TARGET_PAGE_MASK) == io_mem_ram.ram_addr && @@ -2528,10 +2536,6 @@ void cpu_register_physical_memory_log(MemoryRegionSection *section, region_offset = 0; } - if (!readable) { - phys_offset &= ~TARGET_PAGE_MASK & ~IO_MEM_ROMD; - } - if (readonly) { phys_offset |= io_mem_rom.ram_addr; } @@ -4379,7 +4383,7 @@ tb_page_addr_t get_page_addr_code(CPUState *env1, target_ulong addr) } pd = env1->tlb_table[mmu_idx][page_index].addr_code & ~TARGET_PAGE_MASK; if (pd != io_mem_ram.ram_addr && pd != io_mem_rom.ram_addr - && !(pd & IO_MEM_ROMD)) { + && !is_romd(pd)) { #if defined(TARGET_ALPHA) || defined(TARGET_MIPS) || defined(TARGET_SPARC) cpu_unassigned_access(env1, addr, 0, 1, 0, 4); #else diff --git a/memory.c b/memory.c index 24b6b6f8f33bcb6d02c18d2c62d305b9fc7547cd..394cbab10efc83a28c895a831c642e3f59c5ecaa 100644 --- a/memory.c +++ b/memory.c @@ -838,7 +838,7 @@ static void memory_region_destructor_iomem(MemoryRegion *mr) static void memory_region_destructor_rom_device(MemoryRegion *mr) { qemu_ram_free(mr->ram_addr & TARGET_PAGE_MASK); - cpu_unregister_io_memory(mr->ram_addr & ~(TARGET_PAGE_MASK | IO_MEM_ROMD)); + cpu_unregister_io_memory(mr->ram_addr & ~TARGET_PAGE_MASK); } static bool memory_region_wrong_endianness(MemoryRegion *mr) @@ -868,6 +868,7 @@ void memory_region_init(MemoryRegion *mr, mr->ram = false; mr->readable = true; mr->readonly = false; + mr->rom_device = false; mr->destructor = memory_region_destructor_none; mr->priority = 0; mr->may_overlap = false; @@ -1039,10 +1040,10 @@ void memory_region_init_rom_device(MemoryRegion *mr, mr->ops = ops; mr->opaque = opaque; mr->terminates = true; + mr->rom_device = true; mr->destructor = memory_region_destructor_rom_device; mr->ram_addr = qemu_ram_alloc(size, mr); mr->ram_addr |= cpu_register_io_memory(mr); - mr->ram_addr |= IO_MEM_ROMD; } void memory_region_destroy(MemoryRegion *mr) diff --git a/memory.h b/memory.h index fbca6f146c17b2c4207679c5fda8f47ad2f65b29..70f57fbc12d1625840c973936c87f7504a01bddc 100644 --- a/memory.h +++ b/memory.h @@ -125,6 +125,7 @@ struct MemoryRegion { bool ram; bool readonly; /* For RAM regions */ bool enabled; + bool rom_device; MemoryRegion *alias; target_phys_addr_t alias_offset; unsigned priority;