summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/dev/x86/Cmos.py4
-rw-r--r--src/dev/x86/I8259.py2
-rw-r--r--src/dev/x86/PC.py6
-rw-r--r--src/dev/x86/cmos.cc7
-rw-r--r--src/dev/x86/cmos.hh18
-rw-r--r--src/dev/x86/i8259.cc19
-rw-r--r--src/dev/x86/i8259.hh14
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