Skip to content

Commit eef90a0

Browse files
committed
Implement r0 crate in assembly
This implements the `r0::init_data` and `r0::zero_bss` routines in assembly. There is a generic implementation for `riscv32` and `riscv64`, since `riscv64` deals with alignment problems. The routines are kept at their old calling site so that only one hardware thread calls them. Consequently they are also inlined into the `start_rust` function. [Issue #122]
1 parent db136b8 commit eef90a0

File tree

3 files changed

+48
-17
lines changed

3 files changed

+48
-17
lines changed

riscv-rt/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ s-mode = []
1515
single-hart = []
1616

1717
[dependencies]
18-
r0 = "1.0.0"
1918
riscv = "0.10"
2019
riscv-rt-macros = { path = "macros", version = "0.2.0" }
2120

riscv-rt/link.x

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ SECTIONS
8484
_edata = .;
8585
} > REGION_DATA AT > REGION_RODATA
8686

87-
.bss (NOLOAD) :
87+
.bss (NOLOAD) : ALIGN(4)
8888
{
8989
_sbss = .;
9090
*(.sbss .sbss.* .bss .bss.*);

riscv-rt/src/lib.rs

Lines changed: 47 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,8 @@
366366
#[cfg(riscv)]
367367
mod asm;
368368

369+
use core::sync::atomic::{compiler_fence, Ordering};
370+
369371
#[cfg(feature = "s-mode")]
370372
use riscv::register::{scause as xcause, stvec as xtvec, stvec::TrapMode as xTrapMode};
371373

@@ -378,19 +380,6 @@ pub use riscv_rt_macros::{entry, pre_init};
378380
#[doc(hidden)]
379381
pub static __ONCE__: () = ();
380382

381-
extern "C" {
382-
// Boundaries of the .bss section
383-
static mut _ebss: u32;
384-
static mut _sbss: u32;
385-
386-
// Boundaries of the .data section
387-
static mut _edata: u32;
388-
static mut _sdata: u32;
389-
390-
// Initial values of the .data section (stored in Flash)
391-
static _sidata: u32;
392-
}
393-
394383
/// Rust entry point (_start_rust)
395384
///
396385
/// Zeros bss section, initializes data section and calls main. This function never returns.
@@ -424,8 +413,51 @@ pub unsafe extern "C" fn start_rust(a0: usize, a1: usize, a2: usize) -> ! {
424413
if _mp_hook(hartid) {
425414
__pre_init();
426415

427-
r0::zero_bss(&mut _sbss, &mut _ebss);
428-
r0::init_data(&mut _sdata, &mut _edata, &_sidata);
416+
// Initialize RAM (32-bit version)
417+
// 1. Copy over .data from flash to RAM
418+
// 2. Zero out .bss
419+
core::arch::asm!(
420+
"
421+
// Copy over .data
422+
la {start},_sdata
423+
la {end},_edata
424+
la {input},_sidata
425+
426+
1:
427+
addi {a},{start},4
428+
bgeu {a},{end},1f
429+
lw {b},0({input})
430+
sw {b},0({start})
431+
addi {start},{start},4
432+
addi {input},{input},4
433+
j 1b
434+
435+
1:
436+
// Zero out .bss
437+
la {start},_sbss
438+
la {end},_ebss
439+
440+
2:
441+
addi {a},{start},4
442+
bgeu {a},{end},2f
443+
sw zero,0({start})
444+
addi {start},{start},4
445+
j 2b
446+
447+
2:
448+
449+
li {start},0
450+
li {end},0
451+
li {input},0
452+
",
453+
start = out(reg) _,
454+
end = out(reg) _,
455+
input = out(reg) _,
456+
a = out(reg) _,
457+
b = out(reg) _,
458+
);
459+
460+
compiler_fence(Ordering::SeqCst);
429461
}
430462

431463
// TODO: Enable FPU when available

0 commit comments

Comments
 (0)