36 #include "debug/I82094AA.hh"
47 intRequestPort(
name() +
".int_request", this, this,
p.int_latency)
53 assert(
p.apic_id < 0xff);
57 RedirTableEntry entry = 0;
64 for (
int i = 0;
i <
p.port_inputs_connection_count;
i++)
77 panic_if(!intRequestPort.isConnected(),
78 "Int port not connected to anything!");
84 if (if_name ==
"int_requestor")
85 return intRequestPort;
86 if (if_name ==
"inputs")
87 return *inputs.at(idx);
99 pkt->
setLE<uint32_t>(regSel);
102 pkt->
setLE<uint32_t>(readReg(regSel));
105 panic(
"Illegal read from I/O APIC.\n");
118 regSel = pkt->
getLE<uint32_t>();
121 writeReg(regSel, pkt->
getLE<uint32_t>());
124 panic(
"Illegal write to I/O APIC.\n");
134 id =
bits(value, 31, 24);
135 }
else if (
offset == 0x1) {
137 }
else if (
offset == 0x2) {
138 arbId =
bits(value, 31, 24);
139 }
else if (
offset >= 0x10 &&
offset <= (0x10 + TableSize * 2)) {
142 redirTable[
index].topDW = value;
143 redirTable[
index].topReserved = 0;
145 redirTable[
index].bottomDW = value;
146 redirTable[
index].bottomReserved = 0;
149 warn(
"Access to undefined I/O APIC register %#x.\n",
offset);
152 "Wrote %#x to I/O APIC register %#x .\n", value,
offset);
161 }
else if (
offset == 0x1) {
162 result = ((TableSize - 1) << 16) | APICVersion;
163 }
else if (
offset == 0x2) {
164 result = arbId << 24;
165 }
else if (
offset >= 0x10 &&
offset <= (0x10 + TableSize * 2)) {
168 result = redirTable[
index].topDW;
170 result = redirTable[
index].bottomDW;
173 warn(
"Access to undefined I/O APIC register %#x.\n",
offset);
176 "Read %#x from I/O APIC register %#x.\n", result,
offset);
184 assert(line < TableSize);
185 RedirTableEntry entry = redirTable[line];
191 TriggerIntMessage message = 0;
193 message.destination = entry.dest;
194 message.deliveryMode = entry.deliveryMode;
195 message.destMode = entry.destMode;
196 message.level = entry.polarity;
197 message.trigger = entry.trigger;
199 if (entry.deliveryMode == delivery_mode::ExtInt) {
202 auto on_completion = [
this, message](
PacketPtr pkt) {
203 auto msg_copy = message;
204 msg_copy.vector = pkt->
getLE<uint8_t>();
205 signalInterrupt(msg_copy);
208 intRequestPort.sendMessage(pkt, sys->isTimingMode(),
211 message.vector = entry.vector;
212 signalInterrupt(message);
220 int numContexts = sys->threads.size();
221 if (message.destMode == 0) {
222 if (message.deliveryMode == delivery_mode::LowestPriority) {
223 panic(
"Lowest priority delivery mode from the "
224 "IO APIC aren't supported in physical "
225 "destination mode.\n");
227 if (message.destination == 0xFF) {
228 for (
int i = 0;
i < numContexts;
i++) {
232 apics.push_back(message.destination);
235 for (
int i = 0;
i < numContexts;
i++) {
237 getCpuPtr()->getInterruptController(0);
238 auto *localApic =
dynamic_cast<Interrupts *
>(base_int);
240 message.destination) {
241 apics.push_back(localApic->getInitialApicId());
244 if (message.deliveryMode == delivery_mode::LowestPriority &&
250 uint64_t modOffset = lowestPriorityOffset % apics.size();
251 lowestPriorityOffset++;
252 auto apicIt = apics.begin();
253 while (modOffset--) {
255 assert(apicIt != apics.end());
257 int selected = *apicIt;
259 apics.push_back(selected);
262 for (
auto id: apics) {
264 intRequestPort.sendMessage(pkt, sys->isTimingMode());
271 assert(number < TableSize);
272 if (!pinStates[number])
273 requestInterrupt(number);
274 pinStates[number] =
true;
280 assert(number < TableSize);
281 pinStates[number] =
false;
287 uint64_t* redirTableArray = (uint64_t*)redirTable;
300 uint64_t redirTableArray[TableSize];
308 for (
int i = 0;
i < TableSize;
i++) {
309 redirTable[
i] = (RedirTableEntry)redirTableArray[
i];