Skip to content

Commit

Permalink
Merge pull request #3 from Alignof/develop
Browse files Browse the repository at this point in the history
Ver 0.1.0
  • Loading branch information
Alignof authored May 3, 2024
2 parents 6d3d02f + 5aa06b9 commit 2245284
Show file tree
Hide file tree
Showing 24 changed files with 1,841 additions and 0 deletions.
11 changes: 11 additions & 0 deletions .cargo/config
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[target.riscv64imac-unknown-none-elf]
runner = "qemu-system-riscv64 -S -gdb tcp::10000 -d int -machine virt -bios none -nographic -m 2G -initrd fedora-vmlinux -kernel"
#runner = "qemu-system-riscv64 -machine virt -bios none -nographic -m 2G -initrd fedora-vmlinux -kernel"

rustflags = [
"-C", "link-arg=-Tmemory.x",
"-C", "link-arg=-Tlink.x",
]

[build]
target = "riscv64imac-unknown-none-elf"
45 changes: 45 additions & 0 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
name: Rust

on:
push:
branches:
- master
pull_request:

env:
CARGO_INCREMENTAL: 0

# Copyright (c) 2021 sksat
# https://github.com/sksat/action-clippy
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: recursive

- name: install clippy
uses: dtolnay/rust-toolchain@stable
with:
toolchain: stable # Rustup toolchain specifier e.g. stable, nightly, 1.42.0, nightly-2022-01-01.
target: riscv64imac-unknown-none-elf # Comma-separated string of additional targets to install e.g. wasm32-unknown-unknown
components: clippy, rustfmt

- uses: sksat/[email protected]
if: github.event_name == 'push'
with:
reporter: github-check

- uses: sksat/[email protected]
if: github.event_name == 'pull_request'
with:
reporter: github-pr-review

- name: format check
run: cargo fmt --all -- --check

# no crate for test in no_std
#- name: unit test
# run: cargo test

9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,12 @@ Cargo.lock

# MSVC Windows builds of rustc generate these, which store debugging information
*.pdb


# Added by cargo
/target

# Added by me
.gdb_history
fedora-vmlinux
stage4-disk.img
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "wild-screen-alloc"]
path = wild-screen-alloc
url = [email protected]:Alignof/wild-screen-alloc.git
21 changes: 21 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
[package]
name = "hikami"
version = "0.1.0"
edition = "2021"

[lints.clippy]
pedantic = "warn"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[[bin]]
name = "hikami"
path = "src/machine_init.rs"

[dependencies]
elf = { version = "0.7.2", default-features = false }
fdt = "0.1.5"
panic-halt = "0.2.0"
riscv = "0.10.1"
riscv-rt = "0.11.0"
wild_screen_alloc = { version = "0.1.1", path = "wild-screen-alloc" }
14 changes: 14 additions & 0 deletions build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
use std::env;
use std::fs;
use std::path::PathBuf;

fn main() {
let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());

// Put the linker script somewhere the linker can find it.
fs::write(out_dir.join("memory.x"), include_bytes!("memory.x")).unwrap();
println!("cargo:rustc-link-search={}", out_dir.display());
println!("cargo:rerun-if-changed=memory.x");

println!("cargo:rerun-if-changed=build.rs");
}
38 changes: 38 additions & 0 deletions linker.ld
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
OUTPUT_ARCH("riscv")

ENTRY(_start)
EXTERN(abort);

SECTIONS
{
. = 0x80000000;

.reset :
{
KEEP(*(.reset.boot));
}

/* text: Program code section */
.text :
{
*(.text. text.*);
}

/* rodata: Read-only data */
.rodata :
{
*(.rdata .rodata. .rodata.*);
}

/* data: Writable data */
.data :
{
*(.data .data.*);
}

_bss_start = .;
.bss :
{
*(.bss .bss.*);
}
}
21 changes: 21 additions & 0 deletions memory.x
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MEMORY
{
L2_LIM : ORIGIN = 0x807f0000, LENGTH = 64K
RAM : ORIGIN = 0x80200000, LENGTH = 6M
FLASH : ORIGIN = 0x80000000, LENGTH = 2M
}

/*
* L2_LIC (STACK), 0x807f_0000..0x8080_0000
* RAM (DATA, BSS, HEAP), 0x8020_0000..0x8080_0000
* FLASH (TEXT), 0x8000_0000..0x8020_0000
*/

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);
183 changes: 183 additions & 0 deletions src/machine_init.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
#![no_main]
#![no_std]

extern crate alloc;
mod memmap;
mod supervisor_init;
mod trap;
mod util;

use crate::memmap::constant::{DRAM_BASE, HEAP_BASE, HEAP_SIZE, STACK_BASE, STACK_SIZE_PER_HART};
use crate::trap::machine::mtrap_vector;
use core::arch::asm;
use core::panic::PanicInfo;
use riscv::asm::sfence_vma_all;
use riscv::register::{
mcause, mcounteren, medeleg, mepc, mideleg, mie, mscratch, mstatus, mtval, mtvec, pmpaddr0,
pmpcfg0, satp, scause, sepc, stval, stvec,
};
use riscv_rt::entry;
use wild_screen_alloc::WildScreenAlloc;

/// Panic handler
#[panic_handler]
pub fn panic(info: &PanicInfo) -> ! {
println!("{}", info);
loop {
unsafe {
asm!("nop");
}
}
}

#[global_allocator]
static mut ALLOCATOR: WildScreenAlloc = WildScreenAlloc::empty();

/// Entry function. `__risc_v_rt__main` is alias of `__init` function in machine_init.rs.
/// * set stack pointer
/// * init mtvec and stvec
/// * jump to mstart
#[entry]
fn _start(hart_id: usize, dtb_addr: usize) -> ! {
// Initialize global allocator
unsafe {
ALLOCATOR.init(HEAP_BASE, HEAP_SIZE);
}

unsafe {
// set stack pointer
asm!(
"
mv a0, {hart_id}
mv a1, {dtb_addr}
mv t1, {stack_size_per_hart}
mul t0, a0, t1
mv sp, {stack_base}
add sp, sp, t0
csrw mtvec, {DRAM_BASE}
csrw stvec, {DRAM_BASE}
j {mstart}
",
hart_id = in(reg) hart_id,
dtb_addr = in(reg) dtb_addr,
stack_size_per_hart = in(reg) STACK_SIZE_PER_HART,
stack_base = in(reg) STACK_BASE,
DRAM_BASE = in(reg) DRAM_BASE,
mstart = sym mstart,
);
}

unreachable!();
}

/// Machine start function
fn mstart(hart_id: usize, dtb_addr: usize) {
unsafe {
// mideleg = 0x0222
mideleg::set_sext();
mideleg::set_ssoft();
mideleg::set_stimer();
// medeleg = 0xb1ff
medeleg::set_instruction_misaligned();
medeleg::set_instruction_fault();
medeleg::set_illegal_instruction();
medeleg::set_breakpoint();
medeleg::set_load_misaligned();
medeleg::set_load_fault();
medeleg::set_store_misaligned();
medeleg::set_store_fault();
medeleg::set_user_env_call();
medeleg::set_instruction_page_fault();
medeleg::set_load_page_fault();
medeleg::set_store_page_fault();
// mie = 0x088
mie::set_msoft();
mie::set_mtimer();

// mcounteren = 0xffff_ffff
mcounteren::set_cy();
mcounteren::set_tm();
mcounteren::set_ir();
mcounteren::set_hpm(3);
mcounteren::set_hpm(4);
mcounteren::set_hpm(5);
mcounteren::set_hpm(6);
mcounteren::set_hpm(7);
mcounteren::set_hpm(8);
mcounteren::set_hpm(9);
mcounteren::set_hpm(10);
mcounteren::set_hpm(11);
mcounteren::set_hpm(12);
mcounteren::set_hpm(13);
mcounteren::set_hpm(14);
mcounteren::set_hpm(15);
mcounteren::set_hpm(16);
mcounteren::set_hpm(17);
mcounteren::set_hpm(18);
mcounteren::set_hpm(19);
mcounteren::set_hpm(20);
mcounteren::set_hpm(21);
mcounteren::set_hpm(22);
mcounteren::set_hpm(23);
mcounteren::set_hpm(24);
mcounteren::set_hpm(25);
mcounteren::set_hpm(26);
mcounteren::set_hpm(27);
mcounteren::set_hpm(28);
mcounteren::set_hpm(29);
mcounteren::set_hpm(30);
mcounteren::set_hpm(31);
mstatus::set_mpp(mstatus::MPP::Supervisor);
mscratch::write(STACK_BASE + STACK_SIZE_PER_HART * hart_id);
pmpaddr0::write(0xffff_ffff_ffff_ffff);
pmpcfg0::write(pmpcfg0::read().bits | 0x1f);
satp::set(satp::Mode::Bare, 0, 0);

mepc::write(supervisor_init::sstart as *const fn() as usize);

// set trap_vector in trap.S to mtvec
mtvec::write(
mtrap_vector as *const fn() as usize,
mtvec::TrapMode::Direct,
);

sfence_vma_all();
}

enter_supervisor_mode(hart_id, dtb_addr);
}

/// Delegate exception to supervisor mode
#[no_mangle]
extern "C" fn forward_exception() {
unsafe {
sepc::write(mepc::read());
scause::write(mcause::read().bits());
stval::write(mtval::read());
mepc::write(stvec::read().bits() & !0x3);

if mstatus::read().sie() {
mstatus::set_spie();
} else {
// clear?
}

if mstatus::read().mpp() == mstatus::MPP::Supervisor {
mstatus::set_spp(mstatus::SPP::Supervisor);
} else {
mstatus::set_spp(mstatus::SPP::User);
}

mstatus::clear_sie();
mstatus::set_mpp(mstatus::MPP::Supervisor);
}
}

/// Enter supervisor. (just exec mret)
/// Jump to sstart via mret.
#[inline(never)]
fn enter_supervisor_mode(_hart_id: usize, _dtb_addr: usize) {
unsafe {
asm!("mret");
}
}
Loading

0 comments on commit 2245284

Please sign in to comment.