1 // Copyright 2022 The ChromiumOS Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 // Implementation of an xAPIC Local Advanced Programmable Interrupt Controller (LAPIC, aka APIC). 6 // See Intel Software Developer's Manual, Volume 3A, chapter 10 for a specification. 7 // 8 // Some features from the spec aren't supported: 9 // * setting TPR with cr8 register 10 // * changing MMIO base address 11 // * enabling/disabling the APIC with IA32_APIC_BASE MSR 12 // * TSC-deadline timer mode 13 // * cluster-mode logical addressing 14 // * external interrupts -- these are handled by querying `Pic` separately in 15 // `UserspaceIrqChip::inject_interrupts` 16 17 use std::convert::TryFrom; 18 use std::convert::TryInto; 19 use std::time::Duration; 20 use std::time::Instant; 21 22 use base::error; 23 use base::warn; 24 use base::TimerTrait; 25 use bit_field::*; 26 use hypervisor::DeliveryMode; 27 use hypervisor::DeliveryStatus; 28 use hypervisor::DestinationMode; 29 use hypervisor::LapicState; 30 use hypervisor::Level; 31 use hypervisor::MPState; 32 use hypervisor::MsiAddressMessage; 33 use hypervisor::MsiDataMessage; 34 use hypervisor::TriggerMode; 35 36 pub type Vector = u8; 37 38 /// Address of the start of APIC MMIO region. 39 pub const APIC_BASE_ADDRESS: u64 = 0xFEE00000; 40 /// Length in bytes of APIC MMIO region. 41 pub const APIC_MEM_LENGTH_BYTES: u64 = 0x1000; 42 43 // We try to set the APIC timer frequency to the TSC frequency, but if TSC frequency can't be 44 // determined, we use this cycle length as a fallback. 45 const CYCLE_LENGTH_FALLBACK: Duration = Duration::from_nanos(10); 46 // Size (alignment) of each register is 16 bytes. Only the first 4 bytes are actually used. 47 const REG_ALIGN_BYTES: usize = 16; 48 // APIC ID of the processor that starts executing instructions at power on (BSP). 49 const BOOTSTRAP_PROCESSOR: u8 = 0; 50 // 14 is the version for Xeon processors 51 const VERSION: u8 = 0x14; 52 // There are 6 local vector table entries in this version, so the max entry is offset 5. 53 const MAX_LVT: u8 = 5; 54 // Register value to mask an interrupt in the local vector table. 55 const LOCAL_VECTOR_MASKED: u32 = 1 << 16; 56 // Flat-model logical destinations. 57 const DESTINATION_FORMAT_FLAT: u8 = 0xF; 58 // Cluster-model logical destinations. 59 const DESTINATION_FORMAT_CLUSTER: u8 = 0x0; 60 // Physical destination address that goes to all CPUs. 61 const PHYSICAL_BROADCAST_ADDRESS: u8 = 0xFF; 62 // Bitmask for the APIC software enable bit in the Spurious Int register. 63 const SOFTWARE_ENABLE: u32 = 1 << 8; 64 // Bitmask for timer mode bits in the Local Timer register. 65 const TIMER_MODE_MASK: u32 = 3 << 17; 66 const TIMER_MODE_ONE_SHOT: u32 = 0 << 17; 67 const TIMER_MODE_PERIODIC: u32 = 1 << 17; 68 const TIMER_MODE_TSC_DEADLINE: u32 = 2 << 17; 69 // Table for mapping Divide Configuration Register values to timer divisors. The APIC's timer 70 // frequency is the base frequency divided by the value from this table. 71 const TIMER_DIVIDE_TABLE: [u32; 16] = [ 72 2, 4, 8, 16, // 73 1, 1, 1, 1, // Values with bit 2 are reserved and shouldn't be set 74 32, 64, 128, 1, // 75 1, 1, 1, 1, // Values with bit 2 are reserved and shouldn't be set 76 ]; 77 const ZERO_DURATION: Duration = Duration::from_nanos(0); 78 79 pub struct Apic { 80 // Local APIC ID. 81 id: u8, 82 /// Base duration for the APIC timer. A timer set with initial count = 1 and timer frequency 83 /// divide = 1 runs for this long. 84 cycle_length: Duration, 85 // Register state bytes. Each register is 16-byte aligned, but only its first 4 bytes are 86 // used. The register MMIO space is 4 KiB, but only the first 1 KiB (64 registers * 16 87 // bytes) is used. 88 regs: [u8; APIC_MEM_LENGTH_BYTES as usize], 89 // Multiprocessing initialization state: running, waiting for SIPI, etc. 90 mp_state: MPState, 91 // Timer for one-shot and periodic timer interrupts. 92 timer: Box<dyn TimerTrait>, 93 // How long the timer was set for. If the timer is not set (not running), it's None. For 94 // one-shot timers, it's the duration from start until expiration. For periodic timers, it's 95 //the timer interval. 96 timer_length: Option<Duration>, 97 // When the timer started or last ticked. For one-shot timers, this is the Instant when the 98 // timer started. For periodic timers, it's the Instant when it started or last expired. 99 last_tick: Instant, 100 // Pending startup interrupt vector. There can only be one pending startup interrupt at a 101 // time. 102 sipi: Option<Vector>, 103 // True if there's a pending INIT interrupt to send to the CPU. 104 init: bool, 105 // The number of pending non-maskable interrupts to be injected into the CPU. The architecture 106 // specifies that multiple NMIs can be sent concurrently and will be processed in order. 107 // Unlike fixed interrupts there's no architecturally defined place where the NMIs are 108 // queued or stored, we need to store them separately. 109 nmis: u32, 110 } 111 112 impl Apic { 113 /// Constructs a new APIC with local APIC ID `id`. new(id: u8, timer: Box<dyn TimerTrait>) -> Self114 pub fn new(id: u8, timer: Box<dyn TimerTrait>) -> Self { 115 let cycle_length = Duration::from_nanos(1_000_000_000 / Self::frequency() as u64); 116 let mp_state = if id == BOOTSTRAP_PROCESSOR { 117 MPState::Runnable 118 } else { 119 MPState::Uninitialized 120 }; 121 let mut apic = Apic { 122 id, 123 cycle_length, 124 regs: [0; APIC_MEM_LENGTH_BYTES as usize], 125 mp_state, 126 timer, 127 timer_length: None, 128 last_tick: Instant::now(), 129 sipi: None, 130 init: false, 131 nmis: 0, 132 }; 133 apic.load_reset_state(); 134 apic 135 } 136 137 /// Get the Apic frequency in Hz frequency() -> u32138 pub fn frequency() -> u32 { 139 // Our Apic implementation will try to use the host's bus frequency if it 140 // can be determined from cpuid, otherwise it uses 100MHz (cycle length of 10 nanos) 141 match crate::tsc::bus_freq_hz(std::arch::x86_64::__cpuid_count) { 142 Some(hz) => hz, 143 None => (1_000_000_000u128 / CYCLE_LENGTH_FALLBACK.as_nanos()) as u32, 144 } 145 } 146 147 /// Returns the local APIC ID. id(&self) -> u8148 pub fn id(&self) -> u8 { 149 self.id 150 } 151 152 /// Returns the base duration for the APIC timer. A timer set with initial count = 1 and timer 153 /// frequency divide = 1 runs for this long. get_cycle_length(&self) -> Duration154 pub fn get_cycle_length(&self) -> Duration { 155 self.cycle_length 156 } 157 158 /// Returns the state of the APIC registers. get_state(&self) -> LapicState159 pub fn get_state(&self) -> LapicState { 160 let mut state = LapicState { regs: [0; 64] }; 161 for reg in 0..state.regs.len() { 162 state.regs[reg] = self.get_reg(reg * REG_ALIGN_BYTES); 163 } 164 state 165 } 166 167 /// Sets the state of the APIC registers. set_state(&mut self, state: &LapicState)168 pub fn set_state(&mut self, state: &LapicState) { 169 for (reg, val) in state.regs.iter().enumerate() { 170 self.set_reg(reg * REG_ALIGN_BYTES, *val); 171 } 172 173 // This has the same timer semantics as KVM. Timers that are in-progress during get_state 174 // are ignored and during set_state timers are restarted regardless of how much of the timer 175 // has already expired. 176 self.start_timer(); 177 } 178 179 /// Gets the multi-processing state. get_mp_state(&self) -> MPState180 pub fn get_mp_state(&self) -> MPState { 181 self.mp_state 182 } 183 184 /// Sets the multi-processing state. set_mp_state(&mut self, state: &MPState)185 pub fn set_mp_state(&mut self, state: &MPState) { 186 self.mp_state = *state; 187 } 188 189 /// Checks that `offset` is 16-byte aligned and `data` is 4 bytes. valid_mmio(offset: u64, data: &[u8]) -> bool190 fn valid_mmio(offset: u64, data: &[u8]) -> bool { 191 if offset.trailing_zeros() >= 4 && data.len() == 4 { 192 true 193 } else { 194 error!( 195 "Invalid offset {} or size {} for apic mmio", 196 offset, 197 data.len() 198 ); 199 false 200 } 201 } 202 203 /// Handles an MMIO read forwarded from the IRQ chip. Reads data from the APIC's register at 204 /// `offset` into `data`. read(&self, offset: u64, data: &mut [u8])205 pub fn read(&self, offset: u64, data: &mut [u8]) { 206 if !Self::valid_mmio(offset, data) { 207 return; 208 } 209 let offset = offset as usize; 210 let val = match offset { 211 Reg::PPR => self.get_processor_priority() as u32, 212 Reg::TIMER_CURRENT_COUNT => { 213 let count_remaining = self.next_timer_expiration().as_nanos() 214 / self.cycle_length.as_nanos() 215 / self.get_timer_divide_control() as u128; 216 count_remaining.try_into().unwrap_or_else(|_| { 217 warn!("APIC time remaining overflow"); 218 u32::MAX 219 }) 220 } 221 _ => self.get_reg(offset), 222 }; 223 data.copy_from_slice(&val.to_le_bytes()); 224 } 225 226 /// Handles an MMIO write forwarded from the IRQ chip. Writes `data` into the APIC's register 227 /// at `offset`, optionally returning a command back to the IRQ chip. write(&mut self, offset: u64, data: &[u8]) -> Option<ApicBusMsg>228 pub fn write(&mut self, offset: u64, data: &[u8]) -> Option<ApicBusMsg> { 229 if !Self::valid_mmio(offset, data) { 230 return None; 231 } 232 let offset = offset as usize; 233 let data = u32::from_le_bytes(data.try_into().unwrap()); 234 let mut msg: Option<ApicBusMsg> = None; 235 match offset { 236 Reg::ID => {} 237 Reg::TPR => self.set_reg(Reg::TPR, data & 0xFF), // Top 24 bits are reserved. 238 Reg::EOI => { 239 // TODO(srichman): Implement eoi broadcast suppression. 240 if let Some(vector) = self.highest_bit_in_vector(VectorReg::Isr) { 241 self.clear_vector_bit(VectorReg::Isr, vector); 242 msg = Some(ApicBusMsg::Eoi(vector)); 243 // The next call to UserspaceIrqChip::inject_interrupts() at end of the vcpu run 244 // loop will finish the EOI steps by injecting the highest vector in IRR, if 245 // any. 246 } 247 } 248 Reg::INTERRUPT_COMMAND_LO => { 249 // When handling writes to the ICR, we clear the pending bit. 250 self.set_reg(Reg::INTERRUPT_COMMAND_LO, data & !(1 << 12)); 251 let interrupt = self.decode_icr(); 252 msg = Some(ApicBusMsg::Ipi(interrupt)); 253 } 254 255 // TODO(srichman): Many of these have reserved bits which are not supposed to be set. 256 // Currently we allow a guest to set them. 257 // TODO(srichman): Handle software disable closer to spec: set LVT mask bits and don't 258 // accept new irqs. 259 Reg::TIMER_DIVIDE_CONTROL 260 | Reg::LOCAL_CMCI 261 | Reg::INTERRUPT_COMMAND_HI 262 | Reg::SPURIOUS_INT 263 | Reg::LOGICAL_DESTINATION 264 | Reg::DESTINATION_FORMAT => self.set_reg(offset, data), 265 266 Reg::LOCAL_INT_0 267 | Reg::LOCAL_INT_1 268 | Reg::LOCAL_THERMAL 269 | Reg::LOCAL_PERF 270 | Reg::LOCAL_ERROR => { 271 if self.enabled() { 272 self.set_reg(offset, data); 273 } else { 274 // If the APIC is software disabled then the Masked bit can not be unset. 275 self.set_reg(offset, data | LOCAL_VECTOR_MASKED); 276 } 277 } 278 279 Reg::TIMER_INITIAL_COUNT => { 280 self.set_reg(Reg::TIMER_INITIAL_COUNT, data); 281 self.start_timer(); 282 } 283 Reg::LOCAL_TIMER => { 284 let old_mode = self.get_reg(Reg::LOCAL_TIMER) & TIMER_MODE_MASK; 285 let new_mode = data & TIMER_MODE_MASK; 286 if old_mode != new_mode { 287 self.clear_timer(); 288 } 289 self.set_reg(Reg::LOCAL_TIMER, data); 290 } 291 _ => { 292 // TODO(srichman): Inject a GP into the guest. 293 } 294 } 295 msg 296 } 297 298 /// If `dest` specifies a single destination APIC that can be determined quickly without calling 299 /// `match_dest` on each APIC, then return the destination APIC ID, otherwise return None. single_dest_fast(dest: &InterruptDestination) -> Option<u8>300 pub fn single_dest_fast(dest: &InterruptDestination) -> Option<u8> { 301 if dest.shorthand == DestinationShorthand::Self_ { 302 Some(dest.source_id) 303 } else if dest.shorthand == DestinationShorthand::None 304 && dest.mode == DestinationMode::Physical 305 && dest.dest_id != PHYSICAL_BROADCAST_ADDRESS 306 { 307 Some(dest.dest_id) 308 } else { 309 None 310 } 311 } 312 313 /// Returns true if this APIC is one of the destinations of the interrupt `dest`. match_dest(&self, dest: &InterruptDestination) -> bool314 pub fn match_dest(&self, dest: &InterruptDestination) -> bool { 315 match dest.shorthand { 316 DestinationShorthand::All => true, 317 DestinationShorthand::AllExcludingSelf => dest.source_id != self.id, 318 DestinationShorthand::Self_ => dest.source_id == self.id, 319 DestinationShorthand::None => match dest.mode { 320 DestinationMode::Physical => { 321 dest.dest_id == PHYSICAL_BROADCAST_ADDRESS || dest.dest_id == self.id 322 } 323 DestinationMode::Logical => self.matches_logical_address(dest.dest_id), 324 }, 325 } 326 } 327 328 /// Returns the processor priority register. get_processor_priority(&self) -> u8329 pub fn get_processor_priority(&self) -> u8 { 330 // From 10.8 in the manual: 331 // "PPR[7:4] (the processor-priority class) the maximum of TPR[7:4] (the task-priority 332 // class) and ISRV[7:4] (the priority of the highest priority interrupt in service). 333 // PPR[3:0] (the processor-priority sub-class) is determined as follows: 334 // - If TPR[7:4] > ISRV[7:4], PPR[3:0] is TPR[3:0] (the task-priority sub-class). 335 // - If TPR[7:4] < ISRV[7:4], PPR[3:0] is 0. 336 // - If TPR[7:4] = ISRV[7:4], PPR[3:0] may be either TPR[3:0] or 0. The actual behavior 337 // is model-specific." 338 let tpr = self.regs[Reg::TPR]; 339 let isrv = self.highest_bit_in_vector(VectorReg::Isr).unwrap_or(0); 340 if tpr >> 4 >= isrv >> 4 { 341 tpr 342 } else { 343 isrv & !0xF 344 } 345 } 346 347 /// Enqueues an interrupt to be delivered to this APIC's vcpu. accept_irq(&mut self, i: &InterruptData)348 pub fn accept_irq(&mut self, i: &InterruptData) { 349 match i.delivery { 350 DeliveryMode::Fixed | DeliveryMode::Lowest => { 351 self.set_vector_bit(VectorReg::Irr, i.vector); 352 if i.trigger == TriggerMode::Level { 353 self.set_vector_bit(VectorReg::Tmr, i.vector); 354 } else { 355 self.clear_vector_bit(VectorReg::Tmr, i.vector); 356 } 357 self.mp_state = MPState::Runnable; 358 } 359 DeliveryMode::Startup => self.sipi = Some(i.vector), 360 DeliveryMode::Init => { 361 if i.level == Level::Assert { 362 self.init = true; 363 } 364 } 365 DeliveryMode::NMI => self.nmis += 1, 366 DeliveryMode::External => warn!("APIC doesn't handle external interrupts, dropping"), 367 DeliveryMode::RemoteRead => { 368 // This type of interrupt is no longer supported or documented by Intel, but Windows 369 // still issues it, and we ignore it. 370 } 371 DeliveryMode::SMI => warn!("APIC doesn't handle SMIs, dropping interrupt"), 372 } 373 } 374 375 /// Returns the highest-priority vector in the IRR that has high enough priority to be serviced 376 /// (i.e., its priority class is greater than the current processor priority class). If `clear` 377 /// is true, the IRR bit for that vector is cleared and the ISR bit is set. inject_interrupt(&mut self, clear: bool) -> Option<Vector>378 fn inject_interrupt(&mut self, clear: bool) -> Option<Vector> { 379 let irrv = self.highest_bit_in_vector(VectorReg::Irr).unwrap_or(0); 380 // Only the processor priority class bits (PPR[7:4]) are used to decide if the vector has 381 // priority to interrupt. 382 if irrv >> 4 > self.get_processor_priority() >> 4 { 383 if clear { 384 self.clear_vector_bit(VectorReg::Irr, irrv); 385 self.set_vector_bit(VectorReg::Isr, irrv); 386 } 387 Some(irrv) 388 } else { 389 None 390 } 391 } 392 393 /// Parses data from the Interrupt Command Register into an interrupt. decode_icr(&mut self) -> Interrupt394 fn decode_icr(&mut self) -> Interrupt { 395 let hi = self.get_reg(Reg::INTERRUPT_COMMAND_HI) as u64; 396 let lo = self.get_reg(Reg::INTERRUPT_COMMAND_LO) as u64; 397 let icr = hi << 32 | lo; 398 let mut command = InterruptCommand::new(); 399 command.set(0, 64, icr); 400 Interrupt { 401 dest: InterruptDestination { 402 source_id: self.id, 403 dest_id: command.get_destination(), 404 shorthand: command.get_shorthand(), 405 mode: command.get_destination_mode(), 406 }, 407 data: InterruptData { 408 vector: command.get_vector(), 409 delivery: command.get_delivery(), 410 trigger: command.get_trigger(), 411 level: command.get_level(), 412 }, 413 } 414 } 415 416 /// Returns true if the APIC is software-enabled, false if it's software-disabled. enabled(&self) -> bool417 fn enabled(&self) -> bool { 418 self.get_reg(Reg::SPURIOUS_INT) & SOFTWARE_ENABLE != 0 419 } 420 421 /// Sets or unsets the software enabled bit in the Spurious Int register. set_enabled(&mut self, enable: bool)422 pub fn set_enabled(&mut self, enable: bool) { 423 let mut val = self.get_reg(Reg::SPURIOUS_INT); 424 if enable { 425 val |= SOFTWARE_ENABLE; 426 } else { 427 val &= !SOFTWARE_ENABLE; 428 } 429 self.set_reg(Reg::SPURIOUS_INT, val); 430 } 431 432 /// Gets pending interrupts to be injected into this APIC's vcpu. The interrupts returned are 433 /// cleared from the APIC. `vcpu_ready` indicates if the vcpu is ready to receive fixed 434 /// interrupts (i.e., if the vcpu's interrupt window is open, IF flag is set, and the PIC hasn't 435 /// already injected an interrupt). get_pending_irqs(&mut self, vcpu_ready: bool) -> PendingInterrupts436 pub fn get_pending_irqs(&mut self, vcpu_ready: bool) -> PendingInterrupts { 437 let (fixed, needs_window) = if !self.enabled() { 438 (None, false) 439 } else { 440 match self.inject_interrupt(vcpu_ready) { 441 Some(vector) if vcpu_ready => { 442 let has_second_interrupt = self.inject_interrupt(false).is_some(); 443 (Some(vector), has_second_interrupt) 444 } 445 Some(_) if !vcpu_ready => (None, true), 446 None => (None, false), 447 _ => unreachable!(), 448 } 449 }; 450 451 let nmis = self.nmis; 452 self.nmis = 0; 453 454 let init = self.init; 455 self.init = false; 456 457 let startup = self.sipi; 458 self.sipi = None; 459 460 PendingInterrupts { 461 fixed, 462 nmis, 463 init, 464 startup, 465 needs_window, 466 } 467 } 468 469 /// Resets the APIC to its initial state. Used for initializing a new APIC and when the vcpu 470 /// receives an INIT. load_reset_state(&mut self)471 pub fn load_reset_state(&mut self) { 472 for reg in self.regs.iter_mut() { 473 *reg = 0; 474 } 475 self.set_reg(Reg::DESTINATION_FORMAT, 0xFFFFFFFF); 476 477 // All local interrupts start out masked. 478 self.set_reg(Reg::LOCAL_INT_0, LOCAL_VECTOR_MASKED); 479 self.set_reg(Reg::LOCAL_INT_1, LOCAL_VECTOR_MASKED); 480 self.set_reg(Reg::LOCAL_THERMAL, LOCAL_VECTOR_MASKED); 481 self.set_reg(Reg::LOCAL_PERF, LOCAL_VECTOR_MASKED); 482 self.set_reg(Reg::LOCAL_ERROR, LOCAL_VECTOR_MASKED); 483 self.set_reg(Reg::LOCAL_TIMER, LOCAL_VECTOR_MASKED); 484 self.clear_timer(); 485 486 let mut version = VersionRegister::new(); 487 version.set_version(VERSION); 488 version.set_max_lvt(MAX_LVT); 489 version.set_eoi_broadcast_suppression(1); 490 let bits = version.get(0, 32) as u32; 491 self.set_reg(Reg::VERSION, bits); 492 493 self.set_reg(Reg::ID, (self.id as u32) << 24); 494 495 // The apic starts out software disabled (Spurious Int bit 8 is unset). 496 self.set_reg(Reg::SPURIOUS_INT, 0xFF); 497 } 498 debug_status(&self) -> String499 pub fn debug_status(&self) -> String { 500 let mut irr = [0u32; 8]; 501 let mut isr = [0u32; 8]; 502 for i in 0..8 { 503 irr[i] = self.get_reg(Reg::IRR + i * REG_ALIGN_BYTES); 504 isr[i] = self.get_reg(Reg::ISR + i * REG_ALIGN_BYTES); 505 } 506 let irrv = self.highest_bit_in_vector(VectorReg::Irr).unwrap_or(0); 507 let isrv = self.highest_bit_in_vector(VectorReg::Isr).unwrap_or(0); 508 let timer = self 509 .timer_length 510 .map(|d| format!("{}ns", d.as_nanos())) 511 .unwrap_or("None".to_string()); 512 513 format!( 514 "enabled={} irr={:?} irrv={} isr={:?} isrv={} irrv_prio={} proc_prio={}, timer={}", 515 self.enabled(), 516 irr, 517 irrv, 518 isr, 519 isrv, 520 irrv >> 4, 521 self.get_processor_priority() >> 4, 522 timer, 523 ) 524 } 525 526 /// Callback to be called by a timer worker when the timer expires. handle_timer_expiration(&mut self)527 pub fn handle_timer_expiration(&mut self) { 528 if let Err(e) = self.timer.mark_waited() { 529 error!("APIC timer wait unexpectedly failed: {}", e); 530 return; 531 } 532 self.last_tick = Instant::now(); 533 let local_timer = self.get_reg(Reg::LOCAL_TIMER); 534 let is_masked = local_timer & LOCAL_VECTOR_MASKED != 0; 535 if is_masked || self.timer_length.is_none() { 536 return; 537 } 538 // Low 8 bits are the vector. 539 let vector = local_timer as u8; 540 self.accept_irq(&InterruptData { 541 vector, 542 delivery: DeliveryMode::Fixed, 543 trigger: TriggerMode::Edge, 544 level: Level::Deassert, 545 }); 546 } 547 548 /// Returns the first 4 bytes of the register that starts at `offset`. get_reg(&self, offset: usize) -> u32549 fn get_reg(&self, offset: usize) -> u32 { 550 let bytes = &self.regs[offset..offset + 4]; 551 u32::from_le_bytes(bytes.try_into().unwrap()) 552 } 553 554 /// Sets the first 4 bytes of the register that starts at `offset` to `val`. set_reg(&mut self, offset: usize, val: u32)555 fn set_reg(&mut self, offset: usize, val: u32) { 556 self.regs[offset..offset + 4].copy_from_slice(&val.to_le_bytes()); 557 } 558 559 /// Finds the bit for `vector` in vector bitmap register `reg`. 560 /// Returns `(index, bitmask)` where `index` is the index of the register byte for `vector`, and 561 /// `bitmask` has one bit set for the `vector` bit within that byte. reg_bit_for_vector(reg: VectorReg, vector: Vector) -> (usize, u8)562 fn reg_bit_for_vector(reg: VectorReg, vector: Vector) -> (usize, u8) { 563 let vector = vector as usize; 564 // First 3 bits indicate which 16-byte aligned register 565 // Next 2 bits indicate which byte in that register 566 // Last 3 bits indicate which bit in that byte. 567 let index = (reg as usize) + 0x10 * (vector >> 5) + ((vector >> 3) & 0x3); 568 let bitmask = 1 << (vector & 0x7); 569 (index, bitmask) 570 } 571 set_vector_bit(&mut self, reg: VectorReg, vector: Vector)572 fn set_vector_bit(&mut self, reg: VectorReg, vector: Vector) { 573 let (reg, bitmask) = Self::reg_bit_for_vector(reg, vector); 574 self.regs[reg] |= bitmask; 575 } 576 clear_vector_bit(&mut self, reg: VectorReg, vector: Vector)577 fn clear_vector_bit(&mut self, reg: VectorReg, vector: Vector) { 578 let (reg, bitmask) = Self::reg_bit_for_vector(reg, vector); 579 self.regs[reg] &= !bitmask; 580 } 581 582 /// Returns the vector of the highest bit set in `reg`. highest_bit_in_vector(&self, reg: VectorReg) -> Option<Vector>583 fn highest_bit_in_vector(&self, reg: VectorReg) -> Option<Vector> { 584 let reg = reg as usize; 585 for i in (0..8).rev() { 586 let val = self.get_reg(reg + i * REG_ALIGN_BYTES); 587 if val != 0 { 588 let msb_set = 31 - val.leading_zeros() as u8; 589 return Some(msb_set + 32 * i as u8); 590 } 591 } 592 None 593 } 594 595 /// Returns true if this apic is a possible destination for the logical address `dest`. matches_logical_address(&self, dest: u8) -> bool596 fn matches_logical_address(&self, dest: u8) -> bool { 597 let bits = self.get_reg(Reg::DESTINATION_FORMAT) as u64; 598 let mut format = DestinationFormat::new(); 599 format.set(0, 32, bits); 600 let model = format.get_model(); 601 602 let bits = self.get_reg(Reg::LOGICAL_DESTINATION) as u64; 603 let mut logical_dest = LogicalDestination::new(); 604 logical_dest.set(0, 32, bits); 605 let local_logical_id = logical_dest.get_logical_id(); 606 607 match model { 608 DESTINATION_FORMAT_FLAT => dest & local_logical_id != 0, 609 DESTINATION_FORMAT_CLUSTER => { 610 error!("Cluster-mode APIC logical destinations unsupported"); 611 false 612 } 613 _ => { 614 error!("Invalid APIC logical destination format {}", model); 615 false 616 } 617 } 618 } 619 get_timer_divide_control(&self) -> u32620 fn get_timer_divide_control(&self) -> u32 { 621 let div_control = self.get_reg(Reg::TIMER_DIVIDE_CONTROL) as usize & 0xF; 622 TIMER_DIVIDE_TABLE[div_control] 623 } 624 start_timer(&mut self)625 fn start_timer(&mut self) { 626 self.clear_timer(); 627 let initial_count = self.get_reg(Reg::TIMER_INITIAL_COUNT); 628 if initial_count == 0 { 629 return; 630 } 631 let length = self.cycle_length * initial_count * self.get_timer_divide_control(); 632 let mode = self.get_reg(Reg::LOCAL_TIMER) & TIMER_MODE_MASK; 633 let (duration, interval) = match mode { 634 TIMER_MODE_ONE_SHOT => (length, None), 635 TIMER_MODE_PERIODIC => (length, Some(length)), 636 TIMER_MODE_TSC_DEADLINE => { 637 warn!("APIC TSC-deadline timer not supported"); 638 return; 639 } 640 _ => { 641 error!("Invalid APIC timer mode 0x{:X}", mode); 642 return; 643 } 644 }; 645 646 self.last_tick = Instant::now(); 647 if let Err(e) = self.timer.reset(duration, interval) { 648 error!( 649 "Failed to reset APIC timer to duration={:?} interval={:?}: {}", 650 duration, interval, e 651 ); 652 return; 653 } 654 self.timer_length = Some(length); 655 } 656 clear_timer(&mut self)657 fn clear_timer(&mut self) { 658 if self.timer_length.is_some() { 659 if let Err(e) = self.timer.clear() { 660 error!("Failed to clear APIC timer: {}", e); 661 } 662 self.timer_length = None; 663 } 664 } 665 666 /// Returns the duration remaining until the next timer expiration. next_timer_expiration(&self) -> Duration667 fn next_timer_expiration(&self) -> Duration { 668 if let Some(length) = self.timer_length { 669 let elapsed = self.last_tick.elapsed(); 670 length.checked_sub(elapsed).unwrap_or(ZERO_DURATION) 671 } else { 672 ZERO_DURATION 673 } 674 } 675 } 676 677 impl Drop for Apic { drop(&mut self)678 fn drop(&mut self) { 679 self.clear_timer(); 680 } 681 } 682 683 /// A message from an `Apic` to the `UserspaceIrqChip`. 684 #[derive(Debug, Clone, Copy, PartialEq, Eq)] 685 pub enum ApicBusMsg { 686 /// Broadcasts end-of-interrupt for the specified vector. 687 Eoi(Vector), 688 /// Sends an IPI. 689 Ipi(Interrupt), 690 } 691 692 /// Pending `Apic` interrupts to be injected into a vcpu. 693 #[derive(Debug, Clone, Copy, PartialEq, Eq, Default)] 694 pub struct PendingInterrupts { 695 /// Vector of a pending fixed interrupt. 696 pub fixed: Option<Vector>, 697 /// Number of pending non-maskable interrupts. 698 pub nmis: u32, 699 /// True if there is a pending INIT IPI. 700 pub init: bool, 701 /// Vector of a pending startup IPI (SIPI). 702 pub startup: Option<Vector>, 703 /// True if there are additional pending interrupts to delivered in the future, so an interrupt 704 /// window should be requested for the vcpu. 705 pub needs_window: bool, 706 } 707 708 /// A quick method of specifying all processors, all excluding self, or self as the destination. 709 #[bitfield] 710 #[derive(Debug, Clone, Copy, PartialEq, Eq)] 711 pub enum DestinationShorthand { 712 None = 0b00, 713 Self_ = 0b01, 714 All = 0b10, 715 AllExcludingSelf = 0b11, 716 } 717 718 /// An interrupt to be sent to one or more `Apic`s. 719 #[derive(Debug, Clone, Copy, PartialEq, Eq)] 720 pub struct Interrupt { 721 /// Specifies the destination processors for this interrupt. 722 pub dest: InterruptDestination, 723 /// The vector and type of this interrupt. 724 pub data: InterruptData, 725 } 726 727 /// Specifies the destination processors for an `Interrupt`. 728 #[derive(Debug, Clone, Copy, PartialEq, Eq)] 729 pub struct InterruptDestination { 730 /// The APIC ID that sent this interrupt. 731 pub source_id: u8, 732 /// In physical destination mode, used to specify the APIC ID of the destination processor. 733 /// In logical destination mode, used to specify a message destination address (MDA) that can 734 /// be used to select specific processors in clusters. Only used if shorthand is None. 735 pub dest_id: u8, 736 /// Specifies a quick destination of all processors, all excluding self, or self. If None, 737 /// then dest_id and mode are used to find the destinations. 738 pub shorthand: DestinationShorthand, 739 /// Specifies if physical or logical addressing is used for matching dest_id. 740 pub mode: DestinationMode, 741 } 742 743 /// The vector and type of an `Interrupt`. 744 #[derive(Debug, Clone, Copy, PartialEq, Eq)] 745 pub struct InterruptData { 746 /// The index in the OS's interrupt descriptor table for this interrupt. 747 pub vector: Vector, 748 /// The type of interrupt: fixed (regular IDT vector), NMI, startup IPI, etc. 749 pub delivery: DeliveryMode, 750 /// Edge- or level-triggered. 751 pub trigger: TriggerMode, 752 /// For level-triggered interrupts, specifies whether the line should be asserted or 753 /// deasserted. 754 pub level: Level, 755 } 756 757 impl TryFrom<&MsiAddressMessage> for InterruptDestination { 758 type Error = String; 759 try_from(msi: &MsiAddressMessage) -> std::result::Result<Self, Self::Error>760 fn try_from(msi: &MsiAddressMessage) -> std::result::Result<Self, Self::Error> { 761 if msi.get_always_0xfee() != 0xFEE { 762 return Err(format!( 763 "top 12 bits must be 0xFEE but are 0x{:X}", 764 msi.get_always_0xfee() 765 )); 766 } 767 // TODO(srichman): Handle redirection hint? 768 Ok(InterruptDestination { 769 source_id: 0, 770 dest_id: msi.get_destination_id(), 771 shorthand: DestinationShorthand::None, 772 mode: msi.get_destination_mode(), 773 }) 774 } 775 } 776 777 impl From<&MsiDataMessage> for InterruptData { from(msi: &MsiDataMessage) -> Self778 fn from(msi: &MsiDataMessage) -> Self { 779 InterruptData { 780 vector: msi.get_vector(), 781 delivery: msi.get_delivery_mode(), 782 trigger: msi.get_trigger(), 783 level: msi.get_level(), 784 } 785 } 786 } 787 788 #[bitfield] 789 #[derive(Clone, Copy)] 790 struct LocalInterrupt { 791 vector: BitField8, 792 #[bits = 3] 793 delivery_mode: DeliveryMode, 794 reserved1: BitField1, 795 #[bits = 1] 796 delivery_status: DeliveryStatus, 797 polarity: BitField1, 798 remote_irr: BitField1, 799 #[bits = 1] 800 trigger: TriggerMode, 801 masked: BitField1, 802 reserved2: BitField7, 803 reserved3: BitField8, 804 } 805 806 #[bitfield] 807 #[derive(Clone, Copy)] 808 struct VersionRegister { 809 version: BitField8, 810 reserved1: BitField8, 811 max_lvt: BitField8, 812 eoi_broadcast_suppression: BitField1, 813 reserved2: BitField7, 814 } 815 816 #[bitfield] 817 #[derive(Clone, Copy)] 818 struct DestinationFormat { 819 reserved: BitField28, 820 model: BitField4, 821 } 822 823 #[bitfield] 824 #[derive(Clone, Copy)] 825 struct LogicalDestination { 826 reserved: BitField24, 827 logical_id: BitField8, 828 } 829 830 #[bitfield] 831 #[derive(Clone, Copy)] 832 struct InterruptCommand { 833 vector: BitField8, 834 #[bits = 3] 835 delivery: DeliveryMode, 836 #[bits = 1] 837 destination_mode: DestinationMode, 838 #[bits = 1] 839 delivery_status: DeliveryStatus, 840 reserved1: BitField1, 841 #[bits = 1] 842 level: Level, 843 #[bits = 1] 844 trigger: TriggerMode, 845 reserved2: BitField2, 846 #[bits = 2] 847 shorthand: DestinationShorthand, 848 reserved3: BitField36, 849 destination: BitField8, 850 } 851 852 struct Reg; 853 854 impl Reg { 855 const ID: usize = 0x20; 856 const VERSION: usize = 0x30; 857 const TPR: usize = 0x80; 858 const PPR: usize = 0xA0; 859 const EOI: usize = 0xB0; 860 const LOGICAL_DESTINATION: usize = 0xD0; 861 const DESTINATION_FORMAT: usize = 0xE0; 862 const SPURIOUS_INT: usize = 0xF0; 863 // In-service register is 0x100-0x170 864 const ISR: usize = 0x100; 865 // Trigger mode register is 0x180-0x1F0 866 const TMR: usize = 0x180; 867 // Interrupt request regsiter is 0x200-0x270 868 const IRR: usize = 0x200; 869 const LOCAL_CMCI: usize = 0x2F0; 870 const INTERRUPT_COMMAND_LO: usize = 0x300; 871 const INTERRUPT_COMMAND_HI: usize = 0x310; 872 const LOCAL_TIMER: usize = 0x320; 873 const LOCAL_THERMAL: usize = 0x330; 874 const LOCAL_PERF: usize = 0x340; 875 const LOCAL_INT_0: usize = 0x350; 876 const LOCAL_INT_1: usize = 0x360; 877 const LOCAL_ERROR: usize = 0x370; 878 const TIMER_INITIAL_COUNT: usize = 0x380; 879 const TIMER_CURRENT_COUNT: usize = 0x390; 880 const TIMER_DIVIDE_CONTROL: usize = 0x3E0; 881 } 882 883 /// The APIC registers that store interrupt vector bitmaps. Each has 256 bit flags, one for each 884 /// interrupt vector. The flags are spread across the first 32 bits of each of eight 16-byte APIC 885 /// register slots. 886 #[repr(usize)] 887 #[derive(Clone, Copy, Debug, PartialEq, Eq)] 888 enum VectorReg { 889 /// In-service register. A bit is set for each interrupt vector currently being serviced by 890 /// the processor. 891 Isr = Reg::ISR, 892 /// Trigger mode register. Records whether interrupts are edge-triggered (bit is clear) or 893 /// level-triggered (bit is set). 894 Tmr = Reg::TMR, 895 /// Interrupt request register. A bit is set for each interrupt vector received by the APIC 896 /// but not yet serviced by the processor. 897 Irr = Reg::IRR, 898 } 899 900 #[cfg(test)] 901 mod tests { 902 use std::mem; 903 use std::sync::Arc; 904 905 use base::FakeClock; 906 use base::FakeTimer; 907 use sync::Mutex; 908 909 use super::*; 910 911 #[test] struct_size()912 fn struct_size() { 913 assert_eq!(4, mem::size_of::<LocalInterrupt>()); 914 assert_eq!(4, mem::size_of::<VersionRegister>()); 915 assert_eq!(4, mem::size_of::<DestinationFormat>()); 916 assert_eq!(4, mem::size_of::<LogicalDestination>()); 917 assert_eq!(8, mem::size_of::<InterruptCommand>()); 918 } 919 920 #[test] get_reg()921 fn get_reg() { 922 let timer = Box::new(FakeTimer::new(Arc::new(Mutex::new(FakeClock::new())))); 923 let mut a = Apic::new(0, timer); 924 a.regs[0..4].copy_from_slice(&[0xFE, 0xCA, 0xAD, 0xAB]); 925 assert_eq!(a.get_reg(0), 0xABADCAFE); 926 a.regs[4092..4096].copy_from_slice(&[0x0D, 0xF0, 0x1D, 0xC0]); 927 assert_eq!(a.get_reg(4092), 0xC01DF00D); 928 } 929 930 #[test] set_reg()931 fn set_reg() { 932 let timer = Box::new(FakeTimer::new(Arc::new(Mutex::new(FakeClock::new())))); 933 let mut a = Apic::new(0, timer); 934 a.set_reg(0, 0xABADCAFE); 935 assert_eq!(a.regs[0..4], [0xFE, 0xCA, 0xAD, 0xAB]); 936 a.set_reg(4092, 0xC01DF00D); 937 assert_eq!(a.regs[4092..4096], [0x0D, 0xF0, 0x1D, 0xC0]); 938 } 939 940 #[test] lapic_state()941 fn lapic_state() { 942 let timer = Box::new(FakeTimer::new(Arc::new(Mutex::new(FakeClock::new())))); 943 let mut a = Apic::new(0, timer); 944 945 a.set_reg(0, 0xABADCAFE); 946 assert_eq!(a.get_state().regs[0], 0xABADCAFE); 947 948 let mut state = LapicState { regs: [0; 64] }; 949 state.regs[63] = 0xC01DF00D; 950 a.set_state(&state); 951 assert_eq!(a.regs[1008..1012], [0x0D, 0xF0, 0x1D, 0xC0]); 952 } 953 954 #[test] valid_mmio()955 fn valid_mmio() { 956 let timer = Box::new(FakeTimer::new(Arc::new(Mutex::new(FakeClock::new())))); 957 let mut a = Apic::new(42, timer); 958 959 let mut data = [0u8; 4]; 960 a.read(Reg::ID as u64, &mut data); 961 assert_eq!(data, [0, 0, 0, 42]); 962 a.write(Reg::INTERRUPT_COMMAND_HI as u64, &[0xFE, 0xCA, 0xAD, 0xAB]); 963 assert_eq!(a.get_reg(Reg::INTERRUPT_COMMAND_HI), 0xABADCAFE); 964 let mut data = [0u8; 4]; 965 a.read(Reg::INTERRUPT_COMMAND_HI as u64, &mut data); 966 assert_eq!(data, [0xFE, 0xCA, 0xAD, 0xAB]); 967 } 968 969 #[test] invalid_mmio()970 fn invalid_mmio() { 971 let timer = Box::new(FakeTimer::new(Arc::new(Mutex::new(FakeClock::new())))); 972 let mut a = Apic::new(0, timer); 973 a.set_reg(Reg::INTERRUPT_COMMAND_HI, 0xABADCAFE); 974 975 let mut data = [0u8; 5]; 976 a.read(Reg::INTERRUPT_COMMAND_HI as u64, &mut data); 977 assert_eq!(data, [0; 5]); 978 let mut data = [0u8; 4]; 979 a.read(Reg::INTERRUPT_COMMAND_HI as u64 + 1, &mut data); 980 assert_eq!(data, [0; 4]); 981 a.write(Reg::INTERRUPT_COMMAND_HI as u64, &[0; 3]); 982 assert_eq!(a.get_reg(Reg::INTERRUPT_COMMAND_HI), 0xABADCAFE); 983 a.write(Reg::INTERRUPT_COMMAND_HI as u64 + 1, &[0; 4]); 984 assert_eq!(a.get_reg(Reg::INTERRUPT_COMMAND_HI), 0xABADCAFE); 985 } 986 987 #[test] vector_reg()988 fn vector_reg() { 989 let timer = Box::new(FakeTimer::new(Arc::new(Mutex::new(FakeClock::new())))); 990 let mut a = Apic::new(0, timer); 991 992 assert_eq!(a.highest_bit_in_vector(VectorReg::Irr), None); 993 a.set_vector_bit(VectorReg::Irr, 0); 994 assert_eq!(a.highest_bit_in_vector(VectorReg::Irr), Some(0)); 995 a.set_vector_bit(VectorReg::Irr, 7); 996 assert_eq!(a.highest_bit_in_vector(VectorReg::Irr), Some(7)); 997 a.set_vector_bit(VectorReg::Irr, 8); 998 assert_eq!(a.highest_bit_in_vector(VectorReg::Irr), Some(8)); 999 a.set_vector_bit(VectorReg::Irr, 31); 1000 assert_eq!(a.highest_bit_in_vector(VectorReg::Irr), Some(31)); 1001 a.set_vector_bit(VectorReg::Irr, 32); 1002 assert_eq!(a.highest_bit_in_vector(VectorReg::Irr), Some(32)); 1003 a.set_vector_bit(VectorReg::Irr, 74); 1004 assert_eq!(a.highest_bit_in_vector(VectorReg::Irr), Some(74)); 1005 a.set_vector_bit(VectorReg::Irr, 66); 1006 assert_eq!(a.highest_bit_in_vector(VectorReg::Irr), Some(74)); 1007 a.set_vector_bit(VectorReg::Irr, 255); 1008 assert_eq!(a.highest_bit_in_vector(VectorReg::Irr), Some(255)); 1009 assert_eq!( 1010 a.get_reg(Reg::IRR), 1011 0b1000_0000_0000_0000_0000_0001_1000_0001 1012 ); 1013 assert_eq!( 1014 a.get_reg(Reg::IRR + 1 * REG_ALIGN_BYTES), 1015 0b0000_0000_0000_0000_0000_0000_0000_0001 1016 ); 1017 assert_eq!( 1018 a.get_reg(Reg::IRR + 2 * REG_ALIGN_BYTES), 1019 0b0000_0000_0000_0000_0000_0100_0000_0100 1020 ); 1021 assert_eq!(a.get_reg(Reg::IRR + 3 * REG_ALIGN_BYTES), 0); 1022 assert_eq!(a.get_reg(Reg::IRR + 4 * REG_ALIGN_BYTES), 0); 1023 assert_eq!(a.get_reg(Reg::IRR + 5 * REG_ALIGN_BYTES), 0); 1024 assert_eq!(a.get_reg(Reg::IRR + 6 * REG_ALIGN_BYTES), 0); 1025 assert_eq!( 1026 a.get_reg(Reg::IRR + 7 * REG_ALIGN_BYTES), 1027 0b1000_0000_0000_0000_0000_0000_0000_0000 1028 ); 1029 1030 a.clear_vector_bit(VectorReg::Irr, 255); 1031 assert_eq!(a.highest_bit_in_vector(VectorReg::Irr), Some(74)); 1032 a.clear_vector_bit(VectorReg::Irr, 74); 1033 assert_eq!(a.highest_bit_in_vector(VectorReg::Irr), Some(66)); 1034 a.clear_vector_bit(VectorReg::Irr, 32); 1035 a.clear_vector_bit(VectorReg::Irr, 66); 1036 a.clear_vector_bit(VectorReg::Irr, 31); 1037 a.clear_vector_bit(VectorReg::Irr, 200); 1038 assert_eq!(a.highest_bit_in_vector(VectorReg::Irr), Some(8)); 1039 assert_eq!( 1040 a.get_reg(Reg::IRR), 1041 0b0000_0000_0000_0000_0000_0001_1000_0001 1042 ); 1043 assert_eq!(a.get_reg(Reg::IRR + 1 * REG_ALIGN_BYTES), 0); 1044 assert_eq!(a.get_reg(Reg::IRR + 2 * REG_ALIGN_BYTES), 0); 1045 assert_eq!(a.get_reg(Reg::IRR + 3 * REG_ALIGN_BYTES), 0); 1046 assert_eq!(a.get_reg(Reg::IRR + 4 * REG_ALIGN_BYTES), 0); 1047 assert_eq!(a.get_reg(Reg::IRR + 5 * REG_ALIGN_BYTES), 0); 1048 assert_eq!(a.get_reg(Reg::IRR + 6 * REG_ALIGN_BYTES), 0); 1049 assert_eq!(a.get_reg(Reg::IRR + 7 * REG_ALIGN_BYTES), 0); 1050 } 1051 1052 #[test] single_dest()1053 fn single_dest() { 1054 assert_eq!( 1055 Apic::single_dest_fast(&InterruptDestination { 1056 source_id: 0, 1057 dest_id: 254, 1058 shorthand: DestinationShorthand::None, 1059 mode: DestinationMode::Physical, 1060 }), 1061 Some(254) 1062 ); 1063 assert_eq!( 1064 Apic::single_dest_fast(&InterruptDestination { 1065 source_id: 0, 1066 dest_id: 254, 1067 shorthand: DestinationShorthand::Self_, 1068 mode: DestinationMode::Physical, 1069 }), 1070 Some(0) 1071 ); 1072 assert_eq!( 1073 Apic::single_dest_fast(&InterruptDestination { 1074 source_id: 0, 1075 dest_id: PHYSICAL_BROADCAST_ADDRESS, 1076 shorthand: DestinationShorthand::None, 1077 mode: DestinationMode::Physical, 1078 }), 1079 None 1080 ); 1081 assert_eq!( 1082 Apic::single_dest_fast(&InterruptDestination { 1083 source_id: 0, 1084 dest_id: 254, 1085 shorthand: DestinationShorthand::All, 1086 mode: DestinationMode::Physical, 1087 }), 1088 None 1089 ); 1090 assert_eq!( 1091 Apic::single_dest_fast(&InterruptDestination { 1092 source_id: 0, 1093 dest_id: 254, 1094 shorthand: DestinationShorthand::AllExcludingSelf, 1095 mode: DestinationMode::Physical, 1096 }), 1097 None 1098 ); 1099 assert_eq!( 1100 Apic::single_dest_fast(&InterruptDestination { 1101 source_id: 0, 1102 dest_id: 254, 1103 shorthand: DestinationShorthand::None, 1104 mode: DestinationMode::Logical, 1105 }), 1106 None 1107 ); 1108 } 1109 1110 #[test] match_dest()1111 fn match_dest() { 1112 let timer = Box::new(FakeTimer::new(Arc::new(Mutex::new(FakeClock::new())))); 1113 let mut a = Apic::new(254, timer); 1114 a.set_reg(Reg::LOGICAL_DESTINATION, 0b11001001 << 24); 1115 1116 assert!(a.match_dest(&InterruptDestination { 1117 source_id: 0, 1118 dest_id: 254, 1119 shorthand: DestinationShorthand::None, 1120 mode: DestinationMode::Physical, 1121 })); 1122 assert!(a.match_dest(&InterruptDestination { 1123 source_id: 0, 1124 dest_id: PHYSICAL_BROADCAST_ADDRESS, 1125 shorthand: DestinationShorthand::None, 1126 mode: DestinationMode::Physical, 1127 })); 1128 assert!(!a.match_dest(&InterruptDestination { 1129 source_id: 0, 1130 dest_id: 77, 1131 shorthand: DestinationShorthand::None, 1132 mode: DestinationMode::Physical, 1133 })); 1134 assert!(a.match_dest(&InterruptDestination { 1135 source_id: 0, 1136 dest_id: 0b01001000, 1137 shorthand: DestinationShorthand::None, 1138 mode: DestinationMode::Logical, 1139 })); 1140 assert!(!a.match_dest(&InterruptDestination { 1141 source_id: 0, 1142 dest_id: 0b00010010, 1143 shorthand: DestinationShorthand::None, 1144 mode: DestinationMode::Logical, 1145 })); 1146 assert!(a.match_dest(&InterruptDestination { 1147 source_id: 0, 1148 dest_id: 0, 1149 shorthand: DestinationShorthand::All, 1150 mode: DestinationMode::Physical, 1151 })); 1152 assert!(a.match_dest(&InterruptDestination { 1153 source_id: 254, 1154 dest_id: 0, 1155 shorthand: DestinationShorthand::Self_, 1156 mode: DestinationMode::Physical, 1157 })); 1158 assert!(!a.match_dest(&InterruptDestination { 1159 source_id: 0, 1160 dest_id: 0, 1161 shorthand: DestinationShorthand::Self_, 1162 mode: DestinationMode::Physical, 1163 })); 1164 assert!(a.match_dest(&InterruptDestination { 1165 source_id: 0, 1166 dest_id: 0, 1167 shorthand: DestinationShorthand::AllExcludingSelf, 1168 mode: DestinationMode::Physical, 1169 })); 1170 assert!(!a.match_dest(&InterruptDestination { 1171 source_id: 254, 1172 dest_id: 0, 1173 shorthand: DestinationShorthand::AllExcludingSelf, 1174 mode: DestinationMode::Physical, 1175 })); 1176 } 1177 1178 #[test] processor_priority()1179 fn processor_priority() { 1180 let timer = Box::new(FakeTimer::new(Arc::new(Mutex::new(FakeClock::new())))); 1181 let mut a = Apic::new(0, timer); 1182 assert_eq!(a.get_processor_priority(), 0); 1183 a.set_reg(Reg::TPR, 0xF); 1184 let prio = a.get_processor_priority(); 1185 // When TPR[7:4] == ISRV[7:4], the manual allows either 0 or TPR[3:0] for PPR[3:0]. 1186 assert!( 1187 prio == 0 || prio == 0xF, 1188 "Expected priority 0 or 0xF, got {}", 1189 prio 1190 ); 1191 a.set_reg(Reg::TPR, 0x10); 1192 assert_eq!(a.get_processor_priority(), 0x10); 1193 a.set_reg(Reg::TPR, 0); 1194 assert_eq!(a.get_processor_priority(), 0); 1195 1196 let timer = Box::new(FakeTimer::new(Arc::new(Mutex::new(FakeClock::new())))); 1197 let mut a = Apic::new(0, timer); 1198 a.set_vector_bit(VectorReg::Isr, 0xF); 1199 assert_eq!(a.get_processor_priority(), 0); 1200 a.set_vector_bit(VectorReg::Isr, 0x11); 1201 assert_eq!(a.get_processor_priority(), 0x10); 1202 a.clear_vector_bit(VectorReg::Isr, 0x11); 1203 assert_eq!(a.get_processor_priority(), 0); 1204 1205 let timer = Box::new(FakeTimer::new(Arc::new(Mutex::new(FakeClock::new())))); 1206 let mut a = Apic::new(0, timer); 1207 a.set_vector_bit(VectorReg::Isr, 0x25); 1208 a.set_vector_bit(VectorReg::Isr, 0x11); 1209 a.set_reg(Reg::TPR, 0x31); 1210 assert_eq!(a.get_processor_priority(), 0x31); 1211 a.set_reg(Reg::TPR, 0x19); 1212 assert_eq!(a.get_processor_priority(), 0x20); 1213 a.clear_vector_bit(VectorReg::Isr, 0x25); 1214 let prio = a.get_processor_priority(); 1215 assert!( 1216 prio == 0x10 || prio == 0x19, 1217 "Expected priority 0x10 or 0x19, got {}", 1218 prio 1219 ); 1220 } 1221 1222 #[test] accept_irq()1223 fn accept_irq() { 1224 let timer = Box::new(FakeTimer::new(Arc::new(Mutex::new(FakeClock::new())))); 1225 let mut a = Apic::new(0, timer); 1226 assert_eq!(a.init, false); 1227 assert_eq!(a.sipi, None); 1228 assert_eq!(a.nmis, 0); 1229 a.accept_irq(&InterruptData { 1230 vector: 20, 1231 delivery: DeliveryMode::Fixed, 1232 trigger: TriggerMode::Level, 1233 level: Level::Assert, 1234 }); 1235 a.accept_irq(&InterruptData { 1236 vector: 20, 1237 delivery: DeliveryMode::Fixed, 1238 trigger: TriggerMode::Level, 1239 level: Level::Assert, 1240 }); 1241 a.accept_irq(&InterruptData { 1242 vector: 21, 1243 delivery: DeliveryMode::Fixed, 1244 trigger: TriggerMode::Edge, 1245 level: Level::Assert, 1246 }); 1247 a.accept_irq(&InterruptData { 1248 vector: 255, 1249 delivery: DeliveryMode::Lowest, 1250 trigger: TriggerMode::Level, 1251 level: Level::Assert, 1252 }); 1253 a.accept_irq(&InterruptData { 1254 vector: 0, 1255 delivery: DeliveryMode::Init, 1256 trigger: TriggerMode::Level, 1257 level: Level::Assert, 1258 }); 1259 a.accept_irq(&InterruptData { 1260 vector: 7, 1261 delivery: DeliveryMode::Startup, 1262 trigger: TriggerMode::Edge, 1263 level: Level::Assert, 1264 }); 1265 a.accept_irq(&InterruptData { 1266 vector: 8, 1267 delivery: DeliveryMode::Startup, 1268 trigger: TriggerMode::Edge, 1269 level: Level::Assert, 1270 }); 1271 a.accept_irq(&InterruptData { 1272 vector: 0, 1273 delivery: DeliveryMode::NMI, 1274 trigger: TriggerMode::Edge, 1275 level: Level::Assert, 1276 }); 1277 a.accept_irq(&InterruptData { 1278 vector: 0, 1279 delivery: DeliveryMode::NMI, 1280 trigger: TriggerMode::Edge, 1281 level: Level::Assert, 1282 }); 1283 assert_eq!(a.init, true); 1284 assert_eq!(a.sipi, Some(8)); 1285 assert_eq!(a.nmis, 2); 1286 // IRR should be set for 20, 21, and 255. 1287 assert_eq!( 1288 a.get_reg(Reg::IRR), 1289 0b0000_0000_0011_0000_0000_0000_0000_0000 1290 ); 1291 assert_eq!(a.get_reg(Reg::IRR + 1 * REG_ALIGN_BYTES), 0); 1292 assert_eq!(a.get_reg(Reg::IRR + 2 * REG_ALIGN_BYTES), 0); 1293 assert_eq!(a.get_reg(Reg::IRR + 3 * REG_ALIGN_BYTES), 0); 1294 assert_eq!(a.get_reg(Reg::IRR + 4 * REG_ALIGN_BYTES), 0); 1295 assert_eq!(a.get_reg(Reg::IRR + 5 * REG_ALIGN_BYTES), 0); 1296 assert_eq!(a.get_reg(Reg::IRR + 6 * REG_ALIGN_BYTES), 0); 1297 assert_eq!( 1298 a.get_reg(Reg::IRR + 7 * REG_ALIGN_BYTES), 1299 0b1000_0000_0000_0000_0000_0000_0000_0000 1300 ); 1301 // ISR should be unset. 1302 assert_eq!(a.get_reg(Reg::ISR), 0); 1303 assert_eq!(a.get_reg(Reg::ISR + 1 * REG_ALIGN_BYTES), 0); 1304 assert_eq!(a.get_reg(Reg::ISR + 2 * REG_ALIGN_BYTES), 0); 1305 assert_eq!(a.get_reg(Reg::ISR + 3 * REG_ALIGN_BYTES), 0); 1306 assert_eq!(a.get_reg(Reg::ISR + 4 * REG_ALIGN_BYTES), 0); 1307 assert_eq!(a.get_reg(Reg::ISR + 5 * REG_ALIGN_BYTES), 0); 1308 assert_eq!(a.get_reg(Reg::ISR + 6 * REG_ALIGN_BYTES), 0); 1309 assert_eq!(a.get_reg(Reg::ISR + 7 * REG_ALIGN_BYTES), 0); 1310 // TMR should be set for 20 and 255. 1311 assert_eq!( 1312 a.get_reg(Reg::TMR), 1313 0b0000_0000_0001_0000_0000_0000_0000_0000 1314 ); 1315 assert_eq!(a.get_reg(Reg::TMR + 1 * REG_ALIGN_BYTES), 0); 1316 assert_eq!(a.get_reg(Reg::TMR + 2 * REG_ALIGN_BYTES), 0); 1317 assert_eq!(a.get_reg(Reg::TMR + 3 * REG_ALIGN_BYTES), 0); 1318 assert_eq!(a.get_reg(Reg::TMR + 4 * REG_ALIGN_BYTES), 0); 1319 assert_eq!(a.get_reg(Reg::TMR + 5 * REG_ALIGN_BYTES), 0); 1320 assert_eq!(a.get_reg(Reg::TMR + 6 * REG_ALIGN_BYTES), 0); 1321 assert_eq!( 1322 a.get_reg(Reg::TMR + 7 * REG_ALIGN_BYTES), 1323 0b1000_0000_0000_0000_0000_0000_0000_0000 1324 ); 1325 } 1326 1327 #[test] icr_write_sends_ipi()1328 fn icr_write_sends_ipi() { 1329 let timer = Box::new(FakeTimer::new(Arc::new(Mutex::new(FakeClock::new())))); 1330 let mut a = Apic::new(229, timer); 1331 1332 // Top 8 bits of ICR high are the destination. 1333 a.write(Reg::INTERRUPT_COMMAND_HI as u64, &[0, 0, 0, 42]); 1334 #[rustfmt::skip] 1335 let msg = a.write( 1336 Reg::INTERRUPT_COMMAND_LO as u64, 1337 &[ 1338 123, // vector 1339 0b11001001, // level 1, assert 1, reserved 0, idle 0, logical 1, lowest priority 001 1340 0b00001100, // reserved 0000, all excluding self 11, reserved 00 1341 0, // reserved 1342 ], 1343 ); 1344 let msg = msg.unwrap(); 1345 assert_eq!( 1346 msg, 1347 ApicBusMsg::Ipi(Interrupt { 1348 dest: InterruptDestination { 1349 source_id: 229, 1350 dest_id: 42, 1351 shorthand: DestinationShorthand::AllExcludingSelf, 1352 mode: DestinationMode::Logical, 1353 }, 1354 data: InterruptData { 1355 vector: 123, 1356 delivery: DeliveryMode::Lowest, 1357 trigger: TriggerMode::Level, 1358 level: Level::Assert, 1359 }, 1360 }) 1361 ); 1362 1363 a.write(Reg::INTERRUPT_COMMAND_HI as u64, &[0, 0, 0, 161]); 1364 let msg = a.write( 1365 Reg::INTERRUPT_COMMAND_LO as u64, 1366 &[ 1367 255, // vector 1368 0b00010110, // edge 0, deassert 0, reserved 0, pending 1, physical 0, sipi 110 1369 0b00000000, // reserved 0000, no shorthand 00, reserved 00 1370 0, // reserved 1371 ], 1372 ); 1373 let msg = msg.unwrap(); 1374 assert_eq!( 1375 msg, 1376 ApicBusMsg::Ipi(Interrupt { 1377 dest: InterruptDestination { 1378 source_id: 229, 1379 dest_id: 161, 1380 shorthand: DestinationShorthand::None, 1381 mode: DestinationMode::Physical, 1382 }, 1383 data: InterruptData { 1384 vector: 255, 1385 delivery: DeliveryMode::Startup, 1386 trigger: TriggerMode::Edge, 1387 level: Level::Deassert, 1388 }, 1389 }) 1390 ); 1391 } 1392 1393 #[test] end_of_interrupt()1394 fn end_of_interrupt() { 1395 let timer = Box::new(FakeTimer::new(Arc::new(Mutex::new(FakeClock::new())))); 1396 let mut a = Apic::new(0, timer); 1397 let msg = a.write(Reg::EOI as u64, &[0; 4]); 1398 assert_eq!(msg, None); // Spurious EOIs (no interrupt being serviced) should be ignored. 1399 a.set_vector_bit(VectorReg::Isr, 39); 1400 a.set_vector_bit(VectorReg::Isr, 255); 1401 let msg = a.write(Reg::EOI as u64, &[0; 4]).unwrap(); 1402 assert_eq!(msg, ApicBusMsg::Eoi(255)); 1403 assert_eq!(a.highest_bit_in_vector(VectorReg::Isr), Some(39)); 1404 a.set_vector_bit(VectorReg::Isr, 40); 1405 let msg = a.write(Reg::EOI as u64, &[0; 4]).unwrap(); 1406 assert_eq!(msg, ApicBusMsg::Eoi(40)); 1407 assert_eq!(a.highest_bit_in_vector(VectorReg::Isr), Some(39)); 1408 let msg = a.write(Reg::EOI as u64, &[0; 4]).unwrap(); 1409 assert_eq!(msg, ApicBusMsg::Eoi(39)); 1410 assert_eq!(a.highest_bit_in_vector(VectorReg::Isr), None); 1411 let msg = a.write(Reg::EOI as u64, &[0; 4]); 1412 assert_eq!(msg, None); 1413 } 1414 1415 #[test] non_fixed_irqs_injected()1416 fn non_fixed_irqs_injected() { 1417 let timer = Box::new(FakeTimer::new(Arc::new(Mutex::new(FakeClock::new())))); 1418 let mut a = Apic::new(0, timer); 1419 a.set_enabled(true); 1420 1421 a.accept_irq(&InterruptData { 1422 vector: 0, 1423 delivery: DeliveryMode::Init, 1424 trigger: TriggerMode::Level, 1425 level: Level::Assert, 1426 }); 1427 a.accept_irq(&InterruptData { 1428 vector: 7, 1429 delivery: DeliveryMode::Startup, 1430 trigger: TriggerMode::Edge, 1431 level: Level::Assert, 1432 }); 1433 a.accept_irq(&InterruptData { 1434 vector: 0, 1435 delivery: DeliveryMode::NMI, 1436 trigger: TriggerMode::Edge, 1437 level: Level::Assert, 1438 }); 1439 a.accept_irq(&InterruptData { 1440 vector: 0, 1441 delivery: DeliveryMode::NMI, 1442 trigger: TriggerMode::Edge, 1443 level: Level::Assert, 1444 }); 1445 // Non-fixed irqs should be injected even if vcpu_ready is false. */ 1446 let irqs = a.get_pending_irqs(/* vcpu_ready= */ false); 1447 assert_eq!( 1448 irqs, 1449 PendingInterrupts { 1450 fixed: None, 1451 nmis: 2, 1452 init: true, 1453 startup: Some(7), 1454 needs_window: false, 1455 } 1456 ); 1457 assert_eq!(a.nmis, 0); 1458 assert_eq!(a.init, false); 1459 assert_eq!(a.sipi, None); 1460 1461 a.accept_irq(&InterruptData { 1462 vector: 0, 1463 delivery: DeliveryMode::NMI, 1464 trigger: TriggerMode::Edge, 1465 level: Level::Assert, 1466 }); 1467 let irqs = a.get_pending_irqs(/* vcpu_ready= */ true); 1468 assert_eq!( 1469 irqs, 1470 PendingInterrupts { 1471 nmis: 1, 1472 ..Default::default() 1473 } 1474 ); 1475 assert_eq!(a.nmis, 0); 1476 1477 let irqs = a.get_pending_irqs(/* vcpu_ready= */ true); 1478 assert_eq!( 1479 irqs, 1480 PendingInterrupts { 1481 ..Default::default() 1482 } 1483 ); 1484 } 1485 1486 #[test] fixed_irq_injected()1487 fn fixed_irq_injected() { 1488 let timer = Box::new(FakeTimer::new(Arc::new(Mutex::new(FakeClock::new())))); 1489 let mut a = Apic::new(0, timer); 1490 a.set_enabled(true); 1491 1492 a.accept_irq(&InterruptData { 1493 vector: 0x10, 1494 delivery: DeliveryMode::Fixed, 1495 trigger: TriggerMode::Level, 1496 level: Level::Assert, 1497 }); 1498 let irqs = a.get_pending_irqs(/* vcpu_ready= */ false); 1499 assert_eq!( 1500 irqs, 1501 PendingInterrupts { 1502 fixed: None, 1503 needs_window: true, 1504 ..Default::default() 1505 } 1506 ); 1507 assert_eq!(a.highest_bit_in_vector(VectorReg::Irr), Some(0x10)); 1508 assert_eq!(a.highest_bit_in_vector(VectorReg::Isr), None); 1509 let irqs = a.get_pending_irqs(/* vcpu_ready= */ true); 1510 assert_eq!( 1511 irqs, 1512 PendingInterrupts { 1513 fixed: Some(0x10), 1514 needs_window: false, 1515 ..Default::default() 1516 } 1517 ); 1518 assert_eq!(a.highest_bit_in_vector(VectorReg::Irr), None); 1519 assert_eq!(a.highest_bit_in_vector(VectorReg::Isr), Some(0x10)); 1520 } 1521 1522 #[test] high_priority_irq_injected()1523 fn high_priority_irq_injected() { 1524 let timer = Box::new(FakeTimer::new(Arc::new(Mutex::new(FakeClock::new())))); 1525 let mut a = Apic::new(0, timer); 1526 a.set_enabled(true); 1527 1528 a.accept_irq(&InterruptData { 1529 vector: 0x10, 1530 delivery: DeliveryMode::Fixed, 1531 trigger: TriggerMode::Level, 1532 level: Level::Assert, 1533 }); 1534 let _ = a.get_pending_irqs(/* vcpu_ready= */ true); 1535 1536 // An interrupt in a higher priority class should be injected immediately if the window is 1537 // open. 1538 a.accept_irq(&InterruptData { 1539 vector: 0x20, 1540 delivery: DeliveryMode::Fixed, 1541 trigger: TriggerMode::Level, 1542 level: Level::Assert, 1543 }); 1544 let irqs = a.get_pending_irqs(/* vcpu_ready= */ false); 1545 assert_eq!( 1546 irqs, 1547 PendingInterrupts { 1548 fixed: None, 1549 needs_window: true, 1550 ..Default::default() 1551 } 1552 ); 1553 assert_eq!(a.highest_bit_in_vector(VectorReg::Irr), Some(0x20)); 1554 assert_eq!(a.highest_bit_in_vector(VectorReg::Isr), Some(0x10)); 1555 let irqs = a.get_pending_irqs(/* vcpu_ready= */ true); 1556 assert_eq!( 1557 irqs, 1558 PendingInterrupts { 1559 fixed: Some(0x20), 1560 needs_window: false, 1561 ..Default::default() 1562 } 1563 ); 1564 assert_eq!(a.highest_bit_in_vector(VectorReg::Irr), None); 1565 assert_eq!(a.highest_bit_in_vector(VectorReg::Isr), Some(0x20)); 1566 } 1567 1568 #[test] low_priority_irq_deferred()1569 fn low_priority_irq_deferred() { 1570 let timer = Box::new(FakeTimer::new(Arc::new(Mutex::new(FakeClock::new())))); 1571 let mut a = Apic::new(0, timer); 1572 a.set_enabled(true); 1573 1574 a.accept_irq(&InterruptData { 1575 vector: 0x10, 1576 delivery: DeliveryMode::Fixed, 1577 trigger: TriggerMode::Level, 1578 level: Level::Assert, 1579 }); 1580 let _ = a.get_pending_irqs(/* vcpu_ready= */ true); 1581 1582 // An interrupt in the same or lower priority class should be deferred. 1583 a.accept_irq(&InterruptData { 1584 vector: 0x15, 1585 delivery: DeliveryMode::Fixed, 1586 trigger: TriggerMode::Level, 1587 level: Level::Assert, 1588 }); 1589 let irqs = a.get_pending_irqs(/* vcpu_ready= */ true); 1590 assert_eq!( 1591 irqs, 1592 PendingInterrupts { 1593 fixed: None, 1594 // Not injectable due to higher priority ISRV, so no window needed. 1595 needs_window: false, 1596 ..Default::default() 1597 } 1598 ); 1599 assert_eq!(a.highest_bit_in_vector(VectorReg::Irr), Some(0x15)); 1600 assert_eq!(a.highest_bit_in_vector(VectorReg::Isr), Some(0x10)); 1601 1602 // EOI lets it be injected. 1603 let msg = a.write(Reg::EOI as u64, &[0; 4]).unwrap(); 1604 assert_eq!(msg, ApicBusMsg::Eoi(0x10)); 1605 let irqs = a.get_pending_irqs(/* vcpu_ready= */ true); 1606 assert_eq!( 1607 irqs, 1608 PendingInterrupts { 1609 fixed: Some(0x15), 1610 needs_window: false, 1611 ..Default::default() 1612 } 1613 ); 1614 } 1615 1616 #[test] tpr_defers_injection()1617 fn tpr_defers_injection() { 1618 let timer = Box::new(FakeTimer::new(Arc::new(Mutex::new(FakeClock::new())))); 1619 let mut a = Apic::new(0, timer); 1620 a.set_enabled(true); 1621 1622 a.accept_irq(&InterruptData { 1623 vector: 0x25, 1624 delivery: DeliveryMode::Fixed, 1625 trigger: TriggerMode::Level, 1626 level: Level::Assert, 1627 }); 1628 a.set_reg(Reg::TPR, 0x20); 1629 let irqs = a.get_pending_irqs(/* vcpu_ready= */ true); 1630 assert_eq!( 1631 irqs, 1632 PendingInterrupts { 1633 fixed: None, 1634 needs_window: false, 1635 ..Default::default() 1636 } 1637 ); 1638 a.set_reg(Reg::TPR, 0x19); 1639 let irqs = a.get_pending_irqs(/* vcpu_ready= */ true); 1640 assert_eq!( 1641 irqs, 1642 PendingInterrupts { 1643 fixed: Some(0x25), 1644 needs_window: false, 1645 ..Default::default() 1646 } 1647 ); 1648 } 1649 1650 #[test] timer_starts()1651 fn timer_starts() { 1652 let clock = Arc::new(Mutex::new(FakeClock::new())); 1653 let mut a = Apic::new(0, Box::new(FakeTimer::new(clock.clone()))); 1654 a.set_enabled(true); 1655 1656 a.write(Reg::LOCAL_TIMER as u64, &TIMER_MODE_ONE_SHOT.to_le_bytes()); 1657 a.write(Reg::TIMER_DIVIDE_CONTROL as u64, &[1, 0, 0, 0]); // Frequency divided by 4. 1658 a.write(Reg::TIMER_INITIAL_COUNT as u64, &500_000_u32.to_le_bytes()); 1659 1660 let timer_ns = u64::try_from(4 * 500_000 * a.get_cycle_length().as_nanos()).unwrap(); 1661 clock.lock().add_ns(timer_ns - 1); 1662 assert_eq!(a.timer.mark_waited(), Ok(true)); 1663 clock.lock().add_ns(1); 1664 assert_eq!(a.timer.mark_waited(), Ok(false)); 1665 // One-shot timer shouldn't fire again. 1666 clock.lock().add_ns(timer_ns); 1667 assert_eq!(a.timer.mark_waited(), Ok(true)); 1668 1669 a.write(Reg::TIMER_DIVIDE_CONTROL as u64, &[0b1011, 0, 0, 0]); // Frequency divided by 1. 1670 a.write(Reg::LOCAL_TIMER as u64, &TIMER_MODE_PERIODIC.to_le_bytes()); 1671 a.write( 1672 Reg::TIMER_INITIAL_COUNT as u64, 1673 &1_000_000_u32.to_le_bytes(), 1674 ); 1675 1676 let timer_ns = u64::try_from(1 * 1_000_000 * a.get_cycle_length().as_nanos()).unwrap(); 1677 clock.lock().add_ns(timer_ns - 1); 1678 assert_eq!(a.timer.mark_waited(), Ok(true)); 1679 clock.lock().add_ns(1); 1680 assert_eq!(a.timer.mark_waited(), Ok(false)); 1681 clock.lock().add_ns(timer_ns - 1); 1682 assert_eq!(a.timer.mark_waited(), Ok(true)); 1683 clock.lock().add_ns(1); 1684 assert_eq!(a.timer.mark_waited(), Ok(false)); 1685 } 1686 1687 #[test] timer_interrupts()1688 fn timer_interrupts() { 1689 let clock = Arc::new(Mutex::new(FakeClock::new())); 1690 let mut a = Apic::new(0, Box::new(FakeTimer::new(clock.clone()))); 1691 a.set_enabled(true); 1692 1693 // Masked timer shouldn't interrupt. 1694 let val = TIMER_MODE_PERIODIC | LOCAL_VECTOR_MASKED | 123; 1695 a.write(Reg::LOCAL_TIMER as u64, &val.to_le_bytes()); 1696 a.write(Reg::TIMER_DIVIDE_CONTROL as u64, &[0b1011, 0, 0, 0]); // Frequency divided by 1. 1697 a.write(Reg::TIMER_INITIAL_COUNT as u64, &500_000_u32.to_le_bytes()); 1698 clock 1699 .lock() 1700 .add_ns(500_000 * a.get_cycle_length().as_nanos() as u64); 1701 a.handle_timer_expiration(); 1702 assert_eq!(a.highest_bit_in_vector(VectorReg::Irr), None); 1703 1704 // Unmasked timer should interrupt on the vector in LOCAL_TIMER & 0xFF. 1705 let val = TIMER_MODE_PERIODIC | 123; 1706 a.write(Reg::LOCAL_TIMER as u64, &val.to_le_bytes()); 1707 clock 1708 .lock() 1709 .add_ns(500_000 * a.get_cycle_length().as_nanos() as u64); 1710 a.handle_timer_expiration(); 1711 assert_eq!(a.highest_bit_in_vector(VectorReg::Irr), Some(123)); 1712 } 1713 } 1714