Skip to content

Commit 7846e44

Browse files
mkeetercitrus-it
authored andcommitted
Add APOB message to host_sp_comms
1 parent 238e75f commit 7846e44

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
@@ -145,6 +145,11 @@ enum Trace {
145145
#[count(children)]
146146
message: SpToHost,
147147
},
148+
APOBWriteError {
149+
offset: u64,
150+
#[count(children)]
151+
err: APOBError,
152+
},
148153
}
149154

150155
counted_ringbuf!(Trace, 20, Trace::None);
@@ -171,6 +176,31 @@ enum Timers {
171176
TxPeriodicZeroByte,
172177
}
173178

179+
#[derive(Copy, Clone, Debug, Eq, PartialEq, counters::Count)]
180+
enum APOBError {
181+
OffsetOverflow {
182+
offset: u64,
183+
},
184+
NotErased {
185+
offset: u32,
186+
},
187+
EraseFailed {
188+
offset: u32,
189+
#[count(children)]
190+
err: drv_hf_api::HfError,
191+
},
192+
WriteFailed {
193+
offset: u32,
194+
#[count(children)]
195+
err: drv_hf_api::HfError,
196+
},
197+
ReadFailed {
198+
offset: u32,
199+
#[count(children)]
200+
err: drv_hf_api::HfError,
201+
},
202+
}
203+
174204
#[export_name = "main"]
175205
fn main() -> ! {
176206
let mut server = ServerImpl::claim_static_resources();
@@ -993,6 +1023,15 @@ impl ServerImpl {
9931023
}),
9941024
}
9951025
}
1026+
HostToSp::APOB { offset } => {
1027+
Some(match Self::apob_write(&self.hf, offset, data) {
1028+
Ok(()) => SpToHost::APOBResult(0),
1029+
Err(err) => {
1030+
ringbuf_entry!(Trace::APOBWriteError { offset, err });
1031+
SpToHost::APOBResult(1)
1032+
}
1033+
})
1034+
}
9961035
};
9971036

9981037
if let Some(response) = response {
@@ -1021,6 +1060,51 @@ impl ServerImpl {
10211060
Ok(())
10221061
}
10231062

1063+
/// Write data to the bonus region of flash
1064+
///
1065+
/// This does not take `&self` because we need to force a split borrow
1066+
fn apob_write(
1067+
hf: &HostFlash,
1068+
mut offset: u64,
1069+
data: &[u8],
1070+
) -> Result<(), APOBError> {
1071+
for chunk in data.chunks(drv_hf_api::PAGE_SIZE_BYTES) {
1072+
Self::apob_write_page(
1073+
hf,
1074+
offset
1075+
.try_into()
1076+
.map_err(|_| APOBError::OffsetOverflow { offset })?,
1077+
chunk,
1078+
)?;
1079+
offset += chunk.len() as u64;
1080+
}
1081+
Ok(())
1082+
}
1083+
1084+
/// Write a single page of data to the bonus region of flash
1085+
///
1086+
/// This does not take `&self` because we need to force a split borrow
1087+
fn apob_write_page(
1088+
hf: &HostFlash,
1089+
offset: u32,
1090+
data: &[u8],
1091+
) -> Result<(), APOBError> {
1092+
if offset as usize % drv_hf_api::SECTOR_SIZE_BYTES == 0 {
1093+
hf.bonus_sector_erase(offset)
1094+
.map_err(|err| APOBError::EraseFailed { offset, err })?;
1095+
} else {
1096+
// Read back the page and confirm that it's all empty
1097+
let mut scratch = [0u8; drv_hf_api::PAGE_SIZE_BYTES];
1098+
hf.bonus_read(offset, &mut scratch[..data.len()])
1099+
.map_err(|err| APOBError::ReadFailed { offset, err })?;
1100+
if !scratch[..data.len()].iter().all(|b| *b == 0xFF) {
1101+
return Err(APOBError::NotErased { offset });
1102+
}
1103+
}
1104+
hf.bonus_page_program(offset, data)
1105+
.map_err(|err| APOBError::WriteFailed { offset, err })
1106+
}
1107+
10241108
fn handle_sprot(
10251109
&mut self,
10261110
sequence: u64,

0 commit comments

Comments
 (0)