Skip to content

Commit 3e975be

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

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
@@ -283,102 +283,6 @@ impl<'flash, F: Flash> FlashExt<'flash> for &'flash F {
283283
}
284284
}
285285

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

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

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

634561
/// Returns a `Region` big enough to hold a `[T]` with the given number of
635562
/// elements.
636-
///
563+
///
637564
/// Returns `None` on overflow`.
638565
pub fn for_slice<T>(n: usize) -> Option<Self> {
639566
Some(Self::new(0, mem::size_of::<T>().checked_mul(n)? as u32))
@@ -652,7 +579,7 @@ impl Region {
652579

653580
/// Interprets `sub` as a subregion of `self`, returning a new `Region` of
654581
/// the same size as `sub`.
655-
///
582+
///
656583
/// Returns `None` if `sub` is not a subregion of `self`.
657584
pub fn subregion(self, sub: Region) -> Option<Self> {
658585
if sub.len.saturating_add(sub.ptr.address) > self.len {
@@ -666,17 +593,20 @@ impl Region {
666593
}
667594

668595
/// Contracts `self` by dropping the first `n` bytes.
669-
///
596+
///
670597
/// Returns `None` if `n` is greater than `self.len`, or if any overflow
671598
/// occurs.
672599
pub fn skip(self, n: u32) -> Option<Self> {
673-
Some(Region::new(self.ptr.address.checked_add(n)?, self.len.checked_sub(n)?))
600+
Some(Region::new(
601+
self.ptr.address.checked_add(n)?,
602+
self.len.checked_sub(n)?,
603+
))
674604
}
675605

676606
/// Contracts `self` by dropping the last `n` bytes.
677-
///
607+
///
678608
/// Returns `None` if `n` is greater than `self.len`.
679-
pub fn skip_back(self, n: u32) -> Option<Self> {
609+
pub fn take(self, n: u32) -> Option<Self> {
680610
Some(Region::new(self.ptr.address, self.len.checked_sub(n)?))
681611
}
682612
}

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)