Line 19... |
Line 19... |
|
|
#include <stdlib.h>
|
#include <stdlib.h>
|
#include <stdio.h>
|
#include <stdio.h>
|
#include <string.h>
|
#include <string.h>
|
|
|
|
#include "config.h"
|
|
|
|
#ifdef HAVE_INTTYPES_H
|
|
#include <inttypes.h>
|
|
#endif
|
|
|
|
#include "port.h"
|
|
#include "arch.h"
|
#include "abstract.h"
|
#include "abstract.h"
|
#include "except.h"
|
#include "except.h"
|
#include "sprs.h"
|
#include "sprs.h"
|
#include "sim-config.h"
|
#include "sim-config.h"
|
#include "debug_unit.h"
|
#include "debug_unit.h"
|
|
#include "execute.h"
|
|
|
extern int cont_run;
|
extern int cont_run;
|
extern struct iqueue_entry iqueue[20];
|
extern struct iqueue_entry iqueue[20];
|
extern unsigned long pc;
|
|
extern unsigned long pcnext;
|
|
extern unsigned long pc_phy;
|
extern unsigned long pc_phy;
|
extern struct iqueue_entry iqueue[];
|
extern struct iqueue_entry iqueue[];
|
|
|
extern int delay_insn;
|
extern int delay_insn;
|
|
|
Line 46... |
Line 53... |
pending.address = 0;
|
pending.address = 0;
|
pending.saved = 0;
|
pending.saved = 0;
|
}
|
}
|
|
|
/* Asserts OR1K exception. */
|
/* Asserts OR1K exception. */
|
void except_handle(int except, unsigned long ea)
|
void except_handle(oraddr_t except, oraddr_t ea)
|
{
|
{
|
if(debug_ignore_exception (except)) {
|
if(debug_ignore_exception (except)) {
|
clear_pending_exception ();
|
clear_pending_exception ();
|
} else {
|
} else {
|
pending.valid = 1;
|
pending.valid = 1;
|
Line 58... |
Line 65... |
pending.address = ea;
|
pending.address = ea;
|
if (delay_insn)
|
if (delay_insn)
|
pending.saved = pc - 4;
|
pending.saved = pc - 4;
|
else
|
else
|
pending.saved = pc;
|
pending.saved = pc;
|
if (config.sim.verbose) PRINTF("Exception 0x%x (%s) at 0x%lx, EA: 0x%lx, ppc: 0x%lx, npc: 0x%lx, cycles %lld, #%lld\n",
|
if (config.sim.verbose)
|
except, EXCEPT_NAME(except), iqueue[0].insn_addr, ea, pc, pcnext, runtime.sim.cycles, runtime.cpu.instructions);
|
PRINTF("Exception 0x%"PRIxADDR" (%s) at 0x%"PRIxADDR", EA: 0x%"PRIxADDR
|
|
", ppc: 0x%"PRIxADDR", npc: 0x%"PRIxADDR", cycles %lld, #%lld\n",
|
|
except, EXCEPT_NAME(except), iqueue[0].insn_addr, ea, pc, pcnext,
|
|
runtime.sim.cycles, runtime.cpu.instructions);
|
}
|
}
|
}
|
}
|
|
|
/* Actually handles exception */
|
/* Actually handles exception */
|
void except_handle_backend (int except, unsigned long ea, unsigned long pc_saved)
|
void except_handle_backend (oraddr_t except, oraddr_t ea, oraddr_t pc_saved)
|
{
|
{
|
#if ONLY_VIRTUAL_MACHINE
|
#if ONLY_VIRTUAL_MACHINE
|
fprintf(stderr, "WARNING: No exception processing while ONLY_VIRTUAL_MACHINE is defined.\n");
|
fprintf(stderr, "WARNING: No exception processing while ONLY_VIRTUAL_MACHINE is defined.\n");
|
cont_run = 0;
|
cont_run = 0;
|
#else
|
#else
|
Line 76... |
Line 86... |
if (delay_insn) {
|
if (delay_insn) {
|
if (config.sim.verbose) PRINTF("INFO: Exception during execution of delay slot insn.\n");
|
if (config.sim.verbose) PRINTF("INFO: Exception during execution of delay slot insn.\n");
|
pc -= 4;
|
pc -= 4;
|
}
|
}
|
|
|
pc_saved = pc & ~0x3;
|
pc_saved = pc & ~ADDR_C(0x3);
|
if (except == EXCEPT_ILLEGAL)
|
if (except == EXCEPT_ILLEGAL)
|
mtspr(SPR_EPCR_BASE, pending.saved);
|
mtspr(SPR_EPCR_BASE, pending.saved);
|
else if (except == EXCEPT_ALIGN)
|
else if (except == EXCEPT_ALIGN)
|
mtspr(SPR_EPCR_BASE, pending.saved);
|
mtspr(SPR_EPCR_BASE, pending.saved);
|
else if (except == EXCEPT_DTLBMISS)
|
else if (except == EXCEPT_DTLBMISS)
|