Skip to content

Commit

Permalink
hiffy:: Add SendLeaseReadWrite idol function behind 'send-rw' feature.
Browse files Browse the repository at this point in the history
This function is called by `humility hiffy` to call hif operations that
require a read and a write lease. This commit hides this function behind
a new feature `send-rw` because including it in the existing `send`
feature causes the `hiffy` task in g0 images to roll over into another
flash block that isn't available on the donglet images. This new feature
is enabled by the existing `lpc55` and `stm32h7` features making this
mosly transparent to the app.tomls.
  • Loading branch information
flihp committed Jan 11, 2024
1 parent ca9f10a commit dc95c25
Show file tree
Hide file tree
Showing 5 changed files with 164 additions and 2 deletions.
5 changes: 3 additions & 2 deletions task/hiffy/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,10 @@ i2c = []
gpio = []
spi = []
send = []
send-rw = []
sprot = ["drv-sprot-api"]
stm32h7 = ["drv-stm32xx-sys-api/family-stm32h7", "userlib/panic-messages", "send"]
lpc55 = ["drv-lpc55-gpio-api", "userlib/panic-messages", "send"]
stm32h7 = ["drv-stm32xx-sys-api/family-stm32h7", "userlib/panic-messages", "send", "send-rw"]
lpc55 = ["drv-lpc55-gpio-api", "userlib/panic-messages", "send", "send-rw"]
stm32g0 = ["drv-stm32xx-sys-api/family-stm32g0"]
qspi = ["drv-gimlet-hf-api"]
hash = ["drv-hash-api"]
Expand Down
153 changes: 153 additions & 0 deletions task/hiffy/src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,159 @@ pub(crate) fn send_lease_write(
Ok(nreply + nlease)
}

///
/// Function to send an arbitrary message to an arbitrary task with a single
/// read lease and a single write lease attached to the tail end of `rval`
/// (shared with reply bytes)
///
/// arg2+n+3: Size of write lease
/// arg2+n+2: Size of read lease
/// arg2+n+1: Number of reply bytes
/// arg2+n: Number of bytes
/// arg2: Argument bytes
/// arg1: Operation
/// arg0: Task
///
#[cfg(feature = "send-rw")]
#[allow(dead_code)]
pub(crate) fn send_lease_read_write(
stack: &[Option<u32>],
data: &[u8],
rval: &mut [u8],
) -> Result<usize, Failure> {
let mut payload = [0u8; 32];

if stack.len() < 6 {
return Err(Failure::Fault(Fault::MissingParameters));
}

let sp = stack.len();

// get number of bytes in writable lease
let nlease_write = match stack[sp - 1] {
Some(n) => n as usize,
None => {
return Err(Failure::Fault(Fault::EmptyParameter(6)));
}
};

// get number of bytes in the readable lease
let nlease_read = match stack[sp - 2] {
Some(n) => n as usize,
None => {
return Err(Failure::Fault(Fault::EmptyParameter(5)));
}
};

// ensure the size of the provided slice is sufficient to hold the
// size described by the stack
if nlease_read > data.len() {
return Err(Failure::Fault(Fault::BadParameter(5)));
}

// get size of reply required by the op
let nreply = match stack[sp - 3] {
Some(n) => n as usize,
None => {
return Err(Failure::Fault(Fault::EmptyParameter(4)));
}
};

// ensure the reply and writable lease will fit in the provided writable
// slice
if nreply + nlease_write > rval.len() {
return Err(Failure::Fault(Fault::ReturnStackOverflow));
}

// get number of bytes in payload
let nbytes = match stack[sp - 4] {
Some(n) => n as usize,
None => {
return Err(Failure::Fault(Fault::EmptyParameter(3)));
}
};

// ensure stack is large enough to hold the op payload + hif data
if stack.len() < nbytes + 6 {
return Err(Failure::Fault(Fault::StackUnderflow));
}

let fp = sp - (nbytes + 6);

// get id of the task we've been asked to call
let task = match stack[fp + 0] {
Some(task) => {
if task >= NUM_TASKS as u32 {
return Err(Failure::Fault(Fault::BadParameter(0)));
}

let prototype =
TaskId::for_index_and_gen(task as usize, Generation::default());

sys_refresh_task_id(prototype)
}
None => {
return Err(Failure::Fault(Fault::EmptyParameter(0)));
}
};

// get id of the operation we've been asked to call
let op = match stack[fp + 1] {
Some(op) => {
if op > core::u16::MAX.into() {
return Err(Failure::Fault(Fault::BadParameter(1)));
}

op as u16
}
None => {
return Err(Failure::Fault(Fault::EmptyParameter(1)));
}
};

if nbytes > payload.len() {
return Err(Failure::Fault(Fault::StackUnderflow));
}

let base = fp + 2;

// copy the payload from the stack
for i in base..base + nbytes {
payload[i - base] = match stack[i] {
Some(byte) => {
if byte > core::u8::MAX.into() {
return Err(Failure::Fault(Fault::BadParameter(2)));
}

byte as u8
}
None => {
return Err(Failure::Fault(Fault::EmptyParameter(2)));
}
};
}

// split rval into two writable leases: one for the data returned by the
// task / op we're calling, the other for the writable lease passed to same
let (rval, lease) = rval.split_at_mut(nreply);
let (code, _) = sys_send(
task,
op,
&payload[0..nbytes],
&mut rval[0..nreply],
&[
userlib::Lease::read_only(&data[..nlease_read]),
userlib::Lease::write_only(&mut lease[..nlease_write]),
],
);

if code != 0 {
return Err(Failure::FunctionError(code));
}

Ok(nreply + nlease_write)
}

#[cfg(feature = "spi")]
fn spi_args(stack: &[Option<u32>]) -> Result<(TaskId, u8, usize), Failure> {
if stack.len() < 3 {
Expand Down
2 changes: 2 additions & 0 deletions task/hiffy/src/lpc55.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ pub enum Functions {
Sleep(u16, u32),
Send((Task, u16, Buffer, usize), u32),
SendLeaseRead((Task, u16, Buffer, usize, usize), u32),
SendLeaseReadWrite((Task, u16, Buffer, usize, usize, usize), u32),
SendLeaseWrite((Task, u16, Buffer, usize, usize), u32),
#[cfg(feature = "gpio")]
GpioInput(drv_lpc55_gpio_api::Pin, u32),
Expand Down Expand Up @@ -348,6 +349,7 @@ pub(crate) static HIFFY_FUNCS: &[Function] = &[
crate::common::sleep,
crate::common::send,
crate::common::send_lease_read,
crate::common::send_lease_read_write,
crate::common::send_lease_write,
#[cfg(feature = "gpio")]
gpio_input,
Expand Down
4 changes: 4 additions & 0 deletions task/hiffy/src/stm32g0.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ pub enum Functions {
Send((Task, u16, Buffer, usize), u32),
#[cfg(feature = "send")]
SendLeaseRead((Task, u16, Buffer, usize, usize), u32),
#[cfg(feature = "send-rw")]
SendLeaseReadWrite((Task, u16, Buffer, usize, usize, usize), u32),
#[cfg(feature = "send")]
SendLeaseWrite((Task, u16, Buffer, usize, usize), u32),
#[cfg(feature = "i2c")]
Expand Down Expand Up @@ -430,6 +432,8 @@ pub(crate) static HIFFY_FUNCS: &[Function] = &[
crate::common::send,
#[cfg(feature = "send")]
crate::common::send_lease_read,
#[cfg(feature = "send-rw")]
crate::common::send_lease_read_write,
#[cfg(feature = "send")]
crate::common::send_lease_write,
#[cfg(feature = "i2c")]
Expand Down
2 changes: 2 additions & 0 deletions task/hiffy/src/stm32h7.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ pub enum Functions {
Sleep(u16, u32),
Send((Task, u16, Buffer, usize), u32),
SendLeaseRead((Task, u16, Buffer, usize, usize), u32),
SendLeaseReadWrite((Task, u16, Buffer, usize, usize, usize), u32),
SendLeaseWrite((Task, u16, Buffer, usize, usize), u32),
#[cfg(feature = "i2c")]
I2cRead(
Expand Down Expand Up @@ -525,6 +526,7 @@ pub(crate) static HIFFY_FUNCS: &[Function] = &[
crate::common::sleep,
crate::common::send,
crate::common::send_lease_read,
crate::common::send_lease_read_write,
crate::common::send_lease_write,
#[cfg(feature = "i2c")]
i2c_read,
Expand Down

0 comments on commit dc95c25

Please sign in to comment.