Skip to content

Commit 3e4663e

Browse files
committed
[flash] Eliminate SubFlash, emphasizing Region instead
Signed-off-by: Miguel Young de la Sota <[email protected]>
1 parent 7db8ad1 commit 3e4663e

File tree

2 files changed

+36
-105
lines changed

2 files changed

+36
-105
lines changed

src/hardware/flash.rs

Lines changed: 32 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -284,102 +284,6 @@ impl<'flash, F: Flash> FlashExt<'flash> for &'flash F {
284284
}
285285
}
286286

287-
/// Adapter for working with a sub-region of a [`Flash`] type.
288-
///
289-
/// Reads and writes on the device will be constrained to a given [`Region`].
290-
/// This is especially useful for operating on a blob contained within another
291-
/// region of flash.
292-
///
293-
/// There is no requirement that [`Region`] actually overlap with the address
294-
/// space of `F`; the [`Flash`] implementation is still responsible for doing
295-
/// bounds checks, after offsets are bounds-checked within `Region`.
296-
#[derive(Copy, Clone)]
297-
pub struct SubFlash<F>(pub F, pub Region);
298-
299-
impl<F: Flash> SubFlash<F> {
300-
/// Creates a new `SubFlash` representing the entirety of the given device.
301-
pub fn full(flash: F) -> Result<Self, Error> {
302-
let region = Region::new(0, flash.size()?);
303-
Ok(Self(flash, region))
304-
}
305-
}
306-
307-
impl<F> SubFlash<F> {
308-
/// Interprets `region` as a subregion of this `SubFlash`, returning a new
309-
/// `SubFlash` that represents that region.
310-
pub fn reslice(self, region: Region) -> Option<Self> {
311-
if region.len >= self.1.len {
312-
return None;
313-
}
314-
315-
Some(Self(
316-
self.0,
317-
Region::new(
318-
self.1.ptr.address.checked_add(region.ptr.address)?,
319-
region.len,
320-
),
321-
))
322-
}
323-
}
324-
325-
unsafe impl<F: Flash> Flash for SubFlash<F> {
326-
#[inline]
327-
fn size(&self) -> Result<u32, Error> {
328-
Ok(self.1.len)
329-
}
330-
331-
#[inline]
332-
fn read(&self, offset: Ptr, out: &mut [u8]) -> Result<(), Error> {
333-
if offset.address >= self.1.len {
334-
return Err(Error::OutOfRange);
335-
}
336-
let offset = offset
337-
.address
338-
.checked_add(self.1.ptr.address)
339-
.ok_or(Error::OutOfRange)?;
340-
341-
self.0.read(Ptr::new(offset), out)
342-
}
343-
344-
#[inline]
345-
fn read_direct<'a: 'c, 'b: 'c, 'c>(
346-
&'a self,
347-
region: Region,
348-
arena: &'b dyn Arena,
349-
align: usize,
350-
) -> Result<&'c [u8], Error> {
351-
if region.ptr.address >= self.1.len {
352-
return Err(Error::OutOfRange);
353-
}
354-
let offset = region
355-
.ptr
356-
.address
357-
.checked_add(self.1.ptr.address)
358-
.ok_or(Error::OutOfRange)?;
359-
360-
self.0
361-
.read_direct(Region::new(offset, region.len), arena, align)
362-
}
363-
364-
#[inline]
365-
fn program(&mut self, offset: Ptr, buf: &[u8]) -> Result<(), Error> {
366-
if offset.address >= self.1.len {
367-
return Err(Error::OutOfRange);
368-
}
369-
let offset = offset
370-
.address
371-
.checked_add(self.1.ptr.address)
372-
.ok_or(Error::OutOfRange)?;
373-
374-
self.0.program(Ptr::new(offset), buf)
375-
}
376-
377-
#[inline]
378-
fn flush(&mut self) -> Result<(), Error> {
379-
self.0.flush()
380-
}
381-
}
382-
383287
/// Adapter for converting RAM-backed storage into a [`Flash`].
384288
///
385289
/// For the purposes of this type, "RAM-backed" means that `AsRef<[u8]>`
@@ -535,10 +439,29 @@ impl<F: Flash> FlashIo<F> {
535439
pub fn skip(&mut self, bytes: usize) {
536440
self.cursor = self.cursor.saturating_add(bytes as u32);
537441
}
442+
443+
/// Skips the "end" pointer `bytes` bytes forward.
444+
///
445+
/// This operation always succeeds, but attempting to read past the end of
446+
/// flash will always result in an error.
447+
pub fn take(&mut self, bytes: usize) {
448+
self.len = self.len.saturating_sub(bytes as u32);
449+
}
450+
451+
/// Adapts this `FlashIo` to only read bytes out from the selected
452+
/// `Region`.
453+
pub fn reslice(&mut self, region: Region) {
454+
self.cursor = region.ptr.address;
455+
self.len = region.end();
456+
}
538457
}
539458

540459
impl<F: Flash> io::Read for FlashIo<F> {
541460
fn read_bytes(&mut self, out: &mut [u8]) -> Result<(), io::Error> {
461+
if self.remaining_data() == 0 {
462+
return Err(io::Error::BufferExhausted);
463+
}
464+
542465
self.flash
543466
.read(Ptr::new(self.cursor), out)
544467
.map_err(|_| io::Error::Internal)?;
@@ -569,6 +492,10 @@ impl<F: Flash> Iterator for FlashIo<F> {
569492

570493
impl<F: Flash> io::Write for FlashIo<F> {
571494
fn write_bytes(&mut self, buf: &[u8]) -> Result<(), io::Error> {
495+
if self.remaining_data() == 0 {
496+
return Err(io::Error::BufferExhausted);
497+
}
498+
572499
self.flash
573500
.program(Ptr::new(self.cursor), buf)
574501
.map_err(|_| io::Error::Internal)?;
@@ -634,7 +561,7 @@ impl Region {
634561

635562
/// Returns a `Region` big enough to hold a `[T]` with the given number of
636563
/// elements.
637-
///
564+
///
638565
/// Returns `None` on overflow`.
639566
pub fn for_slice<T>(n: usize) -> Option<Self> {
640567
Some(Self::new(0, mem::size_of::<T>().checked_mul(n)? as u32))
@@ -653,7 +580,7 @@ impl Region {
653580

654581
/// Interprets `sub` as a subregion of `self`, returning a new `Region` of
655582
/// the same size as `sub`.
656-
///
583+
///
657584
/// Returns `None` if `sub` is not a subregion of `self`.
658585
pub fn subregion(self, sub: Region) -> Option<Self> {
659586
if sub.len.saturating_add(sub.ptr.address) > self.len {
@@ -667,17 +594,20 @@ impl Region {
667594
}
668595

669596
/// Contracts `self` by dropping the first `n` bytes.
670-
///
597+
///
671598
/// Returns `None` if `n` is greater than `self.len`, or if any overflow
672599
/// occurs.
673600
pub fn skip(self, n: u32) -> Option<Self> {
674-
Some(Region::new(self.ptr.address.checked_add(n)?, self.len.checked_sub(n)?))
601+
Some(Region::new(
602+
self.ptr.address.checked_add(n)?,
603+
self.len.checked_sub(n)?,
604+
))
675605
}
676606

677607
/// Contracts `self` by dropping the last `n` bytes.
678-
///
608+
///
679609
/// Returns `None` if `n` is greater than `self.len`.
680-
pub fn skip_back(self, n: u32) -> Option<Self> {
610+
pub fn take(self, n: u32) -> Option<Self> {
681611
Some(Region::new(self.ptr.address, self.len.checked_sub(n)?))
682612
}
683613
}

src/manifest/container.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ use crate::crypto::sha256::Hasher as _;
4747
use crate::hardware::flash::Flash;
4848
use crate::hardware::flash::FlashIo;
4949
use crate::hardware::flash::Region;
50-
use crate::hardware::flash::SubFlash;
5150
use crate::io;
5251
use crate::io::cursor::SeekPos;
5352
use crate::io::Cursor;
@@ -118,7 +117,8 @@ impl<F: Flash> Container<F, provenance::Signed> {
118117
let (mut c, sig, signed) = Self::parse_inner(flash)?;
119118

120119
let mut bytes = [0u8; 16];
121-
let mut r = FlashIo::new(SubFlash(&mut c.flash, signed))?;
120+
let mut r = FlashIo::new(&mut c.flash)?;
121+
r.reslice(signed);
122122

123123
let mut hasher =
124124
sha.new_hasher().map_err(|_| Error::SignatureFailure)?;
@@ -274,7 +274,8 @@ impl<F: Flash, Provenance> Container<F, Provenance> {
274274
.with_metadata(self.metadata())?;
275275

276276
let mut bytes = [0u8; 16];
277-
let mut r = FlashIo::new(SubFlash(&self.flash, self.body))?;
277+
let mut r = FlashIo::new(self.flash())?;
278+
r.reslice(self.body());
278279
while r.remaining_data() > 0 {
279280
let to_read = r.remaining_data().min(16);
280281
r.read_bytes(&mut bytes[..to_read])?;

0 commit comments

Comments
 (0)