init.rs 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. use super::{
  2. device::{PCIDevice, SegmentGroup, PCIE_DEVICES},
  3. error::PciError,
  4. };
  5. use crate::kernel::mem::PhysAccess as _;
  6. use acpi::{AcpiHandler, PhysicalMapping};
  7. use eonix_mm::address::PAddr;
  8. #[derive(Clone)]
  9. struct AcpiHandlerImpl;
  10. impl AcpiHandler for AcpiHandlerImpl {
  11. unsafe fn map_physical_region<T>(
  12. &self,
  13. physical_address: usize,
  14. size: usize,
  15. ) -> PhysicalMapping<Self, T> {
  16. let virtual_address = unsafe {
  17. // SAFETY: `physical_address` is guaranteed to be valid by the caller.
  18. PAddr::from_val(physical_address).as_ptr()
  19. };
  20. PhysicalMapping::new(physical_address, virtual_address, size, size, self.clone())
  21. }
  22. fn unmap_physical_region<T>(_: &PhysicalMapping<Self, T>) {}
  23. }
  24. pub fn init_pcie() -> Result<(), PciError> {
  25. #[cfg(target_arch = "x86_64")]
  26. {
  27. use acpi::{AcpiTables, PciConfigRegions};
  28. let acpi_tables = unsafe {
  29. // SAFETY: Our impl should be correct.
  30. AcpiTables::search_for_rsdp_bios(AcpiHandlerImpl)?
  31. };
  32. let conf_regions = PciConfigRegions::new(&acpi_tables)?;
  33. for region in conf_regions.iter() {
  34. let segment_group = SegmentGroup::from_entry(&region);
  35. for config_space in segment_group.iter() {
  36. if let Some(header) = config_space.header() {
  37. let pci_device = PCIDevice::new(segment_group.clone(), config_space, header);
  38. PCIE_DEVICES.lock().insert(pci_device);
  39. }
  40. }
  41. }
  42. }
  43. #[cfg(target_arch = "riscv64")]
  44. {
  45. use crate::kernel::constants::{EINVAL, ENOENT};
  46. use eonix_hal::device::FDT;
  47. use eonix_mm::address::PRange;
  48. let pcie_node = FDT.find_node("/soc/pci").ok_or(ENOENT)?;
  49. let bus_range = pcie_node.property("bus-range").ok_or(ENOENT)?;
  50. let reg = pcie_node.reg().ok_or(EINVAL)?.next().ok_or(EINVAL)?;
  51. let mmio_range =
  52. PRange::from(PAddr::from(reg.starting_address as usize)).grow(reg.size.ok_or(EINVAL)?);
  53. if bus_range.value.len() != 8 {
  54. Err(EINVAL)?;
  55. }
  56. let bus_start = u32::from_be_bytes(bus_range.value[..4].try_into().unwrap());
  57. let bus_end = u32::from_be_bytes(bus_range.value[4..].try_into().unwrap());
  58. if bus_start > u8::MAX as u32 || bus_end > u8::MAX as u32 || bus_start > bus_end {
  59. Err(EINVAL)?;
  60. }
  61. let bus_start = bus_start as u8;
  62. let bus_end = bus_end as u8;
  63. let segment_group = SegmentGroup::new(0, bus_start, bus_end, mmio_range.start());
  64. for config_space in segment_group.iter() {
  65. if let Some(header) = config_space.header() {
  66. let pci_device = PCIDevice::new(segment_group.clone(), config_space, header);
  67. PCIE_DEVICES.lock().insert(pci_device);
  68. }
  69. }
  70. }
  71. Ok(())
  72. }