diff options
Diffstat (limited to 'src/dev')
-rw-r--r-- | src/dev/x86/Cmos.py | 4 | ||||
-rw-r--r-- | src/dev/x86/I8259.py | 2 | ||||
-rw-r--r-- | src/dev/x86/PC.py | 6 | ||||
-rw-r--r-- | src/dev/x86/cmos.cc | 7 | ||||
-rw-r--r-- | src/dev/x86/cmos.hh | 18 | ||||
-rw-r--r-- | src/dev/x86/i8259.cc | 19 | ||||
-rw-r--r-- | src/dev/x86/i8259.hh | 14 |
7 files changed, 55 insertions, 15 deletions
diff --git a/src/dev/x86/Cmos.py b/src/dev/x86/Cmos.py index c786eda36..810432035 100644 --- a/src/dev/x86/Cmos.py +++ b/src/dev/x86/Cmos.py @@ -29,6 +29,7 @@ from m5.params import * from m5.proxy import * from Device import BasicPioDevice +from I8259 import I8259 class Cmos(BasicPioDevice): type = 'Cmos' @@ -36,3 +37,6 @@ class Cmos(BasicPioDevice): time = Param.Time('01/01/2009', "System time to use ('Now' for actual time)") pio_latency = Param.Latency('1ns', "Programmed IO latency in simticks") + i8259 = Param.I8259('PIC to send RTC alarm interrupts to') + int_line = Param.Int(0, + 'PIC relative interrupt line to use for alarm interrupts') diff --git a/src/dev/x86/I8259.py b/src/dev/x86/I8259.py index a599a5b3c..19670dde9 100644 --- a/src/dev/x86/I8259.py +++ b/src/dev/x86/I8259.py @@ -34,4 +34,4 @@ class I8259(BasicPioDevice): type = 'I8259' cxx_class='X86ISA::I8259' pio_latency = Param.Latency('1ns', "Programmed IO latency in simticks") - master = Param.Bool(True, 'If this PIC is the master or slave') + master = Param.I8259('The master PIC this PIC is cascaded with, if any') diff --git a/src/dev/x86/PC.py b/src/dev/x86/PC.py index d0516ec13..d3d3118c6 100644 --- a/src/dev/x86/PC.py +++ b/src/dev/x86/PC.py @@ -49,9 +49,9 @@ class PC(Platform): pciconfig = PciConfigAll() south_bridge = SouthBridge() - cmos = Cmos(pio_addr=x86IOAddress(0x70)) - pic1 = I8259(pio_addr=x86IOAddress(0x20), master=True) - pic2 = I8259(pio_addr=x86IOAddress(0xA0), master=False) + pic1 = I8259(pio_addr=x86IOAddress(0x20)) + pic2 = I8259(pio_addr=x86IOAddress(0xA0), master=pic1) + cmos = Cmos(pio_addr=x86IOAddress(0x70), i8259=pic2) # "Non-existant" port used for timing purposes by the linux kernel i_dont_exist = IsaFake(pio_addr=x86IOAddress(0x80), pio_size=1) diff --git a/src/dev/x86/cmos.cc b/src/dev/x86/cmos.cc index 5bbded260..d4ec58ddb 100644 --- a/src/dev/x86/cmos.cc +++ b/src/dev/x86/cmos.cc @@ -29,8 +29,15 @@ */ #include "dev/x86/cmos.hh" +#include "dev/x86/i8259.hh" #include "mem/packet_access.hh" +void +X86ISA::Cmos::X86RTC::handleEvent() +{ + i8259->signalInterrupt(intLine); +} + Tick X86ISA::Cmos::read(PacketPtr pkt) { diff --git a/src/dev/x86/cmos.hh b/src/dev/x86/cmos.hh index 04df9dd04..337fb8b02 100644 --- a/src/dev/x86/cmos.hh +++ b/src/dev/x86/cmos.hh @@ -38,6 +38,8 @@ namespace X86ISA { +class I8259; + class Cmos : public BasicPioDevice { protected: @@ -54,24 +56,26 @@ class Cmos : public BasicPioDevice class X86RTC : public MC146818 { + protected: + I8259 * i8259; + int intLine; public: X86RTC(EventManager *em, const std::string &n, const struct tm time, - bool bcd, Tick frequency) : - MC146818(em, n, time, bcd, frequency) + bool bcd, Tick frequency, I8259 *_i8259, int _intLine) : + MC146818(em, n, time, bcd, frequency), + i8259(_i8259), intLine(_intLine) { } protected: - void handleEvent() - { - return; - } + void handleEvent(); } rtc; public: typedef CmosParams Params; Cmos(const Params *p) : BasicPioDevice(p), latency(p->pio_latency), - rtc(this, "rtc", p->time, true, ULL(5000000000)) + rtc(this, "rtc", p->time, true, ULL(5000000000), + p->i8259, p->int_line) { pioSize = 2; memset(regs, 0, numRegs * sizeof(uint8_t)); diff --git a/src/dev/x86/i8259.cc b/src/dev/x86/i8259.cc index ed9b429c8..2dd6caaff 100644 --- a/src/dev/x86/i8259.cc +++ b/src/dev/x86/i8259.cc @@ -133,12 +133,13 @@ X86ISA::I8259::write(PacketPtr pkt) if (cascadeMode) { initControlWord++; } else { + cascadeBits = 0; initControlWord = 0; } break; case 0x2: DPRINTF(I8259, "Received initialization command word 3.\n"); - if (master) { + if (master == NULL) { DPRINTF(I8259, "Slaves attached to IRQs:%s%s%s%s%s%s%s%s\n", bits(val, 0) ? " 0" : "", bits(val, 1) ? " 1" : "", @@ -148,8 +149,10 @@ X86ISA::I8259::write(PacketPtr pkt) bits(val, 5) ? " 5" : "", bits(val, 6) ? " 6" : "", bits(val, 7) ? " 7" : ""); + cascadeBits = val; } else { DPRINTF(I8259, "Slave ID is %d.\n", val & mask(3)); + cascadeBits = val & mask(3); } if (expectICW4) initControlWord++; @@ -181,6 +184,20 @@ X86ISA::I8259::write(PacketPtr pkt) return latency; } +void +X86ISA::I8259::signalInterrupt(int line) +{ + DPRINTF(I8259, "Interrupt raised on line %d.\n", line); + if (line > 7) + fatal("Line number %d doesn't exist. The max is 7.\n"); + if (bits(IMR, line)) { + DPRINTF(I8259, "Interrupt %d was masked.\n", line); + } else if (master != NULL) { + DPRINTF(I8259, "Propogating interrupt to master.\n"); + master->signalInterrupt(cascadeBits); + } +} + X86ISA::I8259 * I8259Params::create() { diff --git a/src/dev/x86/i8259.hh b/src/dev/x86/i8259.hh index 131adc93f..c51ab1a6a 100644 --- a/src/dev/x86/i8259.hh +++ b/src/dev/x86/i8259.hh @@ -41,7 +41,7 @@ class I8259 : public BasicPioDevice { protected: Tick latency; - bool master; + I8259 *master; // Interrupt Request Register uint8_t IRR; @@ -50,10 +50,16 @@ class I8259 : public BasicPioDevice // Interrupt Mask Register uint8_t IMR; - bool edgeTriggered; bool cascadeMode; - bool expectICW4; + // A bit vector of lines with slaves attached, or the slave id, depending + // on if this is a master or slave PIC. + uint8_t cascadeBits; + + bool edgeTriggered; bool readIRR; + + // State machine information for reading in initialization control words. + bool expectICW4; int initControlWord; public: @@ -77,6 +83,8 @@ class I8259 : public BasicPioDevice Tick read(PacketPtr pkt); Tick write(PacketPtr pkt); + + void signalInterrupt(int line); }; }; // namespace X86ISA |