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