summaryrefslogtreecommitdiff
path: root/nios2.c
diff options
context:
space:
mode:
Diffstat (limited to 'nios2.c')
-rw-r--r--nios2.c121
1 files changed, 112 insertions, 9 deletions
diff --git a/nios2.c b/nios2.c
index 87eb3f3..86dee5e 100644
--- a/nios2.c
+++ b/nios2.c
@@ -16,10 +16,34 @@
void nios2_cpu_reset(struct nios2 *cpu)
{
- memset(cpu, 0x00, sizeof(struct nios2));
+ /* Reset registers */
+ memset(cpu->gp_regs, 0x00, NIOS2_GP_REG_COUNT * sizeof(uint32_t));
+ memset(cpu->ctrl_regs, 0x00, NIOS2_CTRL_REG_COUNT * sizeof(uint32_t));
+
+ cpu->pc = 0;
cpu->mode = NIOS2_SUPERVISOR_MODE;
}
+void nios2_cpu_init(struct nios2 *cpu)
+{
+ /* Set PC to entry address of program */
+ cpu->pc = cpu->mem->image_base;
+}
+
+void nios2_cpu_inc_pc(struct nios2 *cpu)
+{
+ cpu->pc += 4;
+}
+
+void nios2_simulate(struct nios2 *cpu)
+{
+ /* Did anyone write to r0? */
+ if (cpu->gp_regs[zero]) {
+ warn("Written to r0\n");
+ cpu->gp_regs[zero] = 0;
+ }
+}
+
bool nios2_in_user_mode(struct nios2 *cpu)
{
if (!cpu->has_mmu)
@@ -35,21 +59,100 @@ bool nios2_in_supervisor_mode(struct nios2 *cpu)
return !nios2_in_user_mode(cpu);
}
-uint32_t nios2_cpu_fetch_instr(struct nios2 *cpu, uint32_t *mem_base)
+void nios2_exception(struct nios2 *cpu, uint8_t cause)
{
- uint32_t instr = 0;
+ cpu->ctrl_regs[exception] = (cause << 2) & 0x7C;
+}
- return instr;
+uint32_t nios2_fetch_instr(struct nios2 *cpu)
+{
+ struct memory *mem = cpu->mem;
+
+ return mem->base[cpu->pc / 4];
}
-int nios2_cpu_execute_instr(struct nios2 *cpu, uint32_t instr)
+int nios2_execute_instr(struct nios2 *cpu, uint32_t instr)
{
instruction_handler handle_instr = instruction_get_handler(instr);
- if (unlikely(handle_instr == NULL)) {
- err("Invalid instruction %08x\n", instr);
- return -1;
- }
+ if (unlikely(handle_instr == NULL))
+ return INSTR_ERR;
return handle_instr(cpu, instr);
}
+
+static const char *nios2_gp_registers[] = {
+ "zero",
+ "at",
+ "r2",
+ "r3",
+ "r4",
+ "r5",
+ "r6",
+ "r7",
+ "r8",
+ "r9",
+ "r10",
+ "r11",
+ "r12",
+ "r13",
+ "r14",
+ "r15",
+ "r16",
+ "r17",
+ "r18",
+ "r19",
+ "r20",
+ "r21",
+ "r22",
+ "r23",
+ "et",
+ "bt",
+ "gp",
+ "sp",
+ "fp",
+ "ea",
+ "ba",
+ "ra",
+};
+
+static const char *nios2_ctrl_registers[] = {
+ "status",
+ "estatus",
+ "bstatus",
+ "ienable",
+ "ipending",
+ "cpuid",
+ "reserved",
+ "exception",
+ "pteaddr",
+ "tlbacc",
+ "tlbmisc",
+ "reserved",
+ "badaddr",
+ "config",
+ "mpubase",
+ "mpuacc"
+};
+
+void nios2_dump_registers(struct nios2 *cpu)
+{
+ unsigned int i;
+ uint32_t *gp_regs = cpu->gp_regs;
+ uint32_t *ctrl_regs = cpu->ctrl_regs;
+
+ info("General-purpose registers:\n");
+ for (i = 0; i < NIOS2_GP_REG_COUNT; i++) {
+ info(" %8s 0x%08x", nios2_gp_registers[i], gp_regs[i]);
+ if ((i + 1) % 4 == 0)
+ info("\n");
+ }
+
+ info("Control registers:\n");
+ for (i = 0; i < NIOS2_CTRL_REG_COUNT; i++) {
+ info(" %10s 0x%08x", nios2_ctrl_registers[i], ctrl_regs[i]);
+ if ((i + 1) % 4 == 0)
+ info("\n");
+ }
+
+}