diff --git a/src/arch/x86/x86_traits.hh b/src/arch/x86/x86_traits.hh index 9e9882063b..e4a639277c 100644 --- a/src/arch/x86/x86_traits.hh +++ b/src/arch/x86/x86_traits.hh @@ -72,6 +72,9 @@ namespace X86ISA // accesses from the CPU, and the other is for all APICs to communicate. const Addr PhysAddrAPICRangeSize = 1 << 12; + // Put this in an unused part of the 16 bit IO port address space. + const Addr PhysAddrIntA = 0x8000000100000000ULL; + static inline Addr x86IOAddress(const uint32_t port) { diff --git a/src/dev/x86/i8259.cc b/src/dev/x86/i8259.cc index bd6d18c814..c78e12967f 100644 --- a/src/dev/x86/i8259.cc +++ b/src/dev/x86/i8259.cc @@ -28,6 +28,7 @@ #include "dev/x86/i8259.hh" +#include "arch/x86/x86_traits.hh" #include "base/bitfield.hh" #include "base/trace.hh" #include "debug/I8259.hh" @@ -62,6 +63,17 @@ X86ISA::I8259::I8259(const Params &p) state = false; } +AddrRangeList +X86ISA::I8259::getAddrRanges() const +{ + AddrRangeList ranges = BasicPioDevice::getAddrRanges(); + if (mode == enums::I8259Master || mode == enums::I8259Single) { + // Listen for INTA messages. + ranges.push_back(RangeSize(PhysAddrIntA, 1)); + } + return ranges; +} + void X86ISA::I8259::init() { @@ -75,8 +87,11 @@ Tick X86ISA::I8259::read(PacketPtr pkt) { assert(pkt->getSize() == 1); - switch(pkt->getAddr() - pioAddr) - { + if (pkt->getAddr() == PhysAddrIntA) { + assert(mode == enums::I8259Master || mode == enums::I8259Single); + pkt->setLE(getVector()); + } + switch(pkt->getAddr() - pioAddr) { case 0x0: if (readIRR) { DPRINTF(I8259, "Reading IRR as %#x.\n", IRR); diff --git a/src/dev/x86/i8259.hh b/src/dev/x86/i8259.hh index dcc59875cc..afd4894532 100644 --- a/src/dev/x86/i8259.hh +++ b/src/dev/x86/i8259.hh @@ -99,6 +99,8 @@ class I8259 : public BasicPioDevice return BasicPioDevice::getPort(if_name, idx); } + AddrRangeList getAddrRanges() const override; + Tick read(PacketPtr pkt) override; Tick write(PacketPtr pkt) override;