target/openrisc: Implement EVBAR register

Exception Vector Base Address Register (EVBAR) - This optional register
can be used to apply an offset to the exception vector addresses.

The significant bits (31-12) of the vector offset address for each
exception depend on the setting of the Supervision Register (SR)'s EPH
bit and the Exception Vector Base Address Register (EVBAR).

Its presence is indicated by the EVBARP bit in the CPU Configuration
Register (CPUCFGR).

Signed-off-by: Tim 'mithro' Ansell <mithro@mithis.com>
Signed-off-by: Stafford Horne <shorne@gmail.com>
This commit is contained in:
Tim 'mithro' Ansell 2017-04-18 16:15:50 +10:00 committed by Stafford Horne
parent 1d7cf18d79
commit 356a2db3c6
4 changed files with 21 additions and 1 deletions

View File

@ -134,6 +134,7 @@ static void or1200_initfn(Object *obj)
set_feature(cpu, OPENRISC_FEATURE_OB32S);
set_feature(cpu, OPENRISC_FEATURE_OF32S);
set_feature(cpu, OPENRISC_FEATURE_EVBAR);
}
static void openrisc_any_initfn(Object *obj)
@ -141,6 +142,7 @@ static void openrisc_any_initfn(Object *obj)
OpenRISCCPU *cpu = OPENRISC_CPU(obj);
set_feature(cpu, OPENRISC_FEATURE_OB32S);
set_feature(cpu, OPENRISC_FEATURE_EVBAR);
}
typedef struct OpenRISCCPUInfo {

View File

@ -111,6 +111,11 @@ enum {
CPUCFGR_OF32S = (1 << 7),
CPUCFGR_OF64S = (1 << 8),
CPUCFGR_OV64S = (1 << 9),
/* CPUCFGR_ND = (1 << 10), */
/* CPUCFGR_AVRP = (1 << 11), */
CPUCFGR_EVBARP = (1 << 12),
/* CPUCFGR_ISRP = (1 << 13), */
/* CPUCFGR_AECSRP = (1 << 14), */
};
/* DMMU configure register */
@ -200,6 +205,7 @@ enum {
OPENRISC_FEATURE_OF32S = (1 << 7),
OPENRISC_FEATURE_OF64S = (1 << 8),
OPENRISC_FEATURE_OV64S = (1 << 9),
OPENRISC_FEATURE_EVBAR = (1 << 12),
};
/* Tick Timer Mode Register */
@ -289,6 +295,7 @@ typedef struct CPUOpenRISCState {
uint32_t dmmucfgr; /* DMMU configure register */
uint32_t immucfgr; /* IMMU configure register */
uint32_t esr; /* Exception supervisor register */
uint32_t evbar; /* Exception vector base address register */
uint32_t fpcsr; /* Float register */
float_status fp_status;

View File

@ -65,7 +65,11 @@ void openrisc_cpu_do_interrupt(CPUState *cs)
env->lock_addr = -1;
if (cs->exception_index > 0 && cs->exception_index < EXCP_NR) {
env->pc = (cs->exception_index << 8);
hwaddr vect_pc = cs->exception_index << 8;
if (env->cpucfgr & CPUCFGR_EVBARP) {
vect_pc |= env->evbar;
}
env->pc = vect_pc;
} else {
cpu_abort(cs, "Unhandled exception 0x%x\n", cs->exception_index);
}

View File

@ -39,6 +39,10 @@ void HELPER(mtspr)(CPUOpenRISCState *env,
env->vr = rb;
break;
case TO_SPR(0, 11): /* EVBAR */
env->evbar = rb;
break;
case TO_SPR(0, 16): /* NPC */
cpu_restore_state(cs, GETPC());
/* ??? Mirror or1ksim in not trashing delayed branch state
@ -206,6 +210,9 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env,
case TO_SPR(0, 4): /* IMMUCFGR */
return env->immucfgr;
case TO_SPR(0, 11): /* EVBAR */
return env->evbar;
case TO_SPR(0, 16): /* NPC (equals PC) */
cpu_restore_state(cs, GETPC());
return env->pc;