diff --git a/qemu/hw/sparc64/sun4u.c b/qemu/hw/sparc64/sun4u.c index ccfea62e..e7d619f5 100644 --- a/qemu/hw/sparc64/sun4u.c +++ b/qemu/hw/sparc64/sun4u.c @@ -33,19 +33,23 @@ static void sun4u_init(struct uc_struct *uc, MachineState *machine) { const char *cpu_model = machine->cpu_model; + SPARCCPU *cpu; if (cpu_model == NULL) - cpu_model = "sun4uv"; + cpu_model = "Sun UltraSparc IV"; - if (cpu_sparc_init(uc, cpu_model) == NULL) { + cpu = cpu_sparc_init(uc, cpu_model); + if (cpu == NULL) { fprintf(stderr, "Unable to find Sparc CPU definition\n"); exit(1); } + + cpu_sparc_set_id(&cpu->env, 0); } void sun4u_machine_init(struct uc_struct *uc) { - QEMUMachine sun4u_machine = { + static QEMUMachine sun4u_machine = { .name = "sun4u", .init = sun4u_init, .max_cpus = 1, // XXX for now diff --git a/qemu/target-sparc/unicorn64.c b/qemu/target-sparc/unicorn64.c index a3700db0..a51272de 100644 --- a/qemu/target-sparc/unicorn64.c +++ b/qemu/target-sparc/unicorn64.c @@ -6,6 +6,7 @@ #include "sysemu/cpus.h" #include "unicorn.h" #include "cpu.h" +#include "unicorn_common.h" #define READ_QWORD(x) ((uint64)x) @@ -15,6 +16,22 @@ #define READ_BYTE_L(x) (x & 0xff) +static bool sparc_stop_interrupt(int intno) +{ + switch(intno) { + default: + return false; + case TT_ILL_INSN: + return true; + } +} + +static void sparc_set_pc(struct uc_struct *uc, uint64_t address) +{ + ((CPUSPARCState *)uc->current_cpu->env_ptr)->pc = address; + ((CPUSPARCState *)uc->current_cpu->env_ptr)->npc = address + 4; +} + void sparc_reg_reset(struct uc_struct *uc) { CPUArchState *env = first_cpu->env_ptr; @@ -75,7 +92,7 @@ int sparc_reg_write(struct uc_struct *uc, unsigned int regid, const void *value) default: break; case UC_SPARC_REG_PC: SPARC_CPU(uc, mycpu)->env.pc = *(uint64_t *)value; - SPARC_CPU(uc, mycpu)->env.npc = *(uint64_t *)value + 8; + SPARC_CPU(uc, mycpu)->env.npc = *(uint64_t *)value + 4; break; } } @@ -93,4 +110,7 @@ void sparc64_uc_init(struct uc_struct* uc) uc->reg_read = sparc_reg_read; uc->reg_write = sparc_reg_write; uc->reg_reset = sparc_reg_reset; + uc->set_pc = sparc_set_pc; + uc->stop_interrupt = sparc_stop_interrupt; + uc_common_init(uc); } diff --git a/regress/sparc64.py b/regress/sparc64.py index e59412dc..f68e09a3 100755 --- a/regress/sparc64.py +++ b/regress/sparc64.py @@ -3,9 +3,22 @@ from unicorn import * from unicorn.sparc_const import * +PAGE_SIZE = 1 * 1024 * 1024 + uc = Uc(UC_ARCH_SPARC, UC_MODE_64) uc.reg_write(UC_SPARC_REG_SP, 100) -uc.reg_write(UC_SPARC_REG_FP, 100) -print 'writing sp = 100, fp = 100' +print 'writing sp = 100, %%i0 = 2000' + + # 0: b0 06 20 01 inc %i0 + # 4: b2 06 60 01 inc %i1 + +CODE = "\xb0\x06\x20\x01" \ + "\xb2\x06\x60\x01" + +uc.mem_map(0, PAGE_SIZE) +uc.mem_write(0, CODE) +uc.emu_start(0, len(CODE), 0, 2) + print 'sp =', uc.reg_read(UC_SPARC_REG_SP) -print 'fp =', uc.reg_read(UC_SPARC_REG_FP) +print 'i0 =', uc.reg_read(UC_SPARC_REG_I0) +print 'i1 =', uc.reg_read(UC_SPARC_REG_I1)