twizzler_abi/device/bus/
pcie.rs

1#[cfg(any(feature = "kernel"))]
2use core::{mem::size_of, ptr::NonNull};
3
4use twizzler_rt_abi::{
5    error::{ArgumentError, TwzError},
6    Result,
7};
8#[cfg(any(feature = "kernel"))]
9use volatile::VolatilePtr;
10
11/// The base struct for an info sub-object for a PCIe bus.
12#[allow(dead_code)]
13#[repr(C)]
14#[derive(Debug)]
15pub struct PcieInfo {
16    pub bus_start: u8,
17    pub bus_end: u8,
18    pub seg_nr: u16,
19}
20
21/// The base struct for an info sub-object for a PCIe device.
22#[allow(dead_code)]
23#[repr(C)]
24#[derive(Debug)]
25pub struct PcieDeviceInfo {
26    pub seg_nr: u16,
27    pub bus_nr: u8,
28    pub dev_nr: u8,
29    pub func_nr: u8,
30    pub device_id: u16,
31    pub vendor_id: u16,
32    pub class: u8,
33    pub subclass: u8,
34    pub progif: u8,
35    pub revision: u8,
36}
37
38/// PCIe-specific [crate::kso::KactionGenericCmd] values.
39#[repr(u32)]
40pub enum PcieKactionSpecific {
41    /// Register a device ID.
42    RegisterDevice = 0,
43    /// Allocate an interrupt for a device.
44    AllocateInterrupt = 1,
45}
46
47impl From<PcieKactionSpecific> for u32 {
48    fn from(x: PcieKactionSpecific) -> Self {
49        x as u32
50    }
51}
52
53impl TryFrom<u32> for PcieKactionSpecific {
54    type Error = TwzError;
55
56    fn try_from(value: u32) -> Result<Self> {
57        Ok(match value {
58            0 => PcieKactionSpecific::RegisterDevice,
59            1 => PcieKactionSpecific::AllocateInterrupt,
60            _ => return Err(ArgumentError::InvalidArgument.into()),
61        })
62    }
63}
64
65//TODO: can we move this out of this crate?
66/// The standard PCIe function header.
67/// See the PCI spec for more details.
68#[allow(dead_code)]
69#[repr(C, packed(4))]
70#[derive(Copy, Clone, Debug)]
71pub struct PcieFunctionHeader {
72    pub vendor_id: u16,
73    pub device_id: u16,
74    pub command: u16,
75    pub status: u16,
76    pub revision: u8,
77    pub progif: u8,
78    pub subclass: u8,
79    pub class: u8,
80    pub cache_line_size: u8,
81    pub latency_timer: u8,
82    pub header_type: u8,
83    pub bist: u8,
84}
85
86/// The standard PCIe device header.
87/// See the PCI spec for more details.
88#[allow(dead_code)]
89#[repr(C, packed(8))]
90#[derive(Copy, Clone)]
91pub struct PcieDeviceHeader {
92    pub fnheader: PcieFunctionHeader,
93    pub bar0: u32,
94    pub bar1: u32,
95    pub bar2: u32,
96    pub bar3: u32,
97    pub bar4: u32,
98    pub bar5: u32,
99    pub cardbus_cis_ptr: u32,
100    pub subsystem_vendor_id: u16,
101    pub subsystem_id: u16,
102    pub exprom_base: u32,
103    pub cap_ptr: u32,
104    res0: u32,
105    pub int_line: u8,
106    pub int_pin: u8,
107    pub min_grant: u8,
108    pub max_latency: u8,
109}
110
111/// The standard PCIe bridge header.
112/// See the PCI spec for more details.
113#[allow(dead_code)]
114#[repr(C, packed(4096))]
115#[derive(Copy, Clone, Debug)]
116pub struct PcieBridgeHeader {
117    pub fnheader: PcieFunctionHeader,
118    pub bar0: u32,
119    pub bar1: u32,
120    pub primary_bus_nr: u8,
121    pub secondary_bus_nr: u8,
122    pub subordinate_bus_nr: u8,
123    pub secondary_latency_timer: u8,
124    pub io_base: u8,
125    pub io_limit: u8,
126    pub secondary_status: u8,
127    pub memory_base: u16,
128    pub memory_limit: u16,
129    pub pref_memory_base: u16,
130    pub pref_memory_limit: u16,
131    pub pref_base_upper: u32,
132    pub pref_limit_upper: u32,
133    pub io_base_upper: u16,
134    pub io_limit_upper: u16,
135    pub cap_ptr: u32,
136    pub exprom_base: u32,
137    pub int_line: u8,
138    pub int_pin: u8,
139    pub bridge_control: u16,
140}
141
142#[cfg(any(feature = "kernel"))]
143pub fn get_bar(cfg: VolatilePtr<'_, PcieDeviceHeader>, n: usize) -> VolatilePtr<'_, u32> {
144    unsafe {
145        cfg.map(|mut x| {
146            let ptr = (x.as_mut() as *mut _ as *mut u32)
147                .byte_add(size_of::<PcieFunctionHeader>() + size_of::<u32>() * n);
148            NonNull::new(ptr).unwrap()
149        })
150    }
151}
152
153#[derive(Copy, Clone)]
154#[allow(dead_code)]
155#[repr(C, packed)]
156pub struct PcieCapabilityHeader {
157    pub id: u8,
158    pub next: u8,
159}