1#![allow(dead_code)]
2use alloc::vec::Vec;
5use alloc::{boxed::Box, collections::LinkedList};
6use bitflags::bitflags;
7use core::{
8 convert::TryFrom,
9 fmt::{self, Display, Formatter},
10};
11use log::*;
12use spin::{Lazy, RwLock, RwLockReadGuard, RwLockWriteGuard};
13use x86_64::structures::paging::{Page, PageTableFlags, PhysFrame};
14use x86_64::PhysAddr;
15
16use crate::arch::{PciArch, TraitPciArch};
17use crate::memory::{convert_physical_to_virtual, KERNEL_PAGE_TABLE};
18pub static PCI_DEVICE_LINKEDLIST: Lazy<PciDeviceLinkedList> =
22 Lazy::new(|| PciDeviceLinkedList::new());
23pub static PCI_ROOT_0: Lazy<Option<PciRoot>> = Lazy::new(|| match PciRoot::new(0) {
24 Ok(root) => Some(root),
25 Err(err) => {
26 error!("Pci_root init failed because of error: {}", err);
27 None
28 }
29});
30
31pub struct PciDeviceLinkedList {
33 list: RwLock<LinkedList<Box<dyn PciDeviceStructure>>>,
34}
35
36impl PciDeviceLinkedList {
37 fn new() -> Self {
39 PciDeviceLinkedList {
40 list: RwLock::new(LinkedList::new()),
41 }
42 }
43
44 pub fn read(&self) -> RwLockReadGuard<LinkedList<Box<dyn PciDeviceStructure>>> {
46 self.list.read()
47 }
48
49 pub fn write(&self) -> RwLockWriteGuard<LinkedList<Box<dyn PciDeviceStructure>>> {
51 self.list.write()
52 }
53
54 pub fn len(&self) -> usize {
56 let list = self.list.read();
57 list.len()
58 }
59
60 pub fn push_back(&self, device: Box<dyn PciDeviceStructure>) {
62 let mut list = self.list.write();
63 list.push_back(device);
64 }
65}
66
67pub fn get_pci_device_structure_mut<'a>(
70 list: &'a mut RwLockWriteGuard<'_, LinkedList<Box<dyn PciDeviceStructure>>>,
71 class_code: u8,
72 subclass: u8,
73) -> Vec<&'a mut Box<(dyn PciDeviceStructure)>> {
74 let mut result = Vec::new();
75 for box_pci_device_structure in list.iter_mut() {
76 let common_header = (*box_pci_device_structure).common_header();
77 if (common_header.class_code == class_code) && (common_header.subclass == subclass) {
78 result.push(box_pci_device_structure);
79 }
80 }
81 result
82}
83pub fn get_pci_device_structure<'a>(
85 list: &'a mut RwLockReadGuard<'_, LinkedList<Box<dyn PciDeviceStructure>>>,
86 class_code: u8,
87 subclass: u8,
88) -> Vec<&'a Box<(dyn PciDeviceStructure)>> {
89 let mut result = Vec::new();
90 for box_pci_device_structure in list.iter() {
91 let common_header = (*box_pci_device_structure).common_header();
92 if (common_header.class_code == class_code) && (common_header.subclass == subclass) {
93 result.push(box_pci_device_structure);
94 }
95 }
96 result
97}
98
99const BAR0_OFFSET: u8 = 0x10;
101const STATUS_COMMAND_OFFSET: u8 = 0x04;
103pub const PCI_CAP_ID_VNDR: u8 = 0x09;
105pub const PORT_PCI_CONFIG_ADDRESS: u16 = 0xcf8;
106pub const PORT_PCI_CONFIG_DATA: u16 = 0xcfc;
107pub type SegmentGroupNumber = u16; bitflags! {
111 pub struct Status: u16 {
113 const INTERRUPT_STATUS = 1 << 3;
116 const CAPABILITIES_LIST = 1 << 4;
118 const MHZ_66_CAPABLE = 1 << 5;
120 const FAST_BACK_TO_BACK_CAPABLE = 1 << 7;
123 const MASTER_DATA_PARITY_ERROR = 1 << 8;
125 const SIGNALED_TARGET_ABORT = 1 << 11;
128 const RECEIVED_TARGET_ABORT = 1 << 12;
130 const RECEIVED_MASTER_ABORT = 1 << 13;
132 const SIGNALED_SYSTEM_ERROR = 1 << 14;
134 const DETECTED_PARITY_ERROR = 1 << 15;
136 }
137}
138
139bitflags! {
140 pub struct Command: u16 {
142 const IO_SPACE = 1 << 0;
144 const MEMORY_SPACE = 1 << 1;
146 const BUS_MASTER = 1 << 2;
148 const SPECIAL_CYCLES = 1 << 3;
150 const MEMORY_WRITE_AND_INVALIDATE_ENABLE = 1 << 4;
152 const VGA_PALETTE_SNOOP = 1 << 5;
154 const PARITY_ERROR_RESPONSE = 1 << 6;
156 const SERR_ENABLE = 1 << 8;
159 const FAST_BACK_TO_BACK_ENABLE = 1 << 9;
161 const INTERRUPT_DISABLE = 1 << 10;
163 }
164}
165
166#[derive(Copy, Clone, Debug, Eq, PartialEq)]
169pub enum HeaderType {
170 Standard,
172 PciPciBridge,
174 PciCardbusBridge,
176 Unrecognised(u8),
178}
179impl From<u8> for HeaderType {
182 fn from(value: u8) -> Self {
183 match value {
184 0x00 => Self::Standard,
185 0x01 => Self::PciPciBridge,
186 0x02 => Self::PciCardbusBridge,
187 _ => Self::Unrecognised(value),
188 }
189 }
190}
191#[derive(Copy, Clone, Debug, Eq, PartialEq)]
194pub enum PciError {
195 InvalidBarType,
197 CreateMmioError,
198 InvalidBusDeviceFunction,
199 SegmentNotFound,
200 GetWrongHeader,
201 UnrecognisedHeaderType,
202 PciDeviceStructureTransformError,
203}
204
205impl Display for PciError {
206 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
207 match self {
208 Self::InvalidBarType => write!(f, "Invalid PCI BAR type."),
209 Self::CreateMmioError => write!(f, "Error occurred while creating mmio."),
210 Self::InvalidBusDeviceFunction => write!(f, "Found invalid BusDeviceFunction."),
211 Self::SegmentNotFound => write!(f, "Target segment not found"),
212 Self::GetWrongHeader => write!(f, "GetWrongHeader with vendor id 0xffff"),
213 Self::UnrecognisedHeaderType => write!(f, "Found device with unrecognised header type"),
214 Self::PciDeviceStructureTransformError => {
215 write!(f, "Found None When transform Pci device structure")
216 }
217 }
218 }
219}
220
221pub trait PciDeviceStructure: Send + Sync {
223 fn header_type(&self) -> HeaderType;
225 fn as_standard_device(&self) -> Option<&PciDeviceStructureGeneralDevice> {
227 None
228 }
229 fn as_pci_to_pci_bridge_device(&self) -> Option<&PciDeviceStructurePciToPciBridge> {
231 None
232 }
233 fn as_pci_to_carbus_bridge_device(&self) -> Option<&PciDeviceStructurePciToCardbusBridge> {
235 None
236 }
237 fn common_header(&self) -> &PciDeviceStructureHeader;
239 fn as_standard_device_mut(&mut self) -> Option<&mut PciDeviceStructureGeneralDevice> {
241 None
242 }
243 fn as_pci_to_pci_bridge_device_mut(&mut self) -> Option<&mut PciDeviceStructurePciToPciBridge> {
245 None
246 }
247 fn as_pci_to_carbus_bridge_device_mut(
249 &mut self,
250 ) -> Option<&mut PciDeviceStructurePciToCardbusBridge> {
251 None
252 }
253 fn capabilities(&self) -> Option<CapabilityIterator> {
255 None
256 }
257 fn status_command(&self) -> (Status, Command) {
259 let common_header = self.common_header();
260 let status = Status::from_bits_truncate(common_header.status);
261 let command = Command::from_bits_truncate(common_header.command);
262 (status, command)
263 }
264 fn set_command(&mut self, command: Command) {
266 let common_header = self.common_header_mut();
267 let command = command.bits();
268 common_header.command = command;
269 PciArch::write_config(
270 &common_header.bus_device_function,
271 STATUS_COMMAND_OFFSET,
272 command as u32,
273 );
274 }
275 fn common_header_mut(&mut self) -> &mut PciDeviceStructureHeader;
277 fn bar_init(&mut self) -> Option<Result<u8, PciError>> {
280 None
281 }
282 fn msix_init(&mut self) -> Option<Result<u8, PciError>> {
284 None
285 }
286 fn enable_master(&mut self) {
287 self.set_command(Command::IO_SPACE | Command::MEMORY_SPACE | Command::BUS_MASTER);
288 }
289}
290
291#[derive(Clone, Debug)]
293pub struct PciDeviceStructureHeader {
294 pub msix_mmio_vaddr: u64,
296 pub msix_mmio_size: u64, pub msix_offset: u32, pub msix_table_size: u16, pub bus_device_function: BusDeviceFunction,
301 pub vendor_id: u16, pub device_id: u16, pub command: u16, pub status: u16, pub revision_id: u8, pub prog_if: u8, pub subclass: u8, pub class_code: u8, pub cache_line_size: u8, pub latency_timer: u8, pub header_type: u8, pub bist: u8, }
318
319#[derive(Clone, Debug)]
321pub struct PciDeviceStructureGeneralDevice {
322 pub common_header: PciDeviceStructureHeader,
323 pub standard_device_bar: PciStandardDeviceBar,
324 pub cardbus_cis_pointer: u32, pub subsystem_vendor_id: u16,
326 pub subsystem_id: u16,
327 pub expansion_rom_base_address: u32,
328 pub capabilities_pointer: u8,
329 pub reserved0: u8,
330 pub reserved1: u16,
331 pub reserved2: u32,
332 pub interrupt_line: u8, pub interrupt_pin: u8, pub min_grant: u8, pub max_latency: u8, }
337impl PciDeviceStructure for PciDeviceStructureGeneralDevice {
338 fn header_type(&self) -> HeaderType {
339 HeaderType::Standard
340 }
341 fn as_standard_device(&self) -> Option<&PciDeviceStructureGeneralDevice> {
342 Some(self)
343 }
344 fn as_standard_device_mut(&mut self) -> Option<&mut PciDeviceStructureGeneralDevice> {
345 Some(self)
346 }
347 fn common_header(&self) -> &PciDeviceStructureHeader {
348 &self.common_header
349 }
350
351 fn common_header_mut(&mut self) -> &mut PciDeviceStructureHeader {
352 &mut self.common_header
353 }
354 fn capabilities(&self) -> Option<CapabilityIterator> {
355 Some(CapabilityIterator {
356 bus_device_function: self.common_header.bus_device_function,
357 next_capability_offset: Some(self.capabilities_pointer),
358 })
359 }
360 fn bar_init(&mut self) -> Option<Result<u8, PciError>> {
361 let common_header = &self.common_header;
362 match pci_bar_init(common_header.bus_device_function) {
363 Ok(bar) => {
364 self.standard_device_bar = bar;
365 Some(Ok(0))
366 }
367 Err(e) => Some(Err(e)),
368 }
369 }
370}
371#[derive(Clone, Debug)]
373pub struct PciDeviceStructurePciToPciBridge {
374 pub common_header: PciDeviceStructureHeader,
375 pub bar0: u32,
376 pub bar1: u32,
377 pub primary_bus_number: u8,
378 pub secondary_bus_number: u8,
379 pub subordinate_bus_number: u8,
380 pub secondary_latency_timer: u8,
381 pub io_base: u8,
382 pub io_limit: u8,
383 pub secondary_status: u16,
384 pub memory_base: u16,
385 pub memory_limit: u16,
386 pub prefetchable_memory_base: u16,
387 pub prefetchable_memory_limit: u16,
388 pub prefetchable_base_upper_32_bits: u32,
389 pub prefetchable_limit_upper_32_bits: u32,
390 pub io_base_upper_16_bits: u16,
391 pub io_limit_upper_16_bits: u16,
392 pub capability_pointer: u8,
393 pub reserved0: u8,
394 pub reserved1: u16,
395 pub expansion_rom_base_address: u32,
396 pub interrupt_line: u8,
397 pub interrupt_pin: u8,
398 pub bridge_control: u16,
399}
400impl PciDeviceStructure for PciDeviceStructurePciToPciBridge {
401 fn header_type(&self) -> HeaderType {
402 HeaderType::PciPciBridge
403 }
404 fn as_pci_to_pci_bridge_device(&self) -> Option<&PciDeviceStructurePciToPciBridge> {
405 Some(self)
406 }
407 fn as_pci_to_pci_bridge_device_mut(&mut self) -> Option<&mut PciDeviceStructurePciToPciBridge> {
408 Some(self)
409 }
410 fn common_header(&self) -> &PciDeviceStructureHeader {
411 &self.common_header
412 }
413
414 fn common_header_mut(&mut self) -> &mut PciDeviceStructureHeader {
415 &mut self.common_header
416 }
417}
418#[derive(Clone, Debug)]
420pub struct PciDeviceStructurePciToCardbusBridge {
421 pub common_header: PciDeviceStructureHeader,
422 pub cardbus_socket_ex_ca_base_address: u32,
423 pub offset_of_capabilities_list: u8,
424 pub reserved: u8,
425 pub secondary_status: u16,
426 pub pci_bus_number: u8,
427 pub card_bus_bus_number: u8,
428 pub subordinate_bus_number: u8,
429 pub card_bus_latency_timer: u8,
430 pub memory_base_address0: u32,
431 pub memory_limit0: u32,
432 pub memory_base_address1: u32,
433 pub memory_limit1: u32,
434 pub io_base_address0: u32,
435 pub io_limit0: u32,
436 pub io_base_address1: u32,
437 pub io_limit1: u32,
438 pub interrupt_line: u8,
439 pub interrupt_pin: u8,
440 pub bridge_control: u16,
441 pub subsystem_device_id: u16,
442 pub subsystem_vendor_id: u16,
443 pub pc_card_legacy_mode_base_address_16_bit: u32,
444}
445impl PciDeviceStructure for PciDeviceStructurePciToCardbusBridge {
446 fn header_type(&self) -> HeaderType {
447 HeaderType::PciCardbusBridge
448 }
449 fn as_pci_to_carbus_bridge_device(&self) -> Option<&PciDeviceStructurePciToCardbusBridge> {
450 Some(&self)
451 }
452 fn as_pci_to_carbus_bridge_device_mut(
453 &mut self,
454 ) -> Option<&mut PciDeviceStructurePciToCardbusBridge> {
455 Some(self)
456 }
457 fn common_header(&self) -> &PciDeviceStructureHeader {
458 &self.common_header
459 }
460
461 fn common_header_mut(&mut self) -> &mut PciDeviceStructureHeader {
462 &mut self.common_header
463 }
464}
465
466#[derive(Copy, Clone, Debug, PartialEq)]
468pub struct PciRoot {
469 pub physical_address_base: u64, pub mmio_base: Option<*mut u32>, pub segement_group_number: SegmentGroupNumber, pub bus_begin: u8, pub bus_end: u8, }
475unsafe impl Send for PciRoot {}
477unsafe impl Sync for PciRoot {}
478impl Display for PciRoot {
480 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
481 write!(
482 f,
483 "PCI Root with segement:{}, bus begin at {}, bus end at {}, physical address at {},mapped at {:#x}",
484 self.segement_group_number, self.bus_begin, self.bus_end, self.physical_address_base, self.mmio_base.unwrap() as usize
485 )
486 }
487}
488
489impl PciRoot {
490 pub fn new(segment_group_number: SegmentGroupNumber) -> Result<Self, PciError> {
493 let mut pci_root = PciArch::ecam_root(segment_group_number)?;
494 pci_root.map()?;
495 Ok(pci_root)
496 }
497 fn map(&mut self) -> Result<u8, PciError> {
500 let bus_number = self.bus_end - self.bus_begin + 1;
501 let bus_number_double = (bus_number + 1) / 2;
502
503 let paddr = PhysAddr::new(self.physical_address_base);
504 let vaddr = convert_physical_to_virtual(paddr);
505
506 for i in 0..bus_number_double {
507 let mut kernel_page_table = KERNEL_PAGE_TABLE.lock();
508 unsafe {
509 kernel_page_table.map_to_with_table_flags_general(
510 Page::containing_address(vaddr + i as u64 * 4096),
511 PhysFrame::containing_address(paddr + i as u64 * 4096),
512 PageTableFlags::PRESENT | PageTableFlags::WRITABLE,
513 PageTableFlags::PRESENT | PageTableFlags::WRITABLE,
514 )
515 };
516 }
517 self.mmio_base = Some(vaddr.as_u64() as *mut u32);
518 Ok(0)
519 }
520 fn cam_offset(&self, bus_device_function: BusDeviceFunction, register_offset: u16) -> u32 {
525 assert!(bus_device_function.valid());
526 let bdf = ((bus_device_function.bus - self.bus_begin) as u32) << 8
527 | (bus_device_function.device as u32) << 3
528 | bus_device_function.function as u32;
529 let address = bdf << 12 | register_offset as u32;
530 assert!(address & 0x3 == 0);
532 address
533 }
534 pub fn read_config(&self, bus_device_function: BusDeviceFunction, register_offset: u16) -> u32 {
539 let address = self.cam_offset(bus_device_function, register_offset);
540 unsafe {
541 (self.mmio_base.unwrap().add((address >> 2) as usize)).read_volatile()
543 }
544 }
545
546 pub fn write_config(
551 &mut self,
552 bus_device_function: BusDeviceFunction,
553 register_offset: u16,
554 data: u32,
555 ) {
556 let address = self.cam_offset(bus_device_function, register_offset);
557 unsafe {
560 (self.mmio_base.unwrap().add((address >> 2) as usize)).write_volatile(data)
562 }
563 }
564 pub fn external_capabilities(
566 &self,
567 bus_device_function: BusDeviceFunction,
568 ) -> ExternalCapabilityIterator {
569 ExternalCapabilityIterator {
570 root: self,
571 bus_device_function,
572 next_capability_offset: Some(0x100),
573 }
574 }
575}
576pub fn capabilities_offset(bus_device_function: BusDeviceFunction) -> Option<u8> {
581 let result = PciArch::read_config(&bus_device_function, STATUS_COMMAND_OFFSET);
582 let status: Status = Status::from_bits_truncate((result >> 16) as u16);
583 if status.contains(Status::CAPABILITIES_LIST) {
584 let cap_pointer = PciArch::read_config(&bus_device_function, 0x34) as u8 & 0xFC;
585 Some(cap_pointer)
586 } else {
587 None
588 }
589}
590
591fn pci_read_header(
596 bus_device_function: BusDeviceFunction,
597 add_to_list: bool,
598) -> Result<Box<dyn PciDeviceStructure>, PciError> {
599 let result = PciArch::read_config(&bus_device_function, 0x00);
601 let vendor_id = result as u16;
602 let device_id = (result >> 16) as u16;
603
604 let result = PciArch::read_config(&bus_device_function, 0x04);
605 let command = result as u16;
606 let status = (result >> 16) as u16;
607
608 let result = PciArch::read_config(&bus_device_function, 0x08);
609 let revision_id = result as u8;
610 let prog_if = (result >> 8) as u8;
611 let subclass = (result >> 16) as u8;
612 let class_code = (result >> 24) as u8;
613
614 let result = PciArch::read_config(&bus_device_function, 0x0c);
615 let cache_line_size = result as u8;
616 let latency_timer = (result >> 8) as u8;
617 let header_type = (result >> 16) as u8;
618 let bist = (result >> 24) as u8;
619 if vendor_id == 0xffff {
620 return Err(PciError::GetWrongHeader);
621 }
622 let header = PciDeviceStructureHeader {
623 msix_mmio_vaddr: 0,
624 msix_mmio_size: 0,
625 msix_offset: 0,
626 msix_table_size: 0,
627 bus_device_function,
628 vendor_id,
629 device_id,
630 command,
631 status,
632 revision_id,
633 prog_if,
634 subclass,
635 class_code,
636 cache_line_size,
637 latency_timer,
638 header_type,
639 bist,
640 };
641 match HeaderType::from(header_type & 0x7f) {
642 HeaderType::Standard => {
643 let general_device = pci_read_general_device_header(header, &bus_device_function);
644 let box_general_device = Box::new(general_device);
645 let box_general_device_clone = box_general_device.clone();
646 if add_to_list {
647 PCI_DEVICE_LINKEDLIST.push_back(box_general_device);
648 }
649 Ok(box_general_device_clone)
650 }
651 HeaderType::PciPciBridge => {
652 let pci_to_pci_bridge = pci_read_pci_to_pci_bridge_header(header, &bus_device_function);
653 let box_pci_to_pci_bridge = Box::new(pci_to_pci_bridge);
654 let box_pci_to_pci_bridge_clone = box_pci_to_pci_bridge.clone();
655 if add_to_list {
656 PCI_DEVICE_LINKEDLIST.push_back(box_pci_to_pci_bridge);
657 }
658 Ok(box_pci_to_pci_bridge_clone)
659 }
660 HeaderType::PciCardbusBridge => {
661 let pci_cardbus_bridge =
662 pci_read_pci_to_cardbus_bridge_header(header, &bus_device_function);
663 let box_pci_cardbus_bridge = Box::new(pci_cardbus_bridge);
664 let box_pci_cardbus_bridge_clone = box_pci_cardbus_bridge.clone();
665 if add_to_list {
666 PCI_DEVICE_LINKEDLIST.push_back(box_pci_cardbus_bridge);
667 }
668 Ok(box_pci_cardbus_bridge_clone)
669 }
670 HeaderType::Unrecognised(_) => Err(PciError::UnrecognisedHeaderType),
671 }
672}
673
674fn pci_read_general_device_header(
680 common_header: PciDeviceStructureHeader,
681 bus_device_function: &BusDeviceFunction,
682) -> PciDeviceStructureGeneralDevice {
683 let standard_device_bar = PciStandardDeviceBar::default();
684 let cardbus_cis_pointer = PciArch::read_config(bus_device_function, 0x28);
685
686 let result = PciArch::read_config(bus_device_function, 0x2c);
687 let subsystem_vendor_id = result as u16;
688 let subsystem_id = (result >> 16) as u16;
689
690 let expansion_rom_base_address = PciArch::read_config(bus_device_function, 0x30);
691
692 let result = PciArch::read_config(bus_device_function, 0x34);
693 let capabilities_pointer = result as u8;
694 let reserved0 = (result >> 8) as u8;
695 let reserved1 = (result >> 16) as u16;
696
697 let reserved2 = PciArch::read_config(bus_device_function, 0x38);
698
699 let result = PciArch::read_config(bus_device_function, 0x3c);
700 let interrupt_line = result as u8;
701 let interrupt_pin = (result >> 8) as u8;
702 let min_grant = (result >> 16) as u8;
703 let max_latency = (result >> 24) as u8;
704 PciDeviceStructureGeneralDevice {
705 common_header,
706 standard_device_bar,
707 cardbus_cis_pointer,
708 subsystem_vendor_id,
709 subsystem_id,
710 expansion_rom_base_address,
711 capabilities_pointer,
712 reserved0,
713 reserved1,
714 reserved2,
715 interrupt_line,
716 interrupt_pin,
717 min_grant,
718 max_latency,
719 }
720}
721
722fn pci_read_pci_to_pci_bridge_header(
728 common_header: PciDeviceStructureHeader,
729 bus_device_function: &BusDeviceFunction,
730) -> PciDeviceStructurePciToPciBridge {
731 let bar0 = PciArch::read_config(bus_device_function, 0x10);
732 let bar1 = PciArch::read_config(bus_device_function, 0x14);
733
734 let result = PciArch::read_config(bus_device_function, 0x18);
735
736 let primary_bus_number = result as u8;
737 let secondary_bus_number = (result >> 8) as u8;
738 let subordinate_bus_number = (result >> 16) as u8;
739 let secondary_latency_timer = (result >> 24) as u8;
740
741 let result = PciArch::read_config(bus_device_function, 0x1c);
742 let io_base = result as u8;
743 let io_limit = (result >> 8) as u8;
744 let secondary_status = (result >> 16) as u16;
745
746 let result = PciArch::read_config(bus_device_function, 0x20);
747 let memory_base = result as u16;
748 let memory_limit = (result >> 16) as u16;
749
750 let result = PciArch::read_config(bus_device_function, 0x24);
751 let prefetchable_memory_base = result as u16;
752 let prefetchable_memory_limit = (result >> 16) as u16;
753
754 let prefetchable_base_upper_32_bits = PciArch::read_config(bus_device_function, 0x28);
755 let prefetchable_limit_upper_32_bits = PciArch::read_config(bus_device_function, 0x2c);
756
757 let result = PciArch::read_config(bus_device_function, 0x30);
758 let io_base_upper_16_bits = result as u16;
759 let io_limit_upper_16_bits = (result >> 16) as u16;
760
761 let result = PciArch::read_config(bus_device_function, 0x34);
762 let capability_pointer = result as u8;
763 let reserved0 = (result >> 8) as u8;
764 let reserved1 = (result >> 16) as u16;
765
766 let expansion_rom_base_address = PciArch::read_config(bus_device_function, 0x38);
767
768 let result = PciArch::read_config(bus_device_function, 0x3c);
769 let interrupt_line = result as u8;
770 let interrupt_pin = (result >> 8) as u8;
771 let bridge_control = (result >> 16) as u16;
772 PciDeviceStructurePciToPciBridge {
773 common_header,
774 bar0,
775 bar1,
776 primary_bus_number,
777 secondary_bus_number,
778 subordinate_bus_number,
779 secondary_latency_timer,
780 io_base,
781 io_limit,
782 secondary_status,
783 memory_base,
784 memory_limit,
785 prefetchable_memory_base,
786 prefetchable_memory_limit,
787 prefetchable_base_upper_32_bits,
788 prefetchable_limit_upper_32_bits,
789 io_base_upper_16_bits,
790 io_limit_upper_16_bits,
791 capability_pointer,
792 reserved0,
793 reserved1,
794 expansion_rom_base_address,
795 interrupt_line,
796 interrupt_pin,
797 bridge_control,
798 }
799}
800
801fn pci_read_pci_to_cardbus_bridge_header(
807 common_header: PciDeviceStructureHeader,
808 busdevicefunction: &BusDeviceFunction,
809) -> PciDeviceStructurePciToCardbusBridge {
810 let cardbus_socket_ex_ca_base_address = PciArch::read_config(busdevicefunction, 0x10);
811
812 let result = PciArch::read_config(busdevicefunction, 0x14);
813 let offset_of_capabilities_list = result as u8;
814 let reserved = (result >> 8) as u8;
815 let secondary_status = (result >> 16) as u16;
816
817 let result = PciArch::read_config(busdevicefunction, 0x18);
818 let pci_bus_number = result as u8;
819 let card_bus_bus_number = (result >> 8) as u8;
820 let subordinate_bus_number = (result >> 16) as u8;
821 let card_bus_latency_timer = (result >> 24) as u8;
822
823 let memory_base_address0 = PciArch::read_config(busdevicefunction, 0x1c);
824 let memory_limit0 = PciArch::read_config(busdevicefunction, 0x20);
825 let memory_base_address1 = PciArch::read_config(busdevicefunction, 0x24);
826 let memory_limit1 = PciArch::read_config(busdevicefunction, 0x28);
827
828 let io_base_address0 = PciArch::read_config(busdevicefunction, 0x2c);
829 let io_limit0 = PciArch::read_config(busdevicefunction, 0x30);
830 let io_base_address1 = PciArch::read_config(busdevicefunction, 0x34);
831 let io_limit1 = PciArch::read_config(busdevicefunction, 0x38);
832 let result = PciArch::read_config(busdevicefunction, 0x3c);
833 let interrupt_line = result as u8;
834 let interrupt_pin = (result >> 8) as u8;
835 let bridge_control = (result >> 16) as u16;
836
837 let result = PciArch::read_config(busdevicefunction, 0x40);
838 let subsystem_device_id = result as u16;
839 let subsystem_vendor_id = (result >> 16) as u16;
840
841 let pc_card_legacy_mode_base_address_16_bit = PciArch::read_config(busdevicefunction, 0x44);
842 PciDeviceStructurePciToCardbusBridge {
843 common_header,
844 cardbus_socket_ex_ca_base_address,
845 offset_of_capabilities_list,
846 reserved,
847 secondary_status,
848 pci_bus_number,
849 card_bus_bus_number,
850 subordinate_bus_number,
851 card_bus_latency_timer,
852 memory_base_address0,
853 memory_limit0,
854 memory_base_address1,
855 memory_limit1,
856 io_base_address0,
857 io_limit0,
858 io_base_address1,
859 io_limit1,
860 interrupt_line,
861 interrupt_pin,
862 bridge_control,
863 subsystem_device_id,
864 subsystem_vendor_id,
865 pc_card_legacy_mode_base_address_16_bit,
866 }
867}
868
869fn pci_check_all_buses() -> Result<u8, PciError> {
872 info!("Checking all devices in PCI bus...");
873 let busdevicefunction = BusDeviceFunction {
874 bus: 0,
875 device: 0,
876 function: 0,
877 };
878 let header = pci_read_header(busdevicefunction, false)?;
879 let common_header = header.common_header();
880 pci_check_bus(0)?;
881 if common_header.header_type & 0x80 != 0 {
882 for function in 1..8 {
883 pci_check_bus(function)?;
884 }
885 }
886 Ok(0)
887}
888fn pci_check_function(busdevicefunction: BusDeviceFunction) -> Result<u8, PciError> {
891 let header = match pci_read_header(busdevicefunction, true) {
893 Ok(header) => header,
894 Err(PciError::GetWrongHeader) => {
895 return Ok(255);
896 }
897 Err(e) => {
898 return Err(e);
899 }
900 };
901 let common_header = header.common_header();
902 if (common_header.class_code == 0x06)
903 && (common_header.subclass == 0x04 || common_header.subclass == 0x09)
904 {
905 let pci_to_pci_bridge = header
906 .as_pci_to_pci_bridge_device()
907 .ok_or(PciError::PciDeviceStructureTransformError)?;
908 let secondary_bus = pci_to_pci_bridge.secondary_bus_number;
909 pci_check_bus(secondary_bus)?;
910 }
911 Ok(0)
912}
913
914fn pci_check_device(bus: u8, device: u8) -> Result<u8, PciError> {
917 let busdevicefunction = BusDeviceFunction {
919 bus,
920 device,
921 function: 0,
922 };
923 let header = match pci_read_header(busdevicefunction, false) {
924 Ok(header) => header,
925 Err(PciError::GetWrongHeader) => {
926 return Ok(255);
928 }
929 Err(e) => {
930 return Err(e);
931 }
932 };
933 pci_check_function(busdevicefunction)?;
934 let common_header = header.common_header();
935 if common_header.header_type & 0x80 != 0 {
936 debug!(
937 "Detected multi func device in bus{},device{}",
938 busdevicefunction.bus, busdevicefunction.device
939 );
940 for function in 1..8 {
942 let busdevicefunction = BusDeviceFunction {
943 bus,
944 device,
945 function,
946 };
947 pci_check_function(busdevicefunction)?;
948 }
949 }
950 Ok(0)
951}
952fn pci_check_bus(bus: u8) -> Result<u8, PciError> {
955 for device in 0..32 {
957 pci_check_device(bus, device)?;
958 }
959 Ok(0)
960}
961
962pub fn init() {
964 info!("Initializing PCI bus...");
965 if let Err(e) = pci_check_all_buses() {
966 error!("pci init failed when checking bus because of error: {}", e);
967 return;
968 }
969 info!(
970 "Total pci device and function num = {}",
971 PCI_DEVICE_LINKEDLIST.len()
972 );
973 let list = PCI_DEVICE_LINKEDLIST.read();
974 for box_pci_device in list.iter() {
975 let common_header = box_pci_device.common_header();
976 match box_pci_device.header_type() {
977 HeaderType::Standard if common_header.status & 0x10 != 0 => {
978 info!("Found pci standard device with class code ={} subclass={} status={:#x} cap_pointer={:#x} vendor={:#x}, device id={:#x}", common_header.class_code, common_header.subclass, common_header.status, box_pci_device.as_standard_device().unwrap().capabilities_pointer,common_header.vendor_id, common_header.device_id);
979 }
980 HeaderType::Standard => {
981 info!(
982 "Found pci standard device with class code ={} subclass={} status={:#x} ",
983 common_header.class_code, common_header.subclass, common_header.status
984 );
985 }
986 HeaderType::PciPciBridge => {
990 info!(
991 "Found pci-to-pci bridge device with class code ={} subclass={} status={:#x} ",
992 common_header.class_code, common_header.subclass, common_header.status
993 );
994 }
995 HeaderType::PciCardbusBridge => {
996 info!(
997 "Found pcicardbus bridge device with class code ={} subclass={} status={:#x} ",
998 common_header.class_code, common_header.subclass, common_header.status
999 );
1000 }
1001 HeaderType::Unrecognised(_) => {}
1002 }
1003 }
1004 info!("PCI bus initialized.");
1005}
1006
1007#[derive(Copy, Clone, Debug, Eq, PartialEq)]
1010pub struct BusDeviceFunction {
1011 pub bus: u8,
1013 pub device: u8,
1015 pub function: u8,
1017}
1018impl BusDeviceFunction {
1019 #[allow(dead_code)]
1024 pub fn valid(&self) -> bool {
1025 self.device < 32 && self.function < 8
1026 }
1027}
1028impl Display for BusDeviceFunction {
1030 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
1031 write!(f, "{:02x}:{:02x}.{}", self.bus, self.device, self.function)
1032 }
1033}
1034#[derive(Copy, Clone, Debug, Eq, PartialEq)]
1037pub enum MemoryBarType {
1038 Width32,
1040 Below1MiB,
1042 Width64,
1044}
1045impl From<MemoryBarType> for u8 {
1047 fn from(bar_type: MemoryBarType) -> Self {
1048 match bar_type {
1049 MemoryBarType::Width32 => 0,
1050 MemoryBarType::Below1MiB => 1,
1051 MemoryBarType::Width64 => 2,
1052 }
1053 }
1054}
1055impl TryFrom<u8> for MemoryBarType {
1057 type Error = PciError;
1058 fn try_from(value: u8) -> Result<Self, Self::Error> {
1059 match value {
1060 0 => Ok(Self::Width32),
1061 1 => Ok(Self::Below1MiB),
1062 2 => Ok(Self::Width64),
1063 _ => Err(PciError::InvalidBarType),
1064 }
1065 }
1066}
1067
1068#[derive(Clone, Debug, Eq, PartialEq)]
1071pub enum BarInfo {
1072 Memory {
1074 address_type: MemoryBarType,
1076 prefetchable: bool,
1079 address: u64,
1081 size: u32,
1083 virtaddress: u64,
1085 },
1086 IO {
1088 address: u32,
1090 size: u32,
1092 },
1093 Unused,
1094}
1095
1096impl BarInfo {
1097 pub fn memory_address_size(&self) -> Option<(u64, u32)> {
1103 if let Self::Memory { address, size, .. } = self {
1104 Some((*address, *size))
1105 } else {
1106 None
1107 }
1108 }
1109 pub fn virtual_address(&self) -> Option<u64> {
1113 if let Self::Memory { virtaddress, .. } = self {
1114 Some(*virtaddress)
1115 } else {
1116 None
1117 }
1118 }
1119}
1120impl Display for BarInfo {
1122 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1123 match self {
1124 Self::Memory {
1125 address_type,
1126 prefetchable,
1127 address,
1128 size,
1129 virtaddress,
1130 } => write!(
1131 f,
1132 "Memory space at {:#010x}, size {}, type {:?}, prefetchable {},mapped at {:#x}",
1133 address, size, address_type, prefetchable, virtaddress
1134 ),
1135 Self::IO { address, size } => {
1136 write!(f, "I/O space at {:#010x}, size {}", address, size)
1137 }
1138 Self::Unused => {
1139 write!(f, "Unused bar")
1140 }
1141 }
1142 }
1143}
1144#[derive(Clone, Debug, Eq, PartialEq)]
1146pub struct PciStandardDeviceBar {
1147 bar0: BarInfo,
1148 bar1: BarInfo,
1149 bar2: BarInfo,
1150 bar3: BarInfo,
1151 bar4: BarInfo,
1152 bar5: BarInfo,
1153}
1154
1155impl PciStandardDeviceBar {
1156 pub fn get_bar(&self, bar_index: u8) -> Result<&BarInfo, PciError> {
1160 match bar_index {
1161 0 => Ok(&self.bar0),
1162 1 => Ok(&self.bar1),
1163 2 => Ok(&self.bar2),
1164 3 => Ok(&self.bar3),
1165 4 => Ok(&self.bar4),
1166 5 => Ok(&self.bar5),
1167 _ => Err(PciError::InvalidBarType),
1168 }
1169 }
1170}
1171impl Display for PciStandardDeviceBar {
1173 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1174 write!(
1175 f,
1176 "\r\nBar0:{}\r\n Bar1:{}\r\n Bar2:{}\r\n Bar3:{}\r\nBar4:{}\r\nBar5:{}",
1177 self.bar0, self.bar1, self.bar2, self.bar3, self.bar4, self.bar5
1178 )
1179 }
1180}
1181impl Default for PciStandardDeviceBar {
1183 fn default() -> Self {
1184 PciStandardDeviceBar {
1185 bar0: BarInfo::Unused,
1186 bar1: BarInfo::Unused,
1187 bar2: BarInfo::Unused,
1188 bar3: BarInfo::Unused,
1189 bar4: BarInfo::Unused,
1190 bar5: BarInfo::Unused,
1191 }
1192 }
1193}
1194
1195pub fn pci_bar_init(
1199 bus_device_function: BusDeviceFunction,
1200) -> Result<PciStandardDeviceBar, PciError> {
1201 let mut device_bar: PciStandardDeviceBar = PciStandardDeviceBar::default();
1202 let mut bar_index_ignore: u8 = 255;
1203 for bar_index in 0..6 {
1204 if bar_index == bar_index_ignore {
1205 continue;
1206 }
1207 let bar_info;
1208 let bar_orig = PciArch::read_config(&bus_device_function, BAR0_OFFSET + 4 * bar_index);
1209 PciArch::write_config(
1210 &bus_device_function,
1211 BAR0_OFFSET + 4 * bar_index,
1212 0xffffffff,
1213 );
1214 let size_mask = PciArch::read_config(&bus_device_function, BAR0_OFFSET + 4 * bar_index);
1215 let size = (!(size_mask & 0xfffffff0)).wrapping_add(1);
1218 PciArch::write_config(&bus_device_function, BAR0_OFFSET + 4 * bar_index, bar_orig);
1221 if size == 0 {
1222 continue;
1223 }
1224 if bar_orig & 0x00000001 == 0x00000001 {
1225 let address = bar_orig & 0xfffffffc;
1227 bar_info = BarInfo::IO { address, size };
1228 } else {
1229 let mut address = u64::from(bar_orig & 0xfffffff0);
1231 let prefetchable = bar_orig & 0x00000008 != 0;
1232 let address_type = MemoryBarType::try_from(((bar_orig & 0x00000006) >> 1) as u8)?;
1233 if address_type == MemoryBarType::Width64 {
1234 if bar_index >= 5 {
1235 return Err(PciError::InvalidBarType);
1236 }
1237 let address_top =
1238 PciArch::read_config(&bus_device_function, BAR0_OFFSET + 4 * (bar_index + 1));
1239 address |= u64::from(address_top) << 32;
1240 bar_index_ignore = bar_index + 1; }
1242
1243 let paddr = PhysAddr::new(address);
1244 let vaddr = convert_physical_to_virtual(paddr);
1245
1246 for i in 0..(size / 4096) {
1247 let mut kernel_page_table = KERNEL_PAGE_TABLE.lock();
1248 unsafe {
1249 kernel_page_table.map_to_with_table_flags_general(
1250 Page::containing_address(vaddr + i as u64 * 4096),
1251 PhysFrame::containing_address(paddr + i as u64 * 4096),
1252 PageTableFlags::PRESENT | PageTableFlags::WRITABLE,
1253 PageTableFlags::PRESENT | PageTableFlags::WRITABLE,
1254 )
1255 };
1256 }
1257
1258 bar_info = BarInfo::Memory {
1259 address_type,
1260 prefetchable,
1261 address,
1262 size,
1263 virtaddress: vaddr.as_u64(),
1264 };
1265 }
1266 match bar_index {
1267 0 => {
1268 device_bar.bar0 = bar_info;
1269 }
1270 1 => {
1271 device_bar.bar1 = bar_info;
1272 }
1273 2 => {
1274 device_bar.bar2 = bar_info;
1275 }
1276 3 => {
1277 device_bar.bar3 = bar_info;
1278 }
1279 4 => {
1280 device_bar.bar4 = bar_info;
1281 }
1282 5 => {
1283 device_bar.bar5 = bar_info;
1284 }
1285 _ => {}
1286 }
1287 }
1288 debug!("pci_device_bar:{}", device_bar);
1289 return Ok(device_bar);
1290}
1291
1292#[derive(Debug, Copy, Clone, Eq, PartialEq)]
1295pub struct CapabilityInfo {
1296 pub offset: u8,
1298 pub id: u8,
1300 pub private_header: u16,
1302}
1303
1304#[derive(Debug)]
1307pub struct CapabilityIterator {
1308 pub bus_device_function: BusDeviceFunction,
1309 pub next_capability_offset: Option<u8>,
1310}
1311
1312impl Iterator for CapabilityIterator {
1313 type Item = CapabilityInfo;
1314 fn next(&mut self) -> Option<Self::Item> {
1315 let offset = self.next_capability_offset?;
1316
1317 let capability_header = PciArch::read_config(&self.bus_device_function, offset);
1319 let id = capability_header as u8;
1320 let next_offset = (capability_header >> 8) as u8;
1321 let private_header = (capability_header >> 16) as u16;
1322
1323 self.next_capability_offset = if next_offset == 0 {
1324 None
1325 } else if next_offset < 64 || next_offset & 0x3 != 0 {
1326 warn!("Invalid next capability offset {:#04x}", next_offset);
1327 None
1328 } else {
1329 Some(next_offset)
1330 };
1331
1332 Some(CapabilityInfo {
1333 offset,
1334 id,
1335 private_header,
1336 })
1337 }
1338}
1339
1340#[derive(Debug, Copy, Clone, Eq, PartialEq)]
1343pub struct ExternalCapabilityInfo {
1344 pub offset: u16,
1346 pub id: u16,
1348 pub capability_version: u8,
1350}
1351
1352#[derive(Debug)]
1355pub struct ExternalCapabilityIterator<'a> {
1356 pub root: &'a PciRoot,
1357 pub bus_device_function: BusDeviceFunction,
1358 pub next_capability_offset: Option<u16>,
1359}
1360impl<'a> Iterator for ExternalCapabilityIterator<'a> {
1361 type Item = ExternalCapabilityInfo;
1362 fn next(&mut self) -> Option<Self::Item> {
1363 let offset = self.next_capability_offset?;
1364
1365 let capability_header = self.root.read_config(self.bus_device_function, offset);
1367 let id = capability_header as u16;
1368 let next_offset = (capability_header >> 20) as u16;
1369 let capability_version = ((capability_header >> 16) & 0xf) as u8;
1370
1371 self.next_capability_offset = if next_offset == 0 {
1372 None
1373 } else if next_offset < 0x100 || next_offset & 0x3 != 0 {
1374 warn!("Invalid next capability offset {:#04x}", next_offset);
1375 None
1376 } else {
1377 Some(next_offset)
1378 };
1379
1380 Some(ExternalCapabilityInfo {
1381 offset,
1382 id,
1383 capability_version,
1384 })
1385 }
1386}