|
@@ -1,6 +1,6 @@
|
|
|
# RustSBI platforms
|
|
|
|
|
|
-Currently supported platforms:
|
|
|
+Currently provided reference platform support projects:
|
|
|
|
|
|
| Platform | Legacy | Base | IPI | Timer | RFENCE | HSM | SRST | Note |
|
|
|
|:---------|:------:|:----:|:---:|:-----:|:------:|:---:|:----:|:-----|
|
|
@@ -9,11 +9,107 @@ Currently supported platforms:
|
|
|
|
|
|
P: Pending
|
|
|
|
|
|
-## Notes
|
|
|
+## Notes for binary releases
|
|
|
|
|
|
These platforms implementations are only for reference.
|
|
|
Although binaries are released along with RustSBI library itself,
|
|
|
platform developers should consider using RustSBI as a library,
|
|
|
other than adding code into forked project's 'platforms' and make a pull request.
|
|
|
|
|
|
-A reference platform implementation using RustSBI can be found at [shady831213/terminus_bl](https://github.com/shady831213/terminus_bl).
|
|
|
+## Support your own platform
|
|
|
+
|
|
|
+There are RISC-V cores, SoC's, and boards, we can not support them one by one with any software,
|
|
|
+typically platform vendor should provide their own SBI support package.
|
|
|
+RustSBI is designed as a 'building block' library to help on these support packages.
|
|
|
+
|
|
|
+To implement for their own platforms, vendor would typically follow these steps:
|
|
|
+
|
|
|
+1. Pick an RISC-V software runtime
|
|
|
+2. Initialize SBI functions into RustSBI
|
|
|
+3. Add additional support features
|
|
|
+
|
|
|
+### Pick a runtime
|
|
|
+
|
|
|
+When the processor is powering up, it executes few instructions to jump to a processor specific entry address.
|
|
|
+Your SBI implementation should be there, ready to be executed to prepare an environment for Rust code
|
|
|
+and interrupt environment.
|
|
|
+
|
|
|
+This runtime should contain two parts: programming language runtime and interrupt handler.
|
|
|
+Typically, processor vendor or SoC vendor should provide with a minimal runtime.
|
|
|
+Or else, [`riscv-rt`](https://github.com/rust-embedded/riscv-rt) project would be okay to be a runtime
|
|
|
+for all RISC-V chips, this project is provided by community to minimally support Rust language on
|
|
|
+standard RISC-V hardware.
|
|
|
+
|
|
|
+If we have to write own runtime, the runtime should initialize `bss` and `data` sections.
|
|
|
+Crate [`r0`](https://github.com/rust-embedded/r0) would help a lot if we do this work manually.
|
|
|
+
|
|
|
+When you begin to work with custom hardware e.g. interrupt controller, you should use vendor
|
|
|
+provided platform specific packages. Load trap configurations into registers in vendor defined procedures.
|
|
|
+This will provide a machine level trap handler for SBI implementation.
|
|
|
+
|
|
|
+After you pick a runtime, there should be one main entry function and a trap entry function.
|
|
|
+
|
|
|
+### Initialize and use SBI functions
|
|
|
+
|
|
|
+All SBI modules in RustSBI are described as Rust traits. Read RISC-V SBI manual carefully,
|
|
|
+or research on the operating systems you want to support to make a list of modules your SBI should support.
|
|
|
+
|
|
|
+Although it's a legacy function, `console_putchar` function by now is commonly used as an early debug output.
|
|
|
+Use an on-board serial transmitter half, or other ways to implemenet this function's corresponding Rust trait.
|
|
|
+Then, use `init_legacy_stdio` etc. to load this module into RustSBI. RustSBI's documentation lists all these
|
|
|
+traits that RustSBI supports.
|
|
|
+
|
|
|
+Basical function like `mvendorid` and module detections are handled by RustSBI.
|
|
|
+After the modules are initialized, RustSBI automatically implement module detection functions
|
|
|
+and provide an `ecall` handler. You should use this `ecall` handler in runtime defined trap handler,
|
|
|
+see documentation of `rustsbi::ecall` for details.
|
|
|
+
|
|
|
+RustSBI implmenetaion may print `rustsbi::LOGO` and `misa` onto early debug screen.
|
|
|
+There are also some functions in trap handler and entry which a typical SBI implmentation would write.
|
|
|
+Here's a checklist of these functions:
|
|
|
+
|
|
|
+- Delegate exceptions and interrupts to S privilege in `medeleg` and `mideleg`;
|
|
|
+- Emulate `rdtime` instruction in illegal instruction exception;
|
|
|
+- Raise invalid instruction to supervisor if `mstatus::MPP` is not `Machine`.
|
|
|
+
|
|
|
+When we write code for SBI functions, `embedded-hal` packages would be helpful.
|
|
|
+Some of these packages provide a universal abstract for SoC peripherals and are normally provided by SoC vendor.
|
|
|
+If our board uses peripheral outside the SoC, other packages would come into effect.
|
|
|
+
|
|
|
+After SBI functions are written, you should use `enter_privileged` function provided by RustSBI.
|
|
|
+This function uses an entry address of operating system where RustSBI would change privilege level
|
|
|
+and jump into. It would also requires a second opaque parameter that the OS would make use of.
|
|
|
+Now your operating system should boot up and function normally. Congratulations!
|
|
|
+
|
|
|
+### Additional support features
|
|
|
+
|
|
|
+Your prototype bootloader is functional now, to complete its design you may provide more features
|
|
|
+as a software product.
|
|
|
+
|
|
|
+On PC, SBI software would be flashed onto unique flash or small MCU to help boot the processor.
|
|
|
+The processor may be upgraded or replaced. You should check if the processor and its memory is okay.
|
|
|
+Pick or design a small program to check all RISC-V registers, instructions to check if the processor
|
|
|
+is not broken and is ready to run operating system.
|
|
|
+
|
|
|
+According to your platform, there could be a minimal hardware requirement. Personal computer platform
|
|
|
+may require a graphic hardware to boot, you should scan if your processor or board provides one graphic
|
|
|
+hardware. Scan other hardware to prepare for later boot sequences, like setting CPU clocks.
|
|
|
+
|
|
|
+The operating system could be placed anywhere. According to your platform, you may scan for storage
|
|
|
+or connect to the Internet for a functional operating system kernel. Fetch the kernel and provide
|
|
|
+its entry address into `enter_privileged` as mentioned above.
|
|
|
+If multiple operating systems are present, provide a user interface to help your user to select which
|
|
|
+kernel we should boot.
|
|
|
+
|
|
|
+During boot procedure, provide a way to debug hardware errors. For servers and developers,
|
|
|
+activate your on-board buzzer, or provide a debug interface like JTAG to tell where the error comes from.
|
|
|
+For DIY users and overclockers, you may provide EZDebug lights on your board and use SBI to control them.
|
|
|
+
|
|
|
+A full boot sequence may be different on different vendors, and wrong settings on boot sequence can be
|
|
|
+hard to debug. Read its manual carefully or consult the vendor to work out common bugs.
|
|
|
+
|
|
|
+## Reference
|
|
|
+
|
|
|
+Implement your SBI platform is easy! There exists some reference implementations in addition to this repository.
|
|
|
+
|
|
|
+- `terminus_bl` project is a RustSBI implementation for `terminus` emulator: [shady831213/terminus_bl](https://github.com/shady831213/terminus_bl).
|