1/* 2 * Copyright (c) 2008 The Hewlett-Packard Development Company 3 * All rights reserved. 4 * 5 * Redistribution and use of this software in source and binary forms, 6 * with or without modification, are permitted provided that the 7 * following conditions are met: 8 * --- 226 unchanged lines hidden (view full) --- 235 uint32_t val = regs[reg]; 236 pkt->writeData(((uint8_t *)&val) + (offset & mask(3))); 237 DPRINTF(LocalApic, 238 "Writing Local APIC register %d at offset %#x as %#x.\n", 239 reg, offset, gtoh(val)); 240 setReg(reg, gtoh(val)); 241 return latency; 242} |
243void 244X86ISA::Interrupts::requestInterrupt(uint8_t vector, 245 uint8_t deliveryMode, bool level) 246{ 247 /* 248 * Fixed and lowest-priority delivery mode interrupts are handled 249 * using the IRR/ISR registers, checking against the TPR, etc. 250 * The SMI, NMI, ExtInt, INIT, etc interrupts go straight through. 251 */ 252 if (deliveryMode == DeliveryMode::Fixed || 253 deliveryMode == DeliveryMode::LowestPriority) { 254 DPRINTF(LocalApic, "Interrupt is an %s.\n", 255 DeliveryMode::names[deliveryMode]); 256 // Queue up the interrupt in the IRR. 257 if (vector > IRRV) 258 IRRV = vector; 259 if (!getRegArrayBit(APIC_INTERRUPT_REQUEST_BASE, vector)) { 260 setRegArrayBit(APIC_INTERRUPT_REQUEST_BASE, vector); 261 if (level) { 262 setRegArrayBit(APIC_TRIGGER_MODE_BASE, vector); 263 } else { 264 clearRegArrayBit(APIC_TRIGGER_MODE_BASE, vector); 265 } 266 } 267 } else if (!DeliveryMode::isReserved(deliveryMode)) { 268 DPRINTF(LocalApic, "Interrupt is an %s.\n", 269 DeliveryMode::names[deliveryMode]); 270 if (deliveryMode == DeliveryMode::SMI && !pendingSmi) { 271 pendingUnmaskableInt = pendingSmi = true; 272 smiVector = vector; 273 } else if (deliveryMode == DeliveryMode::NMI && !pendingNmi) { 274 pendingUnmaskableInt = pendingNmi = true; 275 nmiVector = vector; 276 } else if (deliveryMode == DeliveryMode::ExtInt && !pendingExtInt) { 277 pendingExtInt = true; 278 extIntVector = vector; 279 } else if (deliveryMode == DeliveryMode::INIT && !pendingInit) { 280 pendingUnmaskableInt = pendingInit = true; 281 initVector = vector; 282 } 283 } 284} |
285 286Tick 287X86ISA::Interrupts::recvMessage(PacketPtr pkt) 288{ 289 uint8_t id = 0; 290 Addr offset = pkt->getAddr() - x86InterruptAddress(id, 0); 291 assert(pkt->cmd == MemCmd::MessageReq); 292 switch(offset) --- 4 unchanged lines hidden (view full) --- 297 uint8_t vector = message.vector; 298 DPRINTF(LocalApic, 299 "Got Trigger Interrupt message with vector %#x.\n", 300 vector); 301 // Make sure we're really supposed to get this. 302 assert((message.destMode == 0 && message.destination == id) || 303 (bits((int)message.destination, id))); 304 |
305 requestInterrupt(message.vector, 306 message.deliveryMode, message.trigger); |
307 } 308 break; 309 default: 310 panic("Local apic got unknown interrupt message at offset %#x.\n", 311 offset); 312 break; 313 } 314 delete pkt->req; --- 184 unchanged lines hidden (view full) --- 499 // These are all probably fairly uncommon, so we'll make them easier to 500 // check for. 501 if (pendingUnmaskableInt) { 502 if (pendingSmi) { 503 DPRINTF(LocalApic, "Generated SMI fault object.\n"); 504 return new SystemManagementInterrupt(); 505 } else if (pendingNmi) { 506 DPRINTF(LocalApic, "Generated NMI fault object.\n"); |
507 return new NonMaskableInterrupt(nmiVector); |
508 } else if (pendingInit) { 509 DPRINTF(LocalApic, "Generated INIT fault object.\n"); |
510 return new InitInterrupt(initVector); |
511 } else { 512 panic("pendingUnmaskableInt set, but no unmaskable " 513 "ints were pending.\n"); 514 return NoFault; 515 } 516 } else if (pendingExtInt) { 517 DPRINTF(LocalApic, "Generated external interrupt fault object.\n"); |
518 return new ExternalInterrupt(extIntVector); |
519 } else { 520 DPRINTF(LocalApic, "Generated regular interrupt fault object.\n"); 521 // The only thing left are fixed and lowest priority interrupts. 522 return new ExternalInterrupt(IRRV); 523 } 524} 525 526void --- 34 unchanged lines hidden --- |