#include <string>
#include <vector>
+#include "arch/x86/intmessage.hh"
#include "arch/x86/x86_traits.hh"
+#include "config/the_isa.hh"
#include "cpu/intr_control.hh"
-#include "dev/terminal.hh"
+#include "dev/x86/i82094aa.hh"
#include "dev/x86/i8254.hh"
+#include "dev/x86/i8259.hh"
#include "dev/x86/pc.hh"
-#include "dev/x86/south_bridge/south_bridge.hh"
+#include "dev/x86/south_bridge.hh"
+#include "dev/terminal.hh"
#include "sim/system.hh"
using namespace std;
using namespace TheISA;
-PC::PC(const Params *p)
+Pc::Pc(const Params *p)
: Platform(p), system(p->system)
{
southBridge = NULL;
- // set the back pointer from the system to myself
- system->platform = this;
}
void
-PC::init()
+Pc::init()
{
assert(southBridge);
+
+ /*
+ * Initialize the timer.
+ */
I8254 & timer = *southBridge->pit;
//Timer 0, mode 2, no bcd, 16 bit count
timer.writeControl(0x34);
//Write a 16 bit count of 0
timer.writeCounter(0, 0);
timer.writeCounter(0, 0);
-}
-Tick
-PC::intrFrequency()
-{
- panic("Need implementation\n");
- M5_DUMMY_RETURN
+ /*
+ * Initialize the I/O APIC.
+ */
+ I82094AA & ioApic = *southBridge->ioApic;
+ I82094AA::RedirTableEntry entry = 0;
+ entry.deliveryMode = DeliveryMode::ExtInt;
+ entry.vector = 0x20;
+ ioApic.writeReg(0x10, entry.bottomDW);
+ ioApic.writeReg(0x11, entry.topDW);
+ entry.deliveryMode = DeliveryMode::Fixed;
+ entry.vector = 0x24;
+ ioApic.writeReg(0x18, entry.bottomDW);
+ ioApic.writeReg(0x19, entry.topDW);
+ entry.mask = 1;
+ entry.vector = 0x21;
+ ioApic.writeReg(0x12, entry.bottomDW);
+ ioApic.writeReg(0x13, entry.topDW);
+ entry.vector = 0x20;
+ ioApic.writeReg(0x14, entry.bottomDW);
+ ioApic.writeReg(0x15, entry.topDW);
+ entry.vector = 0x28;
+ ioApic.writeReg(0x20, entry.bottomDW);
+ ioApic.writeReg(0x21, entry.topDW);
+ entry.vector = 0x2C;
+ ioApic.writeReg(0x28, entry.bottomDW);
+ ioApic.writeReg(0x29, entry.topDW);
+ entry.vector = 0x2E;
+ ioApic.writeReg(0x2C, entry.bottomDW);
+ ioApic.writeReg(0x2D, entry.topDW);
+ entry.vector = 0x30;
+ ioApic.writeReg(0x30, entry.bottomDW);
+ ioApic.writeReg(0x31, entry.topDW);
+
+ /*
+ * Mask the PICs. I'm presuming the BIOS/bootloader would have cleared
+ * these out and masked them before passing control to the OS.
+ */
+ southBridge->pic1->maskAll();
+ southBridge->pic2->maskAll();
}
void
-PC::postConsoleInt()
+Pc::postConsoleInt()
{
- warn_once("Don't know what interrupt to post for console.\n");
- //panic("Need implementation\n");
+ southBridge->ioApic->signalInterrupt(4);
+ southBridge->pic1->signalInterrupt(4);
}
void
-PC::clearConsoleInt()
+Pc::clearConsoleInt()
{
warn_once("Don't know what interrupt to clear for console.\n");
//panic("Need implementation\n");
}
void
-PC::postPciInt(int line)
+Pc::postPciInt(int line)
{
- panic("Need implementation\n");
+ southBridge->ioApic->signalInterrupt(line);
}
void
-PC::clearPciInt(int line)
+Pc::clearPciInt(int line)
{
- panic("Need implementation\n");
+ warn_once("Tried to clear PCI interrupt %d\n", line);
}
Addr
-PC::pciToDma(Addr pciAddr) const
+Pc::pciToDma(Addr pciAddr) const
{
- panic("Need implementation\n");
- M5_DUMMY_RETURN
+ return pciAddr;
}
-
Addr
-PC::calcConfigAddr(int bus, int dev, int func)
+Pc::calcPciConfigAddr(int bus, int dev, int func)
{
assert(func < 8);
assert(dev < 32);
return (PhysAddrPrefixPciConfig | (func << 8) | (dev << 11));
}
-PC *
-PCParams::create()
+Addr
+Pc::calcPciIOAddr(Addr addr)
+{
+ return PhysAddrPrefixIO + addr;
+}
+
+Addr
+Pc::calcPciMemAddr(Addr addr)
+{
+ return addr;
+}
+
+Pc *
+PcParams::create()
{
- return new PC(this);
+ return new Pc(this);
}