From 67546664ed34414fbd16d799c117147997c56e0a Mon Sep 17 00:00:00 2001 From: Drew Galbraith Date: Fri, 30 Aug 2024 17:09:27 -0700 Subject: [PATCH] Move to bitfield structs for AHCI info. --- rust/.cargo/config.toml | 1 + rust/Cargo.lock | 12 ++ rust/sys/denali/Cargo.toml | 1 + rust/sys/denali/src/ahci/controller.rs | 190 ++++++++++++++++++++++++- rust/sys/denali/src/bin/denali.rs | 1 + 5 files changed, 202 insertions(+), 3 deletions(-) diff --git a/rust/.cargo/config.toml b/rust/.cargo/config.toml index 6e70044..c2174c1 100644 --- a/rust/.cargo/config.toml +++ b/rust/.cargo/config.toml @@ -7,3 +7,4 @@ target = "x86_64-acadia-os.json" [alias] test_pc = "test --target=x86_64-unknown-linux-gnu -Z build-std=std --lib" + diff --git a/rust/Cargo.lock b/rust/Cargo.lock index c7d4f7b..e2a667e 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -8,6 +8,17 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +[[package]] +name = "bitfield-struct" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de05f8756f1c68937349406d4632ae96ae35901019b5e59c508d9c38c64715fb" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "convert_case" version = "0.6.0" @@ -21,6 +32,7 @@ dependencies = [ name = "denali" version = "0.1.0" dependencies = [ + "bitfield-struct", "mammoth", "yellowstone-yunq", "yunq", diff --git a/rust/sys/denali/Cargo.toml b/rust/sys/denali/Cargo.toml index 6cb7992..d618354 100644 --- a/rust/sys/denali/Cargo.toml +++ b/rust/sys/denali/Cargo.toml @@ -4,6 +4,7 @@ version = "0.1.0" edition = "2021" [dependencies] +bitfield-struct = "0.8.0" mammoth = { path = "../../lib/mammoth" } yunq = {path = "../../lib/yunq"} diff --git a/rust/sys/denali/src/ahci/controller.rs b/rust/sys/denali/src/ahci/controller.rs index cf02c60..abde094 100644 --- a/rust/sys/denali/src/ahci/controller.rs +++ b/rust/sys/denali/src/ahci/controller.rs @@ -1,5 +1,7 @@ use mammoth::mem::MemoryRegion; +use bitfield_struct::bitfield; + #[repr(C, packed)] pub struct PciDeviceHeader { pub vendor_id: u16, @@ -16,24 +18,195 @@ pub struct PciDeviceHeader { pub bist: u8, pub bars: [u32; 5], pub abar: u32, - pub reserved0: u32, + __: u32, pub subsystem_id: u32, pub expansion_rom: u16, pub cap_ptr: u8, - pub reserved1: [u8; 7], + ___: [u8; 7], pub interrupt_line: u8, pub interrupt_pin: u8, pub min_grant: u8, pub max_latency: u8, } +const fn increment(val: u8) -> u8 { + val + 1 +} + +#[derive(Debug, PartialEq, Eq)] +#[repr(u8)] +enum InterfaceSpeedSupport { + Reserved = 0b0000, + // 1.5 Gbps + Gen1 = 0b0001, + // 3 Gbps + Gen2 = 0b0010, + // 6 Gbps + Gen3 = 0b0011, + Unknown = 0b1111, +} + +impl InterfaceSpeedSupport { + const fn from_bits(value: u8) -> Self { + match value { + 0b0000 => Self::Reserved, + 0b0001 => Self::Gen1, + 0b0010 => Self::Gen2, + 0b0011 => Self::Gen3, + _ => Self::Unknown, + } + } +} + +#[bitfield(u32)] +pub struct AhciCapabilities { + #[bits(5, access = RO, from = increment)] + num_ports: u8, + + #[bits(access = RO)] + supports_external_sata: bool, + + #[bits(access = RO)] + enclosure_management_supported: bool, + + #[bits(access = RO)] + command_completed_coalescing_supported: bool, + + #[bits(5, access = RO, from = increment)] + num_commands: u8, + + #[bits(access = RO)] + partial_state_capable: bool, + + #[bits(access = RO)] + slumber_state_capable: bool, + + #[bits(access = RO)] + pio_multiple_drq_block: bool, + + #[bits(access = RO)] + fis_based_switching_supported: bool, + + #[bits(access = RO)] + supports_port_multiplier: bool, + + #[bits(access = RO)] + supports_ahci_mode_only: bool, + + __: bool, + + #[bits(4, access = RO)] + interface_speed_support: InterfaceSpeedSupport, + + #[bits(access = RO)] + supports_command_list_override: bool, + + #[bits(access = RO)] + supports_activity_led: bool, + + #[bits(access = RO)] + supports_aggressive_link_power_management: bool, + + #[bits(access = RO)] + supports_staggered_spin_up: bool, + + #[bits(access = RO)] + supports_mechanical_presence_switch: bool, + + #[bits(access = RO)] + supports_snotification_register: bool, + + #[bits(access = RO)] + supports_native_command_queueing: bool, + + #[bits(access = RO)] + supports_64_bit_addressing: bool, +} + +#[bitfield(u32)] +pub struct AhciGlobalControl { + hba_reset: bool, + interrupt_enable: bool, + + #[bits(access = RO)] + msi_revert_to_single_message: bool, + + #[bits(28)] + __: u32, + + ahci_enable: bool, +} + +#[bitfield(u32)] +pub struct AhciCapabilitiesExtended { + #[bits(access = RO)] + bios_os_handoff: bool, + + #[bits(access = RO)] + nvmhci_present: bool, + + #[bits(access = RO)] + automatic_partial_to_slumber_transitions: bool, + + #[bits(access = RO)] + supports_device_sleep: bool, + + #[bits(access = RO)] + supports_aggressive_device_sleep_management: bool, + + #[bits(27)] + __: u32, +} + +#[bitfield(u32)] +pub struct AhciBiosHandoffControl { + bios_owned_semaphore: bool, + os_owned_semaphore: bool, + smi_on_os_ownership_change_enable: bool, + os_ownership_change: bool, + bios_busy: bool, + + #[bits(27)] + __: u32, +} + +#[derive(Debug)] +#[repr(C, packed)] +pub struct AhciHba { + pub capabilities: AhciCapabilities, + global_host_control: AhciGlobalControl, + interrupt_status: u32, + port_implemented: u32, + version: u32, + ccc_ctl: u32, // 0x14, Command completion coalescing control + ccc_pts: u32, // 0x18, Command completion coalescing ports + em_loc: u32, // 0x1C, Enclosure management location + em_ctl: u32, // 0x20, Enclosure management control + capabilities_ext: AhciCapabilitiesExtended, + bohc: AhciBiosHandoffControl, +} + pub struct AhciController { pci_memory: MemoryRegion, + hba_memory: MemoryRegion, } impl AhciController { pub fn new(pci_memory: MemoryRegion) -> Self { - Self { pci_memory } + let pci_device_header = unsafe { + pci_memory + .mut_slice::() + .as_mut_ptr() + .cast::() + .as_mut() + .unwrap() + }; + let hba_memory = + MemoryRegion::direct_physical(pci_device_header.abar as u64, 0x1100).unwrap(); + Self { + pci_memory, + hba_memory, + } } pub fn pci_header(&self) -> &mut PciDeviceHeader { @@ -46,4 +219,15 @@ impl AhciController { .unwrap() } } + + pub fn ahci_hba(&self) -> &mut AhciHba { + unsafe { + self.hba_memory + .mut_slice::() + .as_mut_ptr() + .cast::() + .as_mut() + .unwrap() + } + } } diff --git a/rust/sys/denali/src/bin/denali.rs b/rust/sys/denali/src/bin/denali.rs index b685b5d..b4860f6 100644 --- a/rust/sys/denali/src/bin/denali.rs +++ b/rust/sys/denali/src/bin/denali.rs @@ -25,5 +25,6 @@ extern "C" fn main() -> z_err_t { ); mammoth::debug!("AHCI ABAR {:#x}", ahci_controller.pci_header().abar as u64); + mammoth::debug!("AHCI Capabilities: {:?}", ahci_controller.ahci_hba()); 0 }