-
Notifications
You must be signed in to change notification settings - Fork 61
/
trap.js
66 lines (51 loc) · 2.1 KB
/
trap.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
// trap handling
function handle_trap(trap){
//first, need to check EI bit. if it is not one, processor enters ERROR
//mode (throw new RISCVError("ERROR");)
if ((RISCV.priv_reg[PCR["CSR_STATUS"]["num"]] & SR["SR_EI"]) == 0x0) {
// this means exceptions are disabled
// enter ERROR mode:
throw new RISCVError("Exceptions are Disabled but Trap Occurred, Terminating");
}
//console.log("Trap occurred at " + stringIntHex(RISCV.pc));
// store exception code to cause register
var trapec = trap.exceptionCode;
var causeLong = new Long(trap.exceptionCode, trap.interruptBit << 31);
RISCV.priv_reg[PCR["CSR_CAUSE"]["num"]] = causeLong;
var oldsr = RISCV.priv_reg[PCR["CSR_STATUS"]["num"]];
// set SR[PS] = SR[S]
if ((oldsr & SR["SR_S"]) != 0) {
// S is set
oldsr = oldsr | SR["SR_PS"];
} else {
oldsr = oldsr & (~SR["SR_PS"]);
}
if ((oldsr & SR["SR_EI"]) != 0) {
oldsr = oldsr | SR["SR_PEI"];
} else {
oldsr = oldsr & (~SR["SR_PEI"]);
}
// set S to 1 - enable supervisor
oldsr = oldsr | SR["SR_S"];
// set EI to 0
oldsr = oldsr & (~SR["SR_EI"]);
// store modified SR
RISCV.priv_reg[PCR["CSR_STATUS"]["num"]] = oldsr;
// if trap is load/store misaligned address or access fault,
// set badvaddr to faulting address
if (trapec == 0x8 || trapec == 0x9 || trapec == 0xA || trapec == 0xB) {
if ((trap.memaddr.getLowBitsUnsigned() & 0xFF000000) == 0x55000000) {
RISCV.priv_reg[PCR["CSR_BADVADDR"]["num"]] = new Long(trap.memaddr.getLowBitsUnsigned(), 0x155);
} else {
RISCV.priv_reg[PCR["CSR_BADVADDR"]["num"]] = trap.memaddr;
}
}
// store original PC (addr of inst causing exception) to epc reg
if ((RISCV.pc & 0xFF000000) == 0x55000000) {
RISCV.priv_reg[PCR["CSR_EPC"]["num"]] = new Long(RISCV.pc, 0x155);
} else {
RISCV.priv_reg[PCR["CSR_EPC"]["num"]] = signExtLT32_64(RISCV.pc);
}
// set PC = to value in evec register
RISCV.pc = RISCV.priv_reg[PCR["CSR_EVEC"]["num"]].getLowBits();
}