aboutsummaryrefslogtreecommitdiff
path: root/embassy-stm32
diff options
context:
space:
mode:
authorRasmus Melchior Jacobsen <[email protected]>2023-04-01 17:26:32 +0200
committerRasmus Melchior Jacobsen <[email protected]>2023-04-01 17:26:32 +0200
commite11eebfa577b143b8a19fcf6d9d5398c3058c3eb (patch)
tree19ba9a751cd8d818aacf860a2f1a0df29d73483e /embassy-stm32
parent268e29b153c9c8a6e3a798a01757669ee31e5409 (diff)
Ensure that ranges are validated with the region size
Diffstat (limited to 'embassy-stm32')
-rw-r--r--embassy-stm32/src/flash/common.rs57
1 files changed, 22 insertions, 35 deletions
diff --git a/embassy-stm32/src/flash/common.rs b/embassy-stm32/src/flash/common.rs
index 59429e344..287c54f55 100644
--- a/embassy-stm32/src/flash/common.rs
+++ b/embassy-stm32/src/flash/common.rs
@@ -20,21 +20,15 @@ impl<'d> Flash<'d> {
20 } 20 }
21 21
22 pub fn blocking_read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), Error> { 22 pub fn blocking_read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), Error> {
23 let start_address = FLASH_BASE as u32 + offset; 23 blocking_read(FLASH_BASE as u32, FLASH_SIZE as u32, offset, bytes)
24 blocking_read(start_address, bytes)
25 } 24 }
26 25
27 pub fn blocking_write(&mut self, offset: u32, buf: &[u8]) -> Result<(), Error> { 26 pub fn blocking_write(&mut self, offset: u32, bytes: &[u8]) -> Result<(), Error> {
28 let start_address = FLASH_BASE as u32 + offset; 27 unsafe { blocking_write(FLASH_BASE as u32, FLASH_SIZE as u32, offset, bytes) }
29
30 unsafe { blocking_write(start_address, buf) }
31 } 28 }
32 29
33 pub fn blocking_erase(&mut self, from: u32, to: u32) -> Result<(), Error> { 30 pub fn blocking_erase(&mut self, from: u32, to: u32) -> Result<(), Error> {
34 let start_address = FLASH_BASE as u32 + from; 31 unsafe { blocking_erase(FLASH_BASE as u32, from, to) }
35 let end_address = FLASH_BASE as u32 + to;
36
37 unsafe { blocking_erase(start_address, end_address) }
38 } 32 }
39 33
40 pub(crate) fn release(self) -> PeripheralRef<'d, crate::peripherals::FLASH> { 34 pub(crate) fn release(self) -> PeripheralRef<'d, crate::peripherals::FLASH> {
@@ -55,30 +49,29 @@ impl Drop for FlashLayout<'_> {
55 } 49 }
56} 50}
57 51
58fn blocking_read(start_address: u32, bytes: &mut [u8]) -> Result<(), Error> { 52fn blocking_read(base: u32, size: u32, offset: u32, bytes: &mut [u8]) -> Result<(), Error> {
59 assert!(start_address >= FLASH_BASE as u32); 53 if offset + bytes.len() as u32 > size {
60 if start_address as usize + bytes.len() > FLASH_BASE + FLASH_SIZE {
61 return Err(Error::Size); 54 return Err(Error::Size);
62 } 55 }
63 56
57 let start_address = base + offset;
64 let flash_data = unsafe { core::slice::from_raw_parts(start_address as *const u8, bytes.len()) }; 58 let flash_data = unsafe { core::slice::from_raw_parts(start_address as *const u8, bytes.len()) };
65 bytes.copy_from_slice(flash_data); 59 bytes.copy_from_slice(flash_data);
66 Ok(()) 60 Ok(())
67} 61}
68 62
69unsafe fn blocking_write(start_address: u32, buf: &[u8]) -> Result<(), Error> { 63unsafe fn blocking_write(base: u32, size: u32, offset: u32, bytes: &[u8]) -> Result<(), Error> {
70 assert!(start_address >= FLASH_BASE as u32); 64 if offset + bytes.len() as u32 > size {
71 if start_address as usize + buf.len() > FLASH_BASE + FLASH_SIZE {
72 return Err(Error::Size); 65 return Err(Error::Size);
73 } 66 }
74 if (start_address as usize - FLASH_BASE) % WRITE_SIZE != 0 || buf.len() as usize % WRITE_SIZE != 0 { 67 if offset % WRITE_SIZE as u32 != 0 || bytes.len() % WRITE_SIZE != 0 {
75 return Err(Error::Unaligned); 68 return Err(Error::Unaligned);
76 } 69 }
77 70
78 trace!("Writing {} bytes at 0x{:x}", buf.len(), start_address); 71 let mut address = base + offset;
72 trace!("Writing {} bytes at 0x{:x}", bytes.len(), address);
79 73
80 let mut address = start_address; 74 for chunk in bytes.chunks(WRITE_SIZE) {
81 for chunk in buf.chunks(WRITE_SIZE) {
82 critical_section::with(|_| { 75 critical_section::with(|_| {
83 family::clear_all_err(); 76 family::clear_all_err();
84 family::unlock(); 77 family::unlock();
@@ -94,7 +87,9 @@ unsafe fn blocking_write(start_address: u32, buf: &[u8]) -> Result<(), Error> {
94 Ok(()) 87 Ok(())
95} 88}
96 89
97unsafe fn blocking_erase(start_address: u32, end_address: u32) -> Result<(), Error> { 90unsafe fn blocking_erase(base: u32, from: u32, to: u32) -> Result<(), Error> {
91 let start_address = base + from;
92 let end_address = base + to;
98 let regions = family::get_flash_regions(); 93 let regions = family::get_flash_regions();
99 94
100 // Test if the address range is aligned at sector base addresses 95 // Test if the address range is aligned at sector base addresses
@@ -157,19 +152,15 @@ pub(crate) fn get_sector(address: u32, regions: &[&FlashRegion]) -> FlashSector
157 152
158impl FlashRegion { 153impl FlashRegion {
159 pub fn blocking_read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), Error> { 154 pub fn blocking_read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), Error> {
160 let start_address = self.base + offset; 155 blocking_read(self.base, self.size, offset, bytes)
161 blocking_read(start_address, bytes)
162 } 156 }
163 157
164 pub fn blocking_write(&mut self, offset: u32, bytes: &[u8]) -> Result<(), Error> { 158 pub fn blocking_write(&mut self, offset: u32, bytes: &[u8]) -> Result<(), Error> {
165 let start_address = self.base + offset; 159 unsafe { blocking_write(self.base, self.size, offset, bytes) }
166 unsafe { blocking_write(start_address, bytes) }
167 } 160 }
168 161
169 pub fn blocking_erase(&mut self, from: u32, to: u32) -> Result<(), Error> { 162 pub fn blocking_erase(&mut self, from: u32, to: u32) -> Result<(), Error> {
170 let start_address = self.base + from; 163 unsafe { blocking_erase(self.base, from, to) }
171 let end_address = self.base + to;
172 unsafe { blocking_erase(start_address, end_address) }
173 } 164 }
174} 165}
175 166
@@ -177,19 +168,15 @@ foreach_flash_region! {
177 ($type_name:ident, $write_size:literal, $erase_size:literal) => { 168 ($type_name:ident, $write_size:literal, $erase_size:literal) => {
178 impl crate::_generated::flash_regions::$type_name { 169 impl crate::_generated::flash_regions::$type_name {
179 pub fn blocking_read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), Error> { 170 pub fn blocking_read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), Error> {
180 let start_address = self.0.base + offset; 171 blocking_read(self.0.base, self.0.size, offset, bytes)
181 blocking_read(start_address, bytes)
182 } 172 }
183 173
184 pub fn blocking_write(&mut self, offset: u32, bytes: &[u8]) -> Result<(), Error> { 174 pub fn blocking_write(&mut self, offset: u32, bytes: &[u8]) -> Result<(), Error> {
185 let start_address = self.0.base + offset; 175 unsafe { blocking_write(self.0.base, self.0.size, offset, bytes) }
186 unsafe { blocking_write(start_address, bytes) }
187 } 176 }
188 177
189 pub fn blocking_erase(&mut self, from: u32, to: u32) -> Result<(), Error> { 178 pub fn blocking_erase(&mut self, from: u32, to: u32) -> Result<(), Error> {
190 let start_address = self.0.base + from; 179 unsafe { blocking_erase(self.0.base, from, to) }
191 let end_address = self.0.base + to;
192 unsafe { blocking_erase(start_address, end_address) }
193 } 180 }
194 } 181 }
195 182