interrupts.hh (12808:f275fd1244ce) | interrupts.hh (13548:b76f99d052bb) |
---|---|
1/* 2 * Copyright (c) 2011 Google 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; --- 17 unchanged lines hidden (view full) --- 26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 * Authors: Gabe Black 29 */ 30 31#ifndef __ARCH_RISCV_INTERRUPT_HH__ 32#define __ARCH_RISCV_INTERRUPT_HH__ 33 | 1/* 2 * Copyright (c) 2011 Google 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; --- 17 unchanged lines hidden (view full) --- 26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 * Authors: Gabe Black 29 */ 30 31#ifndef __ARCH_RISCV_INTERRUPT_HH__ 32#define __ARCH_RISCV_INTERRUPT_HH__ 33 |
34#include <bitset> 35#include <memory> 36 37#include "arch/riscv/faults.hh" 38#include "arch/riscv/registers.hh" |
|
34#include "base/logging.hh" 35#include "cpu/thread_context.hh" | 39#include "base/logging.hh" 40#include "cpu/thread_context.hh" |
41#include "debug/Interrupt.hh" |
|
36#include "params/RiscvInterrupts.hh" 37#include "sim/sim_object.hh" 38 39class BaseCPU; 40class ThreadContext; 41 42namespace RiscvISA { 43 | 42#include "params/RiscvInterrupts.hh" 43#include "sim/sim_object.hh" 44 45class BaseCPU; 46class ThreadContext; 47 48namespace RiscvISA { 49 |
50/* 51 * This is based on version 1.10 of the RISC-V privileged ISA reference, 52 * chapter 3.1.14. 53 */ |
|
44class Interrupts : public SimObject 45{ 46 private: 47 BaseCPU * cpu; | 54class Interrupts : public SimObject 55{ 56 private: 57 BaseCPU * cpu; |
58 std::bitset<NumInterruptTypes> ip; 59 std::bitset<NumInterruptTypes> ie; |
|
48 49 public: 50 typedef RiscvInterruptsParams Params; 51 52 const Params * 53 params() const 54 { 55 return dynamic_cast<const Params *>(_params); 56 } 57 | 60 61 public: 62 typedef RiscvInterruptsParams Params; 63 64 const Params * 65 params() const 66 { 67 return dynamic_cast<const Params *>(_params); 68 } 69 |
58 Interrupts(Params * p) : SimObject(p), cpu(nullptr) 59 {} | 70 Interrupts(Params * p) : SimObject(p), cpu(nullptr), ip(0), ie(0) {} |
60 | 71 |
61 void 62 setCPU(BaseCPU * _cpu) | 72 void setCPU(BaseCPU * _cpu) { cpu = _cpu; } 73 74 std::bitset<NumInterruptTypes> 75 globalMask(ThreadContext *tc) const |
63 { | 76 { |
64 cpu = _cpu; | 77 INTERRUPT mask; 78 STATUS status = tc->readMiscReg(MISCREG_STATUS); 79 if (status.mie) 80 mask.mei = mask.mti = mask.msi = 1; 81 if (status.sie) 82 mask.sei = mask.sti = mask.ssi = 1; 83 if (status.uie) 84 mask.uei = mask.uti = mask.usi = 1; 85 return std::bitset<NumInterruptTypes>(mask); |
65 } 66 | 86 } 87 |
88 bool checkInterrupt(int num) const { return ip[num] && ie[num]; } 89 bool checkInterrupts(ThreadContext *tc) const 90 { 91 return (ip & ie & globalMask(tc)).any(); 92 } 93 94 Fault 95 getInterrupt(ThreadContext *tc) const 96 { 97 assert(checkInterrupts(tc)); 98 std::bitset<NumInterruptTypes> mask = globalMask(tc); 99 for (int c = 0; c < NumInterruptTypes; c++) 100 if (checkInterrupt(c) && mask[c]) 101 return std::make_shared<InterruptFault>(c); 102 return NoFault; 103 } 104 105 void updateIntrInfo(ThreadContext *tc) {} 106 |
|
67 void 68 post(int int_num, int index) 69 { | 107 void 108 post(int int_num, int index) 109 { |
70 panic("Interrupts::post not implemented.\n"); | 110 DPRINTF(Interrupt, "Interrupt %d:%d posted\n", int_num, index); 111 ip[int_num] = true; |
71 } 72 73 void 74 clear(int int_num, int index) 75 { | 112 } 113 114 void 115 clear(int int_num, int index) 116 { |
76 panic("Interrupts::clear not implemented.\n"); | 117 DPRINTF(Interrupt, "Interrupt %d:%d cleared\n", int_num, index); 118 ip[int_num] = false; |
77 } 78 79 void 80 clearAll() 81 { | 119 } 120 121 void 122 clearAll() 123 { |
82 warn_once("Interrupts::clearAll not implemented.\n"); | 124 DPRINTF(Interrupt, "All interrupts cleared\n"); 125 ip = 0; |
83 } 84 | 126 } 127 |
85 bool 86 checkInterrupts(ThreadContext *tc) const 87 { 88 warn_once("Interrupts::checkInterrupts just rudimentary implemented"); 89 /** 90 * read the machine interrupt register in order to check if interrupts 91 * are pending 92 * should be sufficient for now, as interrupts 93 * are not implemented at all 94 */ 95 if (tc->readMiscReg(MISCREG_IP)) 96 return true; | 128 MiscReg readIP() const { return (MiscReg)ip.to_ulong(); } 129 MiscReg readIE() const { return (MiscReg)ie.to_ulong(); } 130 void setIP(const MiscReg& val) { ip = val; } 131 void setIE(const MiscReg& val) { ie = val; } |
97 | 132 |
98 return false; 99 } 100 101 Fault 102 getInterrupt(ThreadContext *tc) | 133 void 134 serialize(CheckpointOut &cp) |
103 { | 135 { |
104 assert(checkInterrupts(tc)); 105 panic("Interrupts::getInterrupt not implemented.\n"); | 136 SERIALIZE_SCALAR(ip.to_ulong()); 137 SERIALIZE_SCALAR(ie.to_ulong()); |
106 } 107 108 void | 138 } 139 140 void |
109 updateIntrInfo(ThreadContext *tc) | 141 unserialize(CheckpointIn &cp) |
110 { | 142 { |
111 panic("Interrupts::updateIntrInfo not implemented.\n"); | 143 long reg; 144 UNSERIALIZE_SCALAR(reg); 145 ip = reg; 146 UNSERIALIZE_SCALAR(reg); 147 ie = reg; |
112 } 113}; 114 115} // namespace RiscvISA 116 117#endif // __ARCH_RISCV_INTERRUPT_HH__ | 148 } 149}; 150 151} // namespace RiscvISA 152 153#endif // __ARCH_RISCV_INTERRUPT_HH__ |
118 | |