Message ID | f16c0371-918f-fa31-db1f-5c2a8e4bc943@redhat.com |
---|---|
State | New |
Headers | show |
>> So looking at code, i have impression that write will go through the >> cpu_physical_memory_write_rom but the read will still go through >> address_space_rw which will eventually invoke address_space_read. > > Yes, you'd have to modify it a bit. Something like > Sure this will works, thanks for the snippet. > diff --git a/exec.c b/exec.c > index c8389f9..9fc9cef 100644 > --- a/exec.c > +++ b/exec.c > @@ -2689,7 +2689,7 @@ enum write_rom_type { > FLUSH_CACHE, > }; > > -static inline void cpu_physical_memory_write_rom_internal(AddressSpace *as, > +static inline void cpu_physical_memory_rw_debug_internal(AddressSpace *as, > hwaddr addr, const uint8_t *buf, int len, enum write_rom_type type) > { > hwaddr l; > @@ -2705,12 +2705,24 @@ static inline void cpu_physical_memory_write_rom_internal(AddressSpace *as, > if (!(memory_region_is_ram(mr) || > memory_region_is_romd(mr))) { > l = memory_access_size(mr, l, addr1); > + /* Pass MMIO down to address_space_rw. */ > + switch (type) { > + case READ_DATA: > + case WRITE_DATA: > + /* ... set debug in attrs (not necessary anymore perhaps?) */ > + address_space_rw(as, addr, attrs, buf, l, type == WRITE_DATA); > + break; > + case FLUSH_CACHE: > + break; > + } > } else { > /* ROM/RAM case */ > ptr = qemu_map_ram_ptr(mr->ram_block, addr1); > switch (type) { > + case READ_DATA: > + /* ... call hook ... */ > case WRITE_DATA: > - memcpy(ptr, buf, l); > + /* ... call hook ... */ > invalidate_and_set_dirty(mr, addr1, l); > break; > case FLUSH_CACHE: > @@ -2729,7 +2739,7 @@ static inline void cpu_physical_memory_write_rom_internal(AddressSpace *as, > void cpu_physical_memory_write_rom(AddressSpace *as, hwaddr addr, > const uint8_t *buf, int len) > { > - cpu_physical_memory_write_rom_internal(as, addr, buf, len, WRITE_DATA); > + cpu_physical_memory_rw_debug_internal(as, addr, buf, len, WRITE_DATA); > } > > void cpu_flush_icache_range(hwaddr start, int len) > @@ -2744,8 +2754,8 @@ void cpu_flush_icache_range(hwaddr start, int len) > return; > } > > - cpu_physical_memory_write_rom_internal(&address_space_memory, > - start, NULL, len, FLUSH_CACHE); > + cpu_physical_memory_rw_debug_internal(&address_space_memory, > + start, NULL, len, FLUSH_CACHE); > } > > typedef struct { > @@ -3568,6 +3578,7 @@ int cpu_memory_rw_debug(CPUState *cpu, target_ulong addr, > int l; > hwaddr phys_addr; > target_ulong page; > + int mode = is_write ? WRITE_DATA : READ_DATA; > > while (len > 0) { > int asidx; > @@ -3583,14 +3594,9 @@ int cpu_memory_rw_debug(CPUState *cpu, target_ulong addr, > if (l > len) > l = len; > phys_addr += (addr & ~TARGET_PAGE_MASK); > - if (is_write) { > - cpu_physical_memory_write_rom(cpu->cpu_ases[asidx].as, > - phys_addr, buf, l); > - } else { > - address_space_rw(cpu->cpu_ases[asidx].as, phys_addr, > - MEMTXATTRS_UNSPECIFIED, > - buf, l, 0); > - } > + cpu_physical_memory_rw_debug_internal(cpu->cpu_ases[asidx].as, > + phys_addr, buf, l, > + mode); > len -= l; > buf += l; > addr += l; >
diff --git a/exec.c b/exec.c index c8389f9..9fc9cef 100644 --- a/exec.c +++ b/exec.c @@ -2689,7 +2689,7 @@ enum write_rom_type { FLUSH_CACHE, }; -static inline void cpu_physical_memory_write_rom_internal(AddressSpace *as, +static inline void cpu_physical_memory_rw_debug_internal(AddressSpace *as, hwaddr addr, const uint8_t *buf, int len, enum write_rom_type type) { hwaddr l; @@ -2705,12 +2705,24 @@ static inline void cpu_physical_memory_write_rom_internal(AddressSpace *as, if (!(memory_region_is_ram(mr) || memory_region_is_romd(mr))) { l = memory_access_size(mr, l, addr1); + /* Pass MMIO down to address_space_rw. */ + switch (type) { + case READ_DATA: + case WRITE_DATA: + /* ... set debug in attrs (not necessary anymore perhaps?) */ + address_space_rw(as, addr, attrs, buf, l, type == WRITE_DATA); + break; + case FLUSH_CACHE: + break; + } } else { /* ROM/RAM case */ ptr = qemu_map_ram_ptr(mr->ram_block, addr1); switch (type) { + case READ_DATA: + /* ... call hook ... */ case WRITE_DATA: - memcpy(ptr, buf, l); + /* ... call hook ... */ invalidate_and_set_dirty(mr, addr1, l); break; case FLUSH_CACHE: @@ -2729,7 +2739,7 @@ static inline void cpu_physical_memory_write_rom_internal(AddressSpace *as, void cpu_physical_memory_write_rom(AddressSpace *as, hwaddr addr, const uint8_t *buf, int len) { - cpu_physical_memory_write_rom_internal(as, addr, buf, len, WRITE_DATA); + cpu_physical_memory_rw_debug_internal(as, addr, buf, len, WRITE_DATA); } void cpu_flush_icache_range(hwaddr start, int len) @@ -2744,8 +2754,8 @@ void cpu_flush_icache_range(hwaddr start, int len) return; } - cpu_physical_memory_write_rom_internal(&address_space_memory, - start, NULL, len, FLUSH_CACHE); + cpu_physical_memory_rw_debug_internal(&address_space_memory, + start, NULL, len, FLUSH_CACHE); } typedef struct { @@ -3568,6 +3578,7 @@ int cpu_memory_rw_debug(CPUState *cpu, target_ulong addr, int l; hwaddr phys_addr; target_ulong page; + int mode = is_write ? WRITE_DATA : READ_DATA; while (len > 0) { int asidx; @@ -3583,14 +3594,9 @@ int cpu_memory_rw_debug(CPUState *cpu, target_ulong addr, if (l > len) l = len; phys_addr += (addr & ~TARGET_PAGE_MASK); - if (is_write) { - cpu_physical_memory_write_rom(cpu->cpu_ases[asidx].as, - phys_addr, buf, l); - } else { - address_space_rw(cpu->cpu_ases[asidx].as, phys_addr, - MEMTXATTRS_UNSPECIFIED, - buf, l, 0); - } + cpu_physical_memory_rw_debug_internal(cpu->cpu_ases[asidx].as, + phys_addr, buf, l, + mode); len -= l; buf += l; addr += l;