xref: /aosp_15_r20/external/crosvm/devices/tests/irqchip/x86_64.rs (revision bb4ee6a4ae7042d18b07a98463b9c8b875e44b39)
1*bb4ee6a4SAndroid Build Coastguard Worker // Copyright 2022 The ChromiumOS Authors
2*bb4ee6a4SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*bb4ee6a4SAndroid Build Coastguard Worker // found in the LICENSE file.
4*bb4ee6a4SAndroid Build Coastguard Worker 
5*bb4ee6a4SAndroid Build Coastguard Worker #![cfg(target_arch = "x86_64")]
6*bb4ee6a4SAndroid Build Coastguard Worker 
7*bb4ee6a4SAndroid Build Coastguard Worker use devices::IrqChipX86_64;
8*bb4ee6a4SAndroid Build Coastguard Worker use devices::Routes;
9*bb4ee6a4SAndroid Build Coastguard Worker use hypervisor::IrqRoute;
10*bb4ee6a4SAndroid Build Coastguard Worker use hypervisor::IrqSource;
11*bb4ee6a4SAndroid Build Coastguard Worker use hypervisor::IrqSourceChip;
12*bb4ee6a4SAndroid Build Coastguard Worker use hypervisor::PicSelect;
13*bb4ee6a4SAndroid Build Coastguard Worker 
14*bb4ee6a4SAndroid Build Coastguard Worker #[allow(unused)]
test_get_pic(mut chip: impl IrqChipX86_64)15*bb4ee6a4SAndroid Build Coastguard Worker pub fn test_get_pic(mut chip: impl IrqChipX86_64) {
16*bb4ee6a4SAndroid Build Coastguard Worker     let state = chip
17*bb4ee6a4SAndroid Build Coastguard Worker         .get_pic_state(PicSelect::Primary)
18*bb4ee6a4SAndroid Build Coastguard Worker         .expect("could not get pic state");
19*bb4ee6a4SAndroid Build Coastguard Worker 
20*bb4ee6a4SAndroid Build Coastguard Worker     // Default is that no irq lines are asserted
21*bb4ee6a4SAndroid Build Coastguard Worker     assert_eq!(state.irr, 0);
22*bb4ee6a4SAndroid Build Coastguard Worker 
23*bb4ee6a4SAndroid Build Coastguard Worker     // Assert Irq Line 0
24*bb4ee6a4SAndroid Build Coastguard Worker     chip.service_irq(0, true).expect("could not service irq");
25*bb4ee6a4SAndroid Build Coastguard Worker 
26*bb4ee6a4SAndroid Build Coastguard Worker     let state = chip
27*bb4ee6a4SAndroid Build Coastguard Worker         .get_pic_state(PicSelect::Primary)
28*bb4ee6a4SAndroid Build Coastguard Worker         .expect("could not get pic state");
29*bb4ee6a4SAndroid Build Coastguard Worker 
30*bb4ee6a4SAndroid Build Coastguard Worker     // Bit 0 should now be 1
31*bb4ee6a4SAndroid Build Coastguard Worker     assert_eq!(state.irr, 1);
32*bb4ee6a4SAndroid Build Coastguard Worker }
33*bb4ee6a4SAndroid Build Coastguard Worker 
test_set_pic(mut chip: impl IrqChipX86_64)34*bb4ee6a4SAndroid Build Coastguard Worker pub fn test_set_pic(mut chip: impl IrqChipX86_64) {
35*bb4ee6a4SAndroid Build Coastguard Worker     let mut state = chip
36*bb4ee6a4SAndroid Build Coastguard Worker         .get_pic_state(PicSelect::Primary)
37*bb4ee6a4SAndroid Build Coastguard Worker         .expect("could not get pic state");
38*bb4ee6a4SAndroid Build Coastguard Worker 
39*bb4ee6a4SAndroid Build Coastguard Worker     // set bits 0 and 1
40*bb4ee6a4SAndroid Build Coastguard Worker     state.irr = 3;
41*bb4ee6a4SAndroid Build Coastguard Worker 
42*bb4ee6a4SAndroid Build Coastguard Worker     chip.set_pic_state(PicSelect::Primary, &state)
43*bb4ee6a4SAndroid Build Coastguard Worker         .expect("could not set the pic state");
44*bb4ee6a4SAndroid Build Coastguard Worker 
45*bb4ee6a4SAndroid Build Coastguard Worker     let state = chip
46*bb4ee6a4SAndroid Build Coastguard Worker         .get_pic_state(PicSelect::Primary)
47*bb4ee6a4SAndroid Build Coastguard Worker         .expect("could not get pic state");
48*bb4ee6a4SAndroid Build Coastguard Worker 
49*bb4ee6a4SAndroid Build Coastguard Worker     // Bits 1 and 0 should now be 1
50*bb4ee6a4SAndroid Build Coastguard Worker     assert_eq!(state.irr, 3);
51*bb4ee6a4SAndroid Build Coastguard Worker }
52*bb4ee6a4SAndroid Build Coastguard Worker 
test_get_ioapic(mut chip: impl IrqChipX86_64)53*bb4ee6a4SAndroid Build Coastguard Worker pub fn test_get_ioapic(mut chip: impl IrqChipX86_64) {
54*bb4ee6a4SAndroid Build Coastguard Worker     let state = chip.get_ioapic_state().expect("could not get ioapic state");
55*bb4ee6a4SAndroid Build Coastguard Worker 
56*bb4ee6a4SAndroid Build Coastguard Worker     // Default is that no irq lines are asserted
57*bb4ee6a4SAndroid Build Coastguard Worker     assert_eq!(state.current_interrupt_level_bitmap, 0);
58*bb4ee6a4SAndroid Build Coastguard Worker 
59*bb4ee6a4SAndroid Build Coastguard Worker     // Default routing entries has routes 0..24 routed to vectors 0..24
60*bb4ee6a4SAndroid Build Coastguard Worker     for i in 0..24 {
61*bb4ee6a4SAndroid Build Coastguard Worker         // when the ioapic is reset by kvm, it defaults to all zeroes except the
62*bb4ee6a4SAndroid Build Coastguard Worker         // interrupt mask is set to 1, which is bit 16
63*bb4ee6a4SAndroid Build Coastguard Worker         assert_eq!(state.redirect_table[i].get(0, 64), 1 << 16);
64*bb4ee6a4SAndroid Build Coastguard Worker     }
65*bb4ee6a4SAndroid Build Coastguard Worker 
66*bb4ee6a4SAndroid Build Coastguard Worker     // Assert Irq Line 1
67*bb4ee6a4SAndroid Build Coastguard Worker     chip.service_irq(1, true).expect("could not set irq line");
68*bb4ee6a4SAndroid Build Coastguard Worker 
69*bb4ee6a4SAndroid Build Coastguard Worker     let state = chip.get_ioapic_state().expect("could not get ioapic state");
70*bb4ee6a4SAndroid Build Coastguard Worker 
71*bb4ee6a4SAndroid Build Coastguard Worker     // Bit 1 should now be 1
72*bb4ee6a4SAndroid Build Coastguard Worker     assert_eq!(state.current_interrupt_level_bitmap, 2);
73*bb4ee6a4SAndroid Build Coastguard Worker }
74*bb4ee6a4SAndroid Build Coastguard Worker 
test_set_ioapic(mut chip: impl IrqChipX86_64)75*bb4ee6a4SAndroid Build Coastguard Worker pub fn test_set_ioapic(mut chip: impl IrqChipX86_64) {
76*bb4ee6a4SAndroid Build Coastguard Worker     let mut state = chip.get_ioapic_state().expect("could not get ioapic state");
77*bb4ee6a4SAndroid Build Coastguard Worker 
78*bb4ee6a4SAndroid Build Coastguard Worker     // set a vector in the redirect table
79*bb4ee6a4SAndroid Build Coastguard Worker     state.redirect_table[2].set_vector(15);
80*bb4ee6a4SAndroid Build Coastguard Worker     // set the irq line status on that entry
81*bb4ee6a4SAndroid Build Coastguard Worker     state.current_interrupt_level_bitmap = 4;
82*bb4ee6a4SAndroid Build Coastguard Worker 
83*bb4ee6a4SAndroid Build Coastguard Worker     chip.set_ioapic_state(&state)
84*bb4ee6a4SAndroid Build Coastguard Worker         .expect("could not set the ioapic state");
85*bb4ee6a4SAndroid Build Coastguard Worker 
86*bb4ee6a4SAndroid Build Coastguard Worker     let state = chip.get_ioapic_state().expect("could not get ioapic state");
87*bb4ee6a4SAndroid Build Coastguard Worker 
88*bb4ee6a4SAndroid Build Coastguard Worker     // verify that get_ioapic_state returns what we set
89*bb4ee6a4SAndroid Build Coastguard Worker     assert_eq!(state.redirect_table[2].get_vector(), 15);
90*bb4ee6a4SAndroid Build Coastguard Worker     assert_eq!(state.current_interrupt_level_bitmap, 4);
91*bb4ee6a4SAndroid Build Coastguard Worker }
92*bb4ee6a4SAndroid Build Coastguard Worker 
test_get_pit(chip: impl IrqChipX86_64)93*bb4ee6a4SAndroid Build Coastguard Worker pub fn test_get_pit(chip: impl IrqChipX86_64) {
94*bb4ee6a4SAndroid Build Coastguard Worker     let state = chip.get_pit().expect("failed to get pit state");
95*bb4ee6a4SAndroid Build Coastguard Worker 
96*bb4ee6a4SAndroid Build Coastguard Worker     assert_eq!(state.flags, 0);
97*bb4ee6a4SAndroid Build Coastguard Worker     // assert reset state of pit
98*bb4ee6a4SAndroid Build Coastguard Worker     for i in 0..3 {
99*bb4ee6a4SAndroid Build Coastguard Worker         // initial count of 0 sets it to 0x10000;
100*bb4ee6a4SAndroid Build Coastguard Worker         assert_eq!(state.channels[i].count, 0x10000);
101*bb4ee6a4SAndroid Build Coastguard Worker     }
102*bb4ee6a4SAndroid Build Coastguard Worker }
103*bb4ee6a4SAndroid Build Coastguard Worker 
test_set_pit(mut chip: impl IrqChipX86_64)104*bb4ee6a4SAndroid Build Coastguard Worker pub fn test_set_pit(mut chip: impl IrqChipX86_64) {
105*bb4ee6a4SAndroid Build Coastguard Worker     let mut state = chip.get_pit().expect("failed to get pit state");
106*bb4ee6a4SAndroid Build Coastguard Worker 
107*bb4ee6a4SAndroid Build Coastguard Worker     // set some values
108*bb4ee6a4SAndroid Build Coastguard Worker     state.channels[0].count = 500;
109*bb4ee6a4SAndroid Build Coastguard Worker     state.channels[0].mode = 1;
110*bb4ee6a4SAndroid Build Coastguard Worker 
111*bb4ee6a4SAndroid Build Coastguard Worker     // Setting the pit should initialize the one-shot timer
112*bb4ee6a4SAndroid Build Coastguard Worker     chip.set_pit(&state).expect("failed to set pit state");
113*bb4ee6a4SAndroid Build Coastguard Worker 
114*bb4ee6a4SAndroid Build Coastguard Worker     let state = chip.get_pit().expect("failed to get pit state");
115*bb4ee6a4SAndroid Build Coastguard Worker 
116*bb4ee6a4SAndroid Build Coastguard Worker     // check the values we set
117*bb4ee6a4SAndroid Build Coastguard Worker     assert_eq!(state.channels[0].count, 500);
118*bb4ee6a4SAndroid Build Coastguard Worker     assert_eq!(state.channels[0].mode, 1);
119*bb4ee6a4SAndroid Build Coastguard Worker }
120*bb4ee6a4SAndroid Build Coastguard Worker 
121*bb4ee6a4SAndroid Build Coastguard Worker #[allow(unused)]
test_get_lapic(chip: impl IrqChipX86_64)122*bb4ee6a4SAndroid Build Coastguard Worker pub fn test_get_lapic(chip: impl IrqChipX86_64) {
123*bb4ee6a4SAndroid Build Coastguard Worker     let state = chip.get_lapic_state(0).expect("failed to get lapic state");
124*bb4ee6a4SAndroid Build Coastguard Worker 
125*bb4ee6a4SAndroid Build Coastguard Worker     // Checking some APIC reg defaults for KVM:
126*bb4ee6a4SAndroid Build Coastguard Worker     // DFR default is 0xffffffff
127*bb4ee6a4SAndroid Build Coastguard Worker     assert_eq!(state.regs[0xe], 0xffffffff);
128*bb4ee6a4SAndroid Build Coastguard Worker     // SPIV default is 0xff
129*bb4ee6a4SAndroid Build Coastguard Worker     assert_eq!(state.regs[0xf], 0xff);
130*bb4ee6a4SAndroid Build Coastguard Worker }
131*bb4ee6a4SAndroid Build Coastguard Worker 
132*bb4ee6a4SAndroid Build Coastguard Worker #[allow(unused)]
test_set_lapic(mut chip: impl IrqChipX86_64)133*bb4ee6a4SAndroid Build Coastguard Worker pub fn test_set_lapic(mut chip: impl IrqChipX86_64) {
134*bb4ee6a4SAndroid Build Coastguard Worker     // Get default state
135*bb4ee6a4SAndroid Build Coastguard Worker     let mut state = chip.get_lapic_state(0).expect("failed to get lapic state");
136*bb4ee6a4SAndroid Build Coastguard Worker 
137*bb4ee6a4SAndroid Build Coastguard Worker     // ESR should start out as 0
138*bb4ee6a4SAndroid Build Coastguard Worker     assert_eq!(state.regs[8], 0);
139*bb4ee6a4SAndroid Build Coastguard Worker     // Set a value in the ESR
140*bb4ee6a4SAndroid Build Coastguard Worker     state.regs[8] = 1 << 8;
141*bb4ee6a4SAndroid Build Coastguard Worker     chip.set_lapic_state(0, &state)
142*bb4ee6a4SAndroid Build Coastguard Worker         .expect("failed to set lapic state");
143*bb4ee6a4SAndroid Build Coastguard Worker 
144*bb4ee6a4SAndroid Build Coastguard Worker     // check that new ESR value stuck
145*bb4ee6a4SAndroid Build Coastguard Worker     let state = chip.get_lapic_state(0).expect("failed to get lapic state");
146*bb4ee6a4SAndroid Build Coastguard Worker     assert_eq!(state.regs[8], 1 << 8);
147*bb4ee6a4SAndroid Build Coastguard Worker }
148*bb4ee6a4SAndroid Build Coastguard Worker 
149*bb4ee6a4SAndroid Build Coastguard Worker /// Helper function for checking the pic interrupt status
check_pic_interrupts(chip: &impl IrqChipX86_64, select: PicSelect, value: u8)150*bb4ee6a4SAndroid Build Coastguard Worker fn check_pic_interrupts(chip: &impl IrqChipX86_64, select: PicSelect, value: u8) {
151*bb4ee6a4SAndroid Build Coastguard Worker     let state = chip
152*bb4ee6a4SAndroid Build Coastguard Worker         .get_pic_state(select)
153*bb4ee6a4SAndroid Build Coastguard Worker         .expect("could not get ioapic state");
154*bb4ee6a4SAndroid Build Coastguard Worker 
155*bb4ee6a4SAndroid Build Coastguard Worker     assert_eq!(state.irr, value);
156*bb4ee6a4SAndroid Build Coastguard Worker }
157*bb4ee6a4SAndroid Build Coastguard Worker 
158*bb4ee6a4SAndroid Build Coastguard Worker /// Helper function for checking the ioapic interrupt status
check_ioapic_interrupts(chip: &impl IrqChipX86_64, value: u32)159*bb4ee6a4SAndroid Build Coastguard Worker fn check_ioapic_interrupts(chip: &impl IrqChipX86_64, value: u32) {
160*bb4ee6a4SAndroid Build Coastguard Worker     let state = chip.get_ioapic_state().expect("could not get ioapic state");
161*bb4ee6a4SAndroid Build Coastguard Worker 
162*bb4ee6a4SAndroid Build Coastguard Worker     // since the irq route goes nowhere the bitmap should still be 0
163*bb4ee6a4SAndroid Build Coastguard Worker     assert_eq!(state.current_interrupt_level_bitmap, value);
164*bb4ee6a4SAndroid Build Coastguard Worker }
165*bb4ee6a4SAndroid Build Coastguard Worker 
test_route_irq(mut chip: impl IrqChipX86_64)166*bb4ee6a4SAndroid Build Coastguard Worker pub fn test_route_irq(mut chip: impl IrqChipX86_64) {
167*bb4ee6a4SAndroid Build Coastguard Worker     // clear out irq routes
168*bb4ee6a4SAndroid Build Coastguard Worker     chip.set_irq_routes(&[])
169*bb4ee6a4SAndroid Build Coastguard Worker         .expect("failed to set empty irq routes");
170*bb4ee6a4SAndroid Build Coastguard Worker     // assert Irq Line 1
171*bb4ee6a4SAndroid Build Coastguard Worker     chip.service_irq(1, true).expect("could not set irq line");
172*bb4ee6a4SAndroid Build Coastguard Worker 
173*bb4ee6a4SAndroid Build Coastguard Worker     // no pic or ioapic interrupts should be asserted
174*bb4ee6a4SAndroid Build Coastguard Worker     check_pic_interrupts(&chip, PicSelect::Primary, 0);
175*bb4ee6a4SAndroid Build Coastguard Worker     check_ioapic_interrupts(&chip, 0);
176*bb4ee6a4SAndroid Build Coastguard Worker 
177*bb4ee6a4SAndroid Build Coastguard Worker     // now we route gsi 1 to pin 3 of the ioapic and pin 6 of the primary pic
178*bb4ee6a4SAndroid Build Coastguard Worker     chip.route_irq(IrqRoute {
179*bb4ee6a4SAndroid Build Coastguard Worker         gsi: 1,
180*bb4ee6a4SAndroid Build Coastguard Worker         source: IrqSource::Irqchip {
181*bb4ee6a4SAndroid Build Coastguard Worker             chip: IrqSourceChip::Ioapic,
182*bb4ee6a4SAndroid Build Coastguard Worker             pin: 3,
183*bb4ee6a4SAndroid Build Coastguard Worker         },
184*bb4ee6a4SAndroid Build Coastguard Worker     })
185*bb4ee6a4SAndroid Build Coastguard Worker     .expect("failed to assert irq route");
186*bb4ee6a4SAndroid Build Coastguard Worker     // re-assert Irq Line 1
187*bb4ee6a4SAndroid Build Coastguard Worker     chip.service_irq(1, true).expect("could not set irq line");
188*bb4ee6a4SAndroid Build Coastguard Worker 
189*bb4ee6a4SAndroid Build Coastguard Worker     // no pic line should be asserted, ioapic pin 3 should be asserted
190*bb4ee6a4SAndroid Build Coastguard Worker     check_pic_interrupts(&chip, PicSelect::Primary, 0);
191*bb4ee6a4SAndroid Build Coastguard Worker     check_ioapic_interrupts(&chip, 1 << 3);
192*bb4ee6a4SAndroid Build Coastguard Worker 
193*bb4ee6a4SAndroid Build Coastguard Worker     // de-assert Irq Line 1
194*bb4ee6a4SAndroid Build Coastguard Worker     chip.service_irq(1, false).expect("could not set irq line");
195*bb4ee6a4SAndroid Build Coastguard Worker 
196*bb4ee6a4SAndroid Build Coastguard Worker     // no pic or ioapic interrupts should be asserted
197*bb4ee6a4SAndroid Build Coastguard Worker     check_pic_interrupts(&chip, PicSelect::Primary, 0);
198*bb4ee6a4SAndroid Build Coastguard Worker     check_ioapic_interrupts(&chip, 0);
199*bb4ee6a4SAndroid Build Coastguard Worker 
200*bb4ee6a4SAndroid Build Coastguard Worker     // add pic route
201*bb4ee6a4SAndroid Build Coastguard Worker     chip.route_irq(IrqRoute {
202*bb4ee6a4SAndroid Build Coastguard Worker         gsi: 2,
203*bb4ee6a4SAndroid Build Coastguard Worker         source: IrqSource::Irqchip {
204*bb4ee6a4SAndroid Build Coastguard Worker             chip: IrqSourceChip::PicPrimary,
205*bb4ee6a4SAndroid Build Coastguard Worker             pin: 6,
206*bb4ee6a4SAndroid Build Coastguard Worker         },
207*bb4ee6a4SAndroid Build Coastguard Worker     })
208*bb4ee6a4SAndroid Build Coastguard Worker     .expect("failed to route irq");
209*bb4ee6a4SAndroid Build Coastguard Worker 
210*bb4ee6a4SAndroid Build Coastguard Worker     // re-assert Irq Line 1, it should still affect only the ioapic
211*bb4ee6a4SAndroid Build Coastguard Worker     chip.service_irq(1, true).expect("could not set irq line");
212*bb4ee6a4SAndroid Build Coastguard Worker 
213*bb4ee6a4SAndroid Build Coastguard Worker     // no pic line should be asserted, ioapic pin 3 should be asserted
214*bb4ee6a4SAndroid Build Coastguard Worker     check_pic_interrupts(&chip, PicSelect::Primary, 0);
215*bb4ee6a4SAndroid Build Coastguard Worker     check_ioapic_interrupts(&chip, 1 << 3);
216*bb4ee6a4SAndroid Build Coastguard Worker 
217*bb4ee6a4SAndroid Build Coastguard Worker     // assert Irq Line 2
218*bb4ee6a4SAndroid Build Coastguard Worker     chip.service_irq(2, true).expect("could not set irq line");
219*bb4ee6a4SAndroid Build Coastguard Worker 
220*bb4ee6a4SAndroid Build Coastguard Worker     // pic pin 6 should be asserted, ioapic pin 3 should be asserted
221*bb4ee6a4SAndroid Build Coastguard Worker     check_pic_interrupts(&chip, PicSelect::Primary, 1 << 6);
222*bb4ee6a4SAndroid Build Coastguard Worker     check_ioapic_interrupts(&chip, 1 << 3);
223*bb4ee6a4SAndroid Build Coastguard Worker }
224*bb4ee6a4SAndroid Build Coastguard Worker 
225*bb4ee6a4SAndroid Build Coastguard Worker #[test]
add_routes()226*bb4ee6a4SAndroid Build Coastguard Worker fn add_routes() {
227*bb4ee6a4SAndroid Build Coastguard Worker     let ioapic_pins = hypervisor::NUM_IOAPIC_PINS;
228*bb4ee6a4SAndroid Build Coastguard Worker     let mut r = Routes::new();
229*bb4ee6a4SAndroid Build Coastguard Worker     r.replace_all(&Routes::default_pic_ioapic_routes(ioapic_pins))
230*bb4ee6a4SAndroid Build Coastguard Worker         .unwrap();
231*bb4ee6a4SAndroid Build Coastguard Worker 
232*bb4ee6a4SAndroid Build Coastguard Worker     assert_eq!(r[0].len(), 2);
233*bb4ee6a4SAndroid Build Coastguard Worker 
234*bb4ee6a4SAndroid Build Coastguard Worker     assert_eq!(r[ioapic_pins - 1].len(), 1);
235*bb4ee6a4SAndroid Build Coastguard Worker     r.add(IrqRoute {
236*bb4ee6a4SAndroid Build Coastguard Worker         gsi: ioapic_pins as u32 - 1,
237*bb4ee6a4SAndroid Build Coastguard Worker         source: IrqSource::Irqchip {
238*bb4ee6a4SAndroid Build Coastguard Worker             chip: IrqSourceChip::Ioapic,
239*bb4ee6a4SAndroid Build Coastguard Worker             pin: 3,
240*bb4ee6a4SAndroid Build Coastguard Worker         },
241*bb4ee6a4SAndroid Build Coastguard Worker     })
242*bb4ee6a4SAndroid Build Coastguard Worker     .unwrap();
243*bb4ee6a4SAndroid Build Coastguard Worker     assert_eq!(r[ioapic_pins - 1].len(), 1);
244*bb4ee6a4SAndroid Build Coastguard Worker     r.add(IrqRoute {
245*bb4ee6a4SAndroid Build Coastguard Worker         gsi: ioapic_pins as u32 - 1,
246*bb4ee6a4SAndroid Build Coastguard Worker         source: IrqSource::Irqchip {
247*bb4ee6a4SAndroid Build Coastguard Worker             chip: IrqSourceChip::PicPrimary,
248*bb4ee6a4SAndroid Build Coastguard Worker             pin: 3,
249*bb4ee6a4SAndroid Build Coastguard Worker         },
250*bb4ee6a4SAndroid Build Coastguard Worker     })
251*bb4ee6a4SAndroid Build Coastguard Worker     .unwrap();
252*bb4ee6a4SAndroid Build Coastguard Worker     assert_eq!(r[ioapic_pins - 1].len(), 2);
253*bb4ee6a4SAndroid Build Coastguard Worker     assert!(r
254*bb4ee6a4SAndroid Build Coastguard Worker         .add(IrqRoute {
255*bb4ee6a4SAndroid Build Coastguard Worker             gsi: ioapic_pins as u32 - 1,
256*bb4ee6a4SAndroid Build Coastguard Worker             source: IrqSource::Msi {
257*bb4ee6a4SAndroid Build Coastguard Worker                 address: 0,
258*bb4ee6a4SAndroid Build Coastguard Worker                 data: 0
259*bb4ee6a4SAndroid Build Coastguard Worker             },
260*bb4ee6a4SAndroid Build Coastguard Worker         })
261*bb4ee6a4SAndroid Build Coastguard Worker         .is_err(),);
262*bb4ee6a4SAndroid Build Coastguard Worker     assert_eq!(r[ioapic_pins - 1].len(), 2);
263*bb4ee6a4SAndroid Build Coastguard Worker 
264*bb4ee6a4SAndroid Build Coastguard Worker     assert_eq!(r[ioapic_pins].len(), 0);
265*bb4ee6a4SAndroid Build Coastguard Worker     r.add(IrqRoute {
266*bb4ee6a4SAndroid Build Coastguard Worker         gsi: ioapic_pins as u32,
267*bb4ee6a4SAndroid Build Coastguard Worker         source: IrqSource::Msi {
268*bb4ee6a4SAndroid Build Coastguard Worker             address: 0,
269*bb4ee6a4SAndroid Build Coastguard Worker             data: 0,
270*bb4ee6a4SAndroid Build Coastguard Worker         },
271*bb4ee6a4SAndroid Build Coastguard Worker     })
272*bb4ee6a4SAndroid Build Coastguard Worker     .unwrap();
273*bb4ee6a4SAndroid Build Coastguard Worker     assert_eq!(r[ioapic_pins].len(), 1);
274*bb4ee6a4SAndroid Build Coastguard Worker     assert!(r
275*bb4ee6a4SAndroid Build Coastguard Worker         .add(IrqRoute {
276*bb4ee6a4SAndroid Build Coastguard Worker             gsi: ioapic_pins as u32,
277*bb4ee6a4SAndroid Build Coastguard Worker             source: IrqSource::Irqchip {
278*bb4ee6a4SAndroid Build Coastguard Worker                 chip: IrqSourceChip::Ioapic,
279*bb4ee6a4SAndroid Build Coastguard Worker                 pin: 3
280*bb4ee6a4SAndroid Build Coastguard Worker             },
281*bb4ee6a4SAndroid Build Coastguard Worker         })
282*bb4ee6a4SAndroid Build Coastguard Worker         .is_err(),);
283*bb4ee6a4SAndroid Build Coastguard Worker     assert_eq!(r[ioapic_pins].len(), 1);
284*bb4ee6a4SAndroid Build Coastguard Worker 
285*bb4ee6a4SAndroid Build Coastguard Worker     assert_eq!(r[500].len(), 0);
286*bb4ee6a4SAndroid Build Coastguard Worker }
287