pub mod acpi;
pub mod apic;
pub mod gdt;
pub mod interrupts;
pub mod smp;
use acpi::ACPI;
use x86_64::instructions::port::Port;
use crate::drivers::pci::{
BusDeviceFunction, PciError, PciRoot, SegmentGroupNumber, PORT_PCI_CONFIG_ADDRESS,
PORT_PCI_CONFIG_DATA,
};
pub trait TraitPciArch {
fn read_config(bus_device_function: &BusDeviceFunction, offset: u8) -> u32;
fn write_config(bus_device_function: &BusDeviceFunction, offset: u8, data: u32);
fn address_pci_to_address_memory(address: usize) -> Result<usize, PciError>;
fn ecam_root(segement: SegmentGroupNumber) -> Result<PciRoot, PciError>;
}
pub struct X86_64PciArch;
impl TraitPciArch for X86_64PciArch {
fn read_config(bus_device_function: &BusDeviceFunction, offset: u8) -> u32 {
let address = ((bus_device_function.bus as u32) << 16)
| ((bus_device_function.device as u32) << 11)
| ((bus_device_function.function as u32 & 7) << 8)
| (offset & 0xfc) as u32
| (0x80000000);
let ret = unsafe {
Port::<u32>::new(PORT_PCI_CONFIG_ADDRESS).write(address);
let temp = Port::<u32>::new(PORT_PCI_CONFIG_DATA).read();
temp
};
return ret;
}
fn write_config(bus_device_function: &BusDeviceFunction, offset: u8, data: u32) {
let address = ((bus_device_function.bus as u32) << 16)
| ((bus_device_function.device as u32) << 11)
| ((bus_device_function.function as u32 & 7) << 8)
| (offset & 0xfc) as u32
| (0x80000000);
unsafe {
Port::<u32>::new(PORT_PCI_CONFIG_ADDRESS).write(address);
Port::<u32>::new(PORT_PCI_CONFIG_DATA).write(data);
}
}
fn address_pci_to_address_memory(address: usize) -> Result<usize, PciError> {
Ok(address)
}
fn ecam_root(segement: SegmentGroupNumber) -> Result<PciRoot, PciError> {
let mcfg_info = ACPI.try_get().unwrap().mcfg_info.clone();
for segmentgroupconfiguration in mcfg_info {
if segmentgroupconfiguration.pci_segment_group == segement {
return Ok(PciRoot {
physical_address_base: segmentgroupconfiguration.base_address,
mmio_base: None,
segement_group_number: segement,
bus_begin: segmentgroupconfiguration.bus_number_start,
bus_end: segmentgroupconfiguration.bus_number_end,
});
}
}
return Err(PciError::SegmentNotFound);
}
}
pub use X86_64PciArch as PciArch;