diff options
Diffstat (limited to 'usr.bin/oemu/cpu.c')
-rw-r--r-- | usr.bin/oemu/cpu.c | 44 |
1 files changed, 42 insertions, 2 deletions
diff --git a/usr.bin/oemu/cpu.c b/usr.bin/oemu/cpu.c index 58dd134..07ddc7b 100644 --- a/usr.bin/oemu/cpu.c +++ b/usr.bin/oemu/cpu.c @@ -198,6 +198,33 @@ cpu_div(struct oemu_cpu *cpu, inst_t *inst) } /* + * Decode the INST_DIV instruction + */ +static void +cpu_br(struct oemu_cpu *cpu, inst_t *inst) +{ + struct cpu_regs *regs = &cpu->regs; + imm_t imm; + addr_t br_to; + + if (inst->rd > NELEM(regs->xreg)) { + printf("bad register operand for 'br'\n"); + return; + } + + /* + * If we are branching to the reset vector, might + * as well reset all state. + */ + br_to = regs->xreg[inst->rd]; + if (br_to == 0) { + cpu_reset(cpu); + } + + regs->ip = br_to; +} + +/* * Reset a CPU to a default state */ void @@ -205,8 +232,16 @@ cpu_reset(struct oemu_cpu *cpu) { struct cpu_regs *regs; + /* + * When an OSMX64 processor first starts up, it will + * initially be executing in supervisor mode with all + * of its registeres initialized to zeros. + */ regs = &cpu->regs; regs->ip = 0; + regs->sr_state = CPU_SRS_SV; + regs->blr = 0x0; + regs->ilr = 0x0; memset(regs->xreg, 0x0, sizeof(regs->xreg)); } @@ -222,7 +257,8 @@ cpu_regdump(struct oemu_cpu *cpu) "X6=%p, X7=%p, X8=%p\n" "X9=%p, X10=%p, X11=%p\n" "X12=%p, X13=%p, X14=%p\n" - "X15=%p, IP=%p\n", + "X15=%p, IP=%p, SRS=%p\n" + "BLR=%p, ILR=%p\n", regs->xreg[0], regs->xreg[1], regs->xreg[2], regs->xreg[3], regs->xreg[4], regs->xreg[5], @@ -231,7 +267,8 @@ cpu_regdump(struct oemu_cpu *cpu) regs->xreg[10], regs->xreg[11], regs->xreg[12], regs->xreg[13], regs->xreg[14], regs->xreg[15], - regs->ip + regs->ip, regs->sr_state, + regs->blr, regs->ilr ); } @@ -270,6 +307,9 @@ cpu_kick(struct oemu_cpu *cpu, struct sysmem *mem) case INST_DIV: cpu_div(cpu, inst); break; + case INST_BR: + cpu_br(cpu, inst); + break; } /* Is this a halt instruction? */ |