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 match mode { 634 TIMER_MODE_ONE_SHOT => { 635 if let Err(e) = self.timer.reset_oneshot(length) { 636 error!("Failed to reset APIC timer to one-shot({:?}) {}", length, e); 637 return; 638 } 639 } 640 TIMER_MODE_PERIODIC => { 641 if let Err(e) = self.timer.reset_repeating(length) { 642 error!( 643 "Failed to reset APIC timer to repeating({:?}) {}", 644 length, e 645 ); 646 return; 647 } 648 } 649 TIMER_MODE_TSC_DEADLINE => { 650 warn!("APIC TSC-deadline timer not supported"); 651 return; 652 } 653 _ => { 654 error!("Invalid APIC timer mode 0x{:X}", mode); 655 return; 656 } 657 }; 658 659 self.last_tick = Instant::now(); 660 self.timer_length = Some(length); 661 } 662 clear_timer(&mut self)663 fn clear_timer(&mut self) { 664 if self.timer_length.is_some() { 665 if let Err(e) = self.timer.clear() { 666 error!("Failed to clear APIC timer: {}", e); 667 } 668 self.timer_length = None; 669 } 670 } 671 672 /// Returns the duration remaining until the next timer expiration. next_timer_expiration(&self) -> Duration673 fn next_timer_expiration(&self) -> Duration { 674 if let Some(length) = self.timer_length { 675 let elapsed = self.last_tick.elapsed(); 676 length.checked_sub(elapsed).unwrap_or(ZERO_DURATION) 677 } else { 678 ZERO_DURATION 679 } 680 } 681 } 682 683 impl Drop for Apic { drop(&mut self)684 fn drop(&mut self) { 685 self.clear_timer(); 686 } 687 } 688 689 /// A message from an `Apic` to the `UserspaceIrqChip`. 690 #[derive(Debug, Clone, Copy, PartialEq, Eq)] 691 pub enum ApicBusMsg { 692 /// Broadcasts end-of-interrupt for the specified vector. 693 Eoi(Vector), 694 /// Sends an IPI. 695 Ipi(Interrupt), 696 } 697 698 /// Pending `Apic` interrupts to be injected into a vcpu. 699 #[derive(Debug, Clone, Copy, PartialEq, Eq, Default)] 700 pub struct PendingInterrupts { 701 /// Vector of a pending fixed interrupt. 702 pub fixed: Option<Vector>, 703 /// Number of pending non-maskable interrupts. 704 pub nmis: u32, 705 /// True if there is a pending INIT IPI. 706 pub init: bool, 707 /// Vector of a pending startup IPI (SIPI). 708 pub startup: Option<Vector>, 709 /// True if there are additional pending interrupts to delivered in the future, so an interrupt 710 /// window should be requested for the vcpu. 711 pub needs_window: bool, 712 } 713 714 /// A quick method of specifying all processors, all excluding self, or self as the destination. 715 #[bitfield] 716 #[derive(Debug, Clone, Copy, PartialEq, Eq)] 717 pub enum DestinationShorthand { 718 None = 0b00, 719 Self_ = 0b01, 720 All = 0b10, 721 AllExcludingSelf = 0b11, 722 } 723 724 /// An interrupt to be sent to one or more `Apic`s. 725 #[derive(Debug, Clone, Copy, PartialEq, Eq)] 726 pub struct Interrupt { 727 /// Specifies the destination processors for this interrupt. 728 pub dest: InterruptDestination, 729 /// The vector and type of this interrupt. 730 pub data: InterruptData, 731 } 732 733 /// Specifies the destination processors for an `Interrupt`. 734 #[derive(Debug, Clone, Copy, PartialEq, Eq)] 735 pub struct InterruptDestination { 736 /// The APIC ID that sent this interrupt. 737 pub source_id: u8, 738 /// In physical destination mode, used to specify the APIC ID of the destination processor. 739 /// In logical destination mode, used to specify a message destination address (MDA) that can 740 /// be used to select specific processors in clusters. Only used if shorthand is None. 741 pub dest_id: u8, 742 /// Specifies a quick destination of all processors, all excluding self, or self. If None, 743 /// then dest_id and mode are used to find the destinations. 744 pub shorthand: DestinationShorthand, 745 /// Specifies if physical or logical addressing is used for matching dest_id. 746 pub mode: DestinationMode, 747 } 748 749 /// The vector and type of an `Interrupt`. 750 #[derive(Debug, Clone, Copy, PartialEq, Eq)] 751 pub struct InterruptData { 752 /// The index in the OS's interrupt descriptor table for this interrupt. 753 pub vector: Vector, 754 /// The type of interrupt: fixed (regular IDT vector), NMI, startup IPI, etc. 755 pub delivery: DeliveryMode, 756 /// Edge- or level-triggered. 757 pub trigger: TriggerMode, 758 /// For level-triggered interrupts, specifies whether the line should be asserted or 759 /// deasserted. 760 pub level: Level, 761 } 762 763 impl TryFrom<&MsiAddressMessage> for InterruptDestination { 764 type Error = String; 765 try_from(msi: &MsiAddressMessage) -> std::result::Result<Self, Self::Error>766 fn try_from(msi: &MsiAddressMessage) -> std::result::Result<Self, Self::Error> { 767 if msi.get_always_0xfee() != 0xFEE { 768 return Err(format!( 769 "top 12 bits must be 0xFEE but are 0x{:X}", 770 msi.get_always_0xfee() 771 )); 772 } 773 // TODO(srichman): Handle redirection hint? 774 Ok(InterruptDestination { 775 source_id: 0, 776 dest_id: msi.get_destination_id(), 777 shorthand: DestinationShorthand::None, 778 mode: msi.get_destination_mode(), 779 }) 780 } 781 } 782 783 impl From<&MsiDataMessage> for InterruptData { from(msi: &MsiDataMessage) -> Self784 fn from(msi: &MsiDataMessage) -> Self { 785 InterruptData { 786 vector: msi.get_vector(), 787 delivery: msi.get_delivery_mode(), 788 trigger: msi.get_trigger(), 789 level: msi.get_level(), 790 } 791 } 792 } 793 794 #[bitfield] 795 #[derive(Clone, Copy)] 796 struct LocalInterrupt { 797 vector: BitField8, 798 #[bits = 3] 799 delivery_mode: DeliveryMode, 800 reserved1: BitField1, 801 #[bits = 1] 802 delivery_status: DeliveryStatus, 803 polarity: BitField1, 804 remote_irr: BitField1, 805 #[bits = 1] 806 trigger: TriggerMode, 807 masked: BitField1, 808 reserved2: BitField7, 809 reserved3: BitField8, 810 } 811 812 #[bitfield] 813 #[derive(Clone, Copy)] 814 struct VersionRegister { 815 version: BitField8, 816 reserved1: BitField8, 817 max_lvt: BitField8, 818 eoi_broadcast_suppression: BitField1, 819 reserved2: BitField7, 820 } 821 822 #[bitfield] 823 #[derive(Clone, Copy)] 824 struct DestinationFormat { 825 reserved: BitField28, 826 model: BitField4, 827 } 828 829 #[bitfield] 830 #[derive(Clone, Copy)] 831 struct LogicalDestination { 832 reserved: BitField24, 833 logical_id: BitField8, 834 } 835 836 #[bitfield] 837 #[derive(Clone, Copy)] 838 struct InterruptCommand { 839 vector: BitField8, 840 #[bits = 3] 841 delivery: DeliveryMode, 842 #[bits = 1] 843 destination_mode: DestinationMode, 844 #[bits = 1] 845 delivery_status: DeliveryStatus, 846 reserved1: BitField1, 847 #[bits = 1] 848 level: Level, 849 #[bits = 1] 850 trigger: TriggerMode, 851 reserved2: BitField2, 852 #[bits = 2] 853 shorthand: DestinationShorthand, 854 reserved3: BitField36, 855 destination: BitField8, 856 } 857 858 struct Reg; 859 860 impl Reg { 861 const ID: usize = 0x20; 862 const VERSION: usize = 0x30; 863 const TPR: usize = 0x80; 864 const PPR: usize = 0xA0; 865 const EOI: usize = 0xB0; 866 const LOGICAL_DESTINATION: usize = 0xD0; 867 const DESTINATION_FORMAT: usize = 0xE0; 868 const SPURIOUS_INT: usize = 0xF0; 869 // In-service register is 0x100-0x170 870 const ISR: usize = 0x100; 871 // Trigger mode register is 0x180-0x1F0 872 const TMR: usize = 0x180; 873 // Interrupt request regsiter is 0x200-0x270 874 const IRR: usize = 0x200; 875 const LOCAL_CMCI: usize = 0x2F0; 876 const INTERRUPT_COMMAND_LO: usize = 0x300; 877 const INTERRUPT_COMMAND_HI: usize = 0x310; 878 const LOCAL_TIMER: usize = 0x320; 879 const LOCAL_THERMAL: usize = 0x330; 880 const LOCAL_PERF: usize = 0x340; 881 const LOCAL_INT_0: usize = 0x350; 882 const LOCAL_INT_1: usize = 0x360; 883 const LOCAL_ERROR: usize = 0x370; 884 const TIMER_INITIAL_COUNT: usize = 0x380; 885 const TIMER_CURRENT_COUNT: usize = 0x390; 886 const TIMER_DIVIDE_CONTROL: usize = 0x3E0; 887 } 888 889 /// The APIC registers that store interrupt vector bitmaps. Each has 256 bit flags, one for each 890 /// interrupt vector. The flags are spread across the first 32 bits of each of eight 16-byte APIC 891 /// register slots. 892 #[repr(usize)] 893 #[derive(Clone, Copy, Debug, PartialEq, Eq)] 894 enum VectorReg { 895 /// In-service register. A bit is set for each interrupt vector currently being serviced by 896 /// the processor. 897 Isr = Reg::ISR, 898 /// Trigger mode register. Records whether interrupts are edge-triggered (bit is clear) or 899 /// level-triggered (bit is set). 900 Tmr = Reg::TMR, 901 /// Interrupt request register. A bit is set for each interrupt vector received by the APIC 902 /// but not yet serviced by the processor. 903 Irr = Reg::IRR, 904 } 905 906 #[cfg(test)] 907 mod tests { 908 use std::mem; 909 use std::sync::Arc; 910 911 use base::FakeClock; 912 use base::FakeTimer; 913 use sync::Mutex; 914 915 use super::*; 916 917 #[test] struct_size()918 fn struct_size() { 919 assert_eq!(4, mem::size_of::<LocalInterrupt>()); 920 assert_eq!(4, mem::size_of::<VersionRegister>()); 921 assert_eq!(4, mem::size_of::<DestinationFormat>()); 922 assert_eq!(4, mem::size_of::<LogicalDestination>()); 923 assert_eq!(8, mem::size_of::<InterruptCommand>()); 924 } 925 926 #[test] get_reg()927 fn get_reg() { 928 let timer = Box::new(FakeTimer::new(Arc::new(Mutex::new(FakeClock::new())))); 929 let mut a = Apic::new(0, timer); 930 a.regs[0..4].copy_from_slice(&[0xFE, 0xCA, 0xAD, 0xAB]); 931 assert_eq!(a.get_reg(0), 0xABADCAFE); 932 a.regs[4092..4096].copy_from_slice(&[0x0D, 0xF0, 0x1D, 0xC0]); 933 assert_eq!(a.get_reg(4092), 0xC01DF00D); 934 } 935 936 #[test] set_reg()937 fn set_reg() { 938 let timer = Box::new(FakeTimer::new(Arc::new(Mutex::new(FakeClock::new())))); 939 let mut a = Apic::new(0, timer); 940 a.set_reg(0, 0xABADCAFE); 941 assert_eq!(a.regs[0..4], [0xFE, 0xCA, 0xAD, 0xAB]); 942 a.set_reg(4092, 0xC01DF00D); 943 assert_eq!(a.regs[4092..4096], [0x0D, 0xF0, 0x1D, 0xC0]); 944 } 945 946 #[test] lapic_state()947 fn lapic_state() { 948 let timer = Box::new(FakeTimer::new(Arc::new(Mutex::new(FakeClock::new())))); 949 let mut a = Apic::new(0, timer); 950 951 a.set_reg(0, 0xABADCAFE); 952 assert_eq!(a.get_state().regs[0], 0xABADCAFE); 953 954 let mut state = LapicState { regs: [0; 64] }; 955 state.regs[63] = 0xC01DF00D; 956 a.set_state(&state); 957 assert_eq!(a.regs[1008..1012], [0x0D, 0xF0, 0x1D, 0xC0]); 958 } 959 960 #[test] valid_mmio()961 fn valid_mmio() { 962 let timer = Box::new(FakeTimer::new(Arc::new(Mutex::new(FakeClock::new())))); 963 let mut a = Apic::new(42, timer); 964 965 let mut data = [0u8; 4]; 966 a.read(Reg::ID as u64, &mut data); 967 assert_eq!(data, [0, 0, 0, 42]); 968 a.write(Reg::INTERRUPT_COMMAND_HI as u64, &[0xFE, 0xCA, 0xAD, 0xAB]); 969 assert_eq!(a.get_reg(Reg::INTERRUPT_COMMAND_HI), 0xABADCAFE); 970 let mut data = [0u8; 4]; 971 a.read(Reg::INTERRUPT_COMMAND_HI as u64, &mut data); 972 assert_eq!(data, [0xFE, 0xCA, 0xAD, 0xAB]); 973 } 974 975 #[test] invalid_mmio()976 fn invalid_mmio() { 977 let timer = Box::new(FakeTimer::new(Arc::new(Mutex::new(FakeClock::new())))); 978 let mut a = Apic::new(0, timer); 979 a.set_reg(Reg::INTERRUPT_COMMAND_HI, 0xABADCAFE); 980 981 let mut data = [0u8; 5]; 982 a.read(Reg::INTERRUPT_COMMAND_HI as u64, &mut data); 983 assert_eq!(data, [0; 5]); 984 let mut data = [0u8; 4]; 985 a.read(Reg::INTERRUPT_COMMAND_HI as u64 + 1, &mut data); 986 assert_eq!(data, [0; 4]); 987 a.write(Reg::INTERRUPT_COMMAND_HI as u64, &[0; 3]); 988 assert_eq!(a.get_reg(Reg::INTERRUPT_COMMAND_HI), 0xABADCAFE); 989 a.write(Reg::INTERRUPT_COMMAND_HI as u64 + 1, &[0; 4]); 990 assert_eq!(a.get_reg(Reg::INTERRUPT_COMMAND_HI), 0xABADCAFE); 991 } 992 993 #[test] vector_reg()994 fn vector_reg() { 995 let timer = Box::new(FakeTimer::new(Arc::new(Mutex::new(FakeClock::new())))); 996 let mut a = Apic::new(0, timer); 997 998 assert_eq!(a.highest_bit_in_vector(VectorReg::Irr), None); 999 a.set_vector_bit(VectorReg::Irr, 0); 1000 assert_eq!(a.highest_bit_in_vector(VectorReg::Irr), Some(0)); 1001 a.set_vector_bit(VectorReg::Irr, 7); 1002 assert_eq!(a.highest_bit_in_vector(VectorReg::Irr), Some(7)); 1003 a.set_vector_bit(VectorReg::Irr, 8); 1004 assert_eq!(a.highest_bit_in_vector(VectorReg::Irr), Some(8)); 1005 a.set_vector_bit(VectorReg::Irr, 31); 1006 assert_eq!(a.highest_bit_in_vector(VectorReg::Irr), Some(31)); 1007 a.set_vector_bit(VectorReg::Irr, 32); 1008 assert_eq!(a.highest_bit_in_vector(VectorReg::Irr), Some(32)); 1009 a.set_vector_bit(VectorReg::Irr, 74); 1010 assert_eq!(a.highest_bit_in_vector(VectorReg::Irr), Some(74)); 1011 a.set_vector_bit(VectorReg::Irr, 66); 1012 assert_eq!(a.highest_bit_in_vector(VectorReg::Irr), Some(74)); 1013 a.set_vector_bit(VectorReg::Irr, 255); 1014 assert_eq!(a.highest_bit_in_vector(VectorReg::Irr), Some(255)); 1015 assert_eq!( 1016 a.get_reg(Reg::IRR), 1017 0b1000_0000_0000_0000_0000_0001_1000_0001 1018 ); 1019 assert_eq!( 1020 a.get_reg(Reg::IRR + 1 * REG_ALIGN_BYTES), 1021 0b0000_0000_0000_0000_0000_0000_0000_0001 1022 ); 1023 assert_eq!( 1024 a.get_reg(Reg::IRR + 2 * REG_ALIGN_BYTES), 1025 0b0000_0000_0000_0000_0000_0100_0000_0100 1026 ); 1027 assert_eq!(a.get_reg(Reg::IRR + 3 * REG_ALIGN_BYTES), 0); 1028 assert_eq!(a.get_reg(Reg::IRR + 4 * REG_ALIGN_BYTES), 0); 1029 assert_eq!(a.get_reg(Reg::IRR + 5 * REG_ALIGN_BYTES), 0); 1030 assert_eq!(a.get_reg(Reg::IRR + 6 * REG_ALIGN_BYTES), 0); 1031 assert_eq!( 1032 a.get_reg(Reg::IRR + 7 * REG_ALIGN_BYTES), 1033 0b1000_0000_0000_0000_0000_0000_0000_0000 1034 ); 1035 1036 a.clear_vector_bit(VectorReg::Irr, 255); 1037 assert_eq!(a.highest_bit_in_vector(VectorReg::Irr), Some(74)); 1038 a.clear_vector_bit(VectorReg::Irr, 74); 1039 assert_eq!(a.highest_bit_in_vector(VectorReg::Irr), Some(66)); 1040 a.clear_vector_bit(VectorReg::Irr, 32); 1041 a.clear_vector_bit(VectorReg::Irr, 66); 1042 a.clear_vector_bit(VectorReg::Irr, 31); 1043 a.clear_vector_bit(VectorReg::Irr, 200); 1044 assert_eq!(a.highest_bit_in_vector(VectorReg::Irr), Some(8)); 1045 assert_eq!( 1046 a.get_reg(Reg::IRR), 1047 0b0000_0000_0000_0000_0000_0001_1000_0001 1048 ); 1049 assert_eq!(a.get_reg(Reg::IRR + 1 * REG_ALIGN_BYTES), 0); 1050 assert_eq!(a.get_reg(Reg::IRR + 2 * REG_ALIGN_BYTES), 0); 1051 assert_eq!(a.get_reg(Reg::IRR + 3 * REG_ALIGN_BYTES), 0); 1052 assert_eq!(a.get_reg(Reg::IRR + 4 * REG_ALIGN_BYTES), 0); 1053 assert_eq!(a.get_reg(Reg::IRR + 5 * REG_ALIGN_BYTES), 0); 1054 assert_eq!(a.get_reg(Reg::IRR + 6 * REG_ALIGN_BYTES), 0); 1055 assert_eq!(a.get_reg(Reg::IRR + 7 * REG_ALIGN_BYTES), 0); 1056 } 1057 1058 #[test] single_dest()1059 fn single_dest() { 1060 assert_eq!( 1061 Apic::single_dest_fast(&InterruptDestination { 1062 source_id: 0, 1063 dest_id: 254, 1064 shorthand: DestinationShorthand::None, 1065 mode: DestinationMode::Physical, 1066 }), 1067 Some(254) 1068 ); 1069 assert_eq!( 1070 Apic::single_dest_fast(&InterruptDestination { 1071 source_id: 0, 1072 dest_id: 254, 1073 shorthand: DestinationShorthand::Self_, 1074 mode: DestinationMode::Physical, 1075 }), 1076 Some(0) 1077 ); 1078 assert_eq!( 1079 Apic::single_dest_fast(&InterruptDestination { 1080 source_id: 0, 1081 dest_id: PHYSICAL_BROADCAST_ADDRESS, 1082 shorthand: DestinationShorthand::None, 1083 mode: DestinationMode::Physical, 1084 }), 1085 None 1086 ); 1087 assert_eq!( 1088 Apic::single_dest_fast(&InterruptDestination { 1089 source_id: 0, 1090 dest_id: 254, 1091 shorthand: DestinationShorthand::All, 1092 mode: DestinationMode::Physical, 1093 }), 1094 None 1095 ); 1096 assert_eq!( 1097 Apic::single_dest_fast(&InterruptDestination { 1098 source_id: 0, 1099 dest_id: 254, 1100 shorthand: DestinationShorthand::AllExcludingSelf, 1101 mode: DestinationMode::Physical, 1102 }), 1103 None 1104 ); 1105 assert_eq!( 1106 Apic::single_dest_fast(&InterruptDestination { 1107 source_id: 0, 1108 dest_id: 254, 1109 shorthand: DestinationShorthand::None, 1110 mode: DestinationMode::Logical, 1111 }), 1112 None 1113 ); 1114 } 1115 1116 #[test] match_dest()1117 fn match_dest() { 1118 let timer = Box::new(FakeTimer::new(Arc::new(Mutex::new(FakeClock::new())))); 1119 let mut a = Apic::new(254, timer); 1120 a.set_reg(Reg::LOGICAL_DESTINATION, 0b11001001 << 24); 1121 1122 assert!(a.match_dest(&InterruptDestination { 1123 source_id: 0, 1124 dest_id: 254, 1125 shorthand: DestinationShorthand::None, 1126 mode: DestinationMode::Physical, 1127 })); 1128 assert!(a.match_dest(&InterruptDestination { 1129 source_id: 0, 1130 dest_id: PHYSICAL_BROADCAST_ADDRESS, 1131 shorthand: DestinationShorthand::None, 1132 mode: DestinationMode::Physical, 1133 })); 1134 assert!(!a.match_dest(&InterruptDestination { 1135 source_id: 0, 1136 dest_id: 77, 1137 shorthand: DestinationShorthand::None, 1138 mode: DestinationMode::Physical, 1139 })); 1140 assert!(a.match_dest(&InterruptDestination { 1141 source_id: 0, 1142 dest_id: 0b01001000, 1143 shorthand: DestinationShorthand::None, 1144 mode: DestinationMode::Logical, 1145 })); 1146 assert!(!a.match_dest(&InterruptDestination { 1147 source_id: 0, 1148 dest_id: 0b00010010, 1149 shorthand: DestinationShorthand::None, 1150 mode: DestinationMode::Logical, 1151 })); 1152 assert!(a.match_dest(&InterruptDestination { 1153 source_id: 0, 1154 dest_id: 0, 1155 shorthand: DestinationShorthand::All, 1156 mode: DestinationMode::Physical, 1157 })); 1158 assert!(a.match_dest(&InterruptDestination { 1159 source_id: 254, 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::Self_, 1168 mode: DestinationMode::Physical, 1169 })); 1170 assert!(a.match_dest(&InterruptDestination { 1171 source_id: 0, 1172 dest_id: 0, 1173 shorthand: DestinationShorthand::AllExcludingSelf, 1174 mode: DestinationMode::Physical, 1175 })); 1176 assert!(!a.match_dest(&InterruptDestination { 1177 source_id: 254, 1178 dest_id: 0, 1179 shorthand: DestinationShorthand::AllExcludingSelf, 1180 mode: DestinationMode::Physical, 1181 })); 1182 } 1183 1184 #[test] processor_priority()1185 fn processor_priority() { 1186 let timer = Box::new(FakeTimer::new(Arc::new(Mutex::new(FakeClock::new())))); 1187 let mut a = Apic::new(0, timer); 1188 assert_eq!(a.get_processor_priority(), 0); 1189 a.set_reg(Reg::TPR, 0xF); 1190 let prio = a.get_processor_priority(); 1191 // When TPR[7:4] == ISRV[7:4], the manual allows either 0 or TPR[3:0] for PPR[3:0]. 1192 assert!( 1193 prio == 0 || prio == 0xF, 1194 "Expected priority 0 or 0xF, got {}", 1195 prio 1196 ); 1197 a.set_reg(Reg::TPR, 0x10); 1198 assert_eq!(a.get_processor_priority(), 0x10); 1199 a.set_reg(Reg::TPR, 0); 1200 assert_eq!(a.get_processor_priority(), 0); 1201 1202 let timer = Box::new(FakeTimer::new(Arc::new(Mutex::new(FakeClock::new())))); 1203 let mut a = Apic::new(0, timer); 1204 a.set_vector_bit(VectorReg::Isr, 0xF); 1205 assert_eq!(a.get_processor_priority(), 0); 1206 a.set_vector_bit(VectorReg::Isr, 0x11); 1207 assert_eq!(a.get_processor_priority(), 0x10); 1208 a.clear_vector_bit(VectorReg::Isr, 0x11); 1209 assert_eq!(a.get_processor_priority(), 0); 1210 1211 let timer = Box::new(FakeTimer::new(Arc::new(Mutex::new(FakeClock::new())))); 1212 let mut a = Apic::new(0, timer); 1213 a.set_vector_bit(VectorReg::Isr, 0x25); 1214 a.set_vector_bit(VectorReg::Isr, 0x11); 1215 a.set_reg(Reg::TPR, 0x31); 1216 assert_eq!(a.get_processor_priority(), 0x31); 1217 a.set_reg(Reg::TPR, 0x19); 1218 assert_eq!(a.get_processor_priority(), 0x20); 1219 a.clear_vector_bit(VectorReg::Isr, 0x25); 1220 let prio = a.get_processor_priority(); 1221 assert!( 1222 prio == 0x10 || prio == 0x19, 1223 "Expected priority 0x10 or 0x19, got {}", 1224 prio 1225 ); 1226 } 1227 1228 #[test] accept_irq()1229 fn accept_irq() { 1230 let timer = Box::new(FakeTimer::new(Arc::new(Mutex::new(FakeClock::new())))); 1231 let mut a = Apic::new(0, timer); 1232 assert_eq!(a.init, false); 1233 assert_eq!(a.sipi, None); 1234 assert_eq!(a.nmis, 0); 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: 20, 1243 delivery: DeliveryMode::Fixed, 1244 trigger: TriggerMode::Level, 1245 level: Level::Assert, 1246 }); 1247 a.accept_irq(&InterruptData { 1248 vector: 21, 1249 delivery: DeliveryMode::Fixed, 1250 trigger: TriggerMode::Edge, 1251 level: Level::Assert, 1252 }); 1253 a.accept_irq(&InterruptData { 1254 vector: 255, 1255 delivery: DeliveryMode::Lowest, 1256 trigger: TriggerMode::Level, 1257 level: Level::Assert, 1258 }); 1259 a.accept_irq(&InterruptData { 1260 vector: 0, 1261 delivery: DeliveryMode::Init, 1262 trigger: TriggerMode::Level, 1263 level: Level::Assert, 1264 }); 1265 a.accept_irq(&InterruptData { 1266 vector: 7, 1267 delivery: DeliveryMode::Startup, 1268 trigger: TriggerMode::Edge, 1269 level: Level::Assert, 1270 }); 1271 a.accept_irq(&InterruptData { 1272 vector: 8, 1273 delivery: DeliveryMode::Startup, 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 a.accept_irq(&InterruptData { 1284 vector: 0, 1285 delivery: DeliveryMode::NMI, 1286 trigger: TriggerMode::Edge, 1287 level: Level::Assert, 1288 }); 1289 assert_eq!(a.init, true); 1290 assert_eq!(a.sipi, Some(8)); 1291 assert_eq!(a.nmis, 2); 1292 // IRR should be set for 20, 21, and 255. 1293 assert_eq!( 1294 a.get_reg(Reg::IRR), 1295 0b0000_0000_0011_0000_0000_0000_0000_0000 1296 ); 1297 assert_eq!(a.get_reg(Reg::IRR + 1 * REG_ALIGN_BYTES), 0); 1298 assert_eq!(a.get_reg(Reg::IRR + 2 * REG_ALIGN_BYTES), 0); 1299 assert_eq!(a.get_reg(Reg::IRR + 3 * REG_ALIGN_BYTES), 0); 1300 assert_eq!(a.get_reg(Reg::IRR + 4 * REG_ALIGN_BYTES), 0); 1301 assert_eq!(a.get_reg(Reg::IRR + 5 * REG_ALIGN_BYTES), 0); 1302 assert_eq!(a.get_reg(Reg::IRR + 6 * REG_ALIGN_BYTES), 0); 1303 assert_eq!( 1304 a.get_reg(Reg::IRR + 7 * REG_ALIGN_BYTES), 1305 0b1000_0000_0000_0000_0000_0000_0000_0000 1306 ); 1307 // ISR should be unset. 1308 assert_eq!(a.get_reg(Reg::ISR), 0); 1309 assert_eq!(a.get_reg(Reg::ISR + 1 * REG_ALIGN_BYTES), 0); 1310 assert_eq!(a.get_reg(Reg::ISR + 2 * REG_ALIGN_BYTES), 0); 1311 assert_eq!(a.get_reg(Reg::ISR + 3 * REG_ALIGN_BYTES), 0); 1312 assert_eq!(a.get_reg(Reg::ISR + 4 * REG_ALIGN_BYTES), 0); 1313 assert_eq!(a.get_reg(Reg::ISR + 5 * REG_ALIGN_BYTES), 0); 1314 assert_eq!(a.get_reg(Reg::ISR + 6 * REG_ALIGN_BYTES), 0); 1315 assert_eq!(a.get_reg(Reg::ISR + 7 * REG_ALIGN_BYTES), 0); 1316 // TMR should be set for 20 and 255. 1317 assert_eq!( 1318 a.get_reg(Reg::TMR), 1319 0b0000_0000_0001_0000_0000_0000_0000_0000 1320 ); 1321 assert_eq!(a.get_reg(Reg::TMR + 1 * REG_ALIGN_BYTES), 0); 1322 assert_eq!(a.get_reg(Reg::TMR + 2 * REG_ALIGN_BYTES), 0); 1323 assert_eq!(a.get_reg(Reg::TMR + 3 * REG_ALIGN_BYTES), 0); 1324 assert_eq!(a.get_reg(Reg::TMR + 4 * REG_ALIGN_BYTES), 0); 1325 assert_eq!(a.get_reg(Reg::TMR + 5 * REG_ALIGN_BYTES), 0); 1326 assert_eq!(a.get_reg(Reg::TMR + 6 * REG_ALIGN_BYTES), 0); 1327 assert_eq!( 1328 a.get_reg(Reg::TMR + 7 * REG_ALIGN_BYTES), 1329 0b1000_0000_0000_0000_0000_0000_0000_0000 1330 ); 1331 } 1332 1333 #[test] icr_write_sends_ipi()1334 fn icr_write_sends_ipi() { 1335 let timer = Box::new(FakeTimer::new(Arc::new(Mutex::new(FakeClock::new())))); 1336 let mut a = Apic::new(229, timer); 1337 1338 // Top 8 bits of ICR high are the destination. 1339 a.write(Reg::INTERRUPT_COMMAND_HI as u64, &[0, 0, 0, 42]); 1340 #[rustfmt::skip] 1341 let msg = a.write( 1342 Reg::INTERRUPT_COMMAND_LO as u64, 1343 &[ 1344 123, // vector 1345 0b11001001, // level 1, assert 1, reserved 0, idle 0, logical 1, lowest priority 001 1346 0b00001100, // reserved 0000, all excluding self 11, reserved 00 1347 0, // reserved 1348 ], 1349 ); 1350 let msg = msg.unwrap(); 1351 assert_eq!( 1352 msg, 1353 ApicBusMsg::Ipi(Interrupt { 1354 dest: InterruptDestination { 1355 source_id: 229, 1356 dest_id: 42, 1357 shorthand: DestinationShorthand::AllExcludingSelf, 1358 mode: DestinationMode::Logical, 1359 }, 1360 data: InterruptData { 1361 vector: 123, 1362 delivery: DeliveryMode::Lowest, 1363 trigger: TriggerMode::Level, 1364 level: Level::Assert, 1365 }, 1366 }) 1367 ); 1368 1369 a.write(Reg::INTERRUPT_COMMAND_HI as u64, &[0, 0, 0, 161]); 1370 let msg = a.write( 1371 Reg::INTERRUPT_COMMAND_LO as u64, 1372 &[ 1373 255, // vector 1374 0b00010110, // edge 0, deassert 0, reserved 0, pending 1, physical 0, sipi 110 1375 0b00000000, // reserved 0000, no shorthand 00, reserved 00 1376 0, // reserved 1377 ], 1378 ); 1379 let msg = msg.unwrap(); 1380 assert_eq!( 1381 msg, 1382 ApicBusMsg::Ipi(Interrupt { 1383 dest: InterruptDestination { 1384 source_id: 229, 1385 dest_id: 161, 1386 shorthand: DestinationShorthand::None, 1387 mode: DestinationMode::Physical, 1388 }, 1389 data: InterruptData { 1390 vector: 255, 1391 delivery: DeliveryMode::Startup, 1392 trigger: TriggerMode::Edge, 1393 level: Level::Deassert, 1394 }, 1395 }) 1396 ); 1397 } 1398 1399 #[test] end_of_interrupt()1400 fn end_of_interrupt() { 1401 let timer = Box::new(FakeTimer::new(Arc::new(Mutex::new(FakeClock::new())))); 1402 let mut a = Apic::new(0, timer); 1403 let msg = a.write(Reg::EOI as u64, &[0; 4]); 1404 assert_eq!(msg, None); // Spurious EOIs (no interrupt being serviced) should be ignored. 1405 a.set_vector_bit(VectorReg::Isr, 39); 1406 a.set_vector_bit(VectorReg::Isr, 255); 1407 let msg = a.write(Reg::EOI as u64, &[0; 4]).unwrap(); 1408 assert_eq!(msg, ApicBusMsg::Eoi(255)); 1409 assert_eq!(a.highest_bit_in_vector(VectorReg::Isr), Some(39)); 1410 a.set_vector_bit(VectorReg::Isr, 40); 1411 let msg = a.write(Reg::EOI as u64, &[0; 4]).unwrap(); 1412 assert_eq!(msg, ApicBusMsg::Eoi(40)); 1413 assert_eq!(a.highest_bit_in_vector(VectorReg::Isr), Some(39)); 1414 let msg = a.write(Reg::EOI as u64, &[0; 4]).unwrap(); 1415 assert_eq!(msg, ApicBusMsg::Eoi(39)); 1416 assert_eq!(a.highest_bit_in_vector(VectorReg::Isr), None); 1417 let msg = a.write(Reg::EOI as u64, &[0; 4]); 1418 assert_eq!(msg, None); 1419 } 1420 1421 #[test] non_fixed_irqs_injected()1422 fn non_fixed_irqs_injected() { 1423 let timer = Box::new(FakeTimer::new(Arc::new(Mutex::new(FakeClock::new())))); 1424 let mut a = Apic::new(0, timer); 1425 a.set_enabled(true); 1426 1427 a.accept_irq(&InterruptData { 1428 vector: 0, 1429 delivery: DeliveryMode::Init, 1430 trigger: TriggerMode::Level, 1431 level: Level::Assert, 1432 }); 1433 a.accept_irq(&InterruptData { 1434 vector: 7, 1435 delivery: DeliveryMode::Startup, 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 a.accept_irq(&InterruptData { 1446 vector: 0, 1447 delivery: DeliveryMode::NMI, 1448 trigger: TriggerMode::Edge, 1449 level: Level::Assert, 1450 }); 1451 // Non-fixed irqs should be injected even if vcpu_ready is false. */ 1452 let irqs = a.get_pending_irqs(/* vcpu_ready= */ false); 1453 assert_eq!( 1454 irqs, 1455 PendingInterrupts { 1456 fixed: None, 1457 nmis: 2, 1458 init: true, 1459 startup: Some(7), 1460 needs_window: false, 1461 } 1462 ); 1463 assert_eq!(a.nmis, 0); 1464 assert_eq!(a.init, false); 1465 assert_eq!(a.sipi, None); 1466 1467 a.accept_irq(&InterruptData { 1468 vector: 0, 1469 delivery: DeliveryMode::NMI, 1470 trigger: TriggerMode::Edge, 1471 level: Level::Assert, 1472 }); 1473 let irqs = a.get_pending_irqs(/* vcpu_ready= */ true); 1474 assert_eq!( 1475 irqs, 1476 PendingInterrupts { 1477 nmis: 1, 1478 ..Default::default() 1479 } 1480 ); 1481 assert_eq!(a.nmis, 0); 1482 1483 let irqs = a.get_pending_irqs(/* vcpu_ready= */ true); 1484 assert_eq!( 1485 irqs, 1486 PendingInterrupts { 1487 ..Default::default() 1488 } 1489 ); 1490 } 1491 1492 #[test] fixed_irq_injected()1493 fn fixed_irq_injected() { 1494 let timer = Box::new(FakeTimer::new(Arc::new(Mutex::new(FakeClock::new())))); 1495 let mut a = Apic::new(0, timer); 1496 a.set_enabled(true); 1497 1498 a.accept_irq(&InterruptData { 1499 vector: 0x10, 1500 delivery: DeliveryMode::Fixed, 1501 trigger: TriggerMode::Level, 1502 level: Level::Assert, 1503 }); 1504 let irqs = a.get_pending_irqs(/* vcpu_ready= */ false); 1505 assert_eq!( 1506 irqs, 1507 PendingInterrupts { 1508 fixed: None, 1509 needs_window: true, 1510 ..Default::default() 1511 } 1512 ); 1513 assert_eq!(a.highest_bit_in_vector(VectorReg::Irr), Some(0x10)); 1514 assert_eq!(a.highest_bit_in_vector(VectorReg::Isr), None); 1515 let irqs = a.get_pending_irqs(/* vcpu_ready= */ true); 1516 assert_eq!( 1517 irqs, 1518 PendingInterrupts { 1519 fixed: Some(0x10), 1520 needs_window: false, 1521 ..Default::default() 1522 } 1523 ); 1524 assert_eq!(a.highest_bit_in_vector(VectorReg::Irr), None); 1525 assert_eq!(a.highest_bit_in_vector(VectorReg::Isr), Some(0x10)); 1526 } 1527 1528 #[test] high_priority_irq_injected()1529 fn high_priority_irq_injected() { 1530 let timer = Box::new(FakeTimer::new(Arc::new(Mutex::new(FakeClock::new())))); 1531 let mut a = Apic::new(0, timer); 1532 a.set_enabled(true); 1533 1534 a.accept_irq(&InterruptData { 1535 vector: 0x10, 1536 delivery: DeliveryMode::Fixed, 1537 trigger: TriggerMode::Level, 1538 level: Level::Assert, 1539 }); 1540 let _ = a.get_pending_irqs(/* vcpu_ready= */ true); 1541 1542 // An interrupt in a higher priority class should be injected immediately if the window is 1543 // open. 1544 a.accept_irq(&InterruptData { 1545 vector: 0x20, 1546 delivery: DeliveryMode::Fixed, 1547 trigger: TriggerMode::Level, 1548 level: Level::Assert, 1549 }); 1550 let irqs = a.get_pending_irqs(/* vcpu_ready= */ false); 1551 assert_eq!( 1552 irqs, 1553 PendingInterrupts { 1554 fixed: None, 1555 needs_window: true, 1556 ..Default::default() 1557 } 1558 ); 1559 assert_eq!(a.highest_bit_in_vector(VectorReg::Irr), Some(0x20)); 1560 assert_eq!(a.highest_bit_in_vector(VectorReg::Isr), Some(0x10)); 1561 let irqs = a.get_pending_irqs(/* vcpu_ready= */ true); 1562 assert_eq!( 1563 irqs, 1564 PendingInterrupts { 1565 fixed: Some(0x20), 1566 needs_window: false, 1567 ..Default::default() 1568 } 1569 ); 1570 assert_eq!(a.highest_bit_in_vector(VectorReg::Irr), None); 1571 assert_eq!(a.highest_bit_in_vector(VectorReg::Isr), Some(0x20)); 1572 } 1573 1574 #[test] low_priority_irq_deferred()1575 fn low_priority_irq_deferred() { 1576 let timer = Box::new(FakeTimer::new(Arc::new(Mutex::new(FakeClock::new())))); 1577 let mut a = Apic::new(0, timer); 1578 a.set_enabled(true); 1579 1580 a.accept_irq(&InterruptData { 1581 vector: 0x10, 1582 delivery: DeliveryMode::Fixed, 1583 trigger: TriggerMode::Level, 1584 level: Level::Assert, 1585 }); 1586 let _ = a.get_pending_irqs(/* vcpu_ready= */ true); 1587 1588 // An interrupt in the same or lower priority class should be deferred. 1589 a.accept_irq(&InterruptData { 1590 vector: 0x15, 1591 delivery: DeliveryMode::Fixed, 1592 trigger: TriggerMode::Level, 1593 level: Level::Assert, 1594 }); 1595 let irqs = a.get_pending_irqs(/* vcpu_ready= */ true); 1596 assert_eq!( 1597 irqs, 1598 PendingInterrupts { 1599 fixed: None, 1600 // Not injectable due to higher priority ISRV, so no window needed. 1601 needs_window: false, 1602 ..Default::default() 1603 } 1604 ); 1605 assert_eq!(a.highest_bit_in_vector(VectorReg::Irr), Some(0x15)); 1606 assert_eq!(a.highest_bit_in_vector(VectorReg::Isr), Some(0x10)); 1607 1608 // EOI lets it be injected. 1609 let msg = a.write(Reg::EOI as u64, &[0; 4]).unwrap(); 1610 assert_eq!(msg, ApicBusMsg::Eoi(0x10)); 1611 let irqs = a.get_pending_irqs(/* vcpu_ready= */ true); 1612 assert_eq!( 1613 irqs, 1614 PendingInterrupts { 1615 fixed: Some(0x15), 1616 needs_window: false, 1617 ..Default::default() 1618 } 1619 ); 1620 } 1621 1622 #[test] tpr_defers_injection()1623 fn tpr_defers_injection() { 1624 let timer = Box::new(FakeTimer::new(Arc::new(Mutex::new(FakeClock::new())))); 1625 let mut a = Apic::new(0, timer); 1626 a.set_enabled(true); 1627 1628 a.accept_irq(&InterruptData { 1629 vector: 0x25, 1630 delivery: DeliveryMode::Fixed, 1631 trigger: TriggerMode::Level, 1632 level: Level::Assert, 1633 }); 1634 a.set_reg(Reg::TPR, 0x20); 1635 let irqs = a.get_pending_irqs(/* vcpu_ready= */ true); 1636 assert_eq!( 1637 irqs, 1638 PendingInterrupts { 1639 fixed: None, 1640 needs_window: false, 1641 ..Default::default() 1642 } 1643 ); 1644 a.set_reg(Reg::TPR, 0x19); 1645 let irqs = a.get_pending_irqs(/* vcpu_ready= */ true); 1646 assert_eq!( 1647 irqs, 1648 PendingInterrupts { 1649 fixed: Some(0x25), 1650 needs_window: false, 1651 ..Default::default() 1652 } 1653 ); 1654 } 1655 1656 #[test] timer_starts()1657 fn timer_starts() { 1658 let clock = Arc::new(Mutex::new(FakeClock::new())); 1659 let mut a = Apic::new(0, Box::new(FakeTimer::new(clock.clone()))); 1660 a.set_enabled(true); 1661 1662 a.write(Reg::LOCAL_TIMER as u64, &TIMER_MODE_ONE_SHOT.to_le_bytes()); 1663 a.write(Reg::TIMER_DIVIDE_CONTROL as u64, &[1, 0, 0, 0]); // Frequency divided by 4. 1664 a.write(Reg::TIMER_INITIAL_COUNT as u64, &500_000_u32.to_le_bytes()); 1665 1666 let timer_ns = u64::try_from(4 * 500_000 * a.get_cycle_length().as_nanos()).unwrap(); 1667 clock.lock().add_ns(timer_ns - 1); 1668 assert_eq!(a.timer.mark_waited(), Ok(true)); 1669 clock.lock().add_ns(1); 1670 assert_eq!(a.timer.mark_waited(), Ok(false)); 1671 // One-shot timer shouldn't fire again. 1672 clock.lock().add_ns(timer_ns); 1673 assert_eq!(a.timer.mark_waited(), Ok(true)); 1674 1675 a.write(Reg::TIMER_DIVIDE_CONTROL as u64, &[0b1011, 0, 0, 0]); // Frequency divided by 1. 1676 a.write(Reg::LOCAL_TIMER as u64, &TIMER_MODE_PERIODIC.to_le_bytes()); 1677 a.write( 1678 Reg::TIMER_INITIAL_COUNT as u64, 1679 &1_000_000_u32.to_le_bytes(), 1680 ); 1681 1682 let timer_ns = u64::try_from(1 * 1_000_000 * a.get_cycle_length().as_nanos()).unwrap(); 1683 clock.lock().add_ns(timer_ns - 1); 1684 assert_eq!(a.timer.mark_waited(), Ok(true)); 1685 clock.lock().add_ns(1); 1686 assert_eq!(a.timer.mark_waited(), Ok(false)); 1687 clock.lock().add_ns(timer_ns - 1); 1688 assert_eq!(a.timer.mark_waited(), Ok(true)); 1689 clock.lock().add_ns(1); 1690 assert_eq!(a.timer.mark_waited(), Ok(false)); 1691 } 1692 1693 #[test] timer_interrupts()1694 fn timer_interrupts() { 1695 let clock = Arc::new(Mutex::new(FakeClock::new())); 1696 let mut a = Apic::new(0, Box::new(FakeTimer::new(clock.clone()))); 1697 a.set_enabled(true); 1698 1699 // Masked timer shouldn't interrupt. 1700 let val = TIMER_MODE_PERIODIC | LOCAL_VECTOR_MASKED | 123; 1701 a.write(Reg::LOCAL_TIMER as u64, &val.to_le_bytes()); 1702 a.write(Reg::TIMER_DIVIDE_CONTROL as u64, &[0b1011, 0, 0, 0]); // Frequency divided by 1. 1703 a.write(Reg::TIMER_INITIAL_COUNT as u64, &500_000_u32.to_le_bytes()); 1704 clock 1705 .lock() 1706 .add_ns(500_000 * a.get_cycle_length().as_nanos() as u64); 1707 a.handle_timer_expiration(); 1708 assert_eq!(a.highest_bit_in_vector(VectorReg::Irr), None); 1709 1710 // Unmasked timer should interrupt on the vector in LOCAL_TIMER & 0xFF. 1711 let val = TIMER_MODE_PERIODIC | 123; 1712 a.write(Reg::LOCAL_TIMER as u64, &val.to_le_bytes()); 1713 clock 1714 .lock() 1715 .add_ns(500_000 * a.get_cycle_length().as_nanos() as u64); 1716 a.handle_timer_expiration(); 1717 assert_eq!(a.highest_bit_in_vector(VectorReg::Irr), Some(123)); 1718 } 1719 } 1720