36 #include "debug/I82094AA.hh"
44 extIntPic(p->external_int_pic), lowestPriorityOffset(0)
50 assert(p->apic_id < 0xff);
54 RedirTableEntry entry = 0;
76 if (if_name ==
"int_master")
107 pkt->
set<uint32_t>(regSel);
110 pkt->
set<uint32_t>(readReg(regSel));
113 panic(
"Illegal read from I/O APIC.\n");
126 regSel = pkt->
get<uint32_t>();
129 writeReg(regSel, pkt->
get<uint32_t>());
132 panic(
"Illegal write to I/O APIC.\n");
142 id =
bits(value, 31, 24);
143 }
else if (offset == 0x1) {
145 }
else if (offset == 0x2) {
146 arbId =
bits(value, 31, 24);
147 }
else if (offset >= 0x10 && offset <= (0x10 + TableSize * 2)) {
148 int index = (offset - 0x10) / 2;
150 redirTable[
index].topDW = value;
151 redirTable[
index].topReserved = 0;
153 redirTable[
index].bottomDW = value;
154 redirTable[
index].bottomReserved = 0;
157 warn(
"Access to undefined I/O APIC register %#x.\n", offset);
160 "Wrote %#x to I/O APIC register %#x .\n", value, offset);
169 }
else if (offset == 0x1) {
170 result = ((TableSize - 1) << 16) | APICVersion;
171 }
else if (offset == 0x2) {
172 result = arbId << 24;
173 }
else if (offset >= 0x10 && offset <= (0x10 + TableSize * 2)) {
174 int index = (offset - 0x10) / 2;
176 result = redirTable[
index].topDW;
178 result = redirTable[
index].bottomDW;
181 warn(
"Access to undefined I/O APIC register %#x.\n", offset);
184 "Read %#x from I/O APIC register %#x.\n", result, offset);
192 assert(line < TableSize);
193 RedirTableEntry entry = redirTable[line];
198 TriggerIntMessage message = 0;
199 message.destination = entry.dest;
200 if (entry.deliveryMode == DeliveryMode::ExtInt) {
202 message.vector = extIntPic->getVector();
204 message.vector = entry.vector;
206 message.deliveryMode = entry.deliveryMode;
207 message.destMode = entry.destMode;
208 message.level = entry.polarity;
209 message.trigger = entry.trigger;
211 int numContexts = sys->numContexts();
212 if (message.destMode == 0) {
213 if (message.deliveryMode == DeliveryMode::LowestPriority) {
214 panic(
"Lowest priority delivery mode from the "
215 "IO APIC aren't supported in physical "
216 "destination mode.\n");
218 if (message.destination == 0xFF) {
219 for (
int i = 0;
i < numContexts;
i++) {
223 apics.push_back(message.destination);
226 for (
int i = 0;
i < numContexts;
i++) {
228 getCpuPtr()->getInterruptController(0);
230 message.destination) {
234 if (message.deliveryMode == DeliveryMode::LowestPriority &&
240 uint64_t modOffset = lowestPriorityOffset % apics.size();
241 lowestPriorityOffset++;
242 ApicList::iterator apicIt = apics.begin();
243 while (modOffset--) {
245 assert(apicIt != apics.end());
247 int selected = *apicIt;
249 apics.push_back(selected);
252 intMasterPort.sendMessage(apics, message, sys->isTimingMode());
259 assert(number < TableSize);
260 if (!pinStates[number])
261 signalInterrupt(number);
262 pinStates[number] =
true;
268 assert(number < TableSize);
269 pinStates[number] =
false;
275 uint64_t* redirTableArray = (uint64_t*)redirTable;
288 uint64_t redirTableArray[TableSize];
296 for (
int i = 0;
i < TableSize;
i++) {
297 redirTable[
i] = (RedirTableEntry)redirTableArray[
i];
302 I82094AAParams::create()
void set(T v, ByteOrder endian)
Set the value in the data pointer to v using the specified endianness.
bool pinStates[TableSize]
void lowerInterruptPin(int number) override
uint32_t readReg(ApicRegIndex miscReg)
Tick write(PacketPtr pkt) override
Pure virtual function that the device must implement.
BaseMasterPort & getMasterPort(const std::string &if_name, PortID idx=InvalidPortID) override
Get a master port with a given name and index.
Tick recvResponse(PacketPtr pkt) override
T get(ByteOrder endian) const
Get the data in the packet byte swapped from the specified endianness.
static const uint8_t TableSize
#define UNSERIALIZE_SCALAR(scalar)
void serialize(CheckpointOut &cp) const override
Serialize an object.
const Addr PhysAddrAPICRangeSize
void raiseInterruptPin(int number) override
static Addr x86InterruptAddress(const uint8_t id, const uint16_t addr)
uint32_t readReg(uint8_t offset)
void makeAtomicResponse()
uint64_t Tick
Tick count type.
#define SERIALIZE_ARRAY(member, size)
const RequestPtr req
A pointer to the original request.
Tick read(PacketPtr pkt) override
Pure virtual function that the device must implement.
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
A Packet is used to encapsulate a transfer between two objects in the memory system (e...
void writeReg(uint8_t offset, uint32_t value)
#define SERIALIZE_SCALAR(scalar)
EndBitUnion(RedirTableEntry) protected uint8_t regSel
#define UNSERIALIZE_ARRAY(member, size)
AddrRange RangeEx(Addr start, Addr end)
AddrRangeList getIntAddrRange() const override
virtual void init()
init() is called after all C++ SimObjects have been created and all ports are connected.
Declaration of the Packet class.
std::ostream CheckpointOut
A BaseMasterPort is a protocol-agnostic master port, responsible only for the structural connection t...
void unserialize(CheckpointIn &cp) override
Unserialize an object.
RedirTableEntry redirTable[TableSize]
int16_t PortID
Port index/ID type, and a symbolic name for an invalid port id.
void signalInterrupt(int line) override
T bits(T val, int first, int last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it...
virtual BaseMasterPort & getMasterPort(const std::string &if_name, PortID idx=InvalidPortID)
Get a master port with a given name and index.