faults.cc (12808:f275fd1244ce) | faults.cc (12848:67652b15de3b) |
---|---|
1/* 2 * Copyright (c) 2016 RISC-V Foundation 3 * Copyright (c) 2016 The University of Virginia 4 * Copyright (c) 2018 TU Dresden 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions are --- 18 unchanged lines hidden (view full) --- 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 * 30 * Authors: Alec Roelke 31 * Robert Scheffel 32 */ 33#include "arch/riscv/faults.hh" 34 | 1/* 2 * Copyright (c) 2016 RISC-V Foundation 3 * Copyright (c) 2016 The University of Virginia 4 * Copyright (c) 2018 TU Dresden 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions are --- 18 unchanged lines hidden (view full) --- 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 * 30 * Authors: Alec Roelke 31 * Robert Scheffel 32 */ 33#include "arch/riscv/faults.hh" 34 |
35#include "arch/riscv/isa.hh" 36#include "arch/riscv/registers.hh" |
|
35#include "arch/riscv/system.hh" 36#include "arch/riscv/utility.hh" 37#include "cpu/base.hh" 38#include "cpu/thread_context.hh" 39#include "sim/debug.hh" 40#include "sim/full_system.hh" 41 | 37#include "arch/riscv/system.hh" 38#include "arch/riscv/utility.hh" 39#include "cpu/base.hh" 40#include "cpu/thread_context.hh" 41#include "sim/debug.hh" 42#include "sim/full_system.hh" 43 |
42using namespace RiscvISA; | 44namespace RiscvISA 45{ |
43 44void | 46 47void |
45RiscvFault::invoke_se(ThreadContext *tc, const StaticInstPtr &inst) | 48RiscvFault::invokeSE(ThreadContext *tc, const StaticInstPtr &inst) |
46{ 47 panic("Fault %s encountered at pc 0x%016llx.", name(), tc->pcState().pc()); 48} 49 50void 51RiscvFault::invoke(ThreadContext *tc, const StaticInstPtr &inst) 52{ | 49{ 50 panic("Fault %s encountered at pc 0x%016llx.", name(), tc->pcState().pc()); 51} 52 53void 54RiscvFault::invoke(ThreadContext *tc, const StaticInstPtr &inst) 55{ |
56 PCState pcState = tc->pcState(); 57 |
|
53 if (FullSystem) { | 58 if (FullSystem) { |
54 panic("Full system mode not supported for RISC-V."); | 59 PrivilegeMode pp = (PrivilegeMode)tc->readMiscReg(MISCREG_PRV); 60 PrivilegeMode prv = PRV_M; 61 STATUS status = tc->readMiscReg(MISCREG_STATUS); 62 63 // Set fault handler privilege mode 64 if (pp != PRV_M && 65 bits(tc->readMiscReg(MISCREG_MEDELEG), _code) != 0) { 66 prv = PRV_S; 67 } 68 if (pp == PRV_U && 69 bits(tc->readMiscReg(MISCREG_SEDELEG), _code) != 0) { 70 prv = PRV_U; 71 } 72 73 // Set fault registers and status 74 MiscRegIndex cause, epc, tvec; 75 switch (prv) { 76 case PRV_U: 77 cause = MISCREG_UCAUSE; 78 epc = MISCREG_UEPC; 79 tvec = MISCREG_UTVEC; 80 81 status.upie = status.uie; 82 status.uie = 0; 83 break; 84 case PRV_S: 85 cause = MISCREG_SCAUSE; 86 epc = MISCREG_SEPC; 87 tvec = MISCREG_STVEC; 88 89 status.spp = pp; 90 status.spie = status.sie; 91 status.sie = 0; 92 break; 93 case PRV_M: 94 cause = MISCREG_MCAUSE; 95 epc = MISCREG_MEPC; 96 tvec = MISCREG_MTVEC; 97 98 status.mpp = pp; 99 status.mpie = status.sie; 100 status.mie = 0; 101 break; 102 default: 103 panic("Unknown privilege mode %d.", prv); 104 break; 105 } 106 107 // Set fault cause, privilege, and return PC 108 tc->setMiscReg(cause, 109 (isInterrupt() << (sizeof(MiscReg) * 4 - 1)) | _code); 110 tc->setMiscReg(epc, tc->instAddr()); 111 tc->setMiscReg(MISCREG_PRV, prv); 112 tc->setMiscReg(MISCREG_STATUS, status); 113 114 // Set PC to fault handler address 115 pcState.set(tc->readMiscReg(tvec) >> 2); |
55 } else { | 116 } else { |
56 invoke_se(tc, inst); 57 PCState pcState = tc->pcState(); | 117 invokeSE(tc, inst); |
58 advancePC(pcState, inst); | 118 advancePC(pcState, inst); |
59 tc->pcState(pcState); | |
60 } | 119 } |
120 tc->pcState(pcState); |
|
61} 62 63void Reset::invoke(ThreadContext *tc, const StaticInstPtr &inst) 64{ 65 if (FullSystem) { 66 tc->getCpuPtr()->clearInterrupts(tc->threadId()); 67 tc->clearArchRegs(); 68 } 69 70 // Advance the PC to the implementation-defined reset vector 71 PCState pc = static_cast<RiscvSystem *>(tc->getSystemPtr())->resetVect(); 72 tc->pcState(pc); 73} 74 75void | 121} 122 123void Reset::invoke(ThreadContext *tc, const StaticInstPtr &inst) 124{ 125 if (FullSystem) { 126 tc->getCpuPtr()->clearInterrupts(tc->threadId()); 127 tc->clearArchRegs(); 128 } 129 130 // Advance the PC to the implementation-defined reset vector 131 PCState pc = static_cast<RiscvSystem *>(tc->getSystemPtr())->resetVect(); 132 tc->pcState(pc); 133} 134 135void |
76UnknownInstFault::invoke_se(ThreadContext *tc, const StaticInstPtr &inst) | 136UnknownInstFault::invokeSE(ThreadContext *tc, const StaticInstPtr &inst) |
77{ 78 panic("Unknown instruction 0x%08x at pc 0x%016llx", inst->machInst, 79 tc->pcState().pc()); 80} 81 82void | 137{ 138 panic("Unknown instruction 0x%08x at pc 0x%016llx", inst->machInst, 139 tc->pcState().pc()); 140} 141 142void |
83IllegalInstFault::invoke_se(ThreadContext *tc, const StaticInstPtr &inst) | 143IllegalInstFault::invokeSE(ThreadContext *tc, const StaticInstPtr &inst) |
84{ 85 panic("Illegal instruction 0x%08x at pc 0x%016llx: %s", inst->machInst, 86 tc->pcState().pc(), reason.c_str()); 87} 88 89void | 144{ 145 panic("Illegal instruction 0x%08x at pc 0x%016llx: %s", inst->machInst, 146 tc->pcState().pc(), reason.c_str()); 147} 148 149void |
90UnimplementedFault::invoke_se(ThreadContext *tc, | 150UnimplementedFault::invokeSE(ThreadContext *tc, |
91 const StaticInstPtr &inst) 92{ 93 panic("Unimplemented instruction %s at pc 0x%016llx", instName, 94 tc->pcState().pc()); 95} 96 97void | 151 const StaticInstPtr &inst) 152{ 153 panic("Unimplemented instruction %s at pc 0x%016llx", instName, 154 tc->pcState().pc()); 155} 156 157void |
98IllegalFrmFault::invoke_se(ThreadContext *tc, const StaticInstPtr &inst) | 158IllegalFrmFault::invokeSE(ThreadContext *tc, const StaticInstPtr &inst) |
99{ 100 panic("Illegal floating-point rounding mode 0x%x at pc 0x%016llx.", 101 frm, tc->pcState().pc()); 102} 103 104void | 159{ 160 panic("Illegal floating-point rounding mode 0x%x at pc 0x%016llx.", 161 frm, tc->pcState().pc()); 162} 163 164void |
105BreakpointFault::invoke_se(ThreadContext *tc, const StaticInstPtr &inst) | 165BreakpointFault::invokeSE(ThreadContext *tc, const StaticInstPtr &inst) |
106{ 107 schedRelBreak(0); 108} 109 110void | 166{ 167 schedRelBreak(0); 168} 169 170void |
111SyscallFault::invoke_se(ThreadContext *tc, const StaticInstPtr &inst) | 171SyscallFault::invokeSE(ThreadContext *tc, const StaticInstPtr &inst) |
112{ 113 Fault *fault = NoFault; 114 tc->syscall(tc->readIntReg(SyscallNumReg), fault); 115} | 172{ 173 Fault *fault = NoFault; 174 tc->syscall(tc->readIntReg(SyscallNumReg), fault); 175} |
176 177} // namespace RiscvISA |
|