Skip to content

Commit 4099da5

Browse files
committed
mem: Fix to handle unaligned access
Signed-off-by: Akira Moroo <retrage01@gmail.com>
1 parent 339bf7b commit 4099da5

File tree

2 files changed

+22
-12
lines changed

2 files changed

+22
-12
lines changed

src/main.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#![feature(slice_take)]
66
#![feature(stdsimd)]
77
#![feature(stmt_expr_attributes)]
8+
#![feature(strict_provenance)]
89
#![cfg_attr(not(test), no_std)]
910
#![cfg_attr(not(test), no_main)]
1011
#![cfg_attr(

src/mem.rs

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,11 @@ impl MemoryRegion {
3737
/// Read a value from a given offset
3838
fn read<T>(&self, offset: u64) -> T
3939
where
40-
T: Copy,
40+
T: Copy + Sized,
4141
{
4242
assert!((offset + (core::mem::size_of::<T>() - 1) as u64) < self.length);
43-
unsafe { *((self.base + offset) as *const T) }
43+
let ptr: *const T = core::ptr::from_exposed_addr((self.base + offset) as usize);
44+
unsafe { ptr.read_unaligned() }
4445
}
4546

4647
/// Read a single byte at a given offset
@@ -64,11 +65,13 @@ impl MemoryRegion {
6465
}
6566

6667
/// Write a value at the given offset
67-
pub fn write<T>(&self, offset: u64, value: T) {
68+
pub fn write<T>(&self, offset: u64, value: T)
69+
where
70+
T: Sized,
71+
{
6872
assert!((offset + (core::mem::size_of::<T>() - 1) as u64) < self.length);
69-
unsafe {
70-
*((self.base + offset) as *mut T) = value;
71-
}
73+
let ptr: *mut T = core::ptr::from_exposed_addr_mut((self.base + offset) as usize);
74+
unsafe { core::ptr::write_unaligned(ptr, value) }
7275
}
7376

7477
/// Write a single byte at given offset
@@ -95,9 +98,13 @@ impl MemoryRegion {
9598
}
9699

97100
/// Read a value at given offset with a mechanism suitable for MMIO
98-
fn io_read<T>(&self, offset: u64) -> T {
101+
fn io_read<T>(&self, offset: u64) -> T
102+
where
103+
T: Copy + Sized,
104+
{
99105
assert!((offset + (core::mem::size_of::<T>() - 1) as u64) < self.length);
100-
unsafe { core::ptr::read_volatile((self.base + offset) as *const T) }
106+
let ptr: *const T = core::ptr::from_exposed_addr((self.base + offset) as usize);
107+
unsafe { ptr.read_volatile() }
101108
}
102109

103110
/// Read a single byte at given offset with a mechanism suitable for MMIO
@@ -121,11 +128,13 @@ impl MemoryRegion {
121128
}
122129

123130
/// Write a value at given offset using a mechanism suitable for MMIO
124-
fn io_write<T>(&self, offset: u64, value: T) {
131+
pub fn io_write<T>(&self, offset: u64, value: T)
132+
where
133+
T: Sized,
134+
{
125135
assert!((offset + (core::mem::size_of::<T>() - 1) as u64) < self.length);
126-
unsafe {
127-
core::ptr::write_volatile((self.base + offset) as *mut T, value);
128-
}
136+
let ptr: *mut T = core::ptr::from_exposed_addr_mut((self.base + offset) as usize);
137+
unsafe { core::ptr::write_volatile(ptr, value) }
129138
}
130139

131140
/// Write a single byte at given offset with a mechanism suitable for MMIO

0 commit comments

Comments
 (0)