Merge with main repository.
[gem5.git] / src / dev / x86 / pc.cc
index 0cfd2b0f9501c125f32dc8f21a8a9495e80def77..dd8e34d9e55685168fb6166334177a6577463432 100644 (file)
 #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);
@@ -67,51 +73,82 @@ PC::init()
     //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);
@@ -119,8 +156,20 @@ PC::calcConfigAddr(int bus, int dev, int func)
     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);
 }