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