Merge #186
186: Replace 'clone_from_slice' with 'copy_from_slice' r=JOE1994 a=JOE1994
Currently, `shared_memory::safe_copy` uses `clone_from_slice` to
perform memory copy. `clone_from_slice` iterates over each element of
slice to invoke 'clone_from'. According to [docs of `clone_from_slice`](https://doc.rust-lang.org/std/primitive.slice.html#method.clone_from_slice),
it can be more performant to use `copy_from_slice` instead when copy target implements `Copy`.
Since we're copying a `u8` slice, I thought replacing `clone_from_slice` with `copy_from_slice` would be a helpful change regarding performance.
Thank you for reviewing this PR :)
Co-authored-by: JOE1994 <joseph942010@gmail.com>
diff --git a/.travis.yml b/.travis.yml
index 94ba1ed..66cee0b 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -13,16 +13,16 @@
cache: cargo
-# Once Travis supports a version of Ubuntu Disco or newer we can apt install QEMU for RISC-V
+# Once Travis supports a version of Ubuntu that inlcudes QEMU 5.1+
+# we can apt install QEMU for RISC-V.
# Until then we need to build it ourselves
before_install:
# - sudo apt-get -y install qemu-system-misc
# addons:
# apt:
# update: true
- - wget https://download.qemu.org/qemu-4.2.0.tar.xz
- - tar xJf qemu-4.2.0.tar.xz
- - pushd qemu-4.2.0
+ - git clone https://github.com/alistair23/qemu.git -b riscv-tock.next
+ - pushd qemu
- ./configure --target-list=riscv32-softmmu
- make -j8
- sudo ln -s $PWD/riscv32-softmmu/qemu-system-riscv32 /usr/bin/
@@ -35,7 +35,7 @@
- git clone https://github.com/tock/tock.git
- cd tock/boards/hifive1
# Use a known working version of Tock
- - git checkout c94059d3e25dc635e682facff4894ef43b9aca0e
+ - git checkout 152189fe077aea955332ee3c28ccbee519d8b072
- make
- popd
diff --git a/Makefile b/Makefile
index 1467c1a..f1f6dd5 100644
--- a/Makefile
+++ b/Makefile
@@ -59,6 +59,14 @@
analyse-stack-sizes:
cargo stack-sizes $(release) --example $(EXAMPLE) $(features) -- -Z emit-stack-sizes
+.PHONY: apollo3
+apollo3:
+ PLATFORM=apollo3 cargo build $(release) --target=thumbv7em-none-eabi --examples $(features)
+
+.PHONY: flash-apollo3
+flash-apollo3:
+ PLATFORM=apollo3 cargo run $(release) --target=thumbv7em-none-eabi --example $(EXAMPLE) $(features)
+
.PHONY: hail
hail:
PLATFORM=hail cargo build $(release) --target=thumbv7em-none-eabi --examples $(features)
diff --git a/README.md b/README.md
index 36be4b0..a2bad2b 100644
--- a/README.md
+++ b/README.md
@@ -39,7 +39,7 @@
make setup
```
-1. Use `make` to compile and run an example app.
+1. Use `make` to build examples
```shell
make nrf52 # Builds all examples for the nrf52 platform
@@ -53,6 +53,10 @@
make opentitan FEATURES=alloc # Builds all examples for the OpenTitan platform, with alloc feature enabled
```
+ ```bash
+ make flash-hail EXAMPLE=blink # Flash the example 'blink' program to the hail platform
+ ```
+
For an unknown platform, you may have to create your own memory layout definition. Place the layout definition file at `boards/layout_<platform>.ld` and do not forget to enhance the `tockloader_flags` dispatching section in `tools/flash.sh`. You are welcome to create a PR, s.t. the number of supported platforms grows.
## Using libtock-rs
@@ -79,13 +83,13 @@
to the preamble and store your example in the `examples-alloc` folder.
-To run on the code on your board you can use
+To build the examples for your board you can use
```shell
make <platform> [FEATURES=alloc]
```
-The example can also be flashed to the board by running:
+An example can be flashed to your board after the build process by running:
```shell
make flash-<platform> EXAMPLE=<example>
diff --git a/boards/layout_apollo3.ld b/boards/layout_apollo3.ld
new file mode 100644
index 0000000..95fde33
--- /dev/null
+++ b/boards/layout_apollo3.ld
@@ -0,0 +1,17 @@
+/* Layout for the Apollo3 MCU, used by the examples in this repository. */
+
+MEMORY {
+ /* The application region is 64 bytes (0x40) */
+ FLASH (rx) : ORIGIN = 0x00040040, LENGTH = 0x0005FFC0
+ SRAM (rwx) : ORIGIN = 0x10002000, LENGTH = 0x2000
+}
+
+/*
+ * Any change to STACK_SIZE should be accompanied by a corresponding change to
+ * `elf2tab`'s `--stack` option
+ */
+STACK_SIZE = 2048;
+
+MPU_MIN_ALIGN = 8K;
+
+INCLUDE layout_generic.ld
diff --git a/boards/layout_hifive1.ld b/boards/layout_hifive1.ld
index e9bd9d0..2e08580 100644
--- a/boards/layout_hifive1.ld
+++ b/boards/layout_hifive1.ld
@@ -9,7 +9,7 @@
* Note that the SRAM address may need to be changed depending on
* the kernel binary, check for the actual address of APP_MEMORY!
*/
- FLASH (rx) : ORIGIN = 0x20430040, LENGTH = 32M
+ FLASH (rx) : ORIGIN = 0x20040040, LENGTH = 32M
SRAM (rwx) : ORIGIN = 0x80002400, LENGTH = 0x1C00
}
diff --git a/examples/hmac.rs b/examples/hmac.rs
new file mode 100644
index 0000000..97184f7
--- /dev/null
+++ b/examples/hmac.rs
@@ -0,0 +1,55 @@
+#![no_std]
+
+use core::fmt::Write;
+use libtock::hmac::{HmacDataBuffer, HmacDestBuffer, HmacKeyBuffer};
+use libtock::result::TockResult;
+use libtock::syscalls;
+
+#[libtock::main]
+async fn main() -> TockResult<()> {
+ let mut drivers = libtock::retrieve_drivers()?;
+ let mut console = drivers.console.create_console();
+ writeln!(console, "Starting HMAC example")?;
+ let hmac_driver = drivers.hmac.init_driver()?;
+
+ writeln!(console, "Loading in 0 key")?;
+ let mut key_buffer = HmacKeyBuffer::default();
+ let _key_buffer = hmac_driver.init_key_buffer(&mut key_buffer)?;
+ writeln!(console, " done")?;
+
+ writeln!(console, "Creating data buffer")?;
+ let mut data_buffer = HmacDataBuffer::default();
+ let data: &[u8; 72] =
+ b"A language empowering everyone to build reliable and efficient software.";
+
+ for (i, d) in data.iter().enumerate() {
+ data_buffer.buffer[i] = *d;
+ }
+ let _data_buffer = hmac_driver.init_data_buffer(&mut data_buffer)?;
+ writeln!(console, " done")?;
+
+ writeln!(console, "Creating dest buffer")?;
+ let mut dest_buffer = HmacDestBuffer::default();
+ let dest_buffer = hmac_driver.init_dest_buffer(&mut dest_buffer)?;
+ writeln!(console, " done")?;
+
+ let mut temp_buffer = [0; libtock::hmac::DEST_BUFFER_SIZE];
+
+ writeln!(console, "Setting callback and running")?;
+ let mut callback = |_result, _digest| {
+ writeln!(console, "HMAC Complete, printing digest").unwrap();
+ dest_buffer.read_bytes(&mut temp_buffer[..]);
+
+ for buf in temp_buffer.iter().take(libtock::hmac::DEST_BUFFER_SIZE) {
+ write!(console, "{:x}", *buf).unwrap();
+ }
+ };
+
+ let _subscription = hmac_driver.subscribe(&mut callback)?;
+
+ hmac_driver.run()?;
+
+ loop {
+ unsafe { syscalls::raw::yieldk() };
+ }
+}
diff --git a/src/drivers.rs b/src/drivers.rs
index 185f6ea..bd7f45b 100644
--- a/src/drivers.rs
+++ b/src/drivers.rs
@@ -2,6 +2,7 @@
use crate::buttons::ButtonsDriverFactory;
use crate::console::ConsoleDriver;
use crate::gpio::GpioDriverFactory;
+use crate::hmac::HmacDriverFactory;
use crate::leds::LedsDriverFactory;
use crate::result::OtherError;
use crate::result::TockError;
@@ -23,6 +24,7 @@
pub leds: LedsDriverFactory,
pub timer: DriverContext,
pub gpio: GpioDriverFactory,
+ pub hmac: HmacDriverFactory,
pub temperature: TemperatureDriverFactory,
pub buttons: ButtonsDriverFactory,
pub adc: AdcDriverFactory,
@@ -71,6 +73,7 @@
active_timer: Cell::new(None),
},
gpio: GpioDriverFactory,
+ hmac: HmacDriverFactory,
temperature: TemperatureDriverFactory,
rng: RngDriver,
ambient_light_sensor: AmbientLightSensor,
diff --git a/src/hmac.rs b/src/hmac.rs
new file mode 100644
index 0000000..e5475cc
--- /dev/null
+++ b/src/hmac.rs
@@ -0,0 +1,123 @@
+use crate::callback::CallbackSubscription;
+use crate::callback::Consumer;
+use crate::result::TockResult;
+use crate::syscalls;
+use core::marker::PhantomData;
+use libtock_core::shared_memory::SharedMemory;
+
+const DRIVER_NUMBER: usize = 0x40003;
+
+pub const KEY_BUFFER_SIZE: usize = 32;
+pub const DATA_BUFFER_SIZE: usize = 256;
+pub const DEST_BUFFER_SIZE: usize = 32;
+
+mod command_nr {
+ pub const SET_ALGORITHM: usize = 0;
+ pub const RUN: usize = 1;
+}
+
+mod subscribe_nr {
+ pub const SUBSCRIBE_CALLBACK: usize = 0;
+}
+
+mod allow_nr {
+ pub const KEY: usize = 0;
+ pub const DATA: usize = 1;
+ pub const DEST: usize = 2;
+}
+
+#[non_exhaustive]
+pub struct HmacDriverFactory;
+
+impl HmacDriverFactory {
+ pub fn init_driver(&mut self) -> TockResult<HmacDriver> {
+ let hmac = HmacDriver {
+ lifetime: PhantomData,
+ };
+ Ok(hmac)
+ }
+}
+
+struct HmacEventConsumer;
+
+impl<CB: FnMut(usize, usize)> Consumer<CB> for HmacEventConsumer {
+ fn consume(callback: &mut CB, result: usize, digest: usize, _: usize) {
+ callback(result, digest);
+ }
+}
+
+pub struct HmacKeyBuffer {
+ buffer: [u8; KEY_BUFFER_SIZE],
+}
+
+impl Default for HmacKeyBuffer {
+ fn default() -> Self {
+ HmacKeyBuffer {
+ buffer: [0; KEY_BUFFER_SIZE],
+ }
+ }
+}
+
+pub struct HmacDataBuffer {
+ pub buffer: [u8; DATA_BUFFER_SIZE],
+}
+
+impl Default for HmacDataBuffer {
+ fn default() -> Self {
+ HmacDataBuffer {
+ buffer: [0; DATA_BUFFER_SIZE],
+ }
+ }
+}
+
+pub struct HmacDestBuffer {
+ buffer: [u8; DEST_BUFFER_SIZE],
+}
+
+impl Default for HmacDestBuffer {
+ fn default() -> Self {
+ HmacDestBuffer {
+ buffer: [0; DEST_BUFFER_SIZE],
+ }
+ }
+}
+
+pub struct HmacDriver<'a> {
+ lifetime: PhantomData<&'a ()>,
+}
+
+impl<'a> HmacDriver<'a> {
+ pub fn init_key_buffer(&self, buffer: &'a mut HmacKeyBuffer) -> TockResult<SharedMemory> {
+ syscalls::allow(DRIVER_NUMBER, allow_nr::KEY, &mut buffer.buffer).map_err(Into::into)
+ }
+
+ pub fn init_data_buffer(&self, buffer: &'a mut HmacDataBuffer) -> TockResult<SharedMemory> {
+ syscalls::allow(DRIVER_NUMBER, allow_nr::DATA, &mut buffer.buffer).map_err(Into::into)
+ }
+
+ pub fn init_dest_buffer(&self, buffer: &'a mut HmacDestBuffer) -> TockResult<SharedMemory> {
+ syscalls::allow(DRIVER_NUMBER, allow_nr::DEST, &mut buffer.buffer).map_err(Into::into)
+ }
+
+ pub fn subscribe<CB: FnMut(usize, usize) -> () + FnMut(usize, usize)>(
+ &self,
+ callback: &'a mut CB,
+ ) -> TockResult<CallbackSubscription> {
+ syscalls::subscribe::<HmacEventConsumer, _>(
+ DRIVER_NUMBER,
+ subscribe_nr::SUBSCRIBE_CALLBACK,
+ callback,
+ )
+ .map_err(Into::into)
+ }
+
+ pub fn set_algorithm(&self, hash: usize) -> TockResult<()> {
+ syscalls::command(DRIVER_NUMBER, command_nr::SET_ALGORITHM, hash, 0)?;
+ Ok(())
+ }
+
+ pub fn run(&self) -> TockResult<()> {
+ syscalls::command(DRIVER_NUMBER, command_nr::RUN, 0, 0)?;
+ Ok(())
+ }
+}
diff --git a/src/lib.rs b/src/lib.rs
index 152e223..eb13b94 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -11,6 +11,7 @@
pub mod executor;
pub mod futures;
pub mod gpio;
+pub mod hmac;
pub mod leds;
pub mod result;
pub mod rng;
diff --git a/test-runner/src/main.rs b/test-runner/src/main.rs
index 0ee3455..99b941c 100644
--- a/test-runner/src/main.rs
+++ b/test-runner/src/main.rs
@@ -16,11 +16,11 @@
let tests = Command::new("qemu-system-riscv32")
.arg("-M")
- .arg("sifive_e")
+ .arg("sifive_e,revb=true")
.arg("-kernel")
- .arg("../../tock/boards/hifive1/target/riscv32imac-unknown-none-elf/release/hifive1")
+ .arg("../../tock/target/riscv32imac-unknown-none-elf/release/hifive1")
.arg("-device")
- .arg("loader,file=./../target/riscv32imac-unknown-none-elf/tab/hifive1/libtock_test/rv32imac.tbf,addr=0x20430000")
+ .arg("loader,file=./../target/riscv32imac-unknown-none-elf/tab/hifive1/libtock_test/rv32imac.tbf,addr=0x20040000")
.arg("-nographic")
.stdout(Stdio::piped())
.kill_on_drop(true)
diff --git a/tools/flash.sh b/tools/flash.sh
index 7f4c4ea..f24127e 100755
--- a/tools/flash.sh
+++ b/tools/flash.sh
@@ -15,6 +15,11 @@
fi
case "${PLATFORM}" in
+ "apollo3")
+ tockloader_flags=""
+ binary_name=cortex-m4.elf
+ tockload=n
+ ;;
"nrf52"|"nrf52840")
tockloader_flags="--jlink --arch cortex-m4 --board nrf52dk --jtag-device nrf52"
binary_name=cortex-m4.elf