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#[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#[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#[repr(u32)]
40pub enum PcieKactionSpecific {
41 RegisterDevice = 0,
43 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#[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#[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#[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}