@@ -1691,7 +1691,7 @@ void qmp_memsave(int64_t addr, int64_t size, const char *filename,
l = sizeof(buf);
if (l > size)
l = size;
- if (cpu_memory_rw_debug(cpu, addr, buf, l, 0) != 0) {
+ if (cpu_memory_rw_debug(cpu, addr, buf, l, MEMTX_READ) != 0) {
error_setg(errp, "Invalid addr 0x%016" PRIx64 "/size %" PRId64
" specified", orig_addr, orig_size);
goto exit;
@@ -39,7 +39,7 @@ target_read_memory (bfd_vma memaddr,
{
CPUDebug *s = container_of(info, CPUDebug, info);
- cpu_memory_rw_debug(s->cpu, memaddr, myaddr, length, 0);
+ cpu_memory_rw_debug(s->cpu, memaddr, myaddr, length, MEMTX_READ);
return 0;
}
@@ -358,7 +358,7 @@ monitor_read_memory (bfd_vma memaddr, bfd_byte *myaddr, int length,
if (monitor_disas_is_physical) {
cpu_physical_memory_read(memaddr, myaddr, length);
} else {
- cpu_memory_rw_debug(s->cpu, memaddr, myaddr, length, 0);
+ cpu_memory_rw_debug(s->cpu, memaddr, myaddr, length, MEMTX_READ);
}
return 0;
}
@@ -2219,7 +2219,7 @@ static MemTxResult subpage_write(void *opaque, hwaddr addr,
abort();
}
return address_space_write(subpage->as, addr + subpage->base,
- attrs, buf, len);
+ attrs, buf, len, false);
}
static bool subpage_accepts(void *opaque, hwaddr addr,
@@ -2436,7 +2436,7 @@ MemoryRegion *get_system_io(void)
/* physical memory access (slow version, mainly for debug) */
#if defined(CONFIG_USER_ONLY)
int cpu_memory_rw_debug(CPUState *cpu, target_ulong addr,
- uint8_t *buf, int len, int is_write)
+ uint8_t *buf, int len, MemTxType type)
{
int l, flags;
target_ulong page;
@@ -2450,7 +2450,8 @@ int cpu_memory_rw_debug(CPUState *cpu, target_ulong addr,
flags = page_get_flags(page);
if (!(flags & PAGE_VALID))
return -1;
- if (is_write) {
+ if (type == MEMTX_WRITE ||
+ type == MEMTX_PROGRAM) {
if (!(flags & PAGE_WRITE))
return -1;
/* XXX: this code should not depend on lock_user */
@@ -2552,7 +2553,8 @@ static MemTxResult address_space_write_continue(AddressSpace *as, hwaddr addr,
MemTxAttrs attrs,
const uint8_t *buf,
int len, hwaddr addr1,
- hwaddr l, MemoryRegion *mr)
+ hwaddr l, MemoryRegion *mr,
+ bool force)
{
uint8_t *ptr;
uint64_t val;
@@ -2560,7 +2562,14 @@ static MemTxResult address_space_write_continue(AddressSpace *as, hwaddr addr,
bool release_lock = false;
for (;;) {
- if (!memory_access_is_direct(mr, true)) {
+
+ if (memory_access_is_direct(mr, true) ||
+ (force && memory_region_is_romd(mr))) {
+ /* RAM case */
+ ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
+ memcpy(ptr, buf, l);
+ invalidate_and_set_dirty(mr, addr1, l);
+ } else {
release_lock |= prepare_mmio_access(mr);
l = memory_access_size(mr, l, addr1);
/* XXX: could force current_cpu to NULL to avoid
@@ -2593,11 +2602,6 @@ static MemTxResult address_space_write_continue(AddressSpace *as, hwaddr addr,
default:
abort();
}
- } else {
- /* RAM case */
- ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
- memcpy(ptr, buf, l);
- invalidate_and_set_dirty(mr, addr1, l);
}
if (release_lock) {
@@ -2621,7 +2625,7 @@ static MemTxResult address_space_write_continue(AddressSpace *as, hwaddr addr,
}
MemTxResult address_space_write(AddressSpace *as, hwaddr addr, MemTxAttrs attrs,
- const uint8_t *buf, int len)
+ const uint8_t *buf, int len, bool force)
{
hwaddr l;
hwaddr addr1;
@@ -2633,7 +2637,7 @@ MemTxResult address_space_write(AddressSpace *as, hwaddr addr, MemTxAttrs attrs,
l = len;
mr = address_space_translate(as, addr, &addr1, &l, true);
result = address_space_write_continue(as, addr, attrs, buf, len,
- addr1, l, mr);
+ addr1, l, mr, force);
rcu_read_unlock();
}
@@ -2731,12 +2735,17 @@ MemTxResult address_space_read_full(AddressSpace *as, hwaddr addr,
}
MemTxResult address_space_rw(AddressSpace *as, hwaddr addr, MemTxAttrs attrs,
- uint8_t *buf, int len, bool is_write)
+ uint8_t *buf, int len, MemTxType type)
{
- if (is_write) {
- return address_space_write(as, addr, attrs, (uint8_t *)buf, len);
- } else {
+ switch (type) {
+ case MEMTX_READ:
return address_space_read(as, addr, attrs, (uint8_t *)buf, len);
+ case MEMTX_WRITE:
+ return address_space_write(as, addr, attrs, (uint8_t *)buf, len, false);
+ case MEMTX_PROGRAM:
+ return address_space_write(as, addr, attrs, (uint8_t *)buf, len, true);
+ default:
+ abort();
}
}
@@ -3010,7 +3019,7 @@ void address_space_unmap(AddressSpace *as, void *buffer, hwaddr len,
}
if (is_write) {
address_space_write(as, bounce.addr, MEMTXATTRS_UNSPECIFIED,
- bounce.buffer, access_len);
+ bounce.buffer, access_len, false);
}
qemu_vfree(bounce.buffer);
bounce.buffer = NULL;
@@ -3626,7 +3635,7 @@ void stq_be_phys(AddressSpace *as, hwaddr addr, uint64_t val)
/* virtual memory access for debug (includes writing to ROM) */
int cpu_memory_rw_debug(CPUState *cpu, target_ulong addr,
- uint8_t *buf, int len, int is_write)
+ uint8_t *buf, int len, MemTxType type)
{
int l;
hwaddr phys_addr;
@@ -3646,14 +3655,10 @@ 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);
- }
+
+ address_space_rw(cpu->cpu_ases[asidx].as, phys_addr,
+ MEMTXATTRS_UNSPECIFIED,
+ buf, l, type);
len -= l;
buf += l;
addr += l;
@@ -44,14 +44,16 @@
#endif
static inline int target_memory_rw_debug(CPUState *cpu, target_ulong addr,
- uint8_t *buf, int len, bool is_write)
+ uint8_t *buf, int len, MemTxType type)
{
CPUClass *cc = CPU_GET_CLASS(cpu);
if (cc->memory_rw_debug) {
+ const bool is_write = (type == MEMTX_WRITE ||
+ type == MEMTX_PROGRAM);
return cc->memory_rw_debug(cpu, addr, buf, len, is_write);
}
- return cpu_memory_rw_debug(cpu, addr, buf, len, is_write);
+ return cpu_memory_rw_debug(cpu, addr, buf, len, type);
}
enum {
@@ -965,7 +967,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
break;
}
- if (target_memory_rw_debug(s->g_cpu, addr, mem_buf, len, false) != 0) {
+ if (target_memory_rw_debug(s->g_cpu, addr, mem_buf, len, MEMTX_READ) != 0) {
put_packet (s, "E14");
} else {
memtohex(buf, mem_buf, len);
@@ -987,7 +989,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
}
hextomem(mem_buf, p, len);
if (target_memory_rw_debug(s->g_cpu, addr, mem_buf, len,
- true) != 0) {
+ MEMTX_PROGRAM) != 0) {
put_packet(s, "E14");
} else {
put_packet(s, "OK");
@@ -233,7 +233,7 @@ static int evaluate_tpr_instruction(VAPICROMState *s, X86CPU *cpu,
continue;
}
if (cpu_memory_rw_debug(cs, ip - instr->length, opcode,
- sizeof(opcode), 0) < 0) {
+ sizeof(opcode), MEMTX_READ) < 0) {
return -1;
}
if (opcode_matches(opcode, instr)) {
@@ -243,7 +243,7 @@ static int evaluate_tpr_instruction(VAPICROMState *s, X86CPU *cpu,
}
return -1;
} else {
- if (cpu_memory_rw_debug(cs, ip, opcode, sizeof(opcode), 0) < 0) {
+ if (cpu_memory_rw_debug(cs, ip, opcode, sizeof(opcode), MEMTX_READ) < 0) {
return -1;
}
for (i = 0; i < ARRAY_SIZE(tpr_instr); i++) {
@@ -262,7 +262,7 @@ instruction_ok:
*/
if (cpu_memory_rw_debug(cs, ip + instr->addr_offset,
(void *)&real_tpr_addr,
- sizeof(real_tpr_addr), 0) < 0) {
+ sizeof(real_tpr_addr), MEMTX_READ) < 0) {
return -1;
}
real_tpr_addr = le32_to_cpu(real_tpr_addr);
@@ -349,7 +349,7 @@ static int get_kpcr_number(X86CPU *cpu)
} QEMU_PACKED kpcr;
if (cpu_memory_rw_debug(CPU(cpu), env->segs[R_FS].base,
- (void *)&kpcr, sizeof(kpcr), 0) < 0 ||
+ (void *)&kpcr, sizeof(kpcr), MEMTX_READ) < 0 ||
kpcr.self != env->segs[R_FS].base) {
return -1;
}
@@ -378,7 +378,7 @@ static int vapic_enable(VAPICROMState *s, X86CPU *cpu)
static void patch_byte(X86CPU *cpu, target_ulong addr, uint8_t byte)
{
- cpu_memory_rw_debug(CPU(cpu), addr, &byte, 1, 1);
+ cpu_memory_rw_debug(CPU(cpu), addr, &byte, 1, MEMTX_WRITE);
}
static void patch_call(VAPICROMState *s, X86CPU *cpu, target_ulong ip,
@@ -388,7 +388,7 @@ static void patch_call(VAPICROMState *s, X86CPU *cpu, target_ulong ip,
offset = cpu_to_le32(target - ip - 5);
patch_byte(cpu, ip, 0xe8); /* call near */
- cpu_memory_rw_debug(CPU(cpu), ip + 1, (void *)&offset, sizeof(offset), 1);
+ cpu_memory_rw_debug(CPU(cpu), ip + 1, (void *)&offset, sizeof(offset), MEMTX_WRITE);
}
static void patch_instruction(VAPICROMState *s, X86CPU *cpu, target_ulong ip)
@@ -415,7 +415,7 @@ static void patch_instruction(VAPICROMState *s, X86CPU *cpu, target_ulong ip)
pause_all_vcpus();
- cpu_memory_rw_debug(cs, ip, opcode, sizeof(opcode), 0);
+ cpu_memory_rw_debug(cs, ip, opcode, sizeof(opcode), MEMTX_READ);
switch (opcode[0]) {
case 0x89: /* mov r32 to r/m32 */
@@ -434,8 +434,8 @@ static void patch_instruction(VAPICROMState *s, X86CPU *cpu, target_ulong ip)
break;
case 0xc7: /* mov imm32, r/m32 (c7/0) */
patch_byte(cpu, ip, 0x68); /* push imm32 */
- cpu_memory_rw_debug(cs, ip + 6, (void *)&imm32, sizeof(imm32), 0);
- cpu_memory_rw_debug(cs, ip + 1, (void *)&imm32, sizeof(imm32), 1);
+ cpu_memory_rw_debug(cs, ip + 6, (void *)&imm32, sizeof(imm32), MEMTX_READ);
+ cpu_memory_rw_debug(cs, ip + 1, (void *)&imm32, sizeof(imm32), MEMTX_WRITE);
patch_call(s, cpu, ip + 5, handlers->set_tpr);
break;
case 0xff: /* push r/m32 */
@@ -73,7 +73,7 @@ static void rtc_write(void *opaque, hwaddr addr,
{
uint8_t buf = val & 0xff;
address_space_write(&address_space_memory, 0x90000071,
- MEMTXATTRS_UNSPECIFIED, &buf, 1);
+ MEMTXATTRS_UNSPECIFIED, &buf, 1, false);
}
static const MemoryRegionOps rtc_ops = {
@@ -175,7 +175,7 @@ static void raven_io_write(void *opaque, hwaddr addr,
}
address_space_write(&s->pci_io_as, addr + 0x80000000,
- MEMTXATTRS_UNSPECIFIED, buf, size);
+ MEMTXATTRS_UNSPECIFIED, buf, size, false);
}
static const MemoryRegionOps raven_io_ops = {
@@ -164,7 +164,7 @@ static inline void vring_used_write(VirtQueue *vq, VRingUsedElem *uelem,
virtio_tswap32s(vq->vdev, &uelem->len);
pa = vq->vring.used + offsetof(VRingUsed, ring[i]);
address_space_write(&address_space_memory, pa, MEMTXATTRS_UNSPECIFIED,
- (void *)uelem, sizeof(VRingUsedElem));
+ (void *)uelem, sizeof(VRingUsedElem), false);
}
static uint16_t vring_used_idx(VirtQueue *vq)
@@ -302,6 +302,6 @@ void dump_opcount_info(FILE *f, fprintf_function cpu_fprintf);
#endif /* !CONFIG_USER_ONLY */
int cpu_memory_rw_debug(CPUState *cpu, target_ulong addr,
- uint8_t *buf, int len, int is_write);
+ uint8_t *buf, int len, MemTxType type);
#endif /* CPU_ALL_H */
@@ -14,6 +14,13 @@
#ifndef MEMORY_H
#define MEMORY_H
+typedef enum {
+ MEMTX_READ,
+ MEMTX_WRITE,
+ MEMTX_PROGRAM,
+} MemTxType;
+
+
#ifndef CONFIG_USER_ONLY
#define DIRTY_MEMORY_VGA 0
@@ -1240,6 +1247,7 @@ AddressSpace *address_space_init_shareable(MemoryRegion *root,
*/
void address_space_destroy(AddressSpace *as);
+
/**
* address_space_rw: read from or write to an address space.
*
@@ -1251,11 +1259,11 @@ void address_space_destroy(AddressSpace *as);
* @addr: address within that address space
* @attrs: memory transaction attributes
* @buf: buffer with the data transferred
- * @is_write: indicates the transfer direction
+ * @type: indicates the transfer type
*/
MemTxResult address_space_rw(AddressSpace *as, hwaddr addr,
MemTxAttrs attrs, uint8_t *buf,
- int len, bool is_write);
+ int len, MemTxType type);
/**
* address_space_write: write to address space.
@@ -1268,10 +1276,11 @@ MemTxResult address_space_rw(AddressSpace *as, hwaddr addr,
* @addr: address within that address space
* @attrs: memory transaction attributes
* @buf: buffer with the data transferred
+ * @force: force writing to ROM areas
*/
MemTxResult address_space_write(AddressSpace *as, hwaddr addr,
MemTxAttrs attrs,
- const uint8_t *buf, int len);
+ const uint8_t *buf, int len, bool force);
/* address_space_ld*: load from an address space
* address_space_st*: store to an address space
@@ -13,7 +13,7 @@ static inline uint64_t softmmu_tget64(CPUArchState *env, target_ulong addr)
{
uint64_t val;
- cpu_memory_rw_debug(ENV_GET_CPU(env), addr, (uint8_t *)&val, 8, 0);
+ cpu_memory_rw_debug(ENV_GET_CPU(env), addr, (uint8_t *)&val, 8, MEMTX_READ);
return tswap64(val);
}
@@ -21,7 +21,7 @@ static inline uint32_t softmmu_tget32(CPUArchState *env, target_ulong addr)
{
uint32_t val;
- cpu_memory_rw_debug(ENV_GET_CPU(env), addr, (uint8_t *)&val, 4, 0);
+ cpu_memory_rw_debug(ENV_GET_CPU(env), addr, (uint8_t *)&val, 4, MEMTX_READ);
return tswap32(val);
}
@@ -29,7 +29,7 @@ static inline uint32_t softmmu_tget8(CPUArchState *env, target_ulong addr)
{
uint8_t val;
- cpu_memory_rw_debug(ENV_GET_CPU(env), addr, &val, 1, 0);
+ cpu_memory_rw_debug(ENV_GET_CPU(env), addr, &val, 1, MEMTX_READ);
return val;
}
@@ -42,14 +42,14 @@ static inline void softmmu_tput64(CPUArchState *env,
target_ulong addr, uint64_t val)
{
val = tswap64(val);
- cpu_memory_rw_debug(ENV_GET_CPU(env), addr, (uint8_t *)&val, 8, 1);
+ cpu_memory_rw_debug(ENV_GET_CPU(env), addr, (uint8_t *)&val, 8, MEMTX_WRITE);
}
static inline void softmmu_tput32(CPUArchState *env,
target_ulong addr, uint32_t val)
{
val = tswap32(val);
- cpu_memory_rw_debug(ENV_GET_CPU(env), addr, (uint8_t *)&val, 4, 1);
+ cpu_memory_rw_debug(ENV_GET_CPU(env), addr, (uint8_t *)&val, 4, MEMTX_WRITE);
}
#define put_user_u64(arg, p) ({ softmmu_tput64(env, p, arg) ; 0; })
#define put_user_u32(arg, p) ({ softmmu_tput32(env, p, arg) ; 0; })
@@ -62,7 +62,7 @@ static void *softmmu_lock_user(CPUArchState *env,
/* TODO: Make this something that isn't fixed size. */
p = malloc(len);
if (p && copy) {
- cpu_memory_rw_debug(ENV_GET_CPU(env), addr, p, len, 0);
+ cpu_memory_rw_debug(ENV_GET_CPU(env), addr, p, len, MEMTX_READ);
}
return p;
}
@@ -78,7 +78,7 @@ static char *softmmu_lock_user_string(CPUArchState *env, target_ulong addr)
return NULL;
}
do {
- cpu_memory_rw_debug(ENV_GET_CPU(env), addr, &c, 1, 0);
+ cpu_memory_rw_debug(ENV_GET_CPU(env), addr, &c, 1, MEMTX_READ);
addr++;
*(p++) = c;
} while (c);
@@ -89,7 +89,7 @@ static void softmmu_unlock_user(CPUArchState *env, void *p, target_ulong addr,
target_ulong len)
{
if (len) {
- cpu_memory_rw_debug(ENV_GET_CPU(env), addr, p, len, 1);
+ cpu_memory_rw_debug(ENV_GET_CPU(env), addr, p, len, MEMTX_READ);
}
free(p);
}
@@ -59,7 +59,7 @@ void cpu_outb(uint32_t addr, uint8_t val)
{
trace_cpu_out(addr, 'b', val);
address_space_write(&address_space_io, addr, MEMTXATTRS_UNSPECIFIED,
- &val, 1);
+ &val, 1, false);
}
void cpu_outw(uint32_t addr, uint16_t val)
@@ -69,7 +69,7 @@ void cpu_outw(uint32_t addr, uint16_t val)
trace_cpu_out(addr, 'w', val);
stw_p(buf, val);
address_space_write(&address_space_io, addr, MEMTXATTRS_UNSPECIFIED,
- buf, 2);
+ buf, 2, false);
}
void cpu_outl(uint32_t addr, uint32_t val)
@@ -79,7 +79,7 @@ void cpu_outl(uint32_t addr, uint32_t val)
trace_cpu_out(addr, 'l', val);
stl_p(buf, val);
address_space_write(&address_space_io, addr, MEMTXATTRS_UNSPECIFIED,
- buf, 4);
+ buf, 4, false);
}
uint8_t cpu_inb(uint32_t addr)
@@ -1268,7 +1268,7 @@ static void memory_dump(Monitor *mon, int count, int format, int wsize,
if (is_physical) {
cpu_physical_memory_read(addr, buf, l);
} else {
- if (cpu_memory_rw_debug(mon_get_cpu(), addr, buf, l, 0) < 0) {
+ if (cpu_memory_rw_debug(mon_get_cpu(), addr, buf, l, MEMTX_READ) < 0) {
monitor_printf(mon, " Cannot access memory\n");
break;
}
@@ -187,7 +187,7 @@ static void arm_semi_flen_cb(CPUState *cs, target_ulong ret, target_ulong err)
/* The size is always stored in big-endian order, extract
the value. We assume the size always fit in 32 bits. */
uint32_t size;
- cpu_memory_rw_debug(cs, arm_flen_buf(cpu) + 32, (uint8_t *)&size, 4, 0);
+ cpu_memory_rw_debug(cs, arm_flen_buf(cpu) + 32, (uint8_t *)&size, 4, MEMTX_READ);
size = be32_to_cpu(size);
if (is_a64(env)) {
env->xregs[0] = size;
@@ -874,8 +874,8 @@ static const uint32_t brk_insn = 0xd4200000;
int kvm_arch_insert_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp)
{
if (have_guest_debug) {
- if (cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&bp->saved_insn, 4, 0) ||
- cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&brk_insn, 4, 1)) {
+ if (cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&bp->saved_insn, 4, MEMTX_READ) ||
+ cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&brk_insn, 4, MEMTX_WRITE)) {
return -EINVAL;
}
return 0;
@@ -890,9 +890,9 @@ int kvm_arch_remove_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp)
static uint32_t brk;
if (have_guest_debug) {
- if (cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&brk, 4, 0) ||
+ if (cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&brk, 4, MEMTX_READ) ||
brk != brk_insn ||
- cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&bp->saved_insn, 4, 1)) {
+ cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&bp->saved_insn, 4, MEMTX_WRITE)) {
return -EINVAL;
}
return 0;
@@ -555,7 +555,7 @@ void x86_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
cpu_fprintf(f, "Code=");
for (i = 0; i < DUMP_CODE_BYTES_TOTAL; i++) {
- if (cpu_memory_rw_debug(cs, base - offs + i, &code, 1, 0) == 0) {
+ if (cpu_memory_rw_debug(cs, base - offs + i, &code, 1, MEMTX_READ) == 0) {
snprintf(codestr, sizeof(codestr), "%02x", code);
} else {
snprintf(codestr, sizeof(codestr), "??");
@@ -1286,8 +1286,8 @@ int cpu_x86_get_descr_debug(CPUX86State *env, unsigned int selector,
index = selector & ~7;
ptr = dt->base + index;
if ((index + 7) > dt->limit
- || cpu_memory_rw_debug(cs, ptr, (uint8_t *)&e1, sizeof(e1), 0) != 0
- || cpu_memory_rw_debug(cs, ptr+4, (uint8_t *)&e2, sizeof(e2), 0) != 0)
+ || cpu_memory_rw_debug(cs, ptr, (uint8_t *)&e1, sizeof(e1), MEMTX_READ) != 0
+ || cpu_memory_rw_debug(cs, ptr+4, (uint8_t *)&e2, sizeof(e2), MEMTX_READ) != 0)
return 0;
*base = ((e1 >> 16) | ((e2 & 0xff) << 16) | (e2 & 0xff000000));
@@ -2866,8 +2866,8 @@ int kvm_arch_insert_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp)
{
static const uint8_t int3 = 0xcc;
- if (cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&bp->saved_insn, 1, 0) ||
- cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&int3, 1, 1)) {
+ if (cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&bp->saved_insn, 1, MEMTX_READ) ||
+ cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&int3, 1, MEMTX_WRITE)) {
return -EINVAL;
}
return 0;
@@ -2877,8 +2877,8 @@ int kvm_arch_remove_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp)
{
uint8_t int3;
- if (cpu_memory_rw_debug(cs, bp->pc, &int3, 1, 0) || int3 != 0xcc ||
- cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&bp->saved_insn, 1, 1)) {
+ if (cpu_memory_rw_debug(cs, bp->pc, &int3, 1, MEMTX_READ) || int3 != 0xcc ||
+ cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&bp->saved_insn, 1, MEMTX_WRITE)) {
return -EINVAL;
}
return 0;
@@ -1433,8 +1433,8 @@ int kvm_arch_insert_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp)
uint32_t sc = debug_inst_opcode;
if (cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&bp->saved_insn,
- sizeof(sc), 0) ||
- cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&sc, sizeof(sc), 1)) {
+ sizeof(sc), MEMTX_READ) ||
+ cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&sc, sizeof(sc), MEMTX_WRITE)) {
return -EINVAL;
}
@@ -1445,10 +1445,10 @@ int kvm_arch_remove_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp)
{
uint32_t sc;
- if (cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&sc, sizeof(sc), 0) ||
+ if (cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&sc, sizeof(sc), MEMTX_READ) ||
sc != debug_inst_opcode ||
cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&bp->saved_insn,
- sizeof(sc), 1)) {
+ sizeof(sc), MEMTX_WRITE)) {
return -EINVAL;
}
@@ -672,9 +672,9 @@ int kvm_arch_insert_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp)
{
if (cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&bp->saved_insn,
- sizeof(diag_501), 0) ||
+ sizeof(diag_501), MEMTX_READ) ||
cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)diag_501,
- sizeof(diag_501), 1)) {
+ sizeof(diag_501), MEMTX_WIRTE)) {
return -EINVAL;
}
return 0;
@@ -684,12 +684,12 @@ int kvm_arch_remove_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp)
{
uint8_t t[sizeof(diag_501)];
- if (cpu_memory_rw_debug(cs, bp->pc, t, sizeof(diag_501), 0)) {
+ if (cpu_memory_rw_debug(cs, bp->pc, t, sizeof(diag_501), MEMTX_READ)) {
return -EINVAL;
} else if (memcmp(t, diag_501, sizeof(diag_501))) {
return -EINVAL;
} else if (cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&bp->saved_insn,
- sizeof(diag_501), 1)) {
+ sizeof(diag_501), MEMTX_WRITE)) {
return -EINVAL;
}
@@ -202,7 +202,7 @@ void HELPER(simcall)(CPUXtensaState *env)
for (i = 0; i < ARRAY_SIZE(name); ++i) {
rc = cpu_memory_rw_debug(cs, regs[3] + i,
- (uint8_t *)name + i, 1, 0);
+ (uint8_t *)name + i, 1, MEMTX_READ);
if (rc != 0 || name[i] == 0) {
break;
}
@@ -247,7 +247,7 @@ void HELPER(simcall)(CPUXtensaState *env)
if (target_tv) {
cpu_memory_rw_debug(cs, target_tv,
- (uint8_t *)target_tvv, sizeof(target_tvv), 0);
+ (uint8_t *)target_tvv, sizeof(target_tvv), MEMTX_READ);
tv.tv_sec = (int32_t)tswap32(target_tvv[0]);
tv.tv_usec = (int32_t)tswap32(target_tvv[1]);
}
@@ -282,7 +282,7 @@ void HELPER(simcall)(CPUXtensaState *env)
argv.argptr[0] = tswap32(regs[3] + offsetof(struct Argv, text));
cpu_memory_rw_debug(cs,
- regs[3], (uint8_t *)&argv, sizeof(argv), 1);
+ regs[3], (uint8_t *)&argv, sizeof(argv), MEMTX_WRITE);
}
break;
Add code to support writing to memory mapped peripherals via cpu_memory_rw_debug(). The code of that function already supports reading from such memory regions, so this commit makes that functionality "symmetric". One use-case for that functionality is setting various registers of a non-running CPU. A concrete example would be starting QEMU emulating Cortex-M with -S, connecting with GDB and modifying the value of Vector Table Offset register. Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com> --- cpus.c | 2 +- disas.c | 4 ++-- exec.c | 57 ++++++++++++++++++++++++--------------------- gdbstub.c | 10 ++++---- hw/i386/kvmvapic.c | 18 +++++++------- hw/mips/mips_jazz.c | 2 +- hw/pci-host/prep.c | 2 +- hw/virtio/virtio.c | 2 +- include/exec/cpu-all.h | 2 +- include/exec/memory.h | 15 +++++++++--- include/exec/softmmu-semi.h | 16 ++++++------- ioport.c | 6 ++--- monitor.c | 2 +- target-arm/arm-semi.c | 2 +- target-arm/kvm64.c | 8 +++---- target-i386/helper.c | 6 ++--- target-i386/kvm.c | 8 +++---- target-ppc/kvm.c | 8 +++---- target-s390x/kvm.c | 8 +++---- target-xtensa/xtensa-semi.c | 6 ++--- 20 files changed, 100 insertions(+), 84 deletions(-)