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,6 +828,10 @@ extern uint8_t *phys_ram_dirty; | ||
828 | #define IO_MEM_ROM (1 << IO_MEM_SHIFT) /* hardcoded offset */ | 828 | #define IO_MEM_ROM (1 << IO_MEM_SHIFT) /* hardcoded offset */ |
829 | #define IO_MEM_UNASSIGNED (2 << IO_MEM_SHIFT) | 829 | #define IO_MEM_UNASSIGNED (2 << IO_MEM_SHIFT) |
830 | #define IO_MEM_NOTDIRTY (4 << IO_MEM_SHIFT) /* used internally, never use directly */ | 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 | typedef void CPUWriteMemoryFunc(void *opaque, target_phys_addr_t addr, uint32_t value); | 836 | typedef void CPUWriteMemoryFunc(void *opaque, target_phys_addr_t addr, uint32_t value); |
833 | typedef uint32_t CPUReadMemoryFunc(void *opaque, target_phys_addr_t addr); | 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,7 +570,7 @@ static inline target_ulong get_phys_addr_code(CPUState *env, target_ulong addr) | ||
570 | ldub_code(addr); | 570 | ldub_code(addr); |
571 | } | 571 | } |
572 | pd = env->tlb_table[is_user][index].addr_code & ~TARGET_PAGE_MASK; | 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 | cpu_abort(env, "Trying to execute code outside RAM or ROM at 0x%08lx\n", addr); | 574 | cpu_abort(env, "Trying to execute code outside RAM or ROM at 0x%08lx\n", addr); |
575 | } | 575 | } |
576 | return addr + env->tlb_table[is_user][index].addend - (unsigned long)phys_ram_base; | 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,7 +1488,7 @@ int tlb_set_page_exec(CPUState *env, target_ulong vaddr, | ||
1488 | if (is_softmmu) | 1488 | if (is_softmmu) |
1489 | #endif | 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 | /* IO memory case */ | 1492 | /* IO memory case */ |
1493 | address = vaddr | pd; | 1493 | address = vaddr | pd; |
1494 | addend = paddr; | 1494 | addend = paddr; |
@@ -1785,7 +1785,8 @@ void cpu_register_physical_memory(target_phys_addr_t start_addr, | @@ -1785,7 +1785,8 @@ void cpu_register_physical_memory(target_phys_addr_t start_addr, | ||
1785 | for(addr = start_addr; addr != end_addr; addr += TARGET_PAGE_SIZE) { | 1785 | for(addr = start_addr; addr != end_addr; addr += TARGET_PAGE_SIZE) { |
1786 | p = phys_page_find_alloc(addr >> TARGET_PAGE_BITS, 1); | 1786 | p = phys_page_find_alloc(addr >> TARGET_PAGE_BITS, 1); |
1787 | p->phys_offset = phys_offset; | 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 | phys_offset += TARGET_PAGE_SIZE; | 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,7 +2049,8 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, | ||
2048 | } | 2049 | } |
2049 | } | 2050 | } |
2050 | } else { | 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 | /* I/O case */ | 2054 | /* I/O case */ |
2053 | io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1); | 2055 | io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1); |
2054 | if (l >= 4 && ((addr & 3) == 0)) { | 2056 | if (l >= 4 && ((addr & 3) == 0)) { |
@@ -2103,7 +2105,8 @@ void cpu_physical_memory_write_rom(target_phys_addr_t addr, | @@ -2103,7 +2105,8 @@ void cpu_physical_memory_write_rom(target_phys_addr_t addr, | ||
2103 | } | 2105 | } |
2104 | 2106 | ||
2105 | if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM && | 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 | /* do nothing */ | 2110 | /* do nothing */ |
2108 | } else { | 2111 | } else { |
2109 | unsigned long addr1; | 2112 | unsigned long addr1; |
@@ -2135,7 +2138,8 @@ uint32_t ldl_phys(target_phys_addr_t addr) | @@ -2135,7 +2138,8 @@ uint32_t ldl_phys(target_phys_addr_t addr) | ||
2135 | pd = p->phys_offset; | 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 | /* I/O case */ | 2143 | /* I/O case */ |
2140 | io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1); | 2144 | io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1); |
2141 | val = io_mem_read[io_index][2](io_mem_opaque[io_index], addr); | 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,7 +2168,8 @@ uint64_t ldq_phys(target_phys_addr_t addr) | ||
2164 | pd = p->phys_offset; | 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 | /* I/O case */ | 2173 | /* I/O case */ |
2169 | io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1); | 2174 | io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1); |
2170 | #ifdef TARGET_WORDS_BIGENDIAN | 2175 | #ifdef TARGET_WORDS_BIGENDIAN |