xous-core/loader
bunnie c44f117331 fixes to udma SPIM for tx-only mode
- fix tx_await() condition to consider both control and tx channels
- make tx_async more efficient for the common case that the buffer
fits in a single transaction by appending the CS de-assert as part
of the initial command stream
- make trait for the udma global clock setting

The high bit in this exploration is that there seems to be no
way to actually confirm when a UDMA transaction has fully completed
on the hardware interface. All the completion signals tell you
when the software-side UDMA resources are freed up. However, in this
case, the hardware-side resources may still be transmitting/receiving
data.

This is a problem for the case of a '4-wire SPI' display where you
need to set an extra line to control command/data mode addressing.

In this case, the current work-around is to read back the state of
the chip select pin as a GPIO to determine when the hardware has
finished.

I suspect that if we can figure out how to use UDMA in a full duplex
mode that we could do something more essentially linked to the
hardware, but this would also require having a dummy Rx buffer allocated
that is the same depth as the hardware Tx buffer if all you cared about
is the hardware conclusion of a Tx.
2024-10-04 12:53:55 +08:00
..
bin loader: add asm binary and ix build script to pick ARM asm and link.x 2023-03-14 17:13:53 +04:00
curve25519-dalek-loader commit the version bump 2024-09-23 01:46:25 +08:00
ed25519-dalek-loader upgrade zeroize to latest API level 2024-02-08 14:02:58 +08:00
sha2-loader commit the version bump 2024-09-23 01:46:25 +08:00
src fixes to udma SPIM for tx-only mode 2024-10-04 12:53:55 +08:00
test
.gitignore
build.rs format loader 2024-01-14 22:02:55 +08:00
Cargo.toml fix formatting 2024-10-02 01:47:51 +08:00
LICENSE
link.x loader: remove unused imports 2023-03-14 17:15:17 +04:00
README.md chore: cleanup typos in docs, comments 2024-01-15 02:16:43 +08:00

Xous Stage 1 Loader

This contains the stage1 for Xous. This program is responsible for parsing the initial boot arguments, setting up memory maps, and preparing the kernel and its initial programs to run.

This program runs in Machine mode and has access to the entire system. When it jumps to the kernel, the system will be in Supervisor mode with no way to return to Machine mode.

Building

To build the stage-1 module, you will need a riscv32i-unknown-none-elf or riscv32imac-unknown-none-elf target for Rust.

  1. Decide what target you want. For simple, embedded systems this could be riscv32i-unknown-none-elf, and for more complex systems with compressed instructions you could use riscv32imac-unknown-none-elf.
  2. Get Rust. Go to https://rustup.rs/ and follow its instructions.
  3. Install the proper toolchain: rustup target add ${target_arch}
  4. Build the stage-1 loader: cargo build --release --target ${target_arch}
  5. Get an executable binary: riscv64-unknown-elf-gcc -O binary target/${target}/xous-stage1 xous-stage1.bin

If you have made changes to the assembly trampoline which sets up the loader, you will need to manually rebuild this, by running assemble.sh. This will replace a set of objects in the bin directory.

Using

This requires additional components in order to function:

  1. A kernel to run, and optionally additional init processes
  2. A kernel arguments structure to indicate memory regions
  3. A stage-0 bootloader to set up the arguments

The stage-0 bootloader needs to load the kernel arguments structure into memory at some address, then set register $a0 (also known as $x10 or R10 in RISC-V) to point there. It then needs to jump to that address.

For example, in Renode, this is accomplished with the following commands:

    sysbus LoadELF @../stage1/target/riscv32i-unknown-none-elf/debug/xous-stage1
    sysbus LoadBinary @../tools/args.bin 0x40800000
    # Set $a0 to point at the args binary
    cpu SetRegisterUnsafe 10 0x40800000
    cpu PC 0x20500000

There is no additional setup required.

Testing

Because xous-stage1 spends much of its time setting up pagetables for RV32, it depends on a system with 32-bit pointers. If you attempt to run it on a system with 64-bit pointers, it will panic.

The easy solution is to install a 32-bit toolchain and test with that. To get a list of possible toolchains, run rustc --print target-list and pick one that starts with i686-, armv7-, or some other 32-bit arch.

$ rustup target add i686-unknown-linux-musl
15:26:39 info: downloading component 'rust-std' for 'i686-unknown-linux-musl'
15:26:41 info: installing component 'rust-std' for 'i686-unknown-linux-musl'
$

To run tests, use cargo --test. For example:

❯ cargo test --target i686-pc-windows-msvc
   Compiling lazy_static v1.4.0
   Compiling xous-stage1 v0.1.0 (D:\\Code\\Xous\\stage1)
    Finished test [unoptimized + debuginfo] target(s) in 6.32s
     Running target\\i686-pc-windows-msvc\\debug\\deps\\xous_stage1-4e16f995c7c21520.exe

running 6 tests
test test::copy_processes ... ok
test test::full_boot ... ok
test test::allocate_regions ... ok
test test::parse_args_bin ... ok
test test::read_initial_config ... ok
test test::tracker_sane ... ok

test result: ok. 6 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out

❯

Contribution Guidelines

Contributor
Covenant

Please see CONTRIBUTING for details on how to make a contribution.

Please note that this project is released with a Contributor Code of Conduct. By participating in this project you agree to abide its terms.

License

Copyright © 2020

Licensed under the Apache License 2.0 LICENSE