Skip to content

Commit 64d0362

Browse files
authored
Try #164:
2 parents 4d27d24 + 76f96bb commit 64d0362

36 files changed

+236
-196
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
Cargo.lock
22
layout.ld
3+
platform
34
target

Cargo.toml

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,14 @@ license = "MIT/Apache-2.0"
66
edition = "2018"
77

88
[features]
9-
alloc = [ "linked_list_allocator" ]
9+
alloc = ["libtock-core/alloc"]
10+
custom_panic_handler = ["libtock-core/custom_panic_handler"]
11+
custom_alloc_error_handler = ["libtock-core/custom_alloc_error_handler"]
1012

1113
[dependencies]
1214
core = { package = "async-support", path = "async-support" }
15+
libtock-core = { path = "core" }
1316
libtock_codegen = { path = "codegen" }
14-
linked_list_allocator = { optional = true, version = "=0.6.5", default-features = false }
1517
futures = { version = "0.3.1", default-features = false, features = ["unstable", "cfg-target-has-atomic"] }
1618

1719
[dev-dependencies]
@@ -22,22 +24,27 @@ serde = { version = "=1.0.84", default-features = false, features = ["derive"] }
2224

2325
[[example]]
2426
name = "alloc_error"
25-
path = "examples-alloc/alloc_error.rs"
26-
required-features = ["alloc"]
27+
path = "examples-features/alloc_error.rs"
28+
required-features = ["alloc", "custom_alloc_error_handler"]
2729

2830
[[example]]
2931
name = "ble_scanning"
30-
path = "examples-alloc/ble_scanning.rs"
32+
path = "examples-features/ble_scanning.rs"
3133
required-features = ["alloc"]
3234

3335
[[example]]
3436
name = "libtock_test"
35-
path = "examples-alloc/libtock_test.rs"
37+
path = "examples-features/libtock_test.rs"
3638
required-features = ["alloc"]
3739

40+
[[example]]
41+
name = "panic"
42+
path = "examples-features/panic.rs"
43+
required-features = ["custom_panic_handler"]
44+
3845
[[example]]
3946
name = "simple_ble"
40-
path = "examples-alloc/simple_ble.rs"
47+
path = "examples-features/simple_ble.rs"
4148
required-features = ["alloc"]
4249

4350
[profile.dev]
@@ -52,4 +59,5 @@ lto = true
5259
members = [
5360
"async-support",
5461
"codegen",
62+
"core"
5563
]

Makefile

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,9 @@ setup:
4242
examples:
4343
PLATFORM=nrf52 cargo build --release --target=thumbv7em-none-eabi --examples
4444
PLATFORM=nrf52 cargo build --release --target=thumbv7em-none-eabi --examples --features=alloc
45-
PLATFORM=opentitan cargo build --release --target=riscv32imc-unknown-none-elf --examples
45+
PLATFORM=nrf52 cargo build --release --target=thumbv7em-none-eabi --example panic --features=custom_panic_handler,custom_alloc_error_handler
46+
PLATFORM=nrf52 cargo build --release --target=thumbv7em-none-eabi --example alloc_error --features=alloc,custom_alloc_error_handler
47+
PLATFORM=opentitan cargo build --release --target=riscv32imc-unknown-none-elf --examples # Important: This is testing a platform without atomics support
4648

4749
.PHONY: test
4850
test:

core/Cargo.toml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
[package]
2+
name = "libtock-core"
3+
version = "0.1.0"
4+
authors = ["Tock Project Developers <[email protected]>"]
5+
edition = "2018"
6+
7+
[features]
8+
alloc = [ "linked_list_allocator" ]
9+
custom_panic_handler = []
10+
custom_alloc_error_handler = []
11+
12+
[dependencies]
13+
linked_list_allocator = { optional = true, version = "=0.6.5", default-features = false }

core/README.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# libtock-core
2+
3+
Core crate of `libtock-rs`. It contains the architecture specific code of `libtock-rs`. In particular:
4+
5+
* the entry point
6+
* `panic` and `alloc_error` handlers
7+
* the syscalls
8+
* the allocator (optional)
9+
10+
It has three important feature flags
11+
12+
* `alloc` - allow for heap. Enables a linked list allocator.
13+
* `custom_panic_handler` - disable the default panic handler and allow definition of a custom one using `#[panic_handler]`
14+
* `custom_alloc_error_handler` - disable the default alloc error handler and allow definition of a custom one using `#[alloc_error_handler]`
15+
16+
## License
17+
18+
Licensed under either of
19+
20+
- Apache License, Version 2.0
21+
([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
22+
- MIT license
23+
([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
24+
25+
at your option.
26+
27+
### Contribution
28+
29+
Unless you explicitly state otherwise, any contribution intentionally submitted
30+
for inclusion in the work by you, as defined in the Apache-2.0 license, shall be
31+
dual licensed as above, without any additional terms or conditions.
32+
33+
The contribution guidelines are identical to those of `libtock-rs` and can be found here: [contribution guidelines](../CONTRIBUTING.md)

core/src/alloc.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
use core::alloc::GlobalAlloc;
2+
use core::alloc::Layout;
3+
use core::ptr;
4+
use core::ptr::NonNull;
5+
use linked_list_allocator::Heap;
6+
7+
pub static mut HEAP: Heap = Heap::empty();
8+
9+
struct TockAllocator;
10+
11+
unsafe impl GlobalAlloc for TockAllocator {
12+
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
13+
HEAP.allocate_first_fit(layout)
14+
.ok()
15+
.map_or(ptr::null_mut(), NonNull::as_ptr)
16+
}
17+
18+
unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
19+
HEAP.deallocate(NonNull::new_unchecked(ptr), layout)
20+
}
21+
}
22+
23+
#[global_allocator]
24+
static ALLOCATOR: TockAllocator = TockAllocator;
25+
26+
#[cfg(not(feature = "custom_alloc_error_handler"))]
27+
#[alloc_error_handler]
28+
unsafe fn alloc_error_handler(_: Layout) -> ! {
29+
use crate::syscalls;
30+
31+
// Print 0x01 using the LowLevelDebug capsule (if available).
32+
let _ = syscalls::command1_insecure(8, 2, 0x01);
33+
34+
// Signal a panic using the LowLevelDebug capsule (if available).
35+
let _ = syscalls::command1_insecure(8, 1, 0x01);
36+
37+
loop {
38+
syscalls::raw::yieldk();
39+
}
40+
}
File renamed without changes.

core/src/debug/mod.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#[cfg_attr(target_arch = "arm", path = "platform_arm.rs")]
2+
#[cfg_attr(target_arch = "riscv32", path = "platform_riscv32.rs")]
3+
mod platform;
4+
5+
pub use platform::*;

core/src/debug/platform.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
pub fn get_stack_pointer() -> usize {
2+
panic!("No generic implementation.")
3+
}

core/src/debug/platform_arm.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
pub fn get_stack_pointer() -> usize {
2+
let stack_pointer;
3+
unsafe { asm!("mov $0, sp" : "=r"(stack_pointer) : : : "volatile") };
4+
stack_pointer
5+
}

core/src/debug/platform_riscv32.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
pub fn get_stack_pointer() -> usize {
2+
let stack_pointer;
3+
unsafe { asm!("mv $0, sp" : "=r"(stack_pointer) : : : "volatile") };
4+
stack_pointer
5+
}

src/entry_point/mod.rs renamed to core/src/entry_point/mod.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,6 @@ use core::ptr;
5757

5858
#[cfg_attr(target_arch = "riscv32", path = "start_item_riscv32.rs")]
5959
#[cfg_attr(target_arch = "arm", path = "start_item_arm.rs")]
60-
#[cfg_attr(
61-
not(any(target_arch = "arm", target_arch = "riscv32")),
62-
path = "start_item_mock.rs"
63-
)]
6460
mod start_item;
6561

6662
/// The header encoded at the beginning of .text by the linker script. It is

src/lang_items.rs renamed to core/src/lang_items.rs

Lines changed: 6 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,7 @@
1818
//! `rustc_main`. That's covered by the `_start` function in the root of this
1919
//! crate.
2020
21-
use crate::drivers;
22-
use crate::leds::LedsDriver;
23-
use crate::result::TockResult;
24-
use crate::timer::Duration;
25-
use crate::timer::ParallelSleepDriver;
26-
use core::executor;
27-
use core::panic::PanicInfo;
28-
use futures::future;
21+
use crate::syscalls;
2922

3023
#[lang = "start"]
3124
extern "C" fn start<T>(main: fn() -> T, _argc: isize, _argv: *const *const u8) -> bool
@@ -45,52 +38,25 @@ impl Termination for () {
4538
fn check_result(self) {}
4639
}
4740

48-
impl Termination for TockResult<()> {
41+
impl<S, T> Termination for Result<S, T> {
4942
fn check_result(self) {
5043
if self.is_err() {
5144
unsafe { report_panic() };
5245
}
5346
}
5447
}
5548

49+
#[cfg(not(feature = "custom_panic_handler"))]
5650
#[panic_handler]
57-
unsafe fn panic_handler(_info: &PanicInfo) -> ! {
51+
unsafe fn panic_handler(_info: &core::panic::PanicInfo) -> ! {
5852
report_panic()
5953
}
6054

6155
unsafe fn report_panic() -> ! {
6256
// Signal a panic using the LowLevelDebug capsule (if available).
63-
super::debug::low_level_status_code(1);
57+
let _ = syscalls::command1_insecure(8, 1, 1);
6458

65-
// Flash all LEDs (if available).
66-
executor::block_on(async {
67-
let mut drivers = drivers::retrieve_drivers_unsafe();
68-
69-
let leds_driver = drivers.leds.init_driver();
70-
let mut timer_driver = drivers.timer.create_timer_driver();
71-
let timer_driver = timer_driver.activate();
72-
73-
if let (Ok(leds_driver), Ok(timer_driver)) = (leds_driver, timer_driver) {
74-
let _ = blink_all_leds(&leds_driver, &timer_driver).await;
75-
} else {
76-
future::pending::<()>().await
77-
}
78-
loop {}
79-
})
80-
}
81-
82-
async fn blink_all_leds(
83-
leds_driver: &LedsDriver<'_>,
84-
timer_driver: &ParallelSleepDriver<'_>,
85-
) -> TockResult<()> {
8659
loop {
87-
for led in leds_driver.leds() {
88-
led.on()?;
89-
}
90-
timer_driver.sleep(Duration::from_ms(100)).await?;
91-
for led in leds_driver.leds() {
92-
led.off()?;
93-
}
94-
timer_driver.sleep(Duration::from_ms(100)).await?;
60+
syscalls::raw::yieldk();
9561
}
9662
}

core/src/lib.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#![feature(asm, lang_items, naked_functions)]
2+
#![cfg_attr(any(target_arch = "arm", target_arch = "riscv32"), no_std)]
3+
#![cfg_attr(feature = "alloc", feature(alloc_error_handler))]
4+
5+
#[cfg(feature = "alloc")]
6+
mod alloc;
7+
mod entry_point;
8+
#[cfg(any(target_arch = "arm", target_arch = "riscv32"))]
9+
mod lang_items;
10+
11+
pub mod callback;
12+
pub mod debug;
13+
pub mod memop;
14+
pub mod result;
15+
pub mod shared_memory;
16+
pub mod syscalls;
17+
pub mod unwind_symbols;
File renamed without changes.

core/src/result.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#[derive(Copy, Clone)]
2+
pub struct SubscribeError {
3+
pub driver_number: usize,
4+
pub subscribe_number: usize,
5+
pub return_code: isize,
6+
}
7+
8+
#[derive(Copy, Clone)]
9+
pub struct CommandError {
10+
pub driver_number: usize,
11+
pub command_number: usize,
12+
pub arg1: usize,
13+
pub arg2: usize,
14+
pub return_code: isize,
15+
}
16+
17+
#[derive(Copy, Clone)]
18+
pub struct AllowError {
19+
pub driver_number: usize,
20+
pub allow_number: usize,
21+
pub return_code: isize,
22+
}
23+
24+
pub const SUCCESS: isize = 0;
25+
pub const FAIL: isize = -1;
26+
pub const EBUSY: isize = -2;
27+
pub const EALREADY: isize = -3;
28+
pub const EINVAL: isize = -6;
29+
pub const ESIZE: isize = -7;
30+
pub const ENOMEM: isize = -9;
File renamed without changes.

src/syscalls/mod.rs renamed to core/src/syscalls/mod.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,5 @@
11
#[cfg_attr(target_arch = "riscv32", path = "platform_riscv32.rs")]
22
#[cfg_attr(target_arch = "arm", path = "platform_arm.rs")]
3-
#[cfg_attr(
4-
not(any(target_arch = "arm", target_arch = "riscv32")),
5-
path = "platform_mock.rs"
6-
)]
73
mod platform;
84

95
use crate::callback::CallbackSubscription;
File renamed without changes.
File renamed without changes.
File renamed without changes.

examples-alloc/alloc_error.rs

Lines changed: 0 additions & 16 deletions
This file was deleted.

examples-features/alloc_error.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Triggers the out-of-memory handler. Should print an error message.
2+
3+
#![no_std]
4+
#![feature(alloc_error_handler)]
5+
6+
extern crate alloc;
7+
8+
use alloc::vec::Vec;
9+
use core::alloc::Layout;
10+
use core::fmt::Write;
11+
use libtock::result::TockResult;
12+
use libtock::syscalls;
13+
14+
#[libtock::main]
15+
fn main() -> TockResult<()> {
16+
let mut vec = Vec::new();
17+
loop {
18+
vec.push(0);
19+
}
20+
}
21+
22+
#[alloc_error_handler]
23+
unsafe fn alloc_error_handler(_: Layout) -> ! {
24+
if let Ok(drivers) = libtock::retrieve_drivers() {
25+
let mut console = drivers.console.create_console();
26+
let _ = writeln!(console, "alloc_error_handler called");
27+
}
28+
loop {
29+
syscalls::raw::yieldk();
30+
}
31+
}
File renamed without changes.
File renamed without changes.

0 commit comments

Comments
 (0)