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 9 * met: redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer; 11 * redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution; 14 * neither the name of the copyright holders nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 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 9 * met: redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer; 11 * redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution; 14 * neither the name of the copyright holders nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 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
|
| |