Skip to content

Commit

Permalink
feat: add pci temp
Browse files Browse the repository at this point in the history
  • Loading branch information
yfblock committed Sep 21, 2024
1 parent 5b89010 commit f50e186
Show file tree
Hide file tree
Showing 15 changed files with 212 additions and 30 deletions.
11 changes: 11 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ x86_64 = "0.14"
multiboot = "0.8.0"
x2apic = "0.4"
raw-cpuid = "11.0"
acpi = "5.0.0"

[target.'cfg(target_arch = "aarch64")'.dependencies]
aarch64-cpu = "9.3"
Expand Down
11 changes: 11 additions & 0 deletions example/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion example/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ polyhal = { version = "0.1.2", features = [
"logger",
"boot",
"trap",
"graphic"
# "graphic"
] }
log = "0.4"
fdt = "0.1.5"
Expand Down
1 change: 1 addition & 0 deletions example/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ OBJCOPY := rust-objcopy --binary-architecture=riscv64
ifneq ($(GUI), true)
QEMU_EXEC += -nographic
else
BUILD_ARGS += --features "polyhal/graphic"
QEMU_EXEC += -serial stdio -vga std
endif
QEMU_EXEC += -smp $(SMP)
Expand Down
24 changes: 14 additions & 10 deletions example/src/pci.rs
Original file line number Diff line number Diff line change
@@ -1,22 +1,26 @@
use log::{info, trace};
use polyhal::{common::get_fdt, consts::VIRT_ADDR_START};
use polyhal::{common::get_pci_addr, consts::VIRT_ADDR_START};
use virtio_drivers::transport::pci::{
bus::{Cam, Command, DeviceFunction, HeaderType, PciRoot},
virtio_device_type,
};

/// Initialize PCI Configuration.
pub fn init() {
if let Some(fdt) = get_fdt() {
if let Some(pci_node) = fdt.all_nodes().find(|x| x.name.starts_with("pci")) {
let pci_addr = pci_node.reg().map(|mut x| x.next().unwrap()).unwrap();
log::info!("PCI Address: {:#p}", pci_addr.starting_address);
enumerate_pci((pci_addr.starting_address as usize | VIRT_ADDR_START) as *mut u8);
return;
}
// if let Some(fdt) = get_fdt() {
// if let Some(pci_node) = fdt.all_nodes().find(|x| x.name.starts_with("pci")) {
// let pci_addr = pci_node.reg().map(|mut x| x.next().unwrap()).unwrap();
// log::info!("PCI Address: {:#p}", pci_addr.starting_address);
// enumerate_pci((pci_addr.starting_address as usize | VIRT_ADDR_START) as *mut u8);
// return;
// }
// }
// #[cfg(target_arch = "x86_64")]
// enumerate_pci((0xb000_0000 | VIRT_ADDR_START) as *mut u8);
if let Some(pci_addr) = get_pci_addr() {
log::info!("PCI Address: {:#x}", pci_addr);
enumerate_pci((pci_addr | VIRT_ADDR_START) as *mut u8);
}
#[cfg(target_arch = "x86_64")]
enumerate_pci((0xb000_0000 | VIRT_ADDR_START) as *mut u8);
}

/// Enumerate the PCI devices
Expand Down
4 changes: 3 additions & 1 deletion src/components/arch/x86_64.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
pub(crate) mod apic;
pub(crate) mod gdt;
pub(crate) mod idt;
pub(crate) mod acpi;

use core::sync::atomic::AtomicUsize;

use acpi::parse_acpi_info;
use alloc::vec::Vec;
use multiboot::information::MemoryType;

Expand All @@ -18,6 +20,7 @@ use crate::components::{
pub(crate) static MBOOT_PTR: AtomicUsize = AtomicUsize::new(0);

pub(crate) fn arch_init() {
let _ = parse_acpi_info();
DTB_BIN.init_by(Vec::new());
if let Some(mboot) = use_multiboot(MBOOT_PTR.load(core::sync::atomic::Ordering::SeqCst) as _) {
let mut mem_area = Vec::new();
Expand All @@ -29,7 +32,6 @@ pub(crate) fn arch_init() {
.for_each(|x| {
let start = x.base_address() as usize | VIRT_ADDR_START;
let size = x.length() as usize;
// ArchInterface::add_memory_region(start, end);
mem_area.push((start, size));
});
}
Expand Down
65 changes: 65 additions & 0 deletions src/components/arch/x86_64/acpi.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
use core::ptr::NonNull;

use acpi::{AcpiError, AcpiHandler, AcpiTables};

use crate::{common::{CPU_NUM, PCI_ADDR}, consts::VIRT_ADDR_START};

#[derive(Clone)]
struct AcpiImpl;

impl AcpiHandler for AcpiImpl {
unsafe fn map_physical_region<T>(
&self,
physical_address: usize,
size: usize,
) -> acpi::PhysicalMapping<Self, T> {
unsafe {
acpi::PhysicalMapping::new(
physical_address,
NonNull::new((physical_address | VIRT_ADDR_START) as *mut T).unwrap(),
size,
size,
AcpiImpl,
)
}
}

fn unmap_physical_region<T>(_region: &acpi::PhysicalMapping<Self, T>) {}
}

/// Detects the address of acpi through acpi_signature.
///
/// Detects in bios area.
pub(crate) fn detect_acpi() -> Result<(), AcpiError> {
unsafe {
match AcpiTables::search_for_rsdp_bios(AcpiImpl) {
Ok(ref acpi_table) => {
let madt = acpi_table.find_table::<acpi::madt::Madt>()?;
let cpu_count = madt
.entries()
.filter(|x| matches!(x, acpi::madt::MadtEntry::LocalApic(_)))
.count();
CPU_NUM.init(cpu_count);
}
Err(err) => log::warn!("Not Found Available ACPI: {:#x?}", err),
}
}
Err(AcpiError::NoValidRsdp)
}

/// Parse informations from acpi table.
pub(crate) fn parse_acpi_info() -> Result<(), AcpiError> {
unsafe {
match AcpiTables::search_for_rsdp_bios(AcpiImpl) {
Ok(ref acpi_table) => {
acpi::PciConfigRegions::new(acpi_table).expect("can't find pci config");
let pci_addr = acpi::PciConfigRegions::new(acpi_table)?
.physical_address(0, 0, 0, 0)
.ok_or(AcpiError::NoValidRsdp)?;
PCI_ADDR.init(pci_addr as _);
}
Err(err) => log::warn!("Not Found Available ACPI: {:#x?}", err),
}
}
Err(AcpiError::NoValidRsdp)
}
2 changes: 1 addition & 1 deletion src/components/boot/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ extern "Rust" {
}

/// Define the entry point.
///
///
/// TODO: Support secondary Entry Point for the application core.
/// - Implement MultiCore
/// - Jump to _secondary_for_arch function in application core.
Expand Down
2 changes: 1 addition & 1 deletion src/components/boot/riscv64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ pub(crate) fn rust_main(hartid: usize, device_tree: usize) {
init_cpu();

let fdt = unsafe { Fdt::from_ptr(device_tree as *const u8) };
CPU_NUM.init_by(fdt.map(|fdt| fdt.cpus().count()).unwrap_or(1));
CPU_NUM.init(fdt.map(|fdt| fdt.cpus().count()).unwrap_or(1));

DTB_PTR.init_by(device_tree);

Expand Down
12 changes: 5 additions & 7 deletions src/components/boot/x86_64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ use x86_64::registers::control::{Cr0Flags, Cr4, Cr4Flags};
use x86_64::registers::model_specific::EferFlags;
use x86_64::registers::xcontrol::{XCr0, XCr0Flags};

use crate::arch::acpi::detect_acpi;
use crate::common::get_cpu_num;
use crate::components::arch::{self, get_com_port, hart_id, MBOOT_PTR};
use crate::components::common::{CPU_ID, CPU_NUM};
use crate::components::consts::VIRT_ADDR_START;
Expand Down Expand Up @@ -156,8 +158,7 @@ fn rust_tmp_main(magic: usize, mboot_ptr: usize) {
}
});

// TODO: This is will be fixed with ACPI support
CPU_NUM.init_by(1);
let _ = detect_acpi();

// Check Multiboot Magic Number.
assert_eq!(magic, multiboot::information::SIGNATURE_EAX as usize);
Expand All @@ -169,11 +170,8 @@ fn rust_tmp_main(magic: usize, mboot_ptr: usize) {
println!(include_str!("../../banner.txt"));
display_info!("Platform Arch", "x86_64");
if let Some(features) = CpuId::new().get_feature_info() {
display_info!(
"Platform Hart Count",
"{}",
core::cmp::max(1, features.max_logical_processor_ids())
);
CPU_NUM.init(core::cmp::max(1, features.max_logical_processor_ids() as _));
display_info!("Platform Hart Count", "{}", get_cpu_num());
display_info!("Platform FPU Support", "{}", features.has_fpu());
}
display_info!("Platform Boot Header", "{mboot_ptr:#018x}");
Expand Down
32 changes: 26 additions & 6 deletions src/components/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use alloc::vec::Vec;
use fdt::Fdt;

use crate::components::arch::arch_init;
use crate::utils::InitNum;
use crate::{utils::LazyInit, PhysPage};

use super::debug_console::display_info;
Expand All @@ -13,6 +14,8 @@ pub(crate) static CPU_ID: usize = 0;
#[allow(dead_code)]
pub(crate) static DTB_PTR: LazyInit<usize> = LazyInit::new();

pub(crate) static PCI_ADDR: InitNum = InitNum::new(0);

/// Page Allocation trait for privoids that page allocation
pub trait PageAlloc: Sync {
/// Allocate a physical page
Expand All @@ -33,7 +36,7 @@ pub fn init(page_alloc: &'static dyn PageAlloc) {
}

/// Store the number of cpu, this will fill up by startup function.
pub(crate) static CPU_NUM: LazyInit<usize> = LazyInit::new();
pub(crate) static CPU_NUM: InitNum = InitNum::new(0);

/// Store the memory area, this will fill up by the arch_init() function in each architecture.
pub(crate) static MEM_AREA: LazyInit<Vec<(usize, usize)>> = LazyInit::new();
Expand All @@ -52,9 +55,14 @@ pub fn get_fdt() -> Option<Fdt<'static>> {
unsafe { Fdt::from_ptr(*DTB_PTR.get_unchecked() as *const u8).ok() }
}

/// Get the pci area address
pub fn get_pci_addr() -> Option<usize> {
PCI_ADDR.get_option()
}

/// Get the number of cpus
pub fn get_cpu_num() -> usize {
*CPU_NUM
CPU_NUM.get()
}

/// alloc a persistent memory page
Expand All @@ -70,8 +78,8 @@ pub(crate) fn frame_dealloc(ppn: PhysPage) {
}

/// Parse Information from the device tree binary
///
/// Display information when booting
///
/// Display information when booting
/// Initialize the variables and memory from device tree
#[inline]
pub(crate) fn parse_dtb_info() {
Expand All @@ -91,8 +99,20 @@ pub(crate) fn parse_dtb_info() {

display_info!("Boot Args", "{}", fdt.chosen().bootargs().unwrap_or(""));

CPU_NUM.init_by(fdt.cpus().count());
CPU_NUM.init(fdt.cpus().count());

fdt.all_nodes()
.find(|x| x.name.starts_with("pci"))
.inspect(|pci_node| {
PCI_ADDR.init(
pci_node
.reg()
.map(|mut x| x.next().unwrap())
.unwrap()
.starting_address as _,
)
});
} else {
CPU_NUM.init_by(1);
CPU_NUM.init(1);
}
}
30 changes: 27 additions & 3 deletions src/components/multicore/x86_64.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,28 @@
// TODO: Boot a core with top pointer of the stack
pub fn boot_core(_hart_id: usize, _sp_top: usize) {
log::error!("Boot Core is not implemented yet for aarch64");
use core::sync::atomic::{AtomicBool, Ordering};

/// TODO: Boot a core with top pointer of the stack
/// Fina a way to pass the stack pointer to core.
pub fn boot_core(hart_id: usize, _sp_top: usize) {
static BOOT_LOCK: AtomicBool = AtomicBool::new(false);

// Waiting until the previous boot is completed.
while BOOT_LOCK.load(Ordering::SeqCst) {};

// Set the boot lock to true and start the boot process.
BOOT_LOCK.store(true, Ordering::SeqCst);
log::error!("Boot Core is not implemented yet for x86_64");

let apic_id = crate::arch::apic::raw_apic_id(hart_id as _);
let lapic = crate::arch::apic::local_apic();

// This is the
const START_PAGE_IDX: u8 = 6;

unsafe {
lapic.send_init_ipi(apic_id);

lapic.send_sipi(START_PAGE_IDX, apic_id);

lapic.send_sipi(START_PAGE_IDX, apic_id);
}
}
Loading

0 comments on commit f50e186

Please sign in to comment.