xref: /DragonOS/kernel/src/driver/pci/root.rs (revision a17651b14b86dd70655090381db4a2f710853aa1)
1 use core::fmt::Formatter;
2 
3 use alloc::sync::Arc;
4 use hashbrown::HashMap;
5 
6 use crate::{
7     libs::spinlock::{SpinLock, SpinLockGuard},
8     mm::{
9         mmio_buddy::{mmio_pool, MMIOSpaceGuard},
10         page::PAGE_2M_SIZE,
11         PhysAddr,
12     },
13 };
14 
15 use super::pci::{
16     BusDeviceFunction, ExternalCapabilityIterator, PciCam, PciError, SegmentGroupNumber,
17 };
18 
19 lazy_static! {
20     static ref PCI_ROOT_MANAGER: PciRootManager = PciRootManager::new();
21 }
22 
23 #[inline(always)]
24 pub fn pci_root_manager() -> &'static PciRootManager {
25     &PCI_ROOT_MANAGER
26 }
27 
28 /// 代表一个PCI segement greoup.
29 #[derive(Clone, Debug)]
30 pub struct PciRoot {
31     pub physical_address_base: PhysAddr,          //物理地址,acpi获取
32     pub mmio_guard: Option<Arc<MMIOSpaceGuard>>,  //映射后的虚拟地址,为方便访问数据这里转化成指针
33     pub segment_group_number: SegmentGroupNumber, //segement greoup的id
34     pub bus_begin: u8,                            //该分组中的最小bus
35     pub bus_end: u8,                              //该分组中的最大bus
36     /// 配置空间访问机制
37     pub cam: PciCam,
38 }
39 
40 ///线程间共享需要,该结构体只需要在初始化时写入数据,无需读写锁保证线程安全
41 unsafe impl Send for PciRoot {}
42 unsafe impl Sync for PciRoot {}
43 ///实现PciRoot的Display trait,自定义输出
44 impl core::fmt::Display for PciRoot {
45     fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
46         write!(
47                 f,
48                 "PCI Root with segement:{}, bus begin at {}, bus end at {}, physical address at {:?},mapped at {:?}",
49                 self.segment_group_number, self.bus_begin, self.bus_end, self.physical_address_base, self.mmio_guard
50             )
51     }
52 }
53 
54 impl PciRoot {
55     /// 此函数用于初始化一个PciRoot结构体实例,
56     /// 该结构体基于ECAM根的物理地址,将其映射到虚拟地址
57     ///
58     /// ## 参数
59     ///
60     /// - segment_group_number: ECAM根的段组号。
61     /// - cam: PCI配置空间访问机制
62     ///
63     /// ## 返回值
64     ///
65     /// - Ok(Self): 初始化成功,返回一个新的结构体实例。
66     /// - Err(PciError): 初始化过程中发生错误,返回错误信息。
67     ///
68     /// ## 副作用
69     ///
70     /// - 成功执行后,结构体的内部状态将被初始化为包含映射后的虚拟地址。
71     pub fn new(
72         segment_group_number: SegmentGroupNumber,
73         cam: PciCam,
74         phys_base: PhysAddr,
75         bus_begin: u8,
76         bus_end: u8,
77     ) -> Result<Arc<Self>, PciError> {
78         assert_eq!(cam, PciCam::Ecam);
79         let mut pci_root = Self {
80             physical_address_base: phys_base,
81             mmio_guard: None,
82             segment_group_number,
83             bus_begin,
84             bus_end,
85             cam,
86         };
87         pci_root.map()?;
88 
89         Ok(Arc::new(pci_root))
90     }
91     /// @brief  完成物理地址到虚拟地址的映射,并将虚拟地址加入mmio_base变量
92     /// @return 返回错误或Ok(0)
93     fn map(&mut self) -> Result<u8, PciError> {
94         //kdebug!("bus_begin={},bus_end={}", self.bus_begin,self.bus_end);
95         let bus_number = (self.bus_end - self.bus_begin) as u32 + 1;
96         let bus_number_double = (bus_number - 1) / 2 + 1; //一个bus占据1MB空间,计算全部bus占据空间相对于2MB空间的个数
97 
98         let size = (bus_number_double as usize) * PAGE_2M_SIZE;
99         unsafe {
100             let space_guard = mmio_pool()
101                 .create_mmio(size)
102                 .map_err(|_| PciError::CreateMmioError)?;
103             let space_guard = Arc::new(space_guard);
104             self.mmio_guard = Some(space_guard.clone());
105 
106             assert!(space_guard
107                 .map_phys(self.physical_address_base, size)
108                 .is_ok());
109         }
110         return Ok(0);
111     }
112 
113     /// # cam_offset - 获得要操作的寄存器相对于mmio_offset的偏移量
114     ///
115     /// 此函数用于计算一个PCI设备中特定寄存器相对于该设备的MMIO基地址的偏移量。
116     ///
117     /// ## 参数
118     ///
119     /// - `bus_device_function`: BusDeviceFunction,用于标识在同一组中的PCI设备。
120     /// - `register_offset`: u16,寄存器在设备中的偏移量。
121     ///
122     /// ## 返回值
123     ///
124     /// - `u32`: 成功时,返回要操作的寄存器相对于mmio_offset的偏移量。
125     ///
126     /// ## Panic
127     ///
128     /// - 此函数在参数有效性方面进行了断言,如果传入的`bus_device_function`无效,将panic。
129     /// - 此函数计算出的地址需要是字对齐的(即地址与0x3对齐)。如果不是,将panic。
130     fn cam_offset(&self, bus_device_function: BusDeviceFunction, register_offset: u16) -> u32 {
131         assert!(bus_device_function.valid());
132         let bdf = ((bus_device_function.bus - self.bus_begin) as u32) << 8
133             | (bus_device_function.device as u32) << 3
134             | bus_device_function.function as u32;
135         let address =
136             bdf << match self.cam {
137                 PciCam::MmioCam => 8,
138                 PciCam::Ecam => 12,
139             } | register_offset as u32;
140         // Ensure that address is word-aligned.
141         assert!(address & 0x3 == 0);
142         address
143     }
144     /// # read_config - 通过bus_device_function和offset读取相应位置寄存器的值(32位)
145     ///
146     /// 此函数用于通过指定的bus_device_function和register_offset读取PCI设备中相应位置的寄存器值。
147     ///
148     /// ## 参数
149     ///
150     /// - `bus_device_function`: 在同一个group中pci设备的唯一标识符
151     /// - `register_offset`: 寄存器在设备中的offset
152     ///
153     /// ## 返回值
154     ///
155     /// - `u32`: 寄存器读值结果
156     pub fn read_config(&self, bus_device_function: BusDeviceFunction, register_offset: u16) -> u32 {
157         let address = self.cam_offset(bus_device_function, register_offset);
158         unsafe {
159             // Right shift to convert from byte offset to word offset.
160             ((self.mmio_guard.as_ref().unwrap().vaddr().data() as *mut u32)
161                 .add((address >> 2) as usize))
162             .read_volatile()
163         }
164     }
165 
166     /// # write_config - 通过bus_device_function和offset写入相应位置寄存器值(32位)
167     ///
168     /// 此函数用于通过指定的bus_device_function和register_offset,向PCI设备写入一个32位的寄存器值。
169     ///
170     /// ## 参数
171     ///
172     /// - `bus_device_function`: 在同一个group中pci设备的唯一标识符
173     /// - `register_offset`: 寄存器在设备中的offset
174     /// - `data`: 要写入的数据
175     pub fn write_config(
176         &self,
177         bus_device_function: BusDeviceFunction,
178         register_offset: u16,
179         data: u32,
180     ) {
181         let address = self.cam_offset(bus_device_function, register_offset);
182         // Safe because both the `mmio_base` and the address offset are properly aligned, and the
183         // resulting pointer is within the MMIO range of the CAM.
184         unsafe {
185             // Right shift to convert from byte offset to word offset.
186             ((self.mmio_guard.as_ref().unwrap().vaddr().data() as *mut u32)
187                 .add((address >> 2) as usize))
188             .write_volatile(data)
189         }
190     }
191     /// 返回迭代器,遍历pcie设备的external_capabilities
192     #[allow(dead_code)]
193     pub fn external_capabilities(
194         &self,
195         bus_device_function: BusDeviceFunction,
196     ) -> ExternalCapabilityIterator {
197         ExternalCapabilityIterator {
198             root: self,
199             bus_device_function,
200             next_capability_offset: Some(0x100),
201         }
202     }
203 }
204 
205 #[inline(always)]
206 pub fn pci_root_0() -> Arc<PciRoot> {
207     pci_root_manager().get_pci_root(0).unwrap()
208 }
209 
210 pub struct PciRootManager {
211     inner: SpinLock<InnerPciRootManager>,
212 }
213 
214 struct InnerPciRootManager {
215     pci_root: HashMap<SegmentGroupNumber, Arc<PciRoot>>,
216 }
217 
218 impl PciRootManager {
219     pub fn new() -> Self {
220         Self {
221             inner: SpinLock::new(InnerPciRootManager {
222                 pci_root: HashMap::new(),
223             }),
224         }
225     }
226 
227     /// # 添加PciRoot - 向PciRootManager中添加一个PciRoot
228     ///
229     /// 向PciRootManager中添加一个新的PciRoot,通过其segment_group_number进行标识。
230     ///
231     /// ## 参数
232     ///
233     /// - `pci_root`: Arc<PciRoot>,要添加的PciRoot的Arc指针
234     pub fn add_pci_root(&self, pci_root: Arc<PciRoot>) {
235         let mut inner = self.inner.lock();
236         inner
237             .pci_root
238             .insert(pci_root.segment_group_number, pci_root);
239     }
240 
241     /// # 检查是否存在PciRoot - 检查PciRootManager中是否存在指定segment_group_number的PciRoot
242     ///
243     /// 检查PciRootManager中是否存在segment_group_number对应的PciRoot。
244     ///
245     /// ## 参数
246     ///
247     /// - `segement_group_number`: SegmentGroupNumber,要检查的segment_group_number。
248     ///
249     /// ## 返回值
250     ///
251     /// - `true`: 如果存在对应的PciRoot。
252     /// - `false`: 如果不存在对应的PciRoot。
253     pub fn has_root(&self, segement_group_number: SegmentGroupNumber) -> bool {
254         self.inner
255             .lock()
256             .pci_root
257             .contains_key(&segement_group_number)
258     }
259 
260     /// # 获取PciRoot - 从PciRootManager中获取指定segment_group_number的PciRoot
261     ///
262     /// 从PciRootManager中获取segment_group_number对应的PciRoot。
263     ///
264     /// ## 参数
265     ///
266     /// - `segement_group_number`: SegmentGroupNumber,要获取的PciRoot的segment_group_number。
267     ///
268     /// ## 返回值
269     ///
270     /// - `Some(Arc<PciRoot>)`: 如果找到对应的PciRoot,返回其引用。
271     /// - `None`: 如果没有找到对应的PciRoot。
272     pub fn get_pci_root(&self, segement_group_number: SegmentGroupNumber) -> Option<Arc<PciRoot>> {
273         self.inner
274             .lock()
275             .pci_root
276             .get(&segement_group_number)
277             .cloned()
278     }
279 
280     /// # PciRoot迭代器 - 创建一个新的PciRoot迭代器
281     ///
282     /// 创建一个新的迭代器,用于遍历PciRootManager中的所有PciRoot。
283     #[allow(dead_code)]
284     pub fn iter(&self) -> PciRootIterator<'_> {
285         PciRootIterator {
286             inner: self.inner.lock(),
287             index: 0,
288         }
289     }
290 }
291 
292 pub struct PciRootIterator<'a> {
293     inner: SpinLockGuard<'a, InnerPciRootManager>,
294     index: usize,
295 }
296 
297 impl<'a> Iterator for PciRootIterator<'a> {
298     type Item = Arc<PciRoot>;
299 
300     fn next(&mut self) -> Option<Self::Item> {
301         self.inner.pci_root.values().nth(self.index).cloned()
302     }
303 }
304