@@ -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),
@@ -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);
@@ -29,6 +29,7 @@ struct GenericLoaderState {
/* <public> */
CPUState *cpu;
+ uint64_t csbaseaddr;
uint64_t addr;
uint64_t data;
uint8_t data_len;
@@ -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;
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.milo@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(-)