diff --git a/Cargo.toml b/Cargo.toml index 7115987c1..c8a465b67 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -112,7 +112,7 @@ exclude = [ [profile.release] codegen-units = 1 # 1 better optimizations debug = false -strip = true +strip = false lto = "fat" incremental = true #panic = "abort" # Remove panic output, which can reduce file size diff --git a/loader/assemble.ps1 b/loader/assemble.ps1 deleted file mode 100644 index a56afbec4..000000000 --- a/loader/assemble.ps1 +++ /dev/null @@ -1,18 +0,0 @@ -# remove existing blobs because otherwise this will append object files to the old blobs -Remove-Item -Force bin/*.a - -$crate = "xous-kernel" - -riscv64-unknown-elf-gcc -ggdb3 -c -mabi=ilp32 -march=rv32imac src/asm.S -o bin/$crate.o -riscv64-unknown-elf-ar crs bin/riscv32imac-unknown-none-elf.a bin/$crate.o -riscv64-unknown-elf-ar crs bin/riscv32imac-unknown-xous-elf.a bin/$crate.o -riscv64-unknown-elf-ar crs bin/riscv32imc-unknown-none-elf.a bin/$crate.o - -riscv64-unknown-elf-gcc -ggdb3 -c -mabi=ilp32 -march=rv32i src/asm.S -DSKIP_MULTICORE -o bin/$crate.o -riscv64-unknown-elf-ar crs bin/riscv32i-unknown-none-elf.a bin/$crate.o - -riscv64-unknown-elf-gcc -ggdb3 -c -mabi=lp64 -march=rv64imac src/asm.S -o bin/$crate.o -riscv64-unknown-elf-ar crs bin/riscv64imac-unknown-none-elf.a bin/$crate.o -riscv64-unknown-elf-ar crs bin/riscv64gc-unknown-none-elf.a bin/$crate.o - -Remove-Item bin/$crate.o diff --git a/loader/assemble.sh b/loader/assemble.sh deleted file mode 100755 index 62e2a7d13..000000000 --- a/loader/assemble.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/usr/bin/env bash - -set -euxo pipefail - -crate=xous-kernel - -# remove existing blobs because otherwise this will append object files to the old blobs -mkdir -p bin -rm -f bin/*.a - -riscv64-unknown-elf-gcc -ggdb3 -c -mabi=ilp32 -march=rv32imac src/asm.S -o bin/$crate.o -ar crs bin/riscv32imac-unknown-none-elf.a bin/$crate.o -ar crs bin/riscv32imac-unknown-xous-elf.a bin/$crate.o -ar crs bin/riscv32imc-unknown-none-elf.a bin/$crate.o - -riscv64-unknown-elf-gcc -ggdb3 -c -mabi=ilp32 -march=rv32i src/asm.S -DSKIP_MULTICORE -o bin/$crate.o -ar crs bin/riscv32i-unknown-none-elf.a bin/$crate.o - -riscv64-unknown-elf-gcc -ggdb3 -c -mabi=lp64 -march=rv64imac src/asm.S -o bin/$crate.o -ar crs bin/riscv64imac-unknown-none-elf.a bin/$crate.o -ar crs bin/riscv64gc-unknown-none-elf.a bin/$crate.o - -rm bin/$crate.o diff --git a/loader/bin/riscv32i-unknown-none-elf.a b/loader/bin/riscv32i-unknown-none-elf.a deleted file mode 100755 index e4622674b..000000000 Binary files a/loader/bin/riscv32i-unknown-none-elf.a and /dev/null differ diff --git a/loader/bin/riscv32imac-unknown-none-elf.a b/loader/bin/riscv32imac-unknown-none-elf.a deleted file mode 100755 index ef790b671..000000000 Binary files a/loader/bin/riscv32imac-unknown-none-elf.a and /dev/null differ diff --git a/loader/bin/riscv32imac-unknown-xous-elf.a b/loader/bin/riscv32imac-unknown-xous-elf.a deleted file mode 100644 index ef790b671..000000000 Binary files a/loader/bin/riscv32imac-unknown-xous-elf.a and /dev/null differ diff --git a/loader/bin/riscv32imc-unknown-none-elf.a b/loader/bin/riscv32imc-unknown-none-elf.a deleted file mode 100755 index ef790b671..000000000 Binary files a/loader/bin/riscv32imc-unknown-none-elf.a and /dev/null differ diff --git a/loader/bin/riscv64gc-unknown-none-elf.a b/loader/bin/riscv64gc-unknown-none-elf.a deleted file mode 100755 index 6ec46e5fb..000000000 Binary files a/loader/bin/riscv64gc-unknown-none-elf.a and /dev/null differ diff --git a/loader/bin/riscv64imac-unknown-none-elf.a b/loader/bin/riscv64imac-unknown-none-elf.a deleted file mode 100755 index 6ec46e5fb..000000000 Binary files a/loader/bin/riscv64imac-unknown-none-elf.a and /dev/null differ diff --git a/loader/build.rs b/loader/build.rs index 4a10e4160..5386b2fcc 100644 --- a/loader/build.rs +++ b/loader/build.rs @@ -7,17 +7,9 @@ use std::path::PathBuf; fn main() { let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap()); let target = env::var("TARGET").unwrap(); - let name = env::var("CARGO_PKG_NAME").unwrap(); if target.starts_with("riscv") { - fs::copy( - format!("bin/{}.a", target), - out_dir.join(format!("lib{}.a", name)), - ).unwrap(); - - println!("cargo:rustc-link-lib=static={}", name); println!("cargo:rustc-link-search={}", out_dir.display()); - println!("cargo:rerun-if-changed=bin/{}.a", target); println!("cargo:rustc-link-arg=-Tlink.x"); } diff --git a/loader/src/main.rs b/loader/src/main.rs index 2f158be24..0aeb007de 100644 --- a/loader/src/main.rs +++ b/loader/src/main.rs @@ -12,6 +12,7 @@ pub const BACKUP_ARGS_ADDR: usize = crate::platform::RAM_BASE + crate::platform: use core::num::NonZeroUsize; use core::{mem, ptr, slice}; +use core::arch::asm; pub type XousPid = u8; pub const PAGE_SIZE: usize = 4096; @@ -534,19 +535,115 @@ pub struct ProgramDescription { entrypoint: u32, } -extern "C" { - fn start_kernel( - args: usize, - ss: usize, - rpt: usize, - satp: usize, - entrypoint: usize, - stack: usize, - debug: bool, - resume: bool, - ) -> !; +#[link_section = ".text.init"] +#[export_name = "_start"] +pub extern "C" fn _start() { + unsafe { + asm! ( + "li t0, 0xffffffff", + "csrw mideleg, t0", + "csrw medeleg, t0", + + // decorate our stack area with a canary pattern + "li t1, 0xACE0BACE", + "li t0, 0x40FFE01C", // currently allowed stack extent - 8k - (7 words) - 7 words for kernel backup args - see bootloader in betrusted-soc + "li t2, 0x41000000", + "100:", // fillstack + "sw t1, 0(t0)", + "addi t0, t0, 4", + "bltu t0, t2, 100b", + + // Place the stack pointer at the end of RAM + "li t0, 0x40000000", // SRAM start hard-coded into loader -- don't trust kernel boot args to tell us where RAM is, we haven't validated them yet! + "li t1, 0x01000000", // SRAM length + "add sp, t0, t1", + + // Install a machine mode trap handler + "la t0, abort", + "csrw mtvec, t0", + + // Start Rust + "j rust_entry", + + options(noreturn) + ); + } } +#[link_section = ".text.init"] +#[export_name = "abort"] +/// This is only used in debug mode +pub extern "C" fn abort() { + unsafe { + asm! ( + "300:", // abort + "j 300b", + options(noreturn) + ); + } +} + +#[inline(never)] +#[export_name = "start_kernel"] +pub extern "C" fn start_kernel( + args: usize, + ss: usize, + rpt: usize, + satp: usize, + entrypoint: usize, + stack: usize, + debug_: bool, + resume_: bool, +) -> ! { + let debug: usize = if debug_ { 1 } else { 0 }; + let resume: usize = if resume_ { 1 } else { 0 }; + unsafe { + asm! ( + // these generate redundant mv's but it ensures that the arguments are marked as used + "mv a0, {args}", + "mv a1, {ss}", + "mv a2, {rpt}", + "mv a7, {resume}", + // Delegate as much as we can supervisor mode + "li t0, 0xffffffff", + "csrw mideleg, t0", + "csrw medeleg, t0", + + // Return to Supervisor mode (1 << 11) when we call `reti`. + // Disable interrupts (0 << 5) + "li t0, (1 << 11) | (0 << 5)", + // If arg6 is "true", also set mstatus.SUM to allow the kernel + // to access userspace memory. + "mv a6, {debug}", + "andi a6, a6, 1", + "slli a6, a6, 18", + "or t0, t0, a6", + "csrw mstatus, t0", + + // Enable the MMU (once we issue `mret`) and flush the cache + "csrw satp, {satp}", + "sfence.vma", + + // Return to the address pointed to by $a4 + "csrw mepc, {entrypoint}", + + // Reposition the stack at the offset passed by $a5 + "mv sp, {stack}", + + // Issue the return, which will jump to $mepc in Supervisor mode + "mret", + args = in(reg) args, + ss = in(reg) ss, + rpt = in(reg) rpt, + satp = in(reg) satp, + entrypoint = in(reg) entrypoint, + stack = in(reg) stack, + debug = in(reg) debug, + resume = in(reg) resume, + options(noreturn) + ); + } +} impl ProgramDescription { /// Map this ProgramDescription into RAM. @@ -1538,18 +1635,16 @@ fn boot_sequence(args: KernelArguments, _signature: u32) -> ! { let mut gpio_csr = CSR::new(utra::gpio::HW_GPIO_BASE as *mut u32); gpio_csr.wfo(utra::gpio::UARTSEL_UARTSEL, 1); // patch us over to a different UART for debug (1=LOG 2=APP, 0=KERNEL(hw reset default)) - unsafe { - start_kernel( - arg_offset, - ip_offset, - rpt_offset, - cfg.processes[0].satp, - cfg.processes[0].entrypoint, - cfg.processes[0].sp, - cfg.debug, - clean, - ); - } + start_kernel( + arg_offset, + ip_offset, + rpt_offset, + cfg.processes[0].satp, + cfg.processes[0].entrypoint, + cfg.processes[0].sp, + cfg.debug, + clean, + ); } else { #[cfg(feature="resume")] unsafe { @@ -1566,7 +1661,7 @@ fn boot_sequence(args: KernelArguments, _signature: u32) -> ! { println!("Adjusting SATP to the sures process. Was: 0x{:08x} now: 0x{:08x}", (*backup_args)[3], satp); #[cfg(not(feature = "renode-bypass"))] - if true { + { use utralib::generated::*; let mut gpio_csr = CSR::new(utra::gpio::HW_GPIO_BASE as *mut u32); gpio_csr.wfo(utra::gpio::UARTSEL_UARTSEL, 0); // patch us over to a different UART for debug (1=LOG 2=APP, 0=KERNEL(default))