1use intel_spi::{Mapper, SpiDev, PhysicalAddress, VirtualAddress};
4
5use std::{fs, ptr};
6
7pub struct LinuxMapper;
8
9impl Mapper for LinuxMapper {
10 unsafe fn map_aligned(&mut self, address: PhysicalAddress, size: usize) -> Result<VirtualAddress, &'static str> {
11 let fd = libc::open(
12 b"/dev/mem\0".as_ptr() as *const libc::c_char,
13 libc::O_RDWR
14 );
15 if fd < 0 {
16 return Err("failed to open /dev/mem")
17 }
18
19 let ptr = libc::mmap(
20 ptr::null_mut(),
21 size,
22 libc::PROT_READ | libc::PROT_WRITE,
23 libc::MAP_SHARED,
24 fd,
25 address.0 as libc::off_t
26 );
27
28 libc::close(fd);
29
30 if ptr == libc::MAP_FAILED {
31 return Err("failed to map /dev/mem");
32 }
33
34 Ok(VirtualAddress(ptr as usize))
35 }
36
37 unsafe fn unmap_aligned(&mut self, address: VirtualAddress, size: usize) -> Result<(), &'static str> {
38 if libc::munmap(address.0 as *mut libc::c_void, size) == 0 {
39 Ok(())
40 } else {
41 Err("failed to unmap /dev/mem")
42 }
43 }
44
45 fn page_size(&self) -> usize {
46 4096
48 }
49}
50
51pub unsafe fn get_spi() -> SpiDev<'static, LinuxMapper> {
52 static mut LINUX_MAPPER: LinuxMapper = LinuxMapper;
53 let mcfg = fs::read("/sys/firmware/acpi/tables/MCFG").expect("failed to read MCFG");
54 SpiDev::new(&mcfg, &mut LINUX_MAPPER).expect("failed to get SPI device")
55}