X86: Make the CMOS and I8259 devices use IntDev and IntPin.
This commit is contained in:
parent
119e127d71
commit
539563e04b
7 changed files with 42 additions and 29 deletions
|
@ -29,7 +29,6 @@
|
||||||
from m5.params import *
|
from m5.params import *
|
||||||
from m5.proxy import *
|
from m5.proxy import *
|
||||||
from Device import BasicPioDevice
|
from Device import BasicPioDevice
|
||||||
from I8259 import I8259
|
|
||||||
|
|
||||||
class Cmos(BasicPioDevice):
|
class Cmos(BasicPioDevice):
|
||||||
type = 'Cmos'
|
type = 'Cmos'
|
||||||
|
@ -37,6 +36,4 @@ class Cmos(BasicPioDevice):
|
||||||
time = Param.Time('01/01/2009',
|
time = Param.Time('01/01/2009',
|
||||||
"System time to use ('Now' for actual time)")
|
"System time to use ('Now' for actual time)")
|
||||||
pio_latency = Param.Latency('1ns', "Programmed IO latency in simticks")
|
pio_latency = Param.Latency('1ns', "Programmed IO latency in simticks")
|
||||||
i8259 = Param.I8259('PIC to send RTC alarm interrupts to')
|
int_pin = Param.X86IntPin('Pin to signal RTC alarm interrupts to')
|
||||||
int_line = Param.Int(0,
|
|
||||||
'PIC relative interrupt line to use for alarm interrupts')
|
|
||||||
|
|
|
@ -29,9 +29,20 @@
|
||||||
from m5.params import *
|
from m5.params import *
|
||||||
from m5.proxy import *
|
from m5.proxy import *
|
||||||
from Device import BasicPioDevice
|
from Device import BasicPioDevice
|
||||||
|
from X86IntPin import X86IntPin
|
||||||
|
|
||||||
|
class X86I8259CascadeMode(Enum):
|
||||||
|
map = {'I8259Master' : 0,
|
||||||
|
'I8259Slave' : 1,
|
||||||
|
'I8259Single' : 2
|
||||||
|
}
|
||||||
|
|
||||||
class I8259(BasicPioDevice):
|
class I8259(BasicPioDevice):
|
||||||
type = 'I8259'
|
type = 'I8259'
|
||||||
cxx_class='X86ISA::I8259'
|
cxx_class='X86ISA::I8259'
|
||||||
pio_latency = Param.Latency('1ns', "Programmed IO latency in simticks")
|
pio_latency = Param.Latency('1ns', "Programmed IO latency in simticks")
|
||||||
master = Param.I8259('The master PIC this PIC is cascaded with, if any')
|
output = Param.X86IntPin('The pin this I8259 drives')
|
||||||
|
mode = Param.X86I8259CascadeMode('How this I8259 is cascaded')
|
||||||
|
|
||||||
|
def pin(self, line):
|
||||||
|
return X86IntPin(device=self, line=line)
|
||||||
|
|
|
@ -49,9 +49,10 @@ class PC(Platform):
|
||||||
pciconfig = PciConfigAll()
|
pciconfig = PciConfigAll()
|
||||||
|
|
||||||
south_bridge = SouthBridge()
|
south_bridge = SouthBridge()
|
||||||
pic1 = I8259(pio_addr=x86IOAddress(0x20))
|
pic1 = I8259(pio_addr=x86IOAddress(0x20), mode='I8259Master')
|
||||||
pic2 = I8259(pio_addr=x86IOAddress(0xA0), master=pic1)
|
pic2 = I8259(pio_addr=x86IOAddress(0xA0),
|
||||||
cmos = Cmos(pio_addr=x86IOAddress(0x70), i8259=pic2)
|
mode='I8259Slave', output=pic1.pin(2))
|
||||||
|
cmos = Cmos(pio_addr=x86IOAddress(0x70), int_pin=pic2.pin(0))
|
||||||
|
|
||||||
# "Non-existant" port used for timing purposes by the linux kernel
|
# "Non-existant" port used for timing purposes by the linux kernel
|
||||||
i_dont_exist = IsaFake(pio_addr=x86IOAddress(0x80), pio_size=1)
|
i_dont_exist = IsaFake(pio_addr=x86IOAddress(0x80), pio_size=1)
|
||||||
|
|
|
@ -29,13 +29,14 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "dev/x86/cmos.hh"
|
#include "dev/x86/cmos.hh"
|
||||||
#include "dev/x86/i8259.hh"
|
#include "dev/x86/intdev.hh"
|
||||||
#include "mem/packet_access.hh"
|
#include "mem/packet_access.hh"
|
||||||
|
|
||||||
void
|
void
|
||||||
X86ISA::Cmos::X86RTC::handleEvent()
|
X86ISA::Cmos::X86RTC::handleEvent()
|
||||||
{
|
{
|
||||||
i8259->signalInterrupt(intLine);
|
assert(intPin);
|
||||||
|
intPin->signalInterrupt();
|
||||||
}
|
}
|
||||||
|
|
||||||
Tick
|
Tick
|
||||||
|
|
|
@ -38,7 +38,7 @@
|
||||||
namespace X86ISA
|
namespace X86ISA
|
||||||
{
|
{
|
||||||
|
|
||||||
class I8259;
|
class IntPin;
|
||||||
|
|
||||||
class Cmos : public BasicPioDevice
|
class Cmos : public BasicPioDevice
|
||||||
{
|
{
|
||||||
|
@ -57,13 +57,11 @@ class Cmos : public BasicPioDevice
|
||||||
class X86RTC : public MC146818
|
class X86RTC : public MC146818
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
I8259 * i8259;
|
IntPin * intPin;
|
||||||
int intLine;
|
|
||||||
public:
|
public:
|
||||||
X86RTC(EventManager *em, const std::string &n, const struct tm time,
|
X86RTC(EventManager *em, const std::string &n, const struct tm time,
|
||||||
bool bcd, Tick frequency, I8259 *_i8259, int _intLine) :
|
bool bcd, Tick frequency, IntPin * _intPin) :
|
||||||
MC146818(em, n, time, bcd, frequency),
|
MC146818(em, n, time, bcd, frequency), intPin(_intPin)
|
||||||
i8259(_i8259), intLine(_intLine)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
protected:
|
protected:
|
||||||
|
@ -74,8 +72,7 @@ class Cmos : public BasicPioDevice
|
||||||
typedef CmosParams Params;
|
typedef CmosParams Params;
|
||||||
|
|
||||||
Cmos(const Params *p) : BasicPioDevice(p), latency(p->pio_latency),
|
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->int_pin)
|
||||||
p->i8259, p->int_line)
|
|
||||||
{
|
{
|
||||||
pioSize = 2;
|
pioSize = 2;
|
||||||
memset(regs, 0, numRegs * sizeof(uint8_t));
|
memset(regs, 0, numRegs * sizeof(uint8_t));
|
||||||
|
|
|
@ -139,7 +139,7 @@ X86ISA::I8259::write(PacketPtr pkt)
|
||||||
break;
|
break;
|
||||||
case 0x2:
|
case 0x2:
|
||||||
DPRINTF(I8259, "Received initialization command word 3.\n");
|
DPRINTF(I8259, "Received initialization command word 3.\n");
|
||||||
if (master == NULL) {
|
if (mode == Enums::I8259Master) {
|
||||||
DPRINTF(I8259, "Slaves attached to IRQs:%s%s%s%s%s%s%s%s\n",
|
DPRINTF(I8259, "Slaves attached to IRQs:%s%s%s%s%s%s%s%s\n",
|
||||||
bits(val, 0) ? " 0" : "",
|
bits(val, 0) ? " 0" : "",
|
||||||
bits(val, 1) ? " 1" : "",
|
bits(val, 1) ? " 1" : "",
|
||||||
|
@ -192,9 +192,14 @@ X86ISA::I8259::signalInterrupt(int line)
|
||||||
fatal("Line number %d doesn't exist. The max is 7.\n");
|
fatal("Line number %d doesn't exist. The max is 7.\n");
|
||||||
if (bits(IMR, line)) {
|
if (bits(IMR, line)) {
|
||||||
DPRINTF(I8259, "Interrupt %d was masked.\n", line);
|
DPRINTF(I8259, "Interrupt %d was masked.\n", line);
|
||||||
} else if (master != NULL) {
|
} else {
|
||||||
DPRINTF(I8259, "Propogating interrupt to master.\n");
|
if (output) {
|
||||||
master->signalInterrupt(cascadeBits);
|
DPRINTF(I8259, "Propogating interrupt.\n");
|
||||||
|
output->signalInterrupt();
|
||||||
|
} else {
|
||||||
|
warn("Received interrupt but didn't have "
|
||||||
|
"anyone to tell about it.\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,16 +32,19 @@
|
||||||
#define __DEV_X86_I8259_HH__
|
#define __DEV_X86_I8259_HH__
|
||||||
|
|
||||||
#include "dev/io_device.hh"
|
#include "dev/io_device.hh"
|
||||||
|
#include "dev/x86/intdev.hh"
|
||||||
#include "params/I8259.hh"
|
#include "params/I8259.hh"
|
||||||
|
#include "enums/X86I8259CascadeMode.hh"
|
||||||
|
|
||||||
namespace X86ISA
|
namespace X86ISA
|
||||||
{
|
{
|
||||||
|
|
||||||
class I8259 : public BasicPioDevice
|
class I8259 : public BasicPioDevice, public IntDev
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
Tick latency;
|
Tick latency;
|
||||||
I8259 *master;
|
IntPin *output;
|
||||||
|
Enums::X86I8259CascadeMode mode;
|
||||||
|
|
||||||
// Interrupt Request Register
|
// Interrupt Request Register
|
||||||
uint8_t IRR;
|
uint8_t IRR;
|
||||||
|
@ -71,13 +74,11 @@ class I8259 : public BasicPioDevice
|
||||||
return dynamic_cast<const Params *>(_params);
|
return dynamic_cast<const Params *>(_params);
|
||||||
}
|
}
|
||||||
|
|
||||||
I8259(Params * p) : BasicPioDevice(p)
|
I8259(Params * p) : BasicPioDevice(p), latency(p->pio_latency),
|
||||||
|
output(p->output), mode(p->mode), readIRR(true),
|
||||||
|
initControlWord(0)
|
||||||
{
|
{
|
||||||
pioSize = 2;
|
pioSize = 2;
|
||||||
initControlWord = 0;
|
|
||||||
readIRR = true;
|
|
||||||
latency = p->pio_latency;
|
|
||||||
master = p->master;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Tick read(PacketPtr pkt);
|
Tick read(PacketPtr pkt);
|
||||||
|
|
Loading…
Reference in a new issue