1use std::convert::TryFrom;
18use std::convert::TryInto;
19use std::time::Duration;
20use std::time::Instant;
21
22use base::error;
23use base::warn;
24use base::TimerTrait;
25use bit_field::*;
26use hypervisor::DeliveryMode;
27use hypervisor::DeliveryStatus;
28use hypervisor::DestinationMode;
29use hypervisor::LapicState;
30use hypervisor::Level;
31use hypervisor::MPState;
32use hypervisor::MsiAddressMessage;
33use hypervisor::MsiDataMessage;
34use hypervisor::TriggerMode;
35
36pub type Vector = u8;
37
38pub const APIC_BASE_ADDRESS: u64 = 0xFEE00000;
40pub const APIC_MEM_LENGTH_BYTES: u64 = 0x1000;
42
43const CYCLE_LENGTH_FALLBACK: Duration = Duration::from_nanos(10);
46const REG_ALIGN_BYTES: usize = 16;
48const BOOTSTRAP_PROCESSOR: u8 = 0;
50const VERSION: u8 = 0x14;
52const MAX_LVT: u8 = 5;
54const LOCAL_VECTOR_MASKED: u32 = 1 << 16;
56const DESTINATION_FORMAT_FLAT: u8 = 0xF;
58const DESTINATION_FORMAT_CLUSTER: u8 = 0x0;
60const PHYSICAL_BROADCAST_ADDRESS: u8 = 0xFF;
62const SOFTWARE_ENABLE: u32 = 1 << 8;
64const TIMER_MODE_MASK: u32 = 3 << 17;
66const TIMER_MODE_ONE_SHOT: u32 = 0 << 17;
67const TIMER_MODE_PERIODIC: u32 = 1 << 17;
68const TIMER_MODE_TSC_DEADLINE: u32 = 2 << 17;
69const TIMER_DIVIDE_TABLE: [u32; 16] = [
72 2, 4, 8, 16, 1, 1, 1, 1, 32, 64, 128, 1, 1, 1, 1, 1, ];
77const ZERO_DURATION: Duration = Duration::from_nanos(0);
78
79pub struct Apic {
80 id: u8,
82 cycle_length: Duration,
85 regs: [u8; APIC_MEM_LENGTH_BYTES as usize],
89 mp_state: MPState,
91 timer: Box<dyn TimerTrait>,
93 timer_length: Option<Duration>,
97 last_tick: Instant,
100 sipi: Option<Vector>,
103 init: bool,
105 nmis: u32,
110}
111
112impl Apic {
113 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 pub fn frequency() -> u32 {
139 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 pub fn id(&self) -> u8 {
149 self.id
150 }
151
152 pub fn get_cycle_length(&self) -> Duration {
155 self.cycle_length
156 }
157
158 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 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 self.start_timer();
177 }
178
179 pub fn get_mp_state(&self) -> MPState {
181 self.mp_state
182 }
183
184 pub fn set_mp_state(&mut self, state: &MPState) {
186 self.mp_state = *state;
187 }
188
189 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 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 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), Reg::EOI => {
239 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 }
247 }
248 Reg::INTERRUPT_COMMAND_LO => {
249 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 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 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 }
294 }
295 msg
296 }
297
298 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 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 pub fn get_processor_priority(&self) -> u8 {
330 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 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 }
371 DeliveryMode::SMI => warn!("APIC doesn't handle SMIs, dropping interrupt"),
372 }
373 }
374
375 fn inject_interrupt(&mut self, clear: bool) -> Option<Vector> {
379 let irrv = self.highest_bit_in_vector(VectorReg::Irr).unwrap_or(0);
380 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 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 fn enabled(&self) -> bool {
418 self.get_reg(Reg::SPURIOUS_INT) & SOFTWARE_ENABLE != 0
419 }
420
421 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 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 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 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 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 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 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 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 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 fn reg_bit_for_vector(reg: VectorReg, vector: Vector) -> (usize, u8) {
563 let vector = vector as usize;
564 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 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 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 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
683impl Drop for Apic {
684 fn drop(&mut self) {
685 self.clear_timer();
686 }
687}
688
689#[derive(Debug, Clone, Copy, PartialEq, Eq)]
691pub enum ApicBusMsg {
692 Eoi(Vector),
694 Ipi(Interrupt),
696}
697
698#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
700pub struct PendingInterrupts {
701 pub fixed: Option<Vector>,
703 pub nmis: u32,
705 pub init: bool,
707 pub startup: Option<Vector>,
709 pub needs_window: bool,
712}
713
714#[bitfield]
716#[derive(Debug, Clone, Copy, PartialEq, Eq)]
717pub enum DestinationShorthand {
718 None = 0b00,
719 Self_ = 0b01,
720 All = 0b10,
721 AllExcludingSelf = 0b11,
722}
723
724#[derive(Debug, Clone, Copy, PartialEq, Eq)]
726pub struct Interrupt {
727 pub dest: InterruptDestination,
729 pub data: InterruptData,
731}
732
733#[derive(Debug, Clone, Copy, PartialEq, Eq)]
735pub struct InterruptDestination {
736 pub source_id: u8,
738 pub dest_id: u8,
742 pub shorthand: DestinationShorthand,
745 pub mode: DestinationMode,
747}
748
749#[derive(Debug, Clone, Copy, PartialEq, Eq)]
751pub struct InterruptData {
752 pub vector: Vector,
754 pub delivery: DeliveryMode,
756 pub trigger: TriggerMode,
758 pub level: Level,
761}
762
763impl 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 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
783impl 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)]
796struct 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)]
814struct 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)]
824struct DestinationFormat {
825 reserved: BitField28,
826 model: BitField4,
827}
828
829#[bitfield]
830#[derive(Clone, Copy)]
831struct LogicalDestination {
832 reserved: BitField24,
833 logical_id: BitField8,
834}
835
836#[bitfield]
837#[derive(Clone, Copy)]
838struct 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
858struct Reg;
859
860impl 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 const ISR: usize = 0x100;
871 const TMR: usize = 0x180;
873 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#[repr(usize)]
893#[derive(Clone, Copy, Debug, PartialEq, Eq)]
894enum VectorReg {
895 Isr = Reg::ISR,
898 Tmr = Reg::TMR,
901 Irr = Reg::IRR,
904}
905
906#[cfg(test)]
907mod 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 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 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 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 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 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, 0b11001001, 0b00001100, 0, ],
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, 0b00010110, 0b00000000, 0, ],
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); 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 let irqs = a.get_pending_irqs(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(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(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(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(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(true);
1539
1540 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(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(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(true);
1585
1586 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(true);
1594 assert_eq!(
1595 irqs,
1596 PendingInterrupts {
1597 fixed: None,
1598 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 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(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(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(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]); 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 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]); 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 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]); 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 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}