1use std::any::Any;
6use std::str::FromStr;
7use std::sync::Arc;
8
9use base::error;
10use base::warn;
11use base::Event;
12use resources::SystemAllocator;
13use sync::Mutex;
14
15use crate::pci::pci_configuration::PciCapConfig;
16use crate::pci::pci_configuration::PciCapConfigWriteResult;
17use crate::pci::pci_configuration::PciCapMapping;
18use crate::pci::pci_configuration::PciCapability;
19use crate::pci::pcie::pci_bridge::PciBridgeBusRange;
20use crate::pci::pcie::pcie_device::PcieCap;
21use crate::pci::pcie::pcie_device::PcieDevice;
22use crate::pci::pcie::pcie_host::PcieHostPort;
23use crate::pci::pcie::*;
24use crate::pci::pm::PciDevicePower;
25use crate::pci::pm::PciPmCap;
26use crate::pci::pm::PmConfig;
27use crate::pci::pm::PmStatusChange;
28use crate::pci::MsiConfig;
29use crate::pci::PciAddress;
30use crate::pci::PciDeviceError;
31
32const PCIE_BR_MEM_SIZE: u64 = 0x80_0000;
34const PCIE_BR_PREF_MEM_SIZE: u64 = 0x400_0000;
36
37fn trigger_interrupt(msi: &Option<Arc<Mutex<MsiConfig>>>) {
38 if let Some(msi_config) = msi {
39 let msi_config = msi_config.lock();
40 if msi_config.is_msi_enabled() {
41 msi_config.trigger()
42 }
43 }
44}
45
46struct PcieRootCap {
47 secondary_bus_num: u8,
48 subordinate_bus_num: u8,
49
50 control: u16,
51 status: u32,
52 pme_pending_requester_id: Option<u16>,
53
54 msi_config: Option<Arc<Mutex<MsiConfig>>>,
55}
56
57impl PcieRootCap {
58 fn new(secondary_bus_num: u8, subordinate_bus_num: u8) -> Self {
59 PcieRootCap {
60 secondary_bus_num,
61 subordinate_bus_num,
62 control: 0,
63 status: 0,
64 pme_pending_requester_id: None,
65 msi_config: None,
66 }
67 }
68
69 fn clone_interrupt(&mut self, msi_config: Arc<Mutex<MsiConfig>>) {
70 self.msi_config = Some(msi_config);
71 }
72
73 fn trigger_pme_interrupt(&self) {
74 if (self.control & PCIE_ROOTCTL_PME_ENABLE) != 0
75 && (self.status & PCIE_ROOTSTA_PME_STATUS) != 0
76 {
77 trigger_interrupt(&self.msi_config)
78 }
79 }
80}
81
82static PCIE_ROOTS_CAP: Mutex<Vec<Arc<Mutex<PcieRootCap>>>> = Mutex::new(Vec::new());
83
84fn push_pcie_root_cap(root_cap: Arc<Mutex<PcieRootCap>>) {
85 PCIE_ROOTS_CAP.lock().push(root_cap);
86}
87
88fn get_pcie_root_cap(bus_num: u8) -> Option<Arc<Mutex<PcieRootCap>>> {
89 for root_cap in PCIE_ROOTS_CAP.lock().iter() {
90 let root_cap_lock = root_cap.lock();
91 if root_cap_lock.secondary_bus_num <= bus_num
92 && root_cap_lock.subordinate_bus_num >= bus_num
93 {
94 return Some(root_cap.clone());
95 }
96 }
97
98 None
99}
100
101pub struct PciePort {
102 device_id: u16,
103 debug_label: String,
104 preferred_address: Option<PciAddress>,
105 pci_address: Option<PciAddress>,
106 bus_range: PciBridgeBusRange,
107 pcie_host: Option<PcieHostPort>,
108 pcie_config: Arc<Mutex<PcieConfig>>,
109 pm_config: Arc<Mutex<PmConfig>>,
110
111 msi_config: Option<Arc<Mutex<MsiConfig>>>,
112
113 root_cap: Arc<Mutex<PcieRootCap>>,
116 port_type: PcieDevicePortType,
117
118 prepare_hotplug: bool,
119}
120
121impl PciePort {
122 pub fn new(
124 device_id: u16,
125 debug_label: String,
126 primary_bus_num: u8,
127 secondary_bus_num: u8,
128 slot_implemented: bool,
129 port_type: PcieDevicePortType,
130 ) -> Self {
131 let bus_range = PciBridgeBusRange {
132 primary: primary_bus_num,
133 secondary: secondary_bus_num,
134 subordinate: secondary_bus_num,
135 };
136
137 let root_cap = if port_type == PcieDevicePortType::RootPort {
138 let cap = Arc::new(Mutex::new(PcieRootCap::new(
139 secondary_bus_num,
140 secondary_bus_num,
141 )));
142 push_pcie_root_cap(cap.clone());
143 cap
144 } else {
145 get_pcie_root_cap(primary_bus_num).expect("Pcie root port should be created at first")
146 };
147
148 PciePort {
149 device_id,
150 debug_label,
151 preferred_address: None,
152 pci_address: None,
153 bus_range,
154 pcie_host: None,
155 msi_config: None,
156 pcie_config: Arc::new(Mutex::new(PcieConfig::new(
157 root_cap.clone(),
158 slot_implemented,
159 port_type,
160 ))),
161 pm_config: Arc::new(Mutex::new(PmConfig::new(false))),
162
163 root_cap,
164 port_type,
165
166 prepare_hotplug: false,
167 }
168 }
169
170 pub fn new_from_host(
171 pcie_host: PcieHostPort,
172 slot_implemented: bool,
173 port_type: PcieDevicePortType,
174 ) -> std::result::Result<Self, PciDeviceError> {
175 let bus_range = pcie_host.get_bus_range();
176 let host_address = PciAddress::from_str(&pcie_host.host_name())
177 .map_err(|e| PciDeviceError::PciAddressParseFailure(pcie_host.host_name(), e))?;
178 let root_cap = if port_type == PcieDevicePortType::RootPort {
179 let cap = Arc::new(Mutex::new(PcieRootCap::new(
180 bus_range.secondary,
181 bus_range.subordinate,
182 )));
183 push_pcie_root_cap(cap.clone());
184 cap
185 } else {
186 get_pcie_root_cap(bus_range.primary).expect("Pcie root port should be created at first")
187 };
188
189 Ok(PciePort {
190 device_id: pcie_host.read_device_id(),
191 debug_label: pcie_host.host_name(),
192 preferred_address: Some(host_address),
193 pci_address: None,
194 bus_range,
195 pcie_host: Some(pcie_host),
196 msi_config: None,
197 pcie_config: Arc::new(Mutex::new(PcieConfig::new(
198 root_cap.clone(),
199 slot_implemented,
200 port_type,
201 ))),
202 pm_config: Arc::new(Mutex::new(PmConfig::new(false))),
203
204 root_cap,
205 port_type,
206
207 prepare_hotplug: false,
208 })
209 }
210
211 pub fn get_device_id(&self) -> u16 {
212 self.device_id
213 }
214
215 pub fn get_address(&self) -> Option<PciAddress> {
216 self.pci_address
217 }
218
219 pub fn debug_label(&self) -> String {
220 self.debug_label.clone()
221 }
222
223 pub fn preferred_address(&self) -> Option<PciAddress> {
224 self.preferred_address
225 }
226
227 pub fn allocate_address(
228 &mut self,
229 resources: &mut SystemAllocator,
230 ) -> std::result::Result<PciAddress, PciDeviceError> {
231 if self.pci_address.is_none() {
232 if let Some(address) = self.preferred_address {
233 if resources.reserve_pci(address, self.debug_label()) {
234 self.pci_address = Some(address);
235 } else {
236 self.pci_address = None;
237 }
238 } else {
239 self.pci_address =
240 resources.allocate_pci(self.bus_range.primary, self.debug_label());
241 }
242 }
243 self.pci_address.ok_or(PciDeviceError::PciAllocationFailed)
244 }
245
246 pub fn read_config(&self, reg_idx: usize, data: &mut u32) {
247 if let Some(host) = &self.pcie_host {
248 host.read_config(reg_idx, data);
249 }
250 }
251
252 pub fn write_config(&mut self, reg_idx: usize, offset: u64, data: &[u8]) {
253 if let Some(host) = self.pcie_host.as_mut() {
254 host.write_config(reg_idx, offset, data);
255 }
256 }
257
258 pub fn handle_cap_write_result(&mut self, res: Box<dyn PciCapConfigWriteResult>) {
259 if let Some(status) = <dyn Any>::downcast_ref::<PmStatusChange>(&*res) {
260 if status.from == PciDevicePower::D3
261 && status.to == PciDevicePower::D0
262 && self.prepare_hotplug
263 {
264 if let Some(host) = self.pcie_host.as_mut() {
265 host.hotplug_probe();
266 self.prepare_hotplug = false;
267 }
268 }
269 }
270 }
271
272 pub fn get_caps(&self) -> Vec<(Box<dyn PciCapability>, Option<Box<dyn PciCapConfig>>)> {
273 vec![
274 (
275 Box::new(PcieCap::new(self.port_type, self.hotplug_implemented(), 0)),
276 Some(Box::new(self.pcie_config.clone())),
277 ),
278 (
279 Box::new(PciPmCap::new()),
280 Some(Box::new(self.pm_config.clone())),
281 ),
282 ]
283 }
284
285 pub fn get_bus_range(&self) -> Option<PciBridgeBusRange> {
286 Some(self.bus_range)
287 }
288
289 pub fn get_bridge_window_size(&self) -> (u64, u64) {
290 if let Some(host) = &self.pcie_host {
291 host.get_bridge_window_size()
292 } else {
293 (PCIE_BR_MEM_SIZE, PCIE_BR_PREF_MEM_SIZE)
294 }
295 }
296
297 pub fn get_slot_control(&self) -> u16 {
298 self.pcie_config.lock().get_slot_control()
299 }
300
301 pub fn clone_interrupt(&mut self, msi_config: Arc<Mutex<MsiConfig>>) {
302 if self.port_type == PcieDevicePortType::RootPort {
303 self.root_cap.lock().clone_interrupt(msi_config.clone());
304 }
305 self.pcie_config.lock().msi_config = Some(msi_config.clone());
306 self.msi_config = Some(msi_config);
307 }
308
309 pub fn hotplug_implemented(&self) -> bool {
310 self.pcie_config.lock().slot_control.is_some()
311 }
312
313 pub fn inject_pme(&mut self, requester_id: u16) {
314 let mut r = self.root_cap.lock();
315 if (r.status & PCIE_ROOTSTA_PME_STATUS) != 0 {
316 r.status |= PCIE_ROOTSTA_PME_PENDING;
317 r.pme_pending_requester_id = Some(requester_id);
318 } else {
319 r.status &= !PCIE_ROOTSTA_PME_REQ_ID_MASK;
320 r.status |= requester_id as u32;
321 r.pme_pending_requester_id = None;
322 r.status |= PCIE_ROOTSTA_PME_STATUS;
323 r.trigger_pme_interrupt();
324 }
325 }
326
327 pub fn is_hpc_pending(&self) -> bool {
329 self.pcie_config.lock().hpc_sender.is_some()
330 }
331
332 pub fn set_hpc_sender(&mut self, event: Event) {
334 self.pcie_config
335 .lock()
336 .hpc_sender
337 .replace(HotPlugCompleteSender::new(event));
338 }
339
340 pub fn trigger_hp_or_pme_interrupt(&mut self) {
341 if self.pm_config.lock().should_trigger_pme() {
342 self.pcie_config.lock().hp_interrupt_pending = true;
343 self.inject_pme(self.pci_address.unwrap().pme_requester_id());
344 } else {
345 self.pcie_config.lock().trigger_hp_interrupt();
346 }
347 }
348
349 pub fn is_host(&self) -> bool {
350 self.pcie_host.is_some()
351 }
352
353 pub fn is_hotplug_ready(&self) -> bool {
355 self.pcie_config.lock().is_hotplug_ready()
356 }
357
358 pub fn get_ready_notification(&mut self) -> std::result::Result<Event, PciDeviceError> {
361 self.pcie_config.lock().get_ready_notification()
362 }
363
364 pub fn hot_unplug(&mut self) {
365 if let Some(host) = self.pcie_host.as_mut() {
366 host.hot_unplug()
367 }
368 }
369
370 pub fn is_match(&self, host_addr: PciAddress) -> Option<u8> {
371 if host_addr.bus == self.bus_range.secondary || self.pcie_host.is_none() {
372 Some(self.bus_range.secondary)
373 } else {
374 None
375 }
376 }
377
378 pub fn removed_downstream_valid(&self) -> bool {
379 self.pcie_config.lock().removed_downstream_valid
380 }
381
382 pub fn mask_slot_status(&mut self, mask: u16) {
383 self.pcie_config.lock().mask_slot_status(mask);
384 }
385
386 pub fn set_slot_status(&mut self, flag: u16) {
387 self.pcie_config.lock().set_slot_status(flag);
388 }
389
390 pub fn should_trigger_pme(&mut self) -> bool {
391 self.pm_config.lock().should_trigger_pme()
392 }
393
394 pub fn prepare_hotplug(&mut self) {
395 self.prepare_hotplug = true;
396 }
397}
398
399struct HotPlugCompleteSender {
400 sender: Event,
401 armed: bool,
402}
403
404impl HotPlugCompleteSender {
405 fn new(sender: Event) -> Self {
406 Self {
407 sender,
408 armed: false,
409 }
410 }
411
412 fn arm(&mut self) {
413 self.armed = true;
414 }
415
416 fn armed(&self) -> bool {
417 self.armed
418 }
419
420 fn signal(&self) -> base::Result<()> {
421 self.sender.signal()
422 }
423}
424
425pub struct PcieConfig {
426 msi_config: Option<Arc<Mutex<MsiConfig>>>,
427
428 slot_control: Option<u16>,
429 slot_status: u16,
430
431 root_cap: Arc<Mutex<PcieRootCap>>,
434 port_type: PcieDevicePortType,
435
436 hpc_sender: Option<HotPlugCompleteSender>,
437 hp_interrupt_pending: bool,
438 removed_downstream_valid: bool,
439
440 enabled: bool,
441 hot_plug_ready_notifications: Vec<Event>,
442 cap_mapping: Option<PciCapMapping>,
443}
444
445impl PcieConfig {
446 fn new(
447 root_cap: Arc<Mutex<PcieRootCap>>,
448 slot_implemented: bool,
449 port_type: PcieDevicePortType,
450 ) -> Self {
451 PcieConfig {
452 msi_config: None,
453
454 slot_control: if slot_implemented {
455 Some(PCIE_SLTCTL_PIC_OFF | PCIE_SLTCTL_AIC_OFF)
456 } else {
457 None
458 },
459 slot_status: 0,
460
461 root_cap,
462 port_type,
463
464 hpc_sender: None,
465 hp_interrupt_pending: false,
466 removed_downstream_valid: false,
467
468 enabled: false,
469 hot_plug_ready_notifications: Vec::new(),
470 cap_mapping: None,
471 }
472 }
473
474 fn read_pcie_cap(&self, offset: usize, data: &mut u32) {
475 if offset == PCIE_SLTCTL_OFFSET {
476 *data = ((self.slot_status as u32) << 16) | (self.get_slot_control() as u32);
477 } else if offset == PCIE_ROOTCTL_OFFSET {
478 *data = match self.port_type {
479 PcieDevicePortType::RootPort => self.root_cap.lock().control as u32,
480 _ => 0,
481 };
482 } else if offset == PCIE_ROOTSTA_OFFSET {
483 *data = match self.port_type {
484 PcieDevicePortType::RootPort => self.root_cap.lock().status,
485 _ => 0,
486 };
487 }
488 }
489
490 fn is_hotplug_ready(&self) -> bool {
492 let slot_control = self.get_slot_control();
495 (slot_control & (PCIE_SLTCTL_PDCE | PCIE_SLTCTL_ABPE)) != 0
496 && (slot_control & PCIE_SLTCTL_CCIE) != 0
497 && (slot_control & PCIE_SLTCTL_HPIE) != 0
498 }
499
500 fn get_ready_notification(&mut self) -> std::result::Result<Event, PciDeviceError> {
503 let event = Event::new().map_err(|e| PciDeviceError::EventCreationFailed(e.errno()))?;
504 if self.is_hotplug_ready() {
505 event
506 .signal()
507 .map_err(|e| PciDeviceError::EventSignalFailed(e.errno()))?;
508 } else {
509 self.hot_plug_ready_notifications.push(
510 event
511 .try_clone()
512 .map_err(|e| PciDeviceError::EventCloneFailed(e.errno()))?,
513 );
514 }
515 Ok(event)
516 }
517
518 fn write_pcie_cap(&mut self, offset: usize, data: &[u8]) {
519 self.removed_downstream_valid = false;
520 match offset {
521 PCIE_SLTCTL_OFFSET => {
522 let Ok(value) = data.try_into().map(u16::from_le_bytes) else {
523 warn!("write SLTCTL isn't word, len: {}", data.len());
524 return;
525 };
526 if !self.enabled
527 && (value & (PCIE_SLTCTL_PDCE | PCIE_SLTCTL_ABPE)) != 0
528 && (value & PCIE_SLTCTL_CCIE) != 0
529 && (value & PCIE_SLTCTL_HPIE) != 0
530 {
531 for notf_event in self.hot_plug_ready_notifications.drain(..) {
533 if let Err(e) = notf_event.signal() {
534 error!("Failed to signal hot plug ready: {}", e);
535 }
536 }
537 self.enabled = true;
538 }
539
540 let old_control = self.get_slot_control();
543 match self.slot_control.as_mut() {
544 Some(v) => *v = value,
545 None => return,
546 }
547 if (self.slot_status & PCIE_SLTSTA_PDS != 0)
548 && (value & PCIE_SLTCTL_PIC == PCIE_SLTCTL_PIC_OFF)
549 && (old_control & PCIE_SLTCTL_PIC != PCIE_SLTCTL_PIC_OFF)
550 {
551 self.removed_downstream_valid = true;
552 self.slot_status &= !PCIE_SLTSTA_PDS;
553 self.trigger_hp_interrupt();
554 }
555
556 if (old_control & PCIE_SLTCTL_HPIE == 0)
559 && (value & PCIE_SLTCTL_HPIE == PCIE_SLTCTL_HPIE)
560 && self.hp_interrupt_pending
561 {
562 self.hp_interrupt_pending = false;
563 self.trigger_hp_interrupt();
564 }
565
566 if old_control != value {
567 let old_pic_state = old_control & PCIE_SLTCTL_PIC;
568 let pic_state = value & PCIE_SLTCTL_PIC;
569 if old_pic_state == PCIE_SLTCTL_PIC_BLINK && old_pic_state != pic_state {
570 if let Some(sender) = self.hpc_sender.as_mut() {
579 sender.arm();
580 }
581 }
582 self.slot_status |= PCIE_SLTSTA_CC;
583 self.trigger_cc_interrupt();
584 }
585 }
586 PCIE_SLTSTA_OFFSET => {
587 if self.slot_control.is_none() {
588 return;
589 }
590 if let Some(hpc_sender) = self.hpc_sender.as_mut() {
591 if hpc_sender.armed() {
592 if let Err(e) = hpc_sender.signal() {
593 error!("Failed to send hot un/plug complete signal: {}", e);
594 }
595 self.hpc_sender = None;
596 }
597 }
598 let Ok(value) = data.try_into().map(u16::from_le_bytes) else {
599 warn!("write SLTSTA isn't word, len: {}", data.len());
600 return;
601 };
602 if value & PCIE_SLTSTA_ABP != 0 {
603 self.slot_status &= !PCIE_SLTSTA_ABP;
604 }
605 if value & PCIE_SLTSTA_PFD != 0 {
606 self.slot_status &= !PCIE_SLTSTA_PFD;
607 }
608 if value & PCIE_SLTSTA_PDC != 0 {
609 self.slot_status &= !PCIE_SLTSTA_PDC;
610 }
611 if value & PCIE_SLTSTA_CC != 0 {
612 self.slot_status &= !PCIE_SLTSTA_CC;
613 }
614 if value & PCIE_SLTSTA_DLLSC != 0 {
615 self.slot_status &= !PCIE_SLTSTA_DLLSC;
616 }
617 }
618 PCIE_ROOTCTL_OFFSET => {
619 let Ok(v) = data.try_into().map(u16::from_le_bytes) else {
620 warn!("write root control isn't word, len: {}", data.len());
621 return;
622 };
623 if self.port_type == PcieDevicePortType::RootPort {
624 self.root_cap.lock().control = v;
625 } else {
626 warn!("write root control register while device isn't root port");
627 }
628 }
629 PCIE_ROOTSTA_OFFSET => {
630 let Ok(v) = data.try_into().map(u32::from_le_bytes) else {
631 warn!("write root status isn't dword, len: {}", data.len());
632 return;
633 };
634 if self.port_type == PcieDevicePortType::RootPort {
635 if v & PCIE_ROOTSTA_PME_STATUS != 0 {
636 let mut r = self.root_cap.lock();
637 if let Some(requester_id) = r.pme_pending_requester_id {
638 r.status &= !PCIE_ROOTSTA_PME_PENDING;
639 r.status &= !PCIE_ROOTSTA_PME_REQ_ID_MASK;
640 r.status |= requester_id as u32;
641 r.status |= PCIE_ROOTSTA_PME_STATUS;
642 r.pme_pending_requester_id = None;
643 r.trigger_pme_interrupt();
644 } else {
645 r.status &= !PCIE_ROOTSTA_PME_STATUS;
646 }
647 }
648 } else {
649 warn!("write root status register while device isn't root port");
650 }
651 }
652 _ => (),
653 }
654 }
655
656 fn get_slot_control(&self) -> u16 {
657 if let Some(slot_control) = self.slot_control {
658 return slot_control;
659 }
660 0
661 }
662
663 fn trigger_cc_interrupt(&self) {
664 if (self.get_slot_control() & PCIE_SLTCTL_CCIE) != 0
665 && (self.slot_status & PCIE_SLTSTA_CC) != 0
666 {
667 trigger_interrupt(&self.msi_config)
668 }
669 }
670
671 fn trigger_hp_interrupt(&mut self) {
672 let slot_control = self.get_slot_control();
673 if (slot_control & PCIE_SLTCTL_HPIE) != 0 {
674 self.set_slot_status(PCIE_SLTSTA_PDC);
675 if (self.slot_status & slot_control & (PCIE_SLTCTL_ABPE | PCIE_SLTCTL_PDCE)) != 0 {
676 trigger_interrupt(&self.msi_config)
677 }
678 }
679 }
680
681 fn mask_slot_status(&mut self, mask: u16) {
682 self.slot_status &= mask;
683 if let Some(mapping) = self.cap_mapping.as_mut() {
684 mapping.set_reg(
685 PCIE_SLTCTL_OFFSET / 4,
686 (self.slot_status as u32) << 16,
687 0xffff0000,
688 );
689 }
690 }
691
692 fn set_slot_status(&mut self, flag: u16) {
693 self.slot_status |= flag;
694 if let Some(mapping) = self.cap_mapping.as_mut() {
695 mapping.set_reg(
696 PCIE_SLTCTL_OFFSET / 4,
697 (self.slot_status as u32) << 16,
698 0xffff0000,
699 );
700 }
701 }
702}
703
704const PCIE_CONFIG_READ_MASK: [u32; PCIE_CAP_LEN / 4] = {
705 let mut arr: [u32; PCIE_CAP_LEN / 4] = [0; PCIE_CAP_LEN / 4];
706 arr[PCIE_SLTCTL_OFFSET / 4] = 0xffffffff;
707 arr[PCIE_ROOTCTL_OFFSET / 4] = 0xffffffff;
708 arr[PCIE_ROOTSTA_OFFSET / 4] = 0xffffffff;
709 arr
710};
711
712impl PciCapConfig for PcieConfig {
713 fn read_mask(&self) -> &'static [u32] {
714 &PCIE_CONFIG_READ_MASK
715 }
716
717 fn read_reg(&self, reg_idx: usize) -> u32 {
718 let mut data = 0;
719 self.read_pcie_cap(reg_idx * 4, &mut data);
720 data
721 }
722
723 fn write_reg(
724 &mut self,
725 reg_idx: usize,
726 offset: u64,
727 data: &[u8],
728 ) -> Option<Box<dyn PciCapConfigWriteResult>> {
729 self.write_pcie_cap(reg_idx * 4 + offset as usize, data);
730 None
731 }
732
733 fn set_cap_mapping(&mut self, mapping: PciCapMapping) {
734 self.cap_mapping = Some(mapping);
735 }
736}
737
738pub trait PciePortVariant: Send {
741 fn get_pcie_port(&self) -> &PciePort;
742 fn get_pcie_port_mut(&mut self) -> &mut PciePort;
743
744 fn get_removed_devices_impl(&self) -> Vec<PciAddress>;
746
747 fn hotplug_implemented_impl(&self) -> bool;
749
750 fn hotplugged_impl(&self) -> bool;
752}
753
754impl<T: PciePortVariant> PcieDevice for T {
755 fn get_device_id(&self) -> u16 {
756 self.get_pcie_port().get_device_id()
757 }
758
759 fn debug_label(&self) -> String {
760 self.get_pcie_port().debug_label()
761 }
762
763 fn preferred_address(&self) -> Option<PciAddress> {
764 self.get_pcie_port().preferred_address()
765 }
766
767 fn allocate_address(
768 &mut self,
769 resources: &mut SystemAllocator,
770 ) -> std::result::Result<PciAddress, PciDeviceError> {
771 self.get_pcie_port_mut().allocate_address(resources)
772 }
773
774 fn clone_interrupt(&mut self, msi_config: Arc<Mutex<MsiConfig>>) {
775 self.get_pcie_port_mut().clone_interrupt(msi_config);
776 }
777
778 fn read_config(&self, reg_idx: usize, data: &mut u32) {
779 self.get_pcie_port().read_config(reg_idx, data);
780 }
781
782 fn write_config(&mut self, reg_idx: usize, offset: u64, data: &[u8]) {
783 self.get_pcie_port_mut().write_config(reg_idx, offset, data);
784 }
785
786 fn get_caps(&self) -> Vec<(Box<dyn PciCapability>, Option<Box<dyn PciCapConfig>>)> {
787 self.get_pcie_port().get_caps()
788 }
789
790 fn handle_cap_write_result(&mut self, res: Box<dyn PciCapConfigWriteResult>) {
791 self.get_pcie_port_mut().handle_cap_write_result(res)
792 }
793
794 fn get_bus_range(&self) -> Option<PciBridgeBusRange> {
795 self.get_pcie_port().get_bus_range()
796 }
797
798 fn get_removed_devices(&self) -> Vec<PciAddress> {
799 self.get_removed_devices_impl()
800 }
801
802 fn hotplug_implemented(&self) -> bool {
803 self.hotplug_implemented_impl()
804 }
805
806 fn hotplugged(&self) -> bool {
807 self.hotplugged_impl()
808 }
809
810 fn get_bridge_window_size(&self) -> (u64, u64) {
811 self.get_pcie_port().get_bridge_window_size()
812 }
813}