good_os_framework/drivers/
xhci.rs1use core::num::NonZeroUsize;
2
3use x86_64::{
4 structures::paging::{Page, PageTableFlags, PhysFrame},
5 PhysAddr,
6};
7use xhci::accessor::Mapper;
8use xhci::Registers;
9
10use crate::memory::{convert_physical_to_virtual, FRAME_ALLOCATOR, KERNEL_PAGE_TABLE};
11
12#[derive(Clone)]
13pub struct XHCIMapper;
14
15impl Mapper for XHCIMapper {
16 unsafe fn map(&mut self, phys_start: usize, bytes: usize) -> core::num::NonZeroUsize {
17 let physical_address = PhysAddr::new(phys_start as u64);
18 let virtual_address = convert_physical_to_virtual(physical_address);
19
20 let pages = (bytes + 4095) / 4096;
21
22 for page_i in 0..pages {
23 use x86_64::structures::paging::Mapper;
24 if let Ok(tlb) = KERNEL_PAGE_TABLE.lock().map_to(
25 Page::containing_address(virtual_address + page_i as u64 * 4096),
26 PhysFrame::containing_address(physical_address + page_i as u64 * 4096),
27 PageTableFlags::PRESENT | PageTableFlags::WRITABLE,
28 &mut *FRAME_ALLOCATOR.lock(),
29 ) {
30 tlb.flush();
31 }
32 }
33
34 NonZeroUsize::new(virtual_address.as_u64() as usize).unwrap()
35 }
36
37 fn unmap(&mut self, _virt_start: usize, _bytes: usize) {}
38}
39
40pub fn get_xhci(mmio_base: usize) -> Registers<XHCIMapper> {
42 unsafe { Registers::new(mmio_base, XHCIMapper) }
43}