Commit 2a4188a38fa3a91a9286da6fe077b6218378504d
1 parent
4f4fbf77
low level support for memory mapped flash devices (initial patch by Jocelyn Mayer)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2020 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
3 changed files
with
16 additions
and
7 deletions
cpu-all.h
... | ... | @@ -828,6 +828,10 @@ extern uint8_t *phys_ram_dirty; |
828 | 828 | #define IO_MEM_ROM (1 << IO_MEM_SHIFT) /* hardcoded offset */ |
829 | 829 | #define IO_MEM_UNASSIGNED (2 << IO_MEM_SHIFT) |
830 | 830 | #define IO_MEM_NOTDIRTY (4 << IO_MEM_SHIFT) /* used internally, never use directly */ |
831 | +/* acts like a ROM when read and like a device when written. As an | |
832 | + exception, the write memory callback gets the ram offset instead of | |
833 | + the physical address */ | |
834 | +#define IO_MEM_ROMD (1) | |
831 | 835 | |
832 | 836 | typedef void CPUWriteMemoryFunc(void *opaque, target_phys_addr_t addr, uint32_t value); |
833 | 837 | typedef uint32_t CPUReadMemoryFunc(void *opaque, target_phys_addr_t addr); | ... | ... |
exec-all.h
... | ... | @@ -570,7 +570,7 @@ static inline target_ulong get_phys_addr_code(CPUState *env, target_ulong addr) |
570 | 570 | ldub_code(addr); |
571 | 571 | } |
572 | 572 | pd = env->tlb_table[is_user][index].addr_code & ~TARGET_PAGE_MASK; |
573 | - if (pd > IO_MEM_ROM) { | |
573 | + if (pd > IO_MEM_ROM && !(pd & IO_MEM_ROMD)) { | |
574 | 574 | cpu_abort(env, "Trying to execute code outside RAM or ROM at 0x%08lx\n", addr); |
575 | 575 | } |
576 | 576 | return addr + env->tlb_table[is_user][index].addend - (unsigned long)phys_ram_base; | ... | ... |
exec.c
... | ... | @@ -1488,7 +1488,7 @@ int tlb_set_page_exec(CPUState *env, target_ulong vaddr, |
1488 | 1488 | if (is_softmmu) |
1489 | 1489 | #endif |
1490 | 1490 | { |
1491 | - if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM) { | |
1491 | + if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM && !(pd & IO_MEM_ROMD)) { | |
1492 | 1492 | /* IO memory case */ |
1493 | 1493 | address = vaddr | pd; |
1494 | 1494 | addend = paddr; |
... | ... | @@ -1785,7 +1785,8 @@ void cpu_register_physical_memory(target_phys_addr_t start_addr, |
1785 | 1785 | for(addr = start_addr; addr != end_addr; addr += TARGET_PAGE_SIZE) { |
1786 | 1786 | p = phys_page_find_alloc(addr >> TARGET_PAGE_BITS, 1); |
1787 | 1787 | p->phys_offset = phys_offset; |
1788 | - if ((phys_offset & ~TARGET_PAGE_MASK) <= IO_MEM_ROM) | |
1788 | + if ((phys_offset & ~TARGET_PAGE_MASK) <= IO_MEM_ROM || | |
1789 | + (phys_offset & IO_MEM_ROMD)) | |
1789 | 1790 | phys_offset += TARGET_PAGE_SIZE; |
1790 | 1791 | } |
1791 | 1792 | } |
... | ... | @@ -2048,7 +2049,8 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, |
2048 | 2049 | } |
2049 | 2050 | } |
2050 | 2051 | } else { |
2051 | - if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM) { | |
2052 | + if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM && | |
2053 | + !(pd & IO_MEM_ROMD)) { | |
2052 | 2054 | /* I/O case */ |
2053 | 2055 | io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1); |
2054 | 2056 | if (l >= 4 && ((addr & 3) == 0)) { |
... | ... | @@ -2103,7 +2105,8 @@ void cpu_physical_memory_write_rom(target_phys_addr_t addr, |
2103 | 2105 | } |
2104 | 2106 | |
2105 | 2107 | if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM && |
2106 | - (pd & ~TARGET_PAGE_MASK) != IO_MEM_ROM) { | |
2108 | + (pd & ~TARGET_PAGE_MASK) != IO_MEM_ROM && | |
2109 | + !(pd & IO_MEM_ROMD)) { | |
2107 | 2110 | /* do nothing */ |
2108 | 2111 | } else { |
2109 | 2112 | unsigned long addr1; |
... | ... | @@ -2135,7 +2138,8 @@ uint32_t ldl_phys(target_phys_addr_t addr) |
2135 | 2138 | pd = p->phys_offset; |
2136 | 2139 | } |
2137 | 2140 | |
2138 | - if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM) { | |
2141 | + if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM && | |
2142 | + !(pd & IO_MEM_ROMD)) { | |
2139 | 2143 | /* I/O case */ |
2140 | 2144 | io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1); |
2141 | 2145 | val = io_mem_read[io_index][2](io_mem_opaque[io_index], addr); |
... | ... | @@ -2164,7 +2168,8 @@ uint64_t ldq_phys(target_phys_addr_t addr) |
2164 | 2168 | pd = p->phys_offset; |
2165 | 2169 | } |
2166 | 2170 | |
2167 | - if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM) { | |
2171 | + if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM && | |
2172 | + !(pd & IO_MEM_ROMD)) { | |
2168 | 2173 | /* I/O case */ |
2169 | 2174 | io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1); |
2170 | 2175 | #ifdef TARGET_WORDS_BIGENDIAN | ... | ... |