#include "base/logging.hh"
#include "params/PowerInterrupts.hh"
+#define NumInterruptLevels 8
+
+#define SystemReset 0 //System Reset Interrupt(Highest Priority)
+#define MachineCheck 1 //Machine Check Interrupt
+#define DirectExt 2 //Direct External Interrupt
+#define MediatedExt 3 //Mediated External Interrupt
+#define Decrementer 4 //Decrementer Interrupt
+#define PerfMoniter 5 //Performance Monitor Interrupt
+#define DirPriDoorbell 6 //Directed Privileged Doorbell Interrupt
+#define DirHypDoorbell 7 //Directed Hypervisor Doorbell Interrupt
+
class BaseCPU;
class ThreadContext;
{
private:
BaseCPU * cpu;
- bool si = false;
+
+ protected:
+ bool interrupts[NumInterruptLevels];
public:
typedef PowerInterruptsParams Params;
return dynamic_cast<const Params *>(_params);
}
- Interrupts(Params *p) : BaseInterrupts(p) {}
+ Interrupts(Params * p) : SimObject(p), cpu(NULL)
+ {
+ memset(interrupts, 0, sizeof(interrupts));
+ }
+
+ void
+ setCPU(BaseCPU * _cpu)
+ {
+ cpu = _cpu;
+ }
void
post(int int_num, int index)
{
- panic("Interrupts::post not implemented.\n");
+ DPRINTF(Interrupt, "Interrupt %d: posted\n", int_num);
+ if (int_num < 0 || int_num >= NumInterruptLevels)
+ panic("int_num out of bounds for fun POST%d\n",int_num);
+ interrupts[int_num] = 1;
}
void
clear(int int_num, int index)
{
- panic("Interrupts::clear not implemented.\n");
+ DPRINTF(Interrupt, "Interrupt %d:\n", int_num);
+ if (int_num < 0 || int_num >= NumInterruptLevels)
+ panic("int_num out of bounds for fun CLEAR%d\n",int_num);
+ interrupts[int_num] = 0;
}
void
clearAll()
{
- panic("Interrupts::clearAll not implemented.\n");
+ memset(interrupts, 0, sizeof(interrupts));
}
bool
checkInterrupts(ThreadContext *tc)
{
- //panic("Interrupts::checkInterrupts not implemented.\n");
- Msr msr = tc->readIntReg(INTREG_MSR);
- tc->setIntReg(INTREG_TB , tc->readIntReg(INTREG_TB)+1);
- if ( tc->readIntReg(INTREG_DEC) == 0 && msr.ee) {
- si = true;
- return true;
- }
- else if (tc->readIntReg(INTREG_DEC) == 0 && !msr.ee) {
+ Msr msr = tc->readIntReg(INTREG_MSR);
+ tc->setIntReg(INTREG_TB , tc->readIntReg(INTREG_TB)+1);
+ if (tc->readIntReg(INTREG_DEC) != 0)
+ tc->setIntReg(INTREG_DEC , tc->readIntReg(INTREG_DEC)-1);
+ else
+ interrupts[Decrementer] = 1;
+ if (msr.ee)
+ {
+ for (int i = 0; i < NumInterruptLevels; i++) {
+ if (interrupts[i] == 1)
+ return true;
+ }
+ }
+ if (interrupts[DirHypDoorbell] && (!msr.hv || msr.pr))
+ return true;
return false;
- } else {
- tc->setIntReg(INTREG_DEC , tc->readIntReg(INTREG_DEC)-1);
- return false;
- }
}
Fault
getInterrupt()
{
assert(checkInterrupts(tc));
- if (si)
- return std::make_shared<DecrementerInterrupt>();
+ if (interrupts[Decrementer]) {
+ clear(Decrementer,0);
+ return std::make_shared<DecrementerInterrupt>();
+ }
+ else if (interrupts[DirPriDoorbell]) {
+ clear(DirPriDoorbell,0);
+ return std::make_shared<PriDoorbellInterrupt>();
+ }
+ else if (interrupts[DirHypDoorbell]) {
+ clear(DirHypDoorbell,0);
+ return std::make_shared<HypDoorbellInterrupt>();
+ }
else return NoFault;
}
updateIntrInfo()
{
tc->setIntReg(INTREG_DEC , 0xffffffffffffffff);
- si = false;
}
};
for (auto *tc: threads)
all = tc->remove(event) && all;
return all;
+
+void
+System::initState()
+{
+ if (FullSystem) {
+ for (int i = 0; i < threadContexts.size(); i++){
+ printf("[LOG]: Starting CPU with id %d\n",i);
+ TheISA::startupCPU(threadContexts[i], i);}
+ // Moved from the constructor to here since it relies on the
+ // address map being resolved in the interconnect
+ /**
+ * Load the kernel code into memory
+ */
+ if (params()->kernel != "") {
+ if (params()->kernel_addr_check) {
+ // Validate kernel mapping before loading binary
+ if (!(isMemAddr((kernelStart & loadAddrMask) +
+ loadAddrOffset) &&
+ isMemAddr((kernelEnd & loadAddrMask) +
+ loadAddrOffset))) {
+ fatal("Kernel is mapped to invalid location (not memory). "
+ "kernelStart 0x(%x) - kernelEnd 0x(%x) %#x:%#x\n",
+ kernelStart,
+ kernelEnd, (kernelStart & loadAddrMask) +
+ loadAddrOffset,
+ (kernelEnd & loadAddrMask) + loadAddrOffset);
+ }
+ }
+ // Load program sections into memory
+ kernel->loadSections(physProxy, loadAddrMask, loadAddrOffset);
+ for (const auto &extra_kernel : kernelExtras) {
+ extra_kernel->loadSections(physProxy, loadAddrMask,
+ loadAddrOffset);
+ }
+
+ DPRINTF(Loader, "Kernel start = %#x\n", kernelStart);
+ DPRINTF(Loader, "Kernel end = %#x\n", kernelEnd);
+ DPRINTF(Loader, "Kernel entry = %#x\n", kernelEntry);
+ DPRINTF(Loader, "Kernel loaded...\n");
+ }
+ }
}
void