This introduces a new generic-loader setting "csbaseaddr" that allows you to set the segment base address of CS.
Signed-off-by: Danny Milosavljevic <danny.m...@datacom.wien> --- hw/core/generic-loader.c | 5 ++++- include/hw/core/cpu.h | 1 + include/hw/core/generic-loader.h | 1 + target/i386/cpu.c | 11 +++++++++++ 4 files changed, 17 insertions(+), 1 deletion(-) diff --git a/hw/core/generic-loader.c b/hw/core/generic-loader.c index 2b2a7b5e9a..a151dcdd89 100644 --- a/hw/core/generic-loader.c +++ b/hw/core/generic-loader.c @@ -53,6 +53,8 @@ static void generic_loader_reset(void *opaque) cpu_reset(s->cpu); if (cc) { cc->set_pc(s->cpu, s->addr); + if (cc->set_csbase) + cc->set_csbase(s->cpu, s->csbaseaddr); } } @@ -103,7 +105,7 @@ static void generic_loader_realize(DeviceState *dev, Error **errp) if (s->cpu_num != CPU_NONE) { s->set_pc = true; } - } else if (s->addr) { + } else if (s->addr || s->csbaseaddr) { /* User is setting the PC */ if (s->data || s->data_len || s->data_be) { error_setg(errp, "data can not be specified when setting a " @@ -180,6 +182,7 @@ static void generic_loader_unrealize(DeviceState *dev) } static Property generic_loader_props[] = { + DEFINE_PROP_UINT64("csbaseaddr", GenericLoaderState, csbaseaddr, 0xffff0000), DEFINE_PROP_UINT64("addr", GenericLoaderState, addr, 0), DEFINE_PROP_UINT64("data", GenericLoaderState, data, 0), DEFINE_PROP_UINT8("data-len", GenericLoaderState, data_len, 0), diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h index c005d3dc2d..9998b6b986 100644 --- a/include/hw/core/cpu.h +++ b/include/hw/core/cpu.h @@ -161,6 +161,7 @@ struct CPUClass { void (*get_memory_mapping)(CPUState *cpu, MemoryMappingList *list, Error **errp); void (*set_pc)(CPUState *cpu, vaddr value); + void (*set_csbase)(CPUState *cpu, vaddr value); hwaddr (*get_phys_page_debug)(CPUState *cpu, vaddr addr); hwaddr (*get_phys_page_attrs_debug)(CPUState *cpu, vaddr addr, MemTxAttrs *attrs); diff --git a/include/hw/core/generic-loader.h b/include/hw/core/generic-loader.h index 19d87b39c8..b407d8e8e9 100644 --- a/include/hw/core/generic-loader.h +++ b/include/hw/core/generic-loader.h @@ -29,6 +29,7 @@ struct GenericLoaderState { /* <public> */ CPUState *cpu; + uint64_t csbaseaddr; uint64_t addr; uint64_t data; uint8_t data_len; diff --git a/target/i386/cpu.c b/target/i386/cpu.c index 6a53446e6a..7cb4634e18 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -7171,6 +7171,16 @@ static void x86_cpu_set_pc(CPUState *cs, vaddr value) cpu->env.eip = value; } +static void x86_cpu_set_csbase(CPUState *cs, vaddr value) +{ + X86CPU *cpu = X86_CPU(cs); + CPUX86State *env = &cpu->env; + + cpu_x86_load_seg_cache(env, R_CS, 0xf000, value, 0xffff, + DESC_P_MASK | DESC_S_MASK | DESC_CS_MASK | + DESC_R_MASK | DESC_A_MASK); +} + int x86_cpu_pending_interrupt(CPUState *cs, int interrupt_request) { X86CPU *cpu = X86_CPU(cs); @@ -7412,6 +7422,7 @@ static void x86_cpu_common_class_init(ObjectClass *oc, void *data) cc->dump_state = x86_cpu_dump_state; cc->set_pc = x86_cpu_set_pc; + cc->set_csbase = x86_cpu_set_csbase; cc->gdb_read_register = x86_cpu_gdb_read_register; cc->gdb_write_register = x86_cpu_gdb_write_register; cc->get_arch_id = x86_cpu_get_arch_id; -- 2.29.2