diff options
author | Tobias Klauser <tklauser@distanz.ch> | 2010-11-24 18:35:39 +0100 |
---|---|---|
committer | Tobias Klauser <tklauser@distanz.ch> | 2010-11-24 18:35:39 +0100 |
commit | 9a1312e741193778718ed37b3779c2b964649e9d (patch) | |
tree | dc08eedd38da11d283d2cab4f754e03cba2f98c1 /nios2.c | |
parent | 1c7c724aee643060147e0bc792b428ca1c6cde02 (diff) |
Change exception handling, more instructions implemented
Diffstat (limited to 'nios2.c')
-rw-r--r-- | nios2.c | 36 |
1 files changed, 30 insertions, 6 deletions
@@ -24,6 +24,7 @@ void nios2_cpu_reset(struct nios2 *cpu) cpu->pc = 0; cpu->mode = NIOS2_SUPERVISOR_MODE; + cpu->exception_cause = NIOS2_EX_NONE; } void nios2_cpu_init(struct nios2 *cpu) @@ -61,9 +62,32 @@ bool nios2_in_supervisor_mode(struct nios2 *cpu) return !nios2_in_user_mode(cpu); } -void nios2_exception(struct nios2 *cpu, uint8_t cause) +void nios2_handle_exception(struct nios2 *cpu) { - cpu->ctrl_regs[exception] = (cause << 2) & 0x7C; + uint32_t *gp_regs = cpu->gp_regs; + uint32_t *ctrl_regs = cpu->ctrl_regs; + + if (cpu->exception_cause == NIOS2_EX_NONE) + return; + + /* Store the exception cause */ + ctrl_regs[exception] = (cpu->exception_cause << NIOS2_EXCEPTION_CAUSE_OFF) + & NIOS2_EXCEPTION_CAUSE_MASK; + /* Clear status.PIE */ + ctrl_regs[status] &= ~NIOS2_STATUS_PIE_MASK; + /* Clear status.U */ + ctrl_regs[status] &= ~NIOS2_STATUS_U_MASK; + + if (!cpu->has_mmu + || (cpu->has_mmu && !(ctrl_regs[status] & NIOS2_STATUS_EH_MASK))) { + /* Copy status control register to estatus control register */ + ctrl_regs[estatus] = cpu->ctrl_regs[status]; + /* Save address of the instruction following the exception to ea */ + gp_regs[ea] = cpu->pc + 4; + } + + /* TODO */ + } uint32_t nios2_fetch_instr(struct nios2 *cpu) @@ -95,10 +119,10 @@ int nios2_load(struct nios2 *cpu, uint32_t addr, void *data, size_t size) { struct memory *mem = cpu->mem; - dbg("load%zu %08x\n", size * 8, addr); +// dbg("load%zu %08x\n", size * 8, addr); if (is_mem_addr(mem, addr)) { - dbg("load MEM\n"); +// dbg("load MEM\n"); switch (size) { case 1: *((uint8_t *) data) = memory_get_byte(mem, addr); @@ -135,10 +159,10 @@ int nios2_store(struct nios2 *cpu, uint32_t addr, void *data, size_t size) { struct memory *mem = cpu->mem; - dbg("store%zu %08x\n", size, addr); +// dbg("store%zu %08x\n", size, addr); if (is_mem_addr(mem, addr)) { - dbg("store MEM\n"); +// dbg("store MEM\n"); switch (size) { case 1: memory_set_byte(mem, addr, *((uint8_t *) data)); |