dev, x86: Convert x86 devices to the generic int pins.
authorGabe Black <gabeblack@google.com>
Fri, 6 Sep 2019 22:22:22 +0000 (15:22 -0700)
committerGabe Black <gabeblack@google.com>
Fri, 20 Sep 2019 17:54:39 +0000 (17:54 +0000)
Change-Id: I4551ad00cf205c31555c90b53e87bc206a8d8729
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/20701
Reviewed-by: Gabe Black <gabeblack@google.com>
Maintainer: Gabe Black <gabeblack@google.com>
Tested-by: kokoro <noreply+kokoro@google.com>
16 files changed:
src/dev/x86/Cmos.py
src/dev/x86/I8042.py
src/dev/x86/I82094AA.py
src/dev/x86/I8254.py
src/dev/x86/I8259.py
src/dev/x86/SouthBridge.py
src/dev/x86/cmos.cc
src/dev/x86/cmos.hh
src/dev/x86/i8042.cc
src/dev/x86/i8042.hh
src/dev/x86/i82094aa.cc
src/dev/x86/i82094aa.hh
src/dev/x86/i8254.cc
src/dev/x86/i8254.hh
src/dev/x86/i8259.cc
src/dev/x86/i8259.hh

index 9bc395cb208bbd4d4840fe2d71eb6cc9270f3d8b..e5d2d6d34762159fa5da946cad73abca98d4d880 100644 (file)
@@ -29,7 +29,7 @@
 from m5.params import *
 from m5.proxy import *
 from m5.objects.Device import BasicPioDevice
-from m5.objects.X86IntPin import X86IntSourcePin
+from m5.objects.IntPin import IntSourcePin
 
 class Cmos(BasicPioDevice):
     type = 'Cmos'
@@ -37,5 +37,4 @@ class Cmos(BasicPioDevice):
     cxx_header = "dev/x86/cmos.hh"
     time = Param.Time('01/01/2012',
         "System time to use ('Now' for actual time)")
-    int_pin = Param.X86IntSourcePin(X86IntSourcePin(),
-            'Pin to signal RTC alarm interrupts to')
+    int_pin = IntSourcePin('Pin to signal RTC alarm interrupts to')
index 5615d3e9fa18cf4b0e99bc5b4c31c0dc297e8e76..44a1e011f03141d58ac1f0c5f98e28a8b7b86850 100644 (file)
@@ -29,7 +29,7 @@
 from m5.params import *
 from m5.proxy import *
 from m5.objects.Device import BasicPioDevice
-from m5.objects.X86IntPin import X86IntSourcePin
+from m5.objects.IntPin import IntSourcePin
 from m5.objects.PS2 import *
 
 class I8042(BasicPioDevice):
@@ -40,10 +40,8 @@ class I8042(BasicPioDevice):
     pio_addr = 0x0
     data_port = Param.Addr('Data port address')
     command_port = Param.Addr('Command/status port address')
-    mouse_int_pin = Param.X86IntSourcePin(X86IntSourcePin(),
-            'Pin to signal the mouse has data')
-    keyboard_int_pin = Param.X86IntSourcePin(X86IntSourcePin(),
-            'Pin to signal the keyboard has data')
+    mouse_int_pin = IntSourcePin('Pin to signal the mouse has data')
+    keyboard_int_pin = IntSourcePin('Pin to signal the keyboard has data')
 
     keyboard = Param.PS2Device(PS2Keyboard(vnc=NULL), "PS/2 keyboard device")
     mouse = Param.PS2Device(PS2Mouse(), "PS/2 mouse device")
index d848904f0ac95d7bbbd439983e7483458c508121..3336e444204f90d2435d90e039e351b6fb0d1aa0 100644 (file)
@@ -29,7 +29,7 @@
 from m5.params import *
 from m5.proxy import *
 from m5.objects.Device import BasicPioDevice
-from m5.objects.X86IntPin import X86IntSinkPin
+from m5.objects.IntPin import VectorIntSinkPin
 
 class I82094AA(BasicPioDevice):
     type = 'I82094AA'
@@ -41,5 +41,4 @@ class I82094AA(BasicPioDevice):
             "Latency for an interrupt to propagate through this device.")
     external_int_pic = Param.I8259(NULL, "External PIC, if any")
 
-    def pin(self, line):
-        return X86IntSinkPin(device=self, number=line)
+    inputs = VectorIntSinkPin('The pins that drive this IO APIC')
index f0a6b2222cd247531626f278d165b4464c181c58..781609f24b97957e0b8de31e567589d1df30c9fc 100644 (file)
 from m5.params import *
 from m5.proxy import *
 from m5.objects.Device import BasicPioDevice
-from m5.objects.X86IntPin import X86IntSourcePin
+from m5.objects.IntPin import IntSourcePin
 
 class I8254(BasicPioDevice):
     type = 'I8254'
     cxx_class = 'X86ISA::I8254'
     cxx_header = "dev/x86/i8254.hh"
-    int_pin = Param.X86IntSourcePin(X86IntSourcePin(),
-            'Pin to signal timer interrupts to')
+    int_pin = IntSourcePin('Pin to signal timer interrupts to')
index 7066cb846cb9f2c4f7a53471d050fd26d8dae0a7..ef2733a9a0d0fbdd43c292f6417fec658f49b945 100644 (file)
@@ -29,7 +29,7 @@
 from m5.params import *
 from m5.proxy import *
 from m5.objects.Device import BasicPioDevice
-from m5.objects.X86IntPin import X86IntSourcePin, X86IntSinkPin
+from m5.objects.IntPin import IntSourcePin, VectorIntSinkPin
 
 class X86I8259CascadeMode(Enum):
     map = {'I8259Master' : 0,
@@ -41,10 +41,7 @@ class I8259(BasicPioDevice):
     type = 'I8259'
     cxx_class='X86ISA::I8259'
     cxx_header = "dev/x86/i8259.hh"
-    output = Param.X86IntSourcePin(X86IntSourcePin(),
-            'The pin this I8259 drives')
+    output = IntSourcePin('The pin this I8259 drives')
+    inputs = VectorIntSinkPin('The pins that drive this I8259')
     mode = Param.X86I8259CascadeMode('How this I8259 is cascaded')
     slave = Param.I8259(NULL, 'Slave I8259, if any')
-
-    def pin(self, line):
-        return X86IntSinkPin(device=self, number=line)
index 7029eb358d39c329e0254000f009be63605f6efe..80b432d624b80462208421ec86b6637b2be112b0 100644 (file)
@@ -36,7 +36,6 @@ from m5.objects.I8254 import I8254
 from m5.objects.I8259 import I8259
 from m5.objects.Ide import IdeController
 from m5.objects.PcSpeaker import PcSpeaker
-from m5.objects.X86IntPin import X86IntLine
 from m5.SimObject import SimObject
 
 def x86IOAddress(port):
@@ -87,17 +86,14 @@ class SouthBridge(SimObject):
     ide.LegacyIOBase = x86IOAddress(0)
 
     def attachIO(self, bus, dma_ports):
-        # Route interupt signals
-        self.int_lines = \
-          [X86IntLine(source=self.pic1.output, sink=self.io_apic.pin(0)),
-           X86IntLine(source=self.pic2.output, sink=self.pic1.pin(2)),
-           X86IntLine(source=self.cmos.int_pin, sink=self.pic2.pin(0)),
-           X86IntLine(source=self.pit.int_pin, sink=self.pic1.pin(0)),
-           X86IntLine(source=self.pit.int_pin, sink=self.io_apic.pin(2)),
-           X86IntLine(source=self.keyboard.keyboard_int_pin,
-                      sink=self.io_apic.pin(1)),
-           X86IntLine(source=self.keyboard.mouse_int_pin,
-                      sink=self.io_apic.pin(12))]
+        # Route interrupt signals
+        self.pic1.output = self.io_apic.inputs[0]
+        self.pic2.output = self.pic1.inputs[2]
+        self.cmos.int_pin = self.pic2.inputs[0]
+        self.pit.int_pin = self.pic1.inputs[0]
+        self.pit.int_pin = self.io_apic.inputs[2]
+        self.keyboard.keyboard_int_pin = self.io_apic.inputs[1]
+        self.keyboard.mouse_int_pin = self.io_apic.inputs[12]
         # Tell the devices about each other
         self.pic1.slave = self.pic2
         self.speaker.i8254 = self.pit
index 41009c6d116fa66cee86a3a02f3bec1ebd3aa8e2..ccfb279c218b742a8c672be59ee835f1875222e6 100644 (file)
 void
 X86ISA::Cmos::X86RTC::handleEvent()
 {
-    assert(intPin);
-    intPin->raise();
-    //XXX This is a hack.
-    intPin->lower();
+    for (auto *wire: intPin) {
+        wire->raise();
+        //XXX This is a hack.
+        wire->lower();
+    }
 }
 
 Tick
index 1a755be1a22070632c9eed61e35ff062ebcd1c84..2f662070d03e4f4e4adee3bd27710b831fa2d4f6 100644 (file)
@@ -31,6 +31,7 @@
 #ifndef __DEV_X86_CMOS_HH__
 #define __DEV_X86_CMOS_HH__
 
+#include "dev/intpin.hh"
 #include "dev/io_device.hh"
 #include "dev/mc146818.hh"
 #include "params/Cmos.hh"
@@ -38,8 +39,6 @@
 namespace X86ISA
 {
 
-class IntSourcePin;
-
 class Cmos : public BasicPioDevice
 {
   protected:
@@ -56,13 +55,17 @@ class Cmos : public BasicPioDevice
 
     class X86RTC : public MC146818
     {
-      protected:
-        IntSourcePin * intPin;
       public:
+        std::vector<::IntSourcePin<X86RTC> *> intPin;
+
         X86RTC(EventManager *em, const std::string &n, const struct tm time,
-                bool bcd, Tick frequency, IntSourcePin * _intPin) :
-            MC146818(em, n, time, bcd, frequency), intPin(_intPin)
+                bool bcd, Tick frequency, int int_pin_count) :
+            MC146818(em, n, time, bcd, frequency)
         {
+            for (int i = 0; i < int_pin_count; i++) {
+                intPin.push_back(new ::IntSourcePin<X86RTC>(
+                            csprintf("%s.int_pin[%d]", n, i), i, this));
+            }
         }
       protected:
         void handleEvent();
@@ -72,12 +75,22 @@ class Cmos : public BasicPioDevice
     typedef CmosParams Params;
 
     Cmos(const Params *p) : BasicPioDevice(p, 2), latency(p->pio_latency),
-        rtc(this, "rtc", p->time, true, ULL(5000000000), p->int_pin)
+        rtc(this, name() + ".rtc", p->time, true, ULL(5000000000),
+                p->port_int_pin_connection_count)
     {
         memset(regs, 0, numRegs * sizeof(uint8_t));
         address = 0;
     }
 
+    Port &
+    getPort(const std::string &if_name, PortID idx=InvalidPortID) override
+    {
+        if (if_name == "int_pin")
+            return *rtc.intPin.at(idx);
+        else
+            return BasicPioDevice::getPort(if_name, idx);
+    }
+
     Tick read(PacketPtr pkt) override;
 
     Tick write(PacketPtr pkt) override;
index 692f4afa0eec7d3bae7d3a0d7d8ade5186ed6f06..2211df85b8c5c03c06ab40768a2a0ec64e01a68c 100644 (file)
@@ -50,7 +50,6 @@ X86ISA::I8042::I8042(Params *p)
       latency(p->pio_latency),
       dataPort(p->data_port), commandPort(p->command_port),
       statusReg(0), commandByte(0), dataReg(0), lastCommand(NoCommand),
-      mouseIntPin(p->mouse_int_pin), keyboardIntPin(p->keyboard_int_pin),
       mouse(p->mouse), keyboard(p->keyboard)
 {
     fatal_if(!mouse, "The i8042 model requires a mouse instance");
@@ -63,6 +62,15 @@ X86ISA::I8042::I8042(Params *p)
     commandByte.convertScanCodes = 1;
     commandByte.passedSelfTest = 1;
     commandByte.keyboardFullInt = 1;
+
+    for (int i = 0; i < p->port_keyboard_int_pin_connection_count; i++) {
+        keyboardIntPin.push_back(new ::IntSourcePin<I8042>(
+                    csprintf("%s.keyboard_int_pin[%d]", name(), i), i, this));
+    }
+    for (int i = 0; i < p->port_mouse_int_pin_connection_count; i++) {
+        mouseIntPin.push_back(new ::IntSourcePin<I8042>(
+                    csprintf("%s.mouse_int_pin[%d]", name(), i), i, this));
+    }
 }
 
 
@@ -85,14 +93,18 @@ X86ISA::I8042::writeData(uint8_t newData, bool mouse)
     statusReg.mouseOutputFull = (mouse ? 1 : 0);
     if (!mouse && commandByte.keyboardFullInt) {
         DPRINTF(I8042, "Sending keyboard interrupt.\n");
-        keyboardIntPin->raise();
-        //This is a hack
-        keyboardIntPin->lower();
+        for (auto *wire: keyboardIntPin) {
+            wire->raise();
+            //This is a hack
+            wire->lower();
+        }
     } else if (mouse && commandByte.mouseFullInt) {
         DPRINTF(I8042, "Sending mouse interrupt.\n");
-        mouseIntPin->raise();
-        //This is a hack
-        mouseIntPin->lower();
+        for (auto *wire: mouseIntPin) {
+            wire->raise();
+            //This is a hack
+            wire->lower();
+        }
     }
 }
 
index 0f38da9ba0db4bbb7a88df3da8dc810931b236d4..5f62395ddd4129aca05126e9c0b8b597868765da 100644 (file)
 
 #include <deque>
 
+#include "dev/intpin.hh"
 #include "dev/io_device.hh"
 #include "dev/ps2/device.hh"
-#include "dev/x86/intdev.hh"
 #include "params/I8042.hh"
 
 namespace X86ISA
 {
 
-class IntPin;
-
 class I8042 : public BasicPioDevice
 {
   protected:
@@ -110,8 +108,8 @@ class I8042 : public BasicPioDevice
     static const uint16_t NoCommand = (uint16_t)(-1);
     uint16_t lastCommand;
 
-    IntSourcePin *mouseIntPin;
-    IntSourcePin *keyboardIntPin;
+    std::vector<::IntSourcePin<I8042> *> mouseIntPin;
+    std::vector<::IntSourcePin<I8042> *> keyboardIntPin;
 
     PS2Device *mouse;
     PS2Device *keyboard;
@@ -130,6 +128,17 @@ class I8042 : public BasicPioDevice
 
     I8042(Params *p);
 
+    Port &
+    getPort(const std::string &if_name, PortID idx=InvalidPortID) override
+    {
+        if (if_name == "mouse_int_pin")
+            return *mouseIntPin.at(idx);
+        else if (if_name == "keyboard_int_pin")
+            return *keyboardIntPin.at(idx);
+        else
+            return BasicPioDevice::getPort(if_name, idx);
+    }
+
     AddrRangeList getAddrRanges() const override;
 
     Tick read(PacketPtr pkt) override;
index fccc98469718e6179763d4eb08f9c6da12ea4a88..81f1c77eec607387a775a59c1540a7c554d5c98c 100644 (file)
@@ -57,6 +57,10 @@ X86ISA::I82094AA::I82094AA(Params *p)
         redirTable[i] = entry;
         pinStates[i] = false;
     }
+
+    for (int i = 0; i < p->port_inputs_connection_count; i++)
+        inputs.push_back(new ::IntSinkPin<I82094AA>(
+                    csprintf("%s.inputs[%d]", name(), i), i, this));
 }
 
 void
@@ -75,7 +79,10 @@ X86ISA::I82094AA::getPort(const std::string &if_name, PortID idx)
 {
     if (if_name == "int_master")
         return intMasterPort;
-    return BasicPioDevice::getPort(if_name, idx);
+    if (if_name == "inputs")
+        return *inputs.at(idx);
+    else
+        return BasicPioDevice::getPort(if_name, idx);
 }
 
 AddrRangeList
index d5cb42f79a3ff3716d92ec2b4768eab3566111c4..1c65fb310735441456153fb03926e24005f954f2 100644 (file)
@@ -35,6 +35,7 @@
 
 #include "base/bitunion.hh"
 #include "dev/x86/intdev.hh"
+#include "dev/intpin.hh"
 #include "dev/io_device.hh"
 #include "params/I82094AA.hh"
 
@@ -81,6 +82,8 @@ class I82094AA : public BasicPioDevice, public IntDevice
     RedirTableEntry redirTable[TableSize];
     bool pinStates[TableSize];
 
+    std::vector<::IntSinkPin<I82094AA> *> inputs;
+
   public:
     typedef I82094AAParams Params;
 
@@ -107,9 +110,9 @@ class I82094AA : public BasicPioDevice, public IntDevice
 
     Tick recvResponse(PacketPtr pkt) override;
 
-    void signalInterrupt(int line) override;
-    void raiseInterruptPin(int number) override;
-    void lowerInterruptPin(int number) override;
+    void signalInterrupt(int line);
+    void raiseInterruptPin(int number);
+    void lowerInterruptPin(int number);
 
     void serialize(CheckpointOut &cp) const override;
     void unserialize(CheckpointIn &cp) override;
index 1c2780ab6a2e3bc0aaa52b96ac27a7b325a77c8d..b6b639bd4123db385748b8309775f27bbd180467 100644 (file)
@@ -40,9 +40,11 @@ X86ISA::I8254::counterInterrupt(unsigned int num)
 {
     DPRINTF(I8254, "Interrupt from counter %d.\n", num);
     if (num == 0) {
-        intPin->raise();
-        //XXX This is a hack.
-        intPin->lower();
+        for (auto *wire: intPin) {
+            wire->raise();
+            //XXX This is a hack.
+            wire->lower();
+        }
     }
 }
 
index e1de8a1bbf9c5f1836682953061ab22cf642bc4e..70a18b47c8b25881577faa8a73413b13284339c2 100644 (file)
 #define __DEV_X86_I8254_HH__
 
 #include "dev/intel_8254_timer.hh"
+#include "dev/intpin.hh"
 #include "dev/io_device.hh"
 #include "params/I8254.hh"
 
 namespace X86ISA
 {
 
-class IntSourcePin;
-
 class I8254 : public BasicPioDevice
 {
   protected:
@@ -64,13 +63,22 @@ class I8254 : public BasicPioDevice
 
     X86Intel8254Timer pit;
 
-    IntSourcePin *intPin;
+    std::vector<::IntSourcePin<I8254> *> intPin;
 
     void counterInterrupt(unsigned int num);
 
   public:
     typedef I8254Params Params;
 
+    Port &
+    getPort(const std::string &if_name, PortID idx=InvalidPortID) override
+    {
+        if (if_name == "int_pin")
+            return *intPin.at(idx);
+        else
+            return BasicPioDevice::getPort(if_name, idx);
+    }
+
     const Params *
     params() const
     {
@@ -78,8 +86,12 @@ class I8254 : public BasicPioDevice
     }
 
     I8254(Params *p) : BasicPioDevice(p, 4), latency(p->pio_latency),
-            pit(p->name, this), intPin(p->int_pin)
+            pit(p->name, this)
     {
+        for (int i = 0; i < p->port_int_pin_connection_count; i++) {
+            intPin.push_back(new ::IntSourcePin<I8254>(csprintf(
+                            "%s.int_pin[%d]", name(), i), i, this));
+        }
     }
     Tick read(PacketPtr pkt) override;
 
index 4c3b9b272c59228772c441526e6ea38fc17644ef..06e3bf65938c965e2f0ba2a6d2f84e645c7eaa91 100644 (file)
 #include "mem/packet_access.hh"
 
 X86ISA::I8259::I8259(Params * p)
-    : BasicPioDevice(p, 2), IntDevice(this),
-      latency(p->pio_latency), output(p->output),
+    : BasicPioDevice(p, 2),
+      latency(p->pio_latency),
       mode(p->mode), slave(p->slave),
       IRR(0), ISR(0), IMR(0),
       readIRR(true), initControlWord(0), autoEOI(false)
 {
-    for (int i = 0; i < NumLines; i++)
-        pinStates[i] = false;
+    for (int i = 0; i < p->port_output_connection_count; i++) {
+        output.push_back(new ::IntSourcePin<I8259>(
+                    csprintf("%s.output[%d]", name(), i), i, this));
+    }
+
+    int in_count = p->port_inputs_connection_count;
+    panic_if(in_count >= NumLines,
+            "I8259 only supports 8 inputs, but there are %d.", in_count);
+    for (int i = 0; i < in_count; i++) {
+        inputs.push_back(new ::IntSinkPin<I8259>(
+                    csprintf("%s.inputs[%d]", name(), i), i, this));
+    }
+
+    for (bool &state: pinStates)
+        state = false;
+}
+
+void
+X86ISA::I8259::init()
+{
+    BasicPioDevice::init();
+
+    for (auto *input: inputs)
+        pinStates[input->getId()] = input->state();
 }
 
 Tick
@@ -231,11 +253,13 @@ void
 X86ISA::I8259::requestInterrupt(int line)
 {
     if (bits(ISR, 7, line) == 0) {
-        if (output) {
+        if (!output.empty()) {
             DPRINTF(I8259, "Propogating interrupt.\n");
-            output->raise();
-            //XXX This is a hack.
-            output->lower();
+            for (auto *wire: output) {
+                wire->raise();
+                //XXX This is a hack.
+                wire->lower();
+            }
         } else {
             warn("Received interrupt but didn't have "
                     "anyone to tell about it.\n");
index c443f7805f6eff26f4bf78ab60115ad575a18907..8cc12f0be2293a79b19b69adec37b06b7d3bde4e 100644 (file)
@@ -31,7 +31,7 @@
 #ifndef __DEV_X86_I8259_HH__
 #define __DEV_X86_I8259_HH__
 
-#include "dev/x86/intdev.hh"
+#include "dev/intpin.hh"
 #include "dev/io_device.hh"
 #include "enums/X86I8259CascadeMode.hh"
 #include "params/I8259.hh"
 namespace X86ISA
 {
 
-class I8259 : public BasicPioDevice, public IntDevice
+class I8259 : public BasicPioDevice
 {
   protected:
     static const int NumLines = 8;
     bool pinStates[NumLines];
 
+    void init() override;
+
     Tick latency;
-    IntSourcePin *output;
+    std::vector<::IntSourcePin<I8259> *> output;
+    std::vector<::IntSinkPin<I8259> *> inputs;
     Enums::X86I8259CascadeMode mode;
     I8259 * slave;
 
@@ -89,6 +92,17 @@ class I8259 : public BasicPioDevice, public IntDevice
 
     I8259(Params * p);
 
+    Port &
+    getPort(const std::string &if_name, PortID idx=InvalidPortID) override
+    {
+        if (if_name == "inputs")
+            return *inputs.at(idx);
+        else if (if_name == "output")
+            return *output.at(idx);
+        else
+            return BasicPioDevice::getPort(if_name, idx);
+    }
+
     Tick read(PacketPtr pkt) override;
     Tick write(PacketPtr pkt) override;
 
@@ -104,9 +118,9 @@ class I8259 : public BasicPioDevice, public IntDevice
         IMR = 0x00;
     }
 
-    void signalInterrupt(int line) override;
-    void raiseInterruptPin(int number) override;
-    void lowerInterruptPin(int number) override;
+    void signalInterrupt(int line);
+    void raiseInterruptPin(int number);
+    void lowerInterruptPin(int number);
     int getVector();
 
     void serialize(CheckpointOut &cp) const override;