Commit 2a4188a38fa3a91a9286da6fe077b6218378504d

Authored by bellard
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
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;
@@ -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