Skip to content

Commit 65a65da

Browse files
committed
Add APOB message to host_sp_comms
1 parent 1fd855b commit 65a65da

File tree

2 files changed

+89
-0
lines changed

2 files changed

+89
-0
lines changed

lib/host-sp-messages/src/lib.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,10 @@ pub enum HostToSp {
123123
// We use a raw `u8` here for the same reason as in `KeyLookup` above.
124124
key: u8,
125125
},
126+
// APOB is followed by a binary data blob, which should be written to flash
127+
APOB {
128+
offset: u64,
129+
},
126130
}
127131

128132
/// The order of these cases is critical! We are relying on hubpack's encoding
@@ -185,6 +189,7 @@ pub enum SpToHost {
185189
name: [u8; 32],
186190
},
187191
KeySetResult(#[count(children)] KeySetResult),
192+
APOBResult(u8),
188193
}
189194

190195
#[derive(Debug, Clone, Copy, PartialEq, Eq, num_derive::FromPrimitive)]

task/host-sp-comms/src/main.rs

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,11 @@ enum Trace {
137137
#[count(children)]
138138
message: SpToHost,
139139
},
140+
APOBWriteError {
141+
offset: u64,
142+
#[count(children)]
143+
err: APOBError,
144+
},
140145
}
141146

142147
counted_ringbuf!(Trace, 20, Trace::None);
@@ -163,6 +168,31 @@ enum Timers {
163168
TxPeriodicZeroByte,
164169
}
165170

171+
#[derive(Copy, Clone, Debug, Eq, PartialEq, counters::Count)]
172+
enum APOBError {
173+
OffsetOverflow {
174+
offset: u64,
175+
},
176+
NotErased {
177+
offset: u32,
178+
},
179+
EraseFailed {
180+
offset: u32,
181+
#[count(children)]
182+
err: drv_hf_api::HfError,
183+
},
184+
WriteFailed {
185+
offset: u32,
186+
#[count(children)]
187+
err: drv_hf_api::HfError,
188+
},
189+
ReadFailed {
190+
offset: u32,
191+
#[count(children)]
192+
err: drv_hf_api::HfError,
193+
},
194+
}
195+
166196
#[export_name = "main"]
167197
fn main() -> ! {
168198
let mut server = ServerImpl::claim_static_resources();
@@ -965,6 +995,15 @@ impl ServerImpl {
965995
}),
966996
}
967997
}
998+
HostToSp::APOB { offset } => {
999+
Some(match Self::apob_write(&self.hf, offset, data) {
1000+
Ok(()) => SpToHost::APOBResult(0),
1001+
Err(err) => {
1002+
ringbuf_entry!(Trace::APOBWriteError { offset, err });
1003+
SpToHost::APOBResult(1)
1004+
}
1005+
})
1006+
}
9681007
};
9691008

9701009
if let Some(response) = response {
@@ -993,6 +1032,51 @@ impl ServerImpl {
9931032
Ok(())
9941033
}
9951034

1035+
/// Write data to the bonus region of flash
1036+
///
1037+
/// This does not take `&self` because we need to force a split borrow
1038+
fn apob_write(
1039+
hf: &HostFlash,
1040+
mut offset: u64,
1041+
data: &[u8],
1042+
) -> Result<(), APOBError> {
1043+
for chunk in data.chunks(drv_hf_api::PAGE_SIZE_BYTES) {
1044+
Self::apob_write_page(
1045+
hf,
1046+
offset
1047+
.try_into()
1048+
.map_err(|_| APOBError::OffsetOverflow { offset })?,
1049+
chunk,
1050+
)?;
1051+
offset += chunk.len() as u64;
1052+
}
1053+
Ok(())
1054+
}
1055+
1056+
/// Write a single page of data to the bonus region of flash
1057+
///
1058+
/// This does not take `&self` because we need to force a split borrow
1059+
fn apob_write_page(
1060+
hf: &HostFlash,
1061+
offset: u32,
1062+
data: &[u8],
1063+
) -> Result<(), APOBError> {
1064+
if offset as usize % drv_hf_api::SECTOR_SIZE_BYTES == 0 {
1065+
hf.bonus_sector_erase(offset)
1066+
.map_err(|err| APOBError::EraseFailed { offset, err })?;
1067+
} else {
1068+
// Read back the page and confirm that it's all empty
1069+
let mut scratch = [0u8; drv_hf_api::PAGE_SIZE_BYTES];
1070+
hf.bonus_read(offset, &mut scratch[..data.len()])
1071+
.map_err(|err| APOBError::ReadFailed { offset, err })?;
1072+
if !scratch[..data.len()].iter().all(|b| *b == 0xFF) {
1073+
return Err(APOBError::NotErased { offset });
1074+
}
1075+
}
1076+
hf.bonus_page_program(offset, data)
1077+
.map_err(|err| APOBError::WriteFailed { offset, err })
1078+
}
1079+
9961080
fn handle_sprot(
9971081
&mut self,
9981082
sequence: u64,

0 commit comments

Comments
 (0)