Skip to content

Commit

Permalink
Merge branch 'main' into oreboot-bl808
Browse files Browse the repository at this point in the history
  • Loading branch information
orangecms committed Oct 16, 2023
2 parents e6374e6 + 408b431 commit 9230565
Show file tree
Hide file tree
Showing 63 changed files with 2,738 additions and 381 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,6 @@ Cargo.lock

# Ignore all intellij related files
*.idea

# gdb history files
.gdb_history
3 changes: 1 addition & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ members = [

"src/lib/consts",
"src/lib/util",
"src/lib/layoutflash",

"src/mainboard/sipeed/m1s-dock/*",
"src/mainboard/starfive/visionfive1/*",
Expand All @@ -16,8 +17,6 @@ members = [
"src/mainboard/emulation/*",

"xtask",

"tools/layoutflash",
]
default-members = ["xtask"]

Expand Down
22 changes: 14 additions & 8 deletions Documentation/boot-flow.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,19 @@ In the second stage, we are all set, and depending on the platform, we could
already run the final OS, a hypervisor, or any other payload. However, some
platforms require extra steps. For this example, we will look at RISC-V.

RISC-V describes [SBI](https://github.com/riscv-non-isa/riscv-sbi-doc), the
Supervisor Binary Interface, in the [privileged spec](https://riscv.org/technical/specifications/). The role of SBI is to set up or
delegate exception and interrupt handling, register functions for the OS to call
into, and drop into a lower privileged mode named S-mode which makes an [MMU](https://en.wikipedia.org/wiki/Memory_management_unit) available, and finally
execute the operating system. This is where we hand over to LinuxBoot, our
boot loader environment. In oreboot, we implement SBI via [RustSBI](https://github.com/rustsbi/rustsbi), a Rust crate offering all the necessary
functions we need as a library.
RISC-V mentions SBI, the Supervisor Binary Interface, in the ISA spec Volume 2,
[Privileged Specification](https://riscv.org/technical/specifications/). It now
evolves as [SBI specifcation](https://github.com/riscv-non-isa/riscv-sbi-doc).

The role of SBI is to set up or delegate exception and interrupt handling,
register functions for the OS to call into, and drop into a lower privileged
mode named S-mode. While having less access to the hardware, it makes an [MMU](https://en.wikipedia.org/wiki/Memory_management_unit) with [paged virtual memory](https://www.sifive.com/blog/all-aboard-part-9-paging-and-mmu-in-risc-v-linux-kernel)
available. RISC-V complements this in the (UNIX-class) [platform specification](https://github.com/riscv/riscv-platform-spec).

Finally, in S-mode, we execute the operating system. This is where we hand over
to [LinuxBoot](https://linuxboot.org), our boot loader environment. In oreboot,
we implement SBI via [RustSBI](https://github.com/rustsbi/rustsbi), a Rust crate
offering all the necessary functions we need as a library.

### Stage 3: Payload (LinuxBoot)

Expand All @@ -67,6 +73,6 @@ embed [cpud](https://github.com/u-root/cpu) directly, or your own custom app.

There are components on a compute platform that can be scanned for and detected
by the operating system, and others that need a fixed description instead. Those
can be passed to Linux and some other systems in the aforementioned [Device Treeformat](https://www.devicetree.org/). On RISC-V, the DTB needs to sit _behind_
can be passed to Linux and some other systems in the aforementioned [Device Tree format](https://www.devicetree.org/). On RISC-V, the DTB needs to sit _behind_
the Linux kernel, and its memory location passed via defined registers. On some
platforms, e.g., x86, [ACPI](https://uefi.org/specs/ACPI/6.4/) is used instead.
25 changes: 17 additions & 8 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,13 @@ help:
# Turn them all off. We'll turn them back on to try to get to working tests.
MAINBOARDS := $(wildcard src/mainboard/*/*/Makefile)

BINUTILS_VER := 0.3.4
STACK_SIZES_VER := 0.4.0
TARPAULIN_VER := 0.19.1
DPRINT_VER := 0.36.1
# NOTE: These are the host utilities, requiring their own recent Rust version.
RUST_VER := 1.73
BINUTILS_VER := 0.3.6
TARPAULIN_VER := 0.27.1
DPRINT_VER := 0.41.0

CARGOINST := rustup run --install 1.67 cargo install
CARGOINST := rustup run --install $(RUST_VER) cargo install

.PHONY: $(MAINBOARDS)
mainboards: $(MAINBOARDS)
Expand All @@ -32,19 +33,27 @@ $(MAINBOARDS):

firsttime:
$(CARGOINST) $(if $(BINUTILS_VER),--version $(BINUTILS_VER),) cargo-binutils
$(CARGOINST) $(if $(STACK_SIZES_VER),--version $(STACK_SIZES_VER),) stack-sizes
$(CARGOINST) $(if $(TARPAULIN_VER),--version $(TARPAULIN_VER),) cargo-tarpaulin
$(CARGOINST) $(if $(DPRINT_VER),--version $(DPRINT_VER),) dprint

nexttime:
$(CARGOINST) --force $(if $(BINUTILS_VER),--version $(BINUTILS_VER),) cargo-binutils
$(CARGOINST) --force $(if $(STACK_SIZES_VER),--version $(STACK_SIZES_VER),) stack-sizes
$(CARGOINST) --force $(if $(TARPAULIN_VER),--version $(TARPAULIN_VER),) cargo-tarpaulin
$(CARGOINST) --force $(if $(DPRINT_VER),--version $(DPRINT_VER),) dprint


debiansysprepare:
sudo apt-get install device-tree-compiler pkg-config libssl-dev llvm-dev libclang-dev clang qemu-system-x86
sudo apt-get install \
device-tree-compiler \
pkg-config \
libssl-dev \
llvm-dev \
libclang-dev \
clang \
qemu-system-x86 \
binutils-riscv64-unknown-elf \
libudev-dev \

# -y makes it non-interactive.
curl https://sh.rustup.rs -sSf | sh -s -- -y

Expand Down
3 changes: 2 additions & 1 deletion Makefile.mainboard.inc
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ $(shell echo "BOARD = $(BOARD)" 1>&2)

$(IMAGE): $(BOOTBLOB) $(FIXED_DTFS)
# These two environment variable parameters are used in fixed-dtfs.dts
BOOTBLOB=$(BOOTBLOB) FIXED_DTFS=$(FIXED_DTFS) echo NOT doing 'cargo run --target $(TOOLS_TARGET) --manifest-path $(TOOLS_DIR)/layoutflash/Cargo.toml -- $(FIXED_DTFS) $@'
echo "Not running layoutflash any more, it needs to be in xtask"
BOOTBLOB=$(BOOTBLOB) FIXED_DTFS=$(FIXED_DTFS) echo NOT cargo run --target $(TOOLS_TARGET) --manifest-path $(TOOLS_DIR)/layoutflash/Cargo.toml -- $(FIXED_DTFS) $@
@printf "**\n** Output: $@\n**\n"

$(BOOTBLOB): $(ELF)
Expand Down
14 changes: 9 additions & 5 deletions dprint.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
{
"exec": {
"commands": [{
"command": "rustfmt --edition 2021",
"exts": ["rs"]
}]
},
"json": {
},
"markdown": {
},
"rustfmt": {
},
"toml": {
},
"includes": ["**/*.{json,md,toml,rs}"],
Expand All @@ -14,9 +18,9 @@
"3rdparty/"
],
"plugins": [
"https://plugins.dprint.dev/rustfmt-0.6.2.json@886c6f3161cf020c2d75160262b0f56d74a521e05cfb91ec4f956650c8ca76ca",
"https://plugins.dprint.dev/json-0.16.0.wasm",
"https://plugins.dprint.dev/markdown-0.14.1.wasm",
"https://plugins.dprint.dev/exec-0.4.3.json@42343548b8022c99b1d750be6b894fe6b6c7ee25f72ae9f9082226dd2e515072",
"https://plugins.dprint.dev/json-0.17.1.wasm",
"https://plugins.dprint.dev/markdown-0.15.2.wasm",
"https://plugins.dprint.dev/toml-0.5.4.wasm"
]
}
2 changes: 1 addition & 1 deletion rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[toolchain]
channel = "nightly-2023-03-03"
channel = "nightly-2023-10-13"
components = ["rust-src", "llvm-tools-preview", "rustfmt", "clippy"]
targets = [
"aarch64-unknown-none-softfloat",
Expand Down
9 changes: 6 additions & 3 deletions src/arch/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,12 @@ authors = ["Oreboot Authors"]
edition = "2021"

[dependencies]
consts = { path = "../lib/consts" }
util = { path = "../lib/util" }
vcell = "0.1.3"
log = { path = "../lib/log" }

# RISC-V
riscv = { version = "=0.10.1", features = ["critical-section-single-hart"] }
rustsbi = { version = "0.3.2", features = ["legacy"] }
sbi-spec = { version = "0.0.4", features = ["legacy"] }

[features]
riscv64 = []
4 changes: 2 additions & 2 deletions src/arch/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#![feature(asm_const)]
#![feature(naked_functions)]
#![feature(generator_trait)]
#![no_std]

#[cfg(feature = "powerpc64")]
pub mod ppc64;
#[cfg(feature = "riscv64")]
pub mod riscv64;
3 changes: 0 additions & 3 deletions src/arch/src/ppc64/mod.rs

This file was deleted.

22 changes: 6 additions & 16 deletions src/arch/src/riscv64/mod.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,7 @@
use core::arch::asm;

pub fn halt() -> ! {
loop {
// Bug with LLVM marks empty loops as undefined behaviour.
// See: https://github.com/rust-lang/rust/issues/28728
unsafe { asm!("wfi") }
}
}

pub fn fence() {
unsafe { asm!("fence") }
}

pub fn nop() {
unsafe { asm!("nop") }
pub mod sbi {
pub mod execute;
pub mod feature;
pub mod hart_csr_utils;
pub mod info;
pub mod runtime;
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
use crate::feature;
use crate::runtime::{MachineTrap, Runtime, SupervisorContext};
use super::feature;
use super::runtime::{MachineTrap, Runtime, SupervisorContext};
use core::{
arch::asm,
ops::{Generator, GeneratorState},
pin::Pin,
};
use log::{print, println};
use riscv::register::mip;
use riscv::register::scause::{Exception, Trap};
use rustsbi::println;
use rustsbi::spec::binary::SbiRet;
use sbi_spec::legacy::LEGACY_CONSOLE_PUTCHAR;

const ECALL_OREBOOT: usize = 0x0A023B00;
const EBREAK: u16 = 0x9002;
const DEBUG: bool = false;

Expand All @@ -21,7 +23,7 @@ fn ore_sbi(method: usize, args: [usize; 6]) -> SbiRet {
let mut err = 0;
let csr = args[0];
if dbg {
println!("[rustsbi] read CSR {:x}\r", csr);
println!("[rustsbi] read CSR {:x}", csr);
}
match csr {
0x7c0 => unsafe {
Expand All @@ -41,7 +43,7 @@ fn ore_sbi(method: usize, args: [usize; 6]) -> SbiRet {
}
}
if dbg {
println!("[rustsbi] CSR {:x} is {:08x}, err {:x}\r", csr, val, err);
println!("[rustsbi] CSR {:x} is {:08x}, err {:x}", csr, val, err);
}
SbiRet {
value: val,
Expand All @@ -52,21 +54,28 @@ fn ore_sbi(method: usize, args: [usize; 6]) -> SbiRet {
}
}

fn putchar(method: usize, args: [usize; 6]) -> SbiRet {
let char = args[0] as u8 as char;
print!("{char}");
SbiRet { value: 0, error: 0 }
}

pub fn execute_supervisor(supervisor_mepc: usize, a0: usize, a1: usize) -> (usize, usize) {
let mut rt = Runtime::new_sbi_supervisor(supervisor_mepc, a0, a1);
loop {
// NOTE: `resume()` drops into S-mode by calling `mret` (asm) eventually
match Pin::new(&mut rt).resume(()) {
GeneratorState::Yielded(MachineTrap::SbiCall()) => {
let ctx = rt.context_mut();
// specific for 1.9.1; see document for details
feature::preprocess_supervisor_external(ctx);
let param = [ctx.a0, ctx.a1, ctx.a2, ctx.a3, ctx.a4, ctx.a5];
let ans = match ctx.a7 {
0x0A023B00 => ore_sbi(ctx.a6, param),
ECALL_OREBOOT => ore_sbi(ctx.a6, param),
LEGACY_CONSOLE_PUTCHAR => putchar(ctx.a6, param),
_ => {
// if not sbi putchar
if ctx.a7 != 0x1 && DEBUG {
println!("[rustsbi] ecall {:x}\r", ctx.a6);
if ctx.a7 != LEGACY_CONSOLE_PUTCHAR && DEBUG {
println!("[rustsbi] ecall {:x}", ctx.a6);
}
rustsbi::ecall(ctx.a7, ctx.a6, param)
}
Expand All @@ -87,7 +96,7 @@ pub fn execute_supervisor(supervisor_mepc: usize, a0: usize, a1: usize) -> (usiz
// dump context on breakpoints for debugging
// TODO: how would we allow for "real" debugging?
if DEBUG {
println!("[rustsbi] Take an EBREAK!\r {:#04X?}\r", ctx);
println!("[rustsbi] Take an EBREAK!\r {:#04X?}", ctx);
}
// skip instruction; this will likely cause the OS to crash
// use DEBUG to get actual information
Expand All @@ -100,7 +109,7 @@ pub fn execute_supervisor(supervisor_mepc: usize, a0: usize, a1: usize) -> (usiz
Trap::Exception(Exception::IllegalInstruction),
)
} else {
println!("[rustsbi] Na na na! {:#04X?}\r", ctx);
println!("[rustsbi] Na na na! {:#04X?}", ctx);
fail_illegal_instruction(ctx, ins)
}
}
Expand All @@ -111,7 +120,7 @@ pub fn execute_supervisor(supervisor_mepc: usize, a0: usize, a1: usize) -> (usiz
GeneratorState::Yielded(MachineTrap::MachineTimer()) => {
// TODO: Check if this actually works
if DEBUG {
println!("M timer int\r");
println!("M timer int");
}
unsafe {
mip::set_stimer();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::runtime::SupervisorContext;
use super::super::runtime::SupervisorContext;
use core::arch::asm;
use log::println;
use riscv::register::cycle;
use rustsbi::println;

const DEBUG_THIS: bool = false;

Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::runtime::SupervisorContext;
use super::super::runtime::SupervisorContext;
use core::arch::asm;
use riscv::register::{mstatus, satp};

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::runtime::SupervisorContext;
use super::super::runtime::SupervisorContext;
use riscv::register::{mie, mip};

static mut DEVINTRENTRY: usize = 0;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use crate::runtime::SupervisorContext;
use super::super::runtime::SupervisorContext;
use log::println;
use riscv::register::{
mstatus::{self, MPP, SPP},
mtval, scause, sepc, stval, stvec,
};
use rustsbi::println;

pub unsafe fn should_transfer_trap(ctx: &mut SupervisorContext) -> bool {
ctx.mstatus.mpp() != MPP::Machine
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use log::{print, println};
use riscv::register::{
medeleg, mideleg, mie,
misa::{self, MXL},
pmpaddr0, pmpaddr1, pmpaddr10, pmpaddr11, pmpaddr12, pmpaddr13, pmpaddr14, pmpaddr15, pmpaddr2,
pmpaddr3, pmpaddr4, pmpaddr5, pmpaddr6, pmpaddr7, pmpaddr8, pmpaddr9, pmpcfg0, pmpcfg2,
};
use rustsbi::{print, println};

pub const PMP_COUNT: usize = 16;
pub const PMP_SHIFT: usize = 2;
Expand Down Expand Up @@ -48,7 +48,7 @@ fn print_misa() {
print!("{}", ext);
}
}
println!("\r");
println!("");
}
}

Expand Down
11 changes: 11 additions & 0 deletions src/arch/src/riscv64/sbi/info.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
use super::hart_csr_utils;
use log::println;

pub fn print_info(platform: &str, version: &str) {
println!("RustSBI version {}", rustsbi::VERSION);
println!("{}", rustsbi::LOGO);
println!("Platform Name: {}", platform);
println!("Implementation: oreboot version {}", version);
hart_csr_utils::print_hart_csrs();
hart_csr_utils::print_hart_pmp();
}
Loading

0 comments on commit 9230565

Please sign in to comment.