Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
google
GitHub Repository: google/crosvm
Path: blob/main/devices/src/irqchip/apic.rs
5394 views
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`.
114
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
138
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.
148
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.
154
pub fn get_cycle_length(&self) -> Duration {
155
self.cycle_length
156
}
157
158
/// Returns the state of the APIC registers.
159
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.
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.
180
pub fn get_mp_state(&self) -> MPState {
181
self.mp_state
182
}
183
184
/// Sets the multi-processing state.
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.
190
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`.
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.
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.
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`.
314
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.
329
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.
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.
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.
394
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.
417
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.
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).
436
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.
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
499
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.
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`.
549
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`.
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.
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
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
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`.
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`.
596
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
620
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
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
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.
673
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 {
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
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 {
784
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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 {prio}"
1195
);
1196
a.set_reg(Reg::TPR, 0x10);
1197
assert_eq!(a.get_processor_priority(), 0x10);
1198
a.set_reg(Reg::TPR, 0);
1199
assert_eq!(a.get_processor_priority(), 0);
1200
1201
let timer = Box::new(FakeTimer::new(Arc::new(Mutex::new(FakeClock::new()))));
1202
let mut a = Apic::new(0, timer);
1203
a.set_vector_bit(VectorReg::Isr, 0xF);
1204
assert_eq!(a.get_processor_priority(), 0);
1205
a.set_vector_bit(VectorReg::Isr, 0x11);
1206
assert_eq!(a.get_processor_priority(), 0x10);
1207
a.clear_vector_bit(VectorReg::Isr, 0x11);
1208
assert_eq!(a.get_processor_priority(), 0);
1209
1210
let timer = Box::new(FakeTimer::new(Arc::new(Mutex::new(FakeClock::new()))));
1211
let mut a = Apic::new(0, timer);
1212
a.set_vector_bit(VectorReg::Isr, 0x25);
1213
a.set_vector_bit(VectorReg::Isr, 0x11);
1214
a.set_reg(Reg::TPR, 0x31);
1215
assert_eq!(a.get_processor_priority(), 0x31);
1216
a.set_reg(Reg::TPR, 0x19);
1217
assert_eq!(a.get_processor_priority(), 0x20);
1218
a.clear_vector_bit(VectorReg::Isr, 0x25);
1219
let prio = a.get_processor_priority();
1220
assert!(
1221
prio == 0x10 || prio == 0x19,
1222
"Expected priority 0x10 or 0x19, got {prio}"
1223
);
1224
}
1225
1226
#[test]
1227
fn accept_irq() {
1228
let timer = Box::new(FakeTimer::new(Arc::new(Mutex::new(FakeClock::new()))));
1229
let mut a = Apic::new(0, timer);
1230
assert_eq!(a.init, false);
1231
assert_eq!(a.sipi, None);
1232
assert_eq!(a.nmis, 0);
1233
a.accept_irq(&InterruptData {
1234
vector: 20,
1235
delivery: DeliveryMode::Fixed,
1236
trigger: TriggerMode::Level,
1237
level: Level::Assert,
1238
});
1239
a.accept_irq(&InterruptData {
1240
vector: 20,
1241
delivery: DeliveryMode::Fixed,
1242
trigger: TriggerMode::Level,
1243
level: Level::Assert,
1244
});
1245
a.accept_irq(&InterruptData {
1246
vector: 21,
1247
delivery: DeliveryMode::Fixed,
1248
trigger: TriggerMode::Edge,
1249
level: Level::Assert,
1250
});
1251
a.accept_irq(&InterruptData {
1252
vector: 255,
1253
delivery: DeliveryMode::Lowest,
1254
trigger: TriggerMode::Level,
1255
level: Level::Assert,
1256
});
1257
a.accept_irq(&InterruptData {
1258
vector: 0,
1259
delivery: DeliveryMode::Init,
1260
trigger: TriggerMode::Level,
1261
level: Level::Assert,
1262
});
1263
a.accept_irq(&InterruptData {
1264
vector: 7,
1265
delivery: DeliveryMode::Startup,
1266
trigger: TriggerMode::Edge,
1267
level: Level::Assert,
1268
});
1269
a.accept_irq(&InterruptData {
1270
vector: 8,
1271
delivery: DeliveryMode::Startup,
1272
trigger: TriggerMode::Edge,
1273
level: Level::Assert,
1274
});
1275
a.accept_irq(&InterruptData {
1276
vector: 0,
1277
delivery: DeliveryMode::NMI,
1278
trigger: TriggerMode::Edge,
1279
level: Level::Assert,
1280
});
1281
a.accept_irq(&InterruptData {
1282
vector: 0,
1283
delivery: DeliveryMode::NMI,
1284
trigger: TriggerMode::Edge,
1285
level: Level::Assert,
1286
});
1287
assert_eq!(a.init, true);
1288
assert_eq!(a.sipi, Some(8));
1289
assert_eq!(a.nmis, 2);
1290
// IRR should be set for 20, 21, and 255.
1291
assert_eq!(
1292
a.get_reg(Reg::IRR),
1293
0b0000_0000_0011_0000_0000_0000_0000_0000
1294
);
1295
assert_eq!(a.get_reg(Reg::IRR + 1 * REG_ALIGN_BYTES), 0);
1296
assert_eq!(a.get_reg(Reg::IRR + 2 * REG_ALIGN_BYTES), 0);
1297
assert_eq!(a.get_reg(Reg::IRR + 3 * REG_ALIGN_BYTES), 0);
1298
assert_eq!(a.get_reg(Reg::IRR + 4 * REG_ALIGN_BYTES), 0);
1299
assert_eq!(a.get_reg(Reg::IRR + 5 * REG_ALIGN_BYTES), 0);
1300
assert_eq!(a.get_reg(Reg::IRR + 6 * REG_ALIGN_BYTES), 0);
1301
assert_eq!(
1302
a.get_reg(Reg::IRR + 7 * REG_ALIGN_BYTES),
1303
0b1000_0000_0000_0000_0000_0000_0000_0000
1304
);
1305
// ISR should be unset.
1306
assert_eq!(a.get_reg(Reg::ISR), 0);
1307
assert_eq!(a.get_reg(Reg::ISR + 1 * REG_ALIGN_BYTES), 0);
1308
assert_eq!(a.get_reg(Reg::ISR + 2 * REG_ALIGN_BYTES), 0);
1309
assert_eq!(a.get_reg(Reg::ISR + 3 * REG_ALIGN_BYTES), 0);
1310
assert_eq!(a.get_reg(Reg::ISR + 4 * REG_ALIGN_BYTES), 0);
1311
assert_eq!(a.get_reg(Reg::ISR + 5 * REG_ALIGN_BYTES), 0);
1312
assert_eq!(a.get_reg(Reg::ISR + 6 * REG_ALIGN_BYTES), 0);
1313
assert_eq!(a.get_reg(Reg::ISR + 7 * REG_ALIGN_BYTES), 0);
1314
// TMR should be set for 20 and 255.
1315
assert_eq!(
1316
a.get_reg(Reg::TMR),
1317
0b0000_0000_0001_0000_0000_0000_0000_0000
1318
);
1319
assert_eq!(a.get_reg(Reg::TMR + 1 * REG_ALIGN_BYTES), 0);
1320
assert_eq!(a.get_reg(Reg::TMR + 2 * REG_ALIGN_BYTES), 0);
1321
assert_eq!(a.get_reg(Reg::TMR + 3 * REG_ALIGN_BYTES), 0);
1322
assert_eq!(a.get_reg(Reg::TMR + 4 * REG_ALIGN_BYTES), 0);
1323
assert_eq!(a.get_reg(Reg::TMR + 5 * REG_ALIGN_BYTES), 0);
1324
assert_eq!(a.get_reg(Reg::TMR + 6 * REG_ALIGN_BYTES), 0);
1325
assert_eq!(
1326
a.get_reg(Reg::TMR + 7 * REG_ALIGN_BYTES),
1327
0b1000_0000_0000_0000_0000_0000_0000_0000
1328
);
1329
}
1330
1331
#[test]
1332
fn icr_write_sends_ipi() {
1333
let timer = Box::new(FakeTimer::new(Arc::new(Mutex::new(FakeClock::new()))));
1334
let mut a = Apic::new(229, timer);
1335
1336
// Top 8 bits of ICR high are the destination.
1337
a.write(Reg::INTERRUPT_COMMAND_HI as u64, &[0, 0, 0, 42]);
1338
#[rustfmt::skip]
1339
let msg = a.write(
1340
Reg::INTERRUPT_COMMAND_LO as u64,
1341
&[
1342
123, // vector
1343
0b11001001, // level 1, assert 1, reserved 0, idle 0, logical 1, lowest priority 001
1344
0b00001100, // reserved 0000, all excluding self 11, reserved 00
1345
0, // reserved
1346
],
1347
);
1348
let msg = msg.unwrap();
1349
assert_eq!(
1350
msg,
1351
ApicBusMsg::Ipi(Interrupt {
1352
dest: InterruptDestination {
1353
source_id: 229,
1354
dest_id: 42,
1355
shorthand: DestinationShorthand::AllExcludingSelf,
1356
mode: DestinationMode::Logical,
1357
},
1358
data: InterruptData {
1359
vector: 123,
1360
delivery: DeliveryMode::Lowest,
1361
trigger: TriggerMode::Level,
1362
level: Level::Assert,
1363
},
1364
})
1365
);
1366
1367
a.write(Reg::INTERRUPT_COMMAND_HI as u64, &[0, 0, 0, 161]);
1368
let msg = a.write(
1369
Reg::INTERRUPT_COMMAND_LO as u64,
1370
&[
1371
255, // vector
1372
0b00010110, // edge 0, deassert 0, reserved 0, pending 1, physical 0, sipi 110
1373
0b00000000, // reserved 0000, no shorthand 00, reserved 00
1374
0, // reserved
1375
],
1376
);
1377
let msg = msg.unwrap();
1378
assert_eq!(
1379
msg,
1380
ApicBusMsg::Ipi(Interrupt {
1381
dest: InterruptDestination {
1382
source_id: 229,
1383
dest_id: 161,
1384
shorthand: DestinationShorthand::None,
1385
mode: DestinationMode::Physical,
1386
},
1387
data: InterruptData {
1388
vector: 255,
1389
delivery: DeliveryMode::Startup,
1390
trigger: TriggerMode::Edge,
1391
level: Level::Deassert,
1392
},
1393
})
1394
);
1395
}
1396
1397
#[test]
1398
fn end_of_interrupt() {
1399
let timer = Box::new(FakeTimer::new(Arc::new(Mutex::new(FakeClock::new()))));
1400
let mut a = Apic::new(0, timer);
1401
let msg = a.write(Reg::EOI as u64, &[0; 4]);
1402
assert_eq!(msg, None); // Spurious EOIs (no interrupt being serviced) should be ignored.
1403
a.set_vector_bit(VectorReg::Isr, 39);
1404
a.set_vector_bit(VectorReg::Isr, 255);
1405
let msg = a.write(Reg::EOI as u64, &[0; 4]).unwrap();
1406
assert_eq!(msg, ApicBusMsg::Eoi(255));
1407
assert_eq!(a.highest_bit_in_vector(VectorReg::Isr), Some(39));
1408
a.set_vector_bit(VectorReg::Isr, 40);
1409
let msg = a.write(Reg::EOI as u64, &[0; 4]).unwrap();
1410
assert_eq!(msg, ApicBusMsg::Eoi(40));
1411
assert_eq!(a.highest_bit_in_vector(VectorReg::Isr), Some(39));
1412
let msg = a.write(Reg::EOI as u64, &[0; 4]).unwrap();
1413
assert_eq!(msg, ApicBusMsg::Eoi(39));
1414
assert_eq!(a.highest_bit_in_vector(VectorReg::Isr), None);
1415
let msg = a.write(Reg::EOI as u64, &[0; 4]);
1416
assert_eq!(msg, None);
1417
}
1418
1419
#[test]
1420
fn non_fixed_irqs_injected() {
1421
let timer = Box::new(FakeTimer::new(Arc::new(Mutex::new(FakeClock::new()))));
1422
let mut a = Apic::new(0, timer);
1423
a.set_enabled(true);
1424
1425
a.accept_irq(&InterruptData {
1426
vector: 0,
1427
delivery: DeliveryMode::Init,
1428
trigger: TriggerMode::Level,
1429
level: Level::Assert,
1430
});
1431
a.accept_irq(&InterruptData {
1432
vector: 7,
1433
delivery: DeliveryMode::Startup,
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
a.accept_irq(&InterruptData {
1444
vector: 0,
1445
delivery: DeliveryMode::NMI,
1446
trigger: TriggerMode::Edge,
1447
level: Level::Assert,
1448
});
1449
// Non-fixed irqs should be injected even if vcpu_ready is false. */
1450
let irqs = a.get_pending_irqs(/* vcpu_ready= */ false);
1451
assert_eq!(
1452
irqs,
1453
PendingInterrupts {
1454
fixed: None,
1455
nmis: 2,
1456
init: true,
1457
startup: Some(7),
1458
needs_window: false,
1459
}
1460
);
1461
assert_eq!(a.nmis, 0);
1462
assert_eq!(a.init, false);
1463
assert_eq!(a.sipi, None);
1464
1465
a.accept_irq(&InterruptData {
1466
vector: 0,
1467
delivery: DeliveryMode::NMI,
1468
trigger: TriggerMode::Edge,
1469
level: Level::Assert,
1470
});
1471
let irqs = a.get_pending_irqs(/* vcpu_ready= */ true);
1472
assert_eq!(
1473
irqs,
1474
PendingInterrupts {
1475
nmis: 1,
1476
..Default::default()
1477
}
1478
);
1479
assert_eq!(a.nmis, 0);
1480
1481
let irqs = a.get_pending_irqs(/* vcpu_ready= */ true);
1482
assert_eq!(
1483
irqs,
1484
PendingInterrupts {
1485
..Default::default()
1486
}
1487
);
1488
}
1489
1490
#[test]
1491
fn fixed_irq_injected() {
1492
let timer = Box::new(FakeTimer::new(Arc::new(Mutex::new(FakeClock::new()))));
1493
let mut a = Apic::new(0, timer);
1494
a.set_enabled(true);
1495
1496
a.accept_irq(&InterruptData {
1497
vector: 0x10,
1498
delivery: DeliveryMode::Fixed,
1499
trigger: TriggerMode::Level,
1500
level: Level::Assert,
1501
});
1502
let irqs = a.get_pending_irqs(/* vcpu_ready= */ false);
1503
assert_eq!(
1504
irqs,
1505
PendingInterrupts {
1506
fixed: None,
1507
needs_window: true,
1508
..Default::default()
1509
}
1510
);
1511
assert_eq!(a.highest_bit_in_vector(VectorReg::Irr), Some(0x10));
1512
assert_eq!(a.highest_bit_in_vector(VectorReg::Isr), None);
1513
let irqs = a.get_pending_irqs(/* vcpu_ready= */ true);
1514
assert_eq!(
1515
irqs,
1516
PendingInterrupts {
1517
fixed: Some(0x10),
1518
needs_window: false,
1519
..Default::default()
1520
}
1521
);
1522
assert_eq!(a.highest_bit_in_vector(VectorReg::Irr), None);
1523
assert_eq!(a.highest_bit_in_vector(VectorReg::Isr), Some(0x10));
1524
}
1525
1526
#[test]
1527
fn high_priority_irq_injected() {
1528
let timer = Box::new(FakeTimer::new(Arc::new(Mutex::new(FakeClock::new()))));
1529
let mut a = Apic::new(0, timer);
1530
a.set_enabled(true);
1531
1532
a.accept_irq(&InterruptData {
1533
vector: 0x10,
1534
delivery: DeliveryMode::Fixed,
1535
trigger: TriggerMode::Level,
1536
level: Level::Assert,
1537
});
1538
let _ = a.get_pending_irqs(/* vcpu_ready= */ true);
1539
1540
// An interrupt in a higher priority class should be injected immediately if the window is
1541
// open.
1542
a.accept_irq(&InterruptData {
1543
vector: 0x20,
1544
delivery: DeliveryMode::Fixed,
1545
trigger: TriggerMode::Level,
1546
level: Level::Assert,
1547
});
1548
let irqs = a.get_pending_irqs(/* vcpu_ready= */ false);
1549
assert_eq!(
1550
irqs,
1551
PendingInterrupts {
1552
fixed: None,
1553
needs_window: true,
1554
..Default::default()
1555
}
1556
);
1557
assert_eq!(a.highest_bit_in_vector(VectorReg::Irr), Some(0x20));
1558
assert_eq!(a.highest_bit_in_vector(VectorReg::Isr), Some(0x10));
1559
let irqs = a.get_pending_irqs(/* vcpu_ready= */ true);
1560
assert_eq!(
1561
irqs,
1562
PendingInterrupts {
1563
fixed: Some(0x20),
1564
needs_window: false,
1565
..Default::default()
1566
}
1567
);
1568
assert_eq!(a.highest_bit_in_vector(VectorReg::Irr), None);
1569
assert_eq!(a.highest_bit_in_vector(VectorReg::Isr), Some(0x20));
1570
}
1571
1572
#[test]
1573
fn low_priority_irq_deferred() {
1574
let timer = Box::new(FakeTimer::new(Arc::new(Mutex::new(FakeClock::new()))));
1575
let mut a = Apic::new(0, timer);
1576
a.set_enabled(true);
1577
1578
a.accept_irq(&InterruptData {
1579
vector: 0x10,
1580
delivery: DeliveryMode::Fixed,
1581
trigger: TriggerMode::Level,
1582
level: Level::Assert,
1583
});
1584
let _ = a.get_pending_irqs(/* vcpu_ready= */ true);
1585
1586
// An interrupt in the same or lower priority class should be deferred.
1587
a.accept_irq(&InterruptData {
1588
vector: 0x15,
1589
delivery: DeliveryMode::Fixed,
1590
trigger: TriggerMode::Level,
1591
level: Level::Assert,
1592
});
1593
let irqs = a.get_pending_irqs(/* vcpu_ready= */ true);
1594
assert_eq!(
1595
irqs,
1596
PendingInterrupts {
1597
fixed: None,
1598
// Not injectable due to higher priority ISRV, so no window needed.
1599
needs_window: false,
1600
..Default::default()
1601
}
1602
);
1603
assert_eq!(a.highest_bit_in_vector(VectorReg::Irr), Some(0x15));
1604
assert_eq!(a.highest_bit_in_vector(VectorReg::Isr), Some(0x10));
1605
1606
// EOI lets it be injected.
1607
let msg = a.write(Reg::EOI as u64, &[0; 4]).unwrap();
1608
assert_eq!(msg, ApicBusMsg::Eoi(0x10));
1609
let irqs = a.get_pending_irqs(/* vcpu_ready= */ true);
1610
assert_eq!(
1611
irqs,
1612
PendingInterrupts {
1613
fixed: Some(0x15),
1614
needs_window: false,
1615
..Default::default()
1616
}
1617
);
1618
}
1619
1620
#[test]
1621
fn tpr_defers_injection() {
1622
let timer = Box::new(FakeTimer::new(Arc::new(Mutex::new(FakeClock::new()))));
1623
let mut a = Apic::new(0, timer);
1624
a.set_enabled(true);
1625
1626
a.accept_irq(&InterruptData {
1627
vector: 0x25,
1628
delivery: DeliveryMode::Fixed,
1629
trigger: TriggerMode::Level,
1630
level: Level::Assert,
1631
});
1632
a.set_reg(Reg::TPR, 0x20);
1633
let irqs = a.get_pending_irqs(/* vcpu_ready= */ true);
1634
assert_eq!(
1635
irqs,
1636
PendingInterrupts {
1637
fixed: None,
1638
needs_window: false,
1639
..Default::default()
1640
}
1641
);
1642
a.set_reg(Reg::TPR, 0x19);
1643
let irqs = a.get_pending_irqs(/* vcpu_ready= */ true);
1644
assert_eq!(
1645
irqs,
1646
PendingInterrupts {
1647
fixed: Some(0x25),
1648
needs_window: false,
1649
..Default::default()
1650
}
1651
);
1652
}
1653
1654
#[test]
1655
fn timer_starts() {
1656
let clock = Arc::new(Mutex::new(FakeClock::new()));
1657
let mut a = Apic::new(0, Box::new(FakeTimer::new(clock.clone())));
1658
a.set_enabled(true);
1659
1660
a.write(Reg::LOCAL_TIMER as u64, &TIMER_MODE_ONE_SHOT.to_le_bytes());
1661
a.write(Reg::TIMER_DIVIDE_CONTROL as u64, &[1, 0, 0, 0]); // Frequency divided by 4.
1662
a.write(Reg::TIMER_INITIAL_COUNT as u64, &500_000_u32.to_le_bytes());
1663
1664
let timer_ns = u64::try_from(4 * 500_000 * a.get_cycle_length().as_nanos()).unwrap();
1665
clock.lock().add_ns(timer_ns - 1);
1666
assert_eq!(a.timer.mark_waited(), Ok(true));
1667
clock.lock().add_ns(1);
1668
assert_eq!(a.timer.mark_waited(), Ok(false));
1669
// One-shot timer shouldn't fire again.
1670
clock.lock().add_ns(timer_ns);
1671
assert_eq!(a.timer.mark_waited(), Ok(true));
1672
1673
a.write(Reg::TIMER_DIVIDE_CONTROL as u64, &[0b1011, 0, 0, 0]); // Frequency divided by 1.
1674
a.write(Reg::LOCAL_TIMER as u64, &TIMER_MODE_PERIODIC.to_le_bytes());
1675
a.write(
1676
Reg::TIMER_INITIAL_COUNT as u64,
1677
&1_000_000_u32.to_le_bytes(),
1678
);
1679
1680
let timer_ns = u64::try_from(1 * 1_000_000 * a.get_cycle_length().as_nanos()).unwrap();
1681
clock.lock().add_ns(timer_ns - 1);
1682
assert_eq!(a.timer.mark_waited(), Ok(true));
1683
clock.lock().add_ns(1);
1684
assert_eq!(a.timer.mark_waited(), Ok(false));
1685
clock.lock().add_ns(timer_ns - 1);
1686
assert_eq!(a.timer.mark_waited(), Ok(true));
1687
clock.lock().add_ns(1);
1688
assert_eq!(a.timer.mark_waited(), Ok(false));
1689
}
1690
1691
#[test]
1692
fn timer_interrupts() {
1693
let clock = Arc::new(Mutex::new(FakeClock::new()));
1694
let mut a = Apic::new(0, Box::new(FakeTimer::new(clock.clone())));
1695
a.set_enabled(true);
1696
1697
// Masked timer shouldn't interrupt.
1698
let val = TIMER_MODE_PERIODIC | LOCAL_VECTOR_MASKED | 123;
1699
a.write(Reg::LOCAL_TIMER as u64, &val.to_le_bytes());
1700
a.write(Reg::TIMER_DIVIDE_CONTROL as u64, &[0b1011, 0, 0, 0]); // Frequency divided by 1.
1701
a.write(Reg::TIMER_INITIAL_COUNT as u64, &500_000_u32.to_le_bytes());
1702
clock
1703
.lock()
1704
.add_ns(500_000 * a.get_cycle_length().as_nanos() as u64);
1705
a.handle_timer_expiration();
1706
assert_eq!(a.highest_bit_in_vector(VectorReg::Irr), None);
1707
1708
// Unmasked timer should interrupt on the vector in LOCAL_TIMER & 0xFF.
1709
let val = TIMER_MODE_PERIODIC | 123;
1710
a.write(Reg::LOCAL_TIMER as u64, &val.to_le_bytes());
1711
clock
1712
.lock()
1713
.add_ns(500_000 * a.get_cycle_length().as_nanos() as u64);
1714
a.handle_timer_expiration();
1715
assert_eq!(a.highest_bit_in_vector(VectorReg::Irr), Some(123));
1716
}
1717
}
1718
1719