From ab376064bdfa9796eebad5ee8d84c766e7a30bd6 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 6 Sep 2019 15:22:22 -0700 Subject: [PATCH] dev, x86: Convert x86 devices to the generic int pins. Change-Id: I4551ad00cf205c31555c90b53e87bc206a8d8729 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/20701 Reviewed-by: Gabe Black Maintainer: Gabe Black Tested-by: kokoro --- src/dev/x86/Cmos.py | 5 ++--- src/dev/x86/I8042.py | 8 +++----- src/dev/x86/I82094AA.py | 5 ++--- src/dev/x86/I8254.py | 5 ++--- src/dev/x86/I8259.py | 9 +++------ src/dev/x86/SouthBridge.py | 20 ++++++++----------- src/dev/x86/cmos.cc | 9 +++++---- src/dev/x86/cmos.hh | 27 ++++++++++++++++++------- src/dev/x86/i8042.cc | 26 ++++++++++++++++++------- src/dev/x86/i8042.hh | 19 +++++++++++++----- src/dev/x86/i82094aa.cc | 9 ++++++++- src/dev/x86/i82094aa.hh | 9 ++++++--- src/dev/x86/i8254.cc | 8 +++++--- src/dev/x86/i8254.hh | 20 +++++++++++++++---- src/dev/x86/i8259.cc | 40 ++++++++++++++++++++++++++++++-------- src/dev/x86/i8259.hh | 26 +++++++++++++++++++------ 16 files changed, 165 insertions(+), 80 deletions(-) diff --git a/src/dev/x86/Cmos.py b/src/dev/x86/Cmos.py index 9bc395cb2..e5d2d6d34 100644 --- a/src/dev/x86/Cmos.py +++ b/src/dev/x86/Cmos.py @@ -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') diff --git a/src/dev/x86/I8042.py b/src/dev/x86/I8042.py index 5615d3e9f..44a1e011f 100644 --- a/src/dev/x86/I8042.py +++ b/src/dev/x86/I8042.py @@ -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") diff --git a/src/dev/x86/I82094AA.py b/src/dev/x86/I82094AA.py index d848904f0..3336e4442 100644 --- a/src/dev/x86/I82094AA.py +++ b/src/dev/x86/I82094AA.py @@ -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') diff --git a/src/dev/x86/I8254.py b/src/dev/x86/I8254.py index f0a6b2222..781609f24 100644 --- a/src/dev/x86/I8254.py +++ b/src/dev/x86/I8254.py @@ -29,11 +29,10 @@ 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') diff --git a/src/dev/x86/I8259.py b/src/dev/x86/I8259.py index 7066cb846..ef2733a9a 100644 --- a/src/dev/x86/I8259.py +++ b/src/dev/x86/I8259.py @@ -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) diff --git a/src/dev/x86/SouthBridge.py b/src/dev/x86/SouthBridge.py index 7029eb358..80b432d62 100644 --- a/src/dev/x86/SouthBridge.py +++ b/src/dev/x86/SouthBridge.py @@ -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 diff --git a/src/dev/x86/cmos.cc b/src/dev/x86/cmos.cc index 41009c6d1..ccfb279c2 100644 --- a/src/dev/x86/cmos.cc +++ b/src/dev/x86/cmos.cc @@ -37,10 +37,11 @@ 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 diff --git a/src/dev/x86/cmos.hh b/src/dev/x86/cmos.hh index 1a755be1a..2f662070d 100644 --- a/src/dev/x86/cmos.hh +++ b/src/dev/x86/cmos.hh @@ -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 *> 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( + 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; diff --git a/src/dev/x86/i8042.cc b/src/dev/x86/i8042.cc index 692f4afa0..2211df85b 100644 --- a/src/dev/x86/i8042.cc +++ b/src/dev/x86/i8042.cc @@ -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( + 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( + 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(); + } } } diff --git a/src/dev/x86/i8042.hh b/src/dev/x86/i8042.hh index 0f38da9ba..5f62395dd 100644 --- a/src/dev/x86/i8042.hh +++ b/src/dev/x86/i8042.hh @@ -33,16 +33,14 @@ #include +#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 *> mouseIntPin; + std::vector<::IntSourcePin *> 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; diff --git a/src/dev/x86/i82094aa.cc b/src/dev/x86/i82094aa.cc index fccc98469..81f1c77ee 100644 --- a/src/dev/x86/i82094aa.cc +++ b/src/dev/x86/i82094aa.cc @@ -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( + 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 diff --git a/src/dev/x86/i82094aa.hh b/src/dev/x86/i82094aa.hh index d5cb42f79..1c65fb310 100644 --- a/src/dev/x86/i82094aa.hh +++ b/src/dev/x86/i82094aa.hh @@ -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 *> 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; diff --git a/src/dev/x86/i8254.cc b/src/dev/x86/i8254.cc index 1c2780ab6..b6b639bd4 100644 --- a/src/dev/x86/i8254.cc +++ b/src/dev/x86/i8254.cc @@ -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(); + } } } diff --git a/src/dev/x86/i8254.hh b/src/dev/x86/i8254.hh index e1de8a1bb..70a18b47c 100644 --- a/src/dev/x86/i8254.hh +++ b/src/dev/x86/i8254.hh @@ -32,14 +32,13 @@ #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 *> 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(csprintf( + "%s.int_pin[%d]", name(), i), i, this)); + } } Tick read(PacketPtr pkt) override; diff --git a/src/dev/x86/i8259.cc b/src/dev/x86/i8259.cc index 4c3b9b272..06e3bf659 100644 --- a/src/dev/x86/i8259.cc +++ b/src/dev/x86/i8259.cc @@ -37,14 +37,36 @@ #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( + 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( + 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"); diff --git a/src/dev/x86/i8259.hh b/src/dev/x86/i8259.hh index c443f7805..8cc12f0be 100644 --- a/src/dev/x86/i8259.hh +++ b/src/dev/x86/i8259.hh @@ -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" @@ -39,14 +39,17 @@ 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 *> output; + std::vector<::IntSinkPin *> 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; -- 2.30.2