1#![no_std]
2
3extern crate alloc;
4
5use alloc::{boxed::Box, sync::Arc};
6use core::cell::UnsafeCell;
7
8use pci_types::ConfigRegionAccess;
9pub use pci_types::PciAddress;
10pub use rdif_base::{DriverGeneric, KError};
11
12mod addr_alloc;
13mod bar_alloc;
14
15pub use bar_alloc::SimpleBarAllocator;
16
17#[derive(Debug, Clone, Copy)]
18pub struct PciMem32 {
19 pub address: u32,
20 pub size: u32,
21}
22
23#[derive(Debug, Clone, Copy)]
24pub struct PciMem64 {
25 pub address: u64,
26 pub size: u64,
27}
28
29impl rdif_base::DriverGeneric for PcieController {
30 fn name(&self) -> &str {
31 self.as_ref().name()
32 }
33
34 }
41
42pub trait Interface: DriverGeneric {
43 fn read(&mut self, address: PciAddress, offset: u16) -> u32;
49
50 fn write(&mut self, address: PciAddress, offset: u16, value: u32);
56}
57
58pub struct PcieController {
59 chip: Arc<ChipRaw>,
60 pub bar_allocator: Option<SimpleBarAllocator>,
61}
62
63impl PcieController {
64 pub fn new(chip: impl Interface) -> Self {
65 Self {
66 chip: Arc::new(ChipRaw::new(chip)),
67 bar_allocator: None,
68 }
69 }
70 pub fn typed_ref<T: Interface>(&self) -> Option<&T> {
71 self.raw_any()?.downcast_ref()
72 }
73 pub fn typed_mut<T: Interface>(&mut self) -> Option<&mut T> {
74 self.raw_any_mut()?.downcast_mut()
75 }
76
77 fn as_ref(&self) -> &dyn Interface {
78 unsafe { &*self.chip.0.get() }.as_ref()
79 }
80
81 pub fn config_access(&mut self, address: PciAddress) -> ConfigAccess {
82 ConfigAccess {
83 address,
84 chip: self.chip.clone(),
85 }
86 }
87
88 pub fn set_mem32(&mut self, space: PciMem32, perfetchable: bool) {
89 let al = self.bar_allocator.get_or_insert_default();
90 al.set_mem32(space, perfetchable).unwrap();
91 }
92
93 pub fn set_mem64(&mut self, space: PciMem64, perfetchable: bool) {
94 let al = self.bar_allocator.get_or_insert_default();
95 al.set_mem64(space, perfetchable).unwrap();
96 }
97}
98
99impl ConfigRegionAccess for PcieController {
100 unsafe fn read(&self, address: PciAddress, offset: u16) -> u32 {
101 unsafe { (*self.chip.0.get()).read(address, offset) }
102 }
103
104 unsafe fn write(&self, address: PciAddress, offset: u16, value: u32) {
105 unsafe { (*self.chip.0.get()).write(address, offset, value) }
106 }
107}
108
109pub struct ConfigAccess {
110 address: PciAddress,
111 chip: Arc<ChipRaw>,
112}
113
114impl ConfigRegionAccess for ConfigAccess {
115 unsafe fn read(&self, address: PciAddress, offset: u16) -> u32 {
116 assert!(address == self.address);
117 unsafe { (*self.chip.0.get()).read(self.address, offset) }
118 }
119
120 unsafe fn write(&self, address: PciAddress, offset: u16, value: u32) {
121 assert!(address == self.address);
122 unsafe { (*self.chip.0.get()).write(self.address, offset, value) }
123 }
124}
125
126struct ChipRaw(UnsafeCell<Box<dyn Interface>>);
127
128unsafe impl Send for ChipRaw {}
129unsafe impl Sync for ChipRaw {}
130
131impl ChipRaw {
132 fn new(chip: impl Interface) -> Self {
133 Self(UnsafeCell::new(Box::new(chip)))
134 }
135}