Go to the documentation of this file.
36 #include "debug/I82094AA.hh"
44 lowestPriorityOffset(0),
45 intRequestPort(
name() +
".int_request", this, this,
p->int_latency)
51 assert(
p->apic_id < 0xff);
55 RedirTableEntry entry = 0;
62 for (
int i = 0;
i <
p->port_inputs_connection_count;
i++)
75 panic_if(!intRequestPort.isConnected(),
76 "Int port not connected to anything!");
82 if (if_name ==
"int_requestor")
83 return intRequestPort;
84 if (if_name ==
"inputs")
85 return *inputs.at(idx);
97 pkt->
setLE<uint32_t>(regSel);
100 pkt->
setLE<uint32_t>(readReg(regSel));
103 panic(
"Illegal read from I/O APIC.\n");
116 regSel = pkt->
getLE<uint32_t>();
119 writeReg(regSel, pkt->
getLE<uint32_t>());
122 panic(
"Illegal write to I/O APIC.\n");
132 id =
bits(value, 31, 24);
133 }
else if (
offset == 0x1) {
135 }
else if (
offset == 0x2) {
136 arbId =
bits(value, 31, 24);
137 }
else if (
offset >= 0x10 &&
offset <= (0x10 + TableSize * 2)) {
140 redirTable[
index].topDW = value;
141 redirTable[
index].topReserved = 0;
143 redirTable[
index].bottomDW = value;
144 redirTable[
index].bottomReserved = 0;
147 warn(
"Access to undefined I/O APIC register %#x.\n",
offset);
150 "Wrote %#x to I/O APIC register %#x .\n", value,
offset);
159 }
else if (
offset == 0x1) {
160 result = ((TableSize - 1) << 16) | APICVersion;
161 }
else if (
offset == 0x2) {
162 result = arbId << 24;
163 }
else if (
offset >= 0x10 &&
offset <= (0x10 + TableSize * 2)) {
166 result = redirTable[
index].topDW;
168 result = redirTable[
index].bottomDW;
171 warn(
"Access to undefined I/O APIC register %#x.\n",
offset);
174 "Read %#x from I/O APIC register %#x.\n", result,
offset);
182 assert(line < TableSize);
183 RedirTableEntry entry = redirTable[line];
188 TriggerIntMessage message = 0;
189 message.destination = entry.dest;
190 if (entry.deliveryMode == DeliveryMode::ExtInt) {
192 message.vector = extIntPic->getVector();
194 message.vector = entry.vector;
196 message.deliveryMode = entry.deliveryMode;
197 message.destMode = entry.destMode;
198 message.level = entry.polarity;
199 message.trigger = entry.trigger;
201 int numContexts = sys->threads.size();
202 if (message.destMode == 0) {
203 if (message.deliveryMode == DeliveryMode::LowestPriority) {
204 panic(
"Lowest priority delivery mode from the "
205 "IO APIC aren't supported in physical "
206 "destination mode.\n");
208 if (message.destination == 0xFF) {
209 for (
int i = 0;
i < numContexts;
i++) {
213 apics.push_back(message.destination);
216 for (
int i = 0;
i < numContexts;
i++) {
218 getCpuPtr()->getInterruptController(0);
219 auto *localApic =
dynamic_cast<Interrupts *
>(base_int);
221 message.destination) {
222 apics.push_back(localApic->getInitialApicId());
225 if (message.deliveryMode == DeliveryMode::LowestPriority &&
231 uint64_t modOffset = lowestPriorityOffset % apics.size();
232 lowestPriorityOffset++;
233 auto apicIt = apics.begin();
234 while (modOffset--) {
236 assert(apicIt != apics.end());
238 int selected = *apicIt;
240 apics.push_back(selected);
243 for (
auto id: apics) {
245 intRequestPort.sendMessage(pkt, sys->isTimingMode());
253 assert(number < TableSize);
254 if (!pinStates[number])
255 signalInterrupt(number);
256 pinStates[number] =
true;
262 assert(number < TableSize);
263 pinStates[number] =
false;
269 uint64_t* redirTableArray = (uint64_t*)redirTable;
282 uint64_t redirTableArray[TableSize];
290 for (
int i = 0;
i < TableSize;
i++) {
291 redirTable[
i] = (RedirTableEntry)redirTableArray[
i];
296 I82094AAParams::create()
void makeAtomicResponse()
#define UNSERIALIZE_SCALAR(scalar)
Tick read(PacketPtr pkt) override
Pure virtual function that the device must implement.
void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
uint64_t Tick
Tick count type.
int16_t PortID
Port index/ID type, and a symbolic name for an invalid port id.
void raiseInterruptPin(int number)
void writeReg(uint8_t offset, uint32_t value)
Port & getPort(const std::string &if_name, PortID idx=InvalidPortID) override
Get a port with a given name and index.
Ports are used to interface objects to each other.
void signalInterrupt(int line)
static const uint8_t TableSize
#define SERIALIZE_ARRAY(member, size)
Port & getPort(const std::string &if_name, PortID idx=InvalidPortID) override
Get a port with a given name and index.
RedirTableEntry redirTable[TableSize]
bool pinStates[TableSize]
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
const std::string & name()
#define SERIALIZE_SCALAR(scalar)
virtual const std::string name() const
Tick write(PacketPtr pkt) override
Pure virtual function that the device must implement.
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
T getLE() const
Get the data in the packet byte swapped from little endian to host endian.
static PacketPtr buildIntTriggerPacket(int id, TriggerIntMessage message)
#define UNSERIALIZE_ARRAY(member, size)
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
void setLE(T v)
Set the value in the data pointer to v as little endian.
EndBitUnion(RedirTableEntry) protected uint8_t regSel
std::ostream CheckpointOut
void serialize(CheckpointOut &cp) const override
Serialize an object.
std::vector< IntSinkPin< I82094AA > * > inputs
@ APIC_LOGICAL_DESTINATION
void unserialize(CheckpointIn &cp) override
Unserialize an object.
std::string csprintf(const char *format, const Args &...args)
void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
uint32_t readReg(uint8_t offset)
#define panic(...)
This implements a cprintf based panic() function.
void lowerInterruptPin(int number)
T bits(T val, int first, int last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it.
Generated on Wed Sep 30 2020 14:02:11 for gem5 by doxygen 1.8.17