1370472f7SLoGin use core::fmt::Formatter;
2370472f7SLoGin
3370472f7SLoGin use alloc::sync::Arc;
4370472f7SLoGin use hashbrown::HashMap;
5370472f7SLoGin
6370472f7SLoGin use crate::{
7*bde08cdeSMingtao Huang arch::{PciArch, TraitPciArch},
8370472f7SLoGin libs::spinlock::{SpinLock, SpinLockGuard},
9370472f7SLoGin mm::{
10370472f7SLoGin mmio_buddy::{mmio_pool, MMIOSpaceGuard},
11370472f7SLoGin page::PAGE_2M_SIZE,
12370472f7SLoGin },
13370472f7SLoGin };
14370472f7SLoGin
15*bde08cdeSMingtao Huang use super::{
16*bde08cdeSMingtao Huang ecam::EcamRootInfo,
17*bde08cdeSMingtao Huang pci::{BusDeviceFunction, ExternalCapabilityIterator, PciCam, PciError, SegmentGroupNumber},
18370472f7SLoGin };
19370472f7SLoGin
20370472f7SLoGin lazy_static! {
21370472f7SLoGin static ref PCI_ROOT_MANAGER: PciRootManager = PciRootManager::new();
22370472f7SLoGin }
23370472f7SLoGin
24370472f7SLoGin #[inline(always)]
pci_root_manager() -> &'static PciRootManager25370472f7SLoGin pub fn pci_root_manager() -> &'static PciRootManager {
26370472f7SLoGin &PCI_ROOT_MANAGER
27370472f7SLoGin }
28370472f7SLoGin
29370472f7SLoGin /// 代表一个PCI segement greoup.
30370472f7SLoGin #[derive(Clone, Debug)]
31370472f7SLoGin pub struct PciRoot {
32*bde08cdeSMingtao Huang pub ecam_root_info: Option<EcamRootInfo>,
33370472f7SLoGin pub mmio_guard: Option<Arc<MMIOSpaceGuard>>, //映射后的虚拟地址,为方便访问数据这里转化成指针
34370472f7SLoGin /// 配置空间访问机制
35370472f7SLoGin pub cam: PciCam,
36*bde08cdeSMingtao Huang /// bus起始位置
37*bde08cdeSMingtao Huang pub bus_begin: u8,
38*bde08cdeSMingtao Huang /// bus结束位置
39*bde08cdeSMingtao Huang pub bus_end: u8,
40370472f7SLoGin }
41370472f7SLoGin
42370472f7SLoGin ///线程间共享需要,该结构体只需要在初始化时写入数据,无需读写锁保证线程安全
43370472f7SLoGin unsafe impl Send for PciRoot {}
44370472f7SLoGin unsafe impl Sync for PciRoot {}
45370472f7SLoGin ///实现PciRoot的Display trait,自定义输出
46370472f7SLoGin impl core::fmt::Display for PciRoot {
fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result47370472f7SLoGin fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
48*bde08cdeSMingtao Huang if let Some(ecam_root_info) = &self.ecam_root_info {
49370472f7SLoGin write!(
50370472f7SLoGin f,
51*bde08cdeSMingtao Huang "PCI Eacm Root with segment:{}, bus begin at {}, bus end at {}, physical address at {:?},mapped at {:?}",
52*bde08cdeSMingtao Huang ecam_root_info.segment_group_number, ecam_root_info.bus_begin, ecam_root_info.bus_end, ecam_root_info.physical_address_base, self.mmio_guard
53370472f7SLoGin )
54*bde08cdeSMingtao Huang } else {
55*bde08cdeSMingtao Huang write!(f, "PCI Root cam is {:?}", self.cam,)
56*bde08cdeSMingtao Huang }
57370472f7SLoGin }
58370472f7SLoGin }
59370472f7SLoGin
60370472f7SLoGin impl PciRoot {
61370472f7SLoGin /// 此函数用于初始化一个PciRoot结构体实例,
62370472f7SLoGin /// 该结构体基于ECAM根的物理地址,将其映射到虚拟地址
63370472f7SLoGin ///
64370472f7SLoGin /// ## 参数
65370472f7SLoGin ///
66370472f7SLoGin /// - segment_group_number: ECAM根的段组号。
67370472f7SLoGin /// - cam: PCI配置空间访问机制
68370472f7SLoGin ///
69370472f7SLoGin /// ## 返回值
70370472f7SLoGin ///
71370472f7SLoGin /// - Ok(Self): 初始化成功,返回一个新的结构体实例。
72370472f7SLoGin /// - Err(PciError): 初始化过程中发生错误,返回错误信息。
73370472f7SLoGin ///
74370472f7SLoGin /// ## 副作用
75370472f7SLoGin ///
76370472f7SLoGin /// - 成功执行后,结构体的内部状态将被初始化为包含映射后的虚拟地址。
new( ecam_root_info: Option<EcamRootInfo>, cam: PciCam, bus_begin: u8, bus_end: u8, ) -> Result<Arc<Self>, PciError>77370472f7SLoGin pub fn new(
78*bde08cdeSMingtao Huang ecam_root_info: Option<EcamRootInfo>,
79370472f7SLoGin cam: PciCam,
80370472f7SLoGin bus_begin: u8,
81370472f7SLoGin bus_end: u8,
82370472f7SLoGin ) -> Result<Arc<Self>, PciError> {
83370472f7SLoGin let mut pci_root = Self {
84*bde08cdeSMingtao Huang ecam_root_info,
85370472f7SLoGin mmio_guard: None,
86*bde08cdeSMingtao Huang cam,
87370472f7SLoGin bus_begin,
88370472f7SLoGin bus_end,
89370472f7SLoGin };
90*bde08cdeSMingtao Huang
91*bde08cdeSMingtao Huang if ecam_root_info.is_some() {
92370472f7SLoGin pci_root.map()?;
93*bde08cdeSMingtao Huang }
94370472f7SLoGin
95370472f7SLoGin Ok(Arc::new(pci_root))
96370472f7SLoGin }
97*bde08cdeSMingtao Huang
98*bde08cdeSMingtao Huang /// # 完成物理地址到虚拟地址的映射,并将虚拟地址加入mmio_base变量
99*bde08cdeSMingtao Huang /// ## return 返回错误或Ok(0)
map(&mut self) -> Result<u8, PciError>100370472f7SLoGin fn map(&mut self) -> Result<u8, PciError> {
1012eab6dd7S曾俊 //debug!("bus_begin={},bus_end={}", self.bus_begin,self.bus_end);
102370472f7SLoGin let bus_number = (self.bus_end - self.bus_begin) as u32 + 1;
103370472f7SLoGin let bus_number_double = (bus_number - 1) / 2 + 1; //一个bus占据1MB空间,计算全部bus占据空间相对于2MB空间的个数
104370472f7SLoGin
105370472f7SLoGin let size = (bus_number_double as usize) * PAGE_2M_SIZE;
106370472f7SLoGin unsafe {
107370472f7SLoGin let space_guard = mmio_pool()
108370472f7SLoGin .create_mmio(size)
109370472f7SLoGin .map_err(|_| PciError::CreateMmioError)?;
110370472f7SLoGin let space_guard = Arc::new(space_guard);
111370472f7SLoGin self.mmio_guard = Some(space_guard.clone());
112370472f7SLoGin
113370472f7SLoGin assert!(space_guard
114*bde08cdeSMingtao Huang .map_phys(self.ecam_root_info.unwrap().physical_address_base, size)
115370472f7SLoGin .is_ok());
116370472f7SLoGin }
117370472f7SLoGin return Ok(0);
118370472f7SLoGin }
119370472f7SLoGin
120370472f7SLoGin /// # cam_offset - 获得要操作的寄存器相对于mmio_offset的偏移量
121370472f7SLoGin ///
122370472f7SLoGin /// 此函数用于计算一个PCI设备中特定寄存器相对于该设备的MMIO基地址的偏移量。
123370472f7SLoGin ///
124370472f7SLoGin /// ## 参数
125370472f7SLoGin ///
126370472f7SLoGin /// - `bus_device_function`: BusDeviceFunction,用于标识在同一组中的PCI设备。
127370472f7SLoGin /// - `register_offset`: u16,寄存器在设备中的偏移量。
128370472f7SLoGin ///
129370472f7SLoGin /// ## 返回值
130370472f7SLoGin ///
131370472f7SLoGin /// - `u32`: 成功时,返回要操作的寄存器相对于mmio_offset的偏移量。
132370472f7SLoGin ///
133370472f7SLoGin /// ## Panic
134370472f7SLoGin ///
135370472f7SLoGin /// - 此函数在参数有效性方面进行了断言,如果传入的`bus_device_function`无效,将panic。
136370472f7SLoGin /// - 此函数计算出的地址需要是字对齐的(即地址与0x3对齐)。如果不是,将panic。
cam_offset(&self, bus_device_function: BusDeviceFunction, register_offset: u16) -> u32137370472f7SLoGin fn cam_offset(&self, bus_device_function: BusDeviceFunction, register_offset: u16) -> u32 {
138370472f7SLoGin assert!(bus_device_function.valid());
139*bde08cdeSMingtao Huang let bdf = ((bus_device_function.bus - self.ecam_root_info.unwrap().bus_begin) as u32) << 8
140370472f7SLoGin | (bus_device_function.device as u32) << 3
141370472f7SLoGin | bus_device_function.function as u32;
142370472f7SLoGin let address =
143370472f7SLoGin bdf << match self.cam {
144*bde08cdeSMingtao Huang PciCam::Portiocam => 4,
145370472f7SLoGin PciCam::MmioCam => 8,
146370472f7SLoGin PciCam::Ecam => 12,
147370472f7SLoGin } | register_offset as u32;
148370472f7SLoGin // Ensure that address is word-aligned.
149370472f7SLoGin assert!(address & 0x3 == 0);
150370472f7SLoGin address
151370472f7SLoGin }
152*bde08cdeSMingtao Huang
153370472f7SLoGin /// # read_config - 通过bus_device_function和offset读取相应位置寄存器的值(32位)
154370472f7SLoGin ///
155370472f7SLoGin /// 此函数用于通过指定的bus_device_function和register_offset读取PCI设备中相应位置的寄存器值。
156370472f7SLoGin ///
157370472f7SLoGin /// ## 参数
158370472f7SLoGin ///
159370472f7SLoGin /// - `bus_device_function`: 在同一个group中pci设备的唯一标识符
160370472f7SLoGin /// - `register_offset`: 寄存器在设备中的offset
161370472f7SLoGin ///
162370472f7SLoGin /// ## 返回值
163370472f7SLoGin ///
164370472f7SLoGin /// - `u32`: 寄存器读值结果
read_config(&self, bus_device_function: BusDeviceFunction, register_offset: u16) -> u32165370472f7SLoGin pub fn read_config(&self, bus_device_function: BusDeviceFunction, register_offset: u16) -> u32 {
166*bde08cdeSMingtao Huang if self.ecam_root_info.is_some() {
167370472f7SLoGin let address = self.cam_offset(bus_device_function, register_offset);
168370472f7SLoGin unsafe {
169370472f7SLoGin // Right shift to convert from byte offset to word offset.
170370472f7SLoGin ((self.mmio_guard.as_ref().unwrap().vaddr().data() as *mut u32)
171370472f7SLoGin .add((address >> 2) as usize))
172370472f7SLoGin .read_volatile()
173370472f7SLoGin }
174*bde08cdeSMingtao Huang } else {
175*bde08cdeSMingtao Huang PciArch::read_config(&bus_device_function, register_offset as u8)
176*bde08cdeSMingtao Huang }
177370472f7SLoGin }
178370472f7SLoGin
179370472f7SLoGin /// # write_config - 通过bus_device_function和offset写入相应位置寄存器值(32位)
180370472f7SLoGin ///
181370472f7SLoGin /// 此函数用于通过指定的bus_device_function和register_offset,向PCI设备写入一个32位的寄存器值。
182370472f7SLoGin ///
183370472f7SLoGin /// ## 参数
184370472f7SLoGin ///
185370472f7SLoGin /// - `bus_device_function`: 在同一个group中pci设备的唯一标识符
186370472f7SLoGin /// - `register_offset`: 寄存器在设备中的offset
187370472f7SLoGin /// - `data`: 要写入的数据
write_config( &self, bus_device_function: BusDeviceFunction, register_offset: u16, data: u32, )188370472f7SLoGin pub fn write_config(
189370472f7SLoGin &self,
190370472f7SLoGin bus_device_function: BusDeviceFunction,
191370472f7SLoGin register_offset: u16,
192370472f7SLoGin data: u32,
193370472f7SLoGin ) {
194*bde08cdeSMingtao Huang if self.ecam_root_info.is_some() {
195370472f7SLoGin let address = self.cam_offset(bus_device_function, register_offset);
196370472f7SLoGin // Safe because both the `mmio_base` and the address offset are properly aligned, and the
197370472f7SLoGin // resulting pointer is within the MMIO range of the CAM.
198370472f7SLoGin unsafe {
199370472f7SLoGin // Right shift to convert from byte offset to word offset.
200370472f7SLoGin ((self.mmio_guard.as_ref().unwrap().vaddr().data() as *mut u32)
201370472f7SLoGin .add((address >> 2) as usize))
202370472f7SLoGin .write_volatile(data)
203370472f7SLoGin }
204*bde08cdeSMingtao Huang } else {
205*bde08cdeSMingtao Huang PciArch::write_config(&bus_device_function, register_offset as u8, data);
206370472f7SLoGin }
207*bde08cdeSMingtao Huang }
208*bde08cdeSMingtao Huang
209370472f7SLoGin /// 返回迭代器,遍历pcie设备的external_capabilities
210370472f7SLoGin #[allow(dead_code)]
external_capabilities( &self, bus_device_function: BusDeviceFunction, ) -> ExternalCapabilityIterator211370472f7SLoGin pub fn external_capabilities(
212370472f7SLoGin &self,
213370472f7SLoGin bus_device_function: BusDeviceFunction,
214370472f7SLoGin ) -> ExternalCapabilityIterator {
215370472f7SLoGin ExternalCapabilityIterator {
216370472f7SLoGin root: self,
217370472f7SLoGin bus_device_function,
218370472f7SLoGin next_capability_offset: Some(0x100),
219370472f7SLoGin }
220370472f7SLoGin }
221370472f7SLoGin }
222370472f7SLoGin
223370472f7SLoGin #[inline(always)]
pci_root_0() -> Arc<PciRoot>224370472f7SLoGin pub fn pci_root_0() -> Arc<PciRoot> {
225370472f7SLoGin pci_root_manager().get_pci_root(0).unwrap()
226370472f7SLoGin }
227370472f7SLoGin
228370472f7SLoGin pub struct PciRootManager {
229370472f7SLoGin inner: SpinLock<InnerPciRootManager>,
230370472f7SLoGin }
231370472f7SLoGin
232370472f7SLoGin struct InnerPciRootManager {
233370472f7SLoGin pci_root: HashMap<SegmentGroupNumber, Arc<PciRoot>>,
234370472f7SLoGin }
235370472f7SLoGin
236370472f7SLoGin impl PciRootManager {
new() -> Self237370472f7SLoGin pub fn new() -> Self {
238370472f7SLoGin Self {
239370472f7SLoGin inner: SpinLock::new(InnerPciRootManager {
240370472f7SLoGin pci_root: HashMap::new(),
241370472f7SLoGin }),
242370472f7SLoGin }
243370472f7SLoGin }
244370472f7SLoGin
245370472f7SLoGin /// # 添加PciRoot - 向PciRootManager中添加一个PciRoot
246370472f7SLoGin ///
247370472f7SLoGin /// 向PciRootManager中添加一个新的PciRoot,通过其segment_group_number进行标识。
248370472f7SLoGin ///
249370472f7SLoGin /// ## 参数
250370472f7SLoGin ///
251370472f7SLoGin /// - `pci_root`: Arc<PciRoot>,要添加的PciRoot的Arc指针
add_pci_root(&self, pci_root: Arc<PciRoot>)252370472f7SLoGin pub fn add_pci_root(&self, pci_root: Arc<PciRoot>) {
253370472f7SLoGin let mut inner = self.inner.lock();
254*bde08cdeSMingtao Huang
255*bde08cdeSMingtao Huang if let Some(ecam_root_info) = pci_root.ecam_root_info {
256370472f7SLoGin inner
257370472f7SLoGin .pci_root
258*bde08cdeSMingtao Huang .insert(ecam_root_info.segment_group_number, pci_root);
259*bde08cdeSMingtao Huang } else {
260*bde08cdeSMingtao Huang inner.pci_root.insert(pci_root.bus_begin as u16, pci_root);
261*bde08cdeSMingtao Huang }
262370472f7SLoGin }
263370472f7SLoGin
264370472f7SLoGin /// # 检查是否存在PciRoot - 检查PciRootManager中是否存在指定segment_group_number的PciRoot
265370472f7SLoGin ///
266370472f7SLoGin /// 检查PciRootManager中是否存在segment_group_number对应的PciRoot。
267370472f7SLoGin ///
268370472f7SLoGin /// ## 参数
269370472f7SLoGin ///
270370472f7SLoGin /// - `segement_group_number`: SegmentGroupNumber,要检查的segment_group_number。
271370472f7SLoGin ///
272370472f7SLoGin /// ## 返回值
273370472f7SLoGin ///
274370472f7SLoGin /// - `true`: 如果存在对应的PciRoot。
275370472f7SLoGin /// - `false`: 如果不存在对应的PciRoot。
has_root(&self, segement_group_number: SegmentGroupNumber) -> bool276370472f7SLoGin pub fn has_root(&self, segement_group_number: SegmentGroupNumber) -> bool {
277370472f7SLoGin self.inner
278370472f7SLoGin .lock()
279370472f7SLoGin .pci_root
280370472f7SLoGin .contains_key(&segement_group_number)
281370472f7SLoGin }
282370472f7SLoGin
283370472f7SLoGin /// # 获取PciRoot - 从PciRootManager中获取指定segment_group_number的PciRoot
284370472f7SLoGin ///
285370472f7SLoGin /// 从PciRootManager中获取segment_group_number对应的PciRoot。
286370472f7SLoGin ///
287370472f7SLoGin /// ## 参数
288370472f7SLoGin ///
289370472f7SLoGin /// - `segement_group_number`: SegmentGroupNumber,要获取的PciRoot的segment_group_number。
290370472f7SLoGin ///
291370472f7SLoGin /// ## 返回值
292370472f7SLoGin ///
293370472f7SLoGin /// - `Some(Arc<PciRoot>)`: 如果找到对应的PciRoot,返回其引用。
294370472f7SLoGin /// - `None`: 如果没有找到对应的PciRoot。
get_pci_root(&self, segement_group_number: SegmentGroupNumber) -> Option<Arc<PciRoot>>295370472f7SLoGin pub fn get_pci_root(&self, segement_group_number: SegmentGroupNumber) -> Option<Arc<PciRoot>> {
296370472f7SLoGin self.inner
297370472f7SLoGin .lock()
298370472f7SLoGin .pci_root
299370472f7SLoGin .get(&segement_group_number)
300370472f7SLoGin .cloned()
301370472f7SLoGin }
302370472f7SLoGin
303370472f7SLoGin /// # PciRoot迭代器 - 创建一个新的PciRoot迭代器
304370472f7SLoGin ///
305370472f7SLoGin /// 创建一个新的迭代器,用于遍历PciRootManager中的所有PciRoot。
306370472f7SLoGin #[allow(dead_code)]
iter(&self) -> PciRootIterator<'_>307370472f7SLoGin pub fn iter(&self) -> PciRootIterator<'_> {
308370472f7SLoGin PciRootIterator {
309370472f7SLoGin inner: self.inner.lock(),
310370472f7SLoGin index: 0,
311370472f7SLoGin }
312370472f7SLoGin }
313370472f7SLoGin }
314370472f7SLoGin
315370472f7SLoGin pub struct PciRootIterator<'a> {
316370472f7SLoGin inner: SpinLockGuard<'a, InnerPciRootManager>,
317370472f7SLoGin index: usize,
318370472f7SLoGin }
319370472f7SLoGin
320370472f7SLoGin impl<'a> Iterator for PciRootIterator<'a> {
321370472f7SLoGin type Item = Arc<PciRoot>;
322370472f7SLoGin
next(&mut self) -> Option<Self::Item>323370472f7SLoGin fn next(&mut self) -> Option<Self::Item> {
324370472f7SLoGin self.inner.pci_root.values().nth(self.index).cloned()
325370472f7SLoGin }
326370472f7SLoGin }
327