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