Browse Source

Update documentation

Vadim Kaushan 5 năm trước cách đây
mục cha
commit
6d144111f3
2 tập tin đã thay đổi với 82 bổ sung29 xóa
  1. 2 2
      riscv-rt/link.x
  2. 80 27
      riscv-rt/src/lib.rs

+ 2 - 2
riscv-rt/link.x

@@ -14,8 +14,8 @@ PROVIDE(__pre_init = default_pre_init);
 /* # Multi-processing hook function
    fn _mp_hook() -> bool;
 
-   This function is called from all the harts and should return true only for one hart,
-   which will perform memory initialization. For other harts it should return false
+   This function is called from all the harts and must return true only for one hart,
+   which will perform memory initialization. For other harts it must return false
    and implement wake-up in platform-dependent way (e.g. after waiting for a user interrupt).
 */
 PROVIDE(_mp_hook = default_mp_hook);

+ 80 - 27
riscv-rt/src/lib.rs

@@ -13,14 +13,14 @@
 //!
 //! - Before main initialization of the `.bss` and `.data` sections.
 //!
-//! - Before main initialization of the FPU (for targets that have a FPU).
-//!
 //! - `#[entry]` to declare the entry point of the program
 //! - `#[pre_init]` to run code *before* `static` variables are initialized
 //!
 //! - A linker script that encodes the memory layout of a generic RISC-V
 //!   microcontroller. This linker script is missing some information that must
-//!   be supplied through a `memory.x` file (see example below).
+//!   be supplied through a `memory.x` file (see example below). This file
+//!   must be supplied using rustflags and listed *before* `link.x`. Arbitrary
+//!   filename can be use instead of `memory.x`.
 //!
 //! - A `_sheap` symbol at whose address you can locate a heap.
 //!
@@ -37,11 +37,17 @@
 //! $ edit memory.x && cat $_
 //! MEMORY
 //! {
-//!   /* NOTE K = KiBi = 1024 bytes */
-//!   FLASH : ORIGIN = 0x20000000, LENGTH = 16M
 //!   RAM : ORIGIN = 0x80000000, LENGTH = 16K
+//!   FLASH : ORIGIN = 0x20000000, LENGTH = 16M
 //! }
 //!
+//! REGION_ALIAS("REGION_TEXT", FLASH);
+//! REGION_ALIAS("REGION_RODATA", FLASH);
+//! REGION_ALIAS("REGION_DATA", RAM);
+//! REGION_ALIAS("REGION_BSS", RAM);
+//! REGION_ALIAS("REGION_HEAP", RAM);
+//! REGION_ALIAS("REGION_STACK", RAM);
+//!
 //! $ edit src/main.rs && cat $_
 //! ```
 //!
@@ -66,7 +72,8 @@
 //! $ mkdir .cargo && edit .cargo/config && cat $_
 //! [target.riscv32imac-unknown-none-elf]
 //! rustflags = [
-//!   "-C", "link-arg=-Tlink.x"
+//!   "-C", "link-arg=-Tmemory.x",
+//!   "-C", "link-arg=-Tlink.x",
 //! ]
 //!
 //! [build]
@@ -124,14 +131,27 @@
 //!
 //! The main information that this file must provide is the memory layout of
 //! the device in the form of the `MEMORY` command. The command is documented
-//! [here][2], but at a minimum you'll want to create two memory regions: one
-//! for Flash memory and another for RAM.
+//! [here][2], but at a minimum you'll want to create at least one memory region.
 //!
 //! [2]: https://sourceware.org/binutils/docs/ld/MEMORY.html
 //!
-//! The program instructions (the `.text` section) will be stored in the memory
-//! region named FLASH, and the program `static` variables (the sections `.bss`
-//! and `.data`) will be allocated in the memory region named RAM.
+//! To support different relocation models (RAM-only, FLASH+RAM) multiple regions are used:
+//!
+//! - `REGION_TEXT` - for `.init`, `.trap` and `.text` sections
+//! - `REGION_RODATA` - for `.rodata` section and storing initial values for `.data` section
+//! - `REGION_DATA` - for `.data` section
+//! - `REGION_BSS` - for `.bss` section
+//! - `REGION_HEAP` - for the heap area
+//! - `REGION_STACK` - for hart stacks
+//!
+//! Specific aliases for these regions must be defined in `memory.x` file (see example below).
+//!
+//! ### `_stext`
+//!
+//! This symbol provides the loading address of `.text` section. This value can be changed
+//! to override the loading address of the firmware (for example, in case of bootloader present).
+//!
+//! If omitted this symbol value will default to `ORIGIN(REGION_TEXT)`.
 //!
 //! ### `_stack_start`
 //!
@@ -140,25 +160,49 @@
 //! valid RAM address plus one (this *is* an invalid address but the processor
 //! will decrement the stack pointer *before* using its value as an address).
 //!
-//! If omitted this symbol value will default to `ORIGIN(RAM) + LENGTH(RAM)`.
+//! In case of multiple harts present, this address defines the initial stack pointer for hart 0.
+//! Stack pointer for hart `N` is calculated as  `_stack_start - N * _hart_stack_size`.
+//!
+//! If omitted this symbol value will default to `ORIGIN(REGION_STACK) + LENGTH(REGION_STACK)`.
 //!
 //! #### Example
 //!
 //! Allocating the call stack on a different RAM region.
 //!
-//! ```
+//! ``` text
 //! MEMORY
 //! {
-//!   /* call stack will go here */
-//!   CCRAM : ORIGIN = 0x10000000, LENGTH = 8K
-//!   FLASH : ORIGIN = 0x08000000, LENGTH = 256K
-//!   /* static variables will go here */
-//!   RAM : ORIGIN = 0x20000000, LENGTH = 40K
+//!   L2_LIM : ORIGIN = 0x08000000, LENGTH = 1M
+//!   RAM : ORIGIN = 0x80000000, LENGTH = 16K
+//!   FLASH : ORIGIN = 0x20000000, LENGTH = 16M
 //! }
 //!
-//! _stack_start = ORIGIN(CCRAM) + LENGTH(CCRAM);
+//! REGION_ALIAS("REGION_TEXT", FLASH);
+//! REGION_ALIAS("REGION_RODATA", FLASH);
+//! REGION_ALIAS("REGION_DATA", RAM);
+//! REGION_ALIAS("REGION_BSS", RAM);
+//! REGION_ALIAS("REGION_HEAP", RAM);
+//! REGION_ALIAS("REGION_STACK", L2_LIM);
+//!
+//! _stack_start = ORIGIN(L2_LIM) + LENGTH(L2_LIM);
 //! ```
 //!
+//! ### `_max_hart_id`
+//!
+//! This symbol defines the maximum hart id suppoted. All harts with id
+//! greater than `_max_hart_id` will be redirected to `abort()`.
+//!
+//! This symbol is supposed to be redefined in platform support crates for
+//! multi-core targets.
+//!
+//! If omitted this symbol value will default to 0 (single core).
+//!
+//! ### `_hart_stack_size`
+//!
+//! This symbol defines stack area size for *one* hart.
+//!
+//! If omitted this symbol value will default to 2K.
+//!
 //! ### `_heap_size`
 //!
 //! This symbol provides the size of a heap region. The default value is 0. You can set `_heap_size`
@@ -172,7 +216,7 @@
 //!
 //! #### Example
 //!
-//! ```
+//! ``` no_run
 //! extern crate some_allocator;
 //!
 //! extern "C" {
@@ -189,13 +233,22 @@
 //! }
 //! ```
 //!
-//! ## `pre_init!`
+//! ### `_mp_hook`
+//!
+//! This function is called from all the harts and must return true only for one hart,
+//! which will perform memory initialization. For other harts it must return false
+//! and implement wake-up in platform-dependent way (e.g. after waiting for a user interrupt).
 //!
-//! A user-defined function can be run at the start of the reset handler, before RAM is
-//! initialized. The macro `pre_init!` can be called to set the function to be run. The function is
-//! intended to perform actions that cannot wait the time it takes for RAM to be initialized, such
-//! as disabling a watchdog. As the function is called before RAM is initialized, any access of
-//! static variables will result in undefined behavior.
+//! This function can be redefined in the following way:
+//!
+//! ``` no_run
+//! #[export_name = "_mp_hook"]
+//! pub extern "Rust" fn mp_hook() -> bool {
+//!    // ...
+//! }
+//! ```
+//!
+//! Default implementation of this function wakes hart 0 and busy-loops all the other harts.
 
 // NOTE: Adapted from cortex-m/src/lib.rs
 #![no_std]
@@ -281,7 +334,7 @@ pub extern "C" fn start_trap_rust() {
 }
 
 
-/// Default Trap Handler
+#[doc(hidden)]
 #[no_mangle]
 pub fn default_trap_handler() {}