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