From 0cf7d35af2f8f287c9a92213c23b64f52e02c130 Mon Sep 17 00:00:00 2001 From: Alingof Date: Mon, 26 Jun 2023 15:25:43 +0900 Subject: [PATCH 001/133] [add] cargo init --- .gitignore | 5 +++++ Cargo.toml | 8 ++++++++ src/main.rs | 3 +++ 3 files changed, 16 insertions(+) create mode 100644 Cargo.toml create mode 100644 src/main.rs diff --git a/.gitignore b/.gitignore index 6985cf1..196e176 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,8 @@ Cargo.lock # MSVC Windows builds of rustc generate these, which store debugging information *.pdb + + +# Added by cargo + +/target diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..ba64816 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "hikami" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..e7a11a9 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, world!"); +} From 6a62b7566d44ab12545b170bd0e034dbe106c0d7 Mon Sep 17 00:00:00 2001 From: Alingof Date: Mon, 10 Jul 2023 23:31:52 +0900 Subject: [PATCH 002/133] [add] add .cargo/config --- .cargo/config | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .cargo/config diff --git a/.cargo/config b/.cargo/config new file mode 100644 index 0000000..86e09f1 --- /dev/null +++ b/.cargo/config @@ -0,0 +1,2 @@ +[build] +target = "riscv64imac-unknown-none-elf" From 9be2362855544cbd2a8b98c98e5ca05843bf5cb3 Mon Sep 17 00:00:00 2001 From: Alingof Date: Tue, 11 Jul 2023 17:28:24 +0900 Subject: [PATCH 003/133] [add] add panic handler --- src/main.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/main.rs b/src/main.rs index e7a11a9..8dc88bb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,9 @@ -fn main() { - println!("Hello, world!"); +#![no_main] +#![no_std] + +use core::panic::PanicInfo; + +#[panic_handler] +fn panic(_panic: &PanicInfo<'_>) -> ! { + loop {} } From 856578fece5c76092e197532cac6118e1fb2b7f4 Mon Sep 17 00:00:00 2001 From: Alingof Date: Wed, 12 Jul 2023 17:20:04 +0900 Subject: [PATCH 004/133] [add] add runner to .cargo/config --- .cargo/config | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.cargo/config b/.cargo/config index 86e09f1..3c7a0d7 100644 --- a/.cargo/config +++ b/.cargo/config @@ -1,2 +1,5 @@ +[target.riscv64imac-unknown-none-elf] +runner = "qemu-system-riscv64 -S -gdb tcp::10000 -bios none -nographic -machine sifive_u -kernel" + [build] target = "riscv64imac-unknown-none-elf" From e71411c161c8b192e5781010b35ea107bd5b30d0 Mon Sep 17 00:00:00 2001 From: Alingof Date: Wed, 12 Jul 2023 17:20:51 +0900 Subject: [PATCH 005/133] [wip][add] add __start_rust and global_asm(fix needed) --- src/main.rs | 43 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/src/main.rs b/src/main.rs index 8dc88bb..1d6acc3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,9 +1,48 @@ #![no_main] #![no_std] -use core::panic::PanicInfo; +use core::arch::global_asm; + +#[link_section = ".boot"] +global_asm!( + r#" +.global _start +_start: + /* Set up stack pointer. */ + lui sp, %hi(stack_end) + ori sp, sp, %lo(stack_end) + + /* Now jump to the rust world; __start_rust. */ + j __start_rust + +.bss +stack_start: + .skip 1024 +stack_end: +"# +); + +#[no_mangle] +pub extern "C" fn __start_rust() -> ! { + let uart = 0x1001_1000 as *mut u8; + for c in b"Hello from Rust!".iter() { + unsafe { + *uart = *c as u8; + } + } + + loop {} +} + +use core::panic::PanicInfo; #[panic_handler] -fn panic(_panic: &PanicInfo<'_>) -> ! { +#[no_mangle] +pub fn panic(_info: &PanicInfo) -> ! { + loop {} +} + +#[no_mangle] +pub extern "C" fn abort() -> ! { loop {} } From 7c490cc05b2a83bbf665614f061c92d544c20c95 Mon Sep 17 00:00:00 2001 From: Alingof Date: Thu, 13 Jul 2023 21:19:51 +0900 Subject: [PATCH 006/133] [add] add linker.ld --- .cargo/config | 3 +++ linker.ld | 38 ++++++++++++++++++++++++++++++++++++++ src/main.rs | 13 +++++++------ 3 files changed, 48 insertions(+), 6 deletions(-) create mode 100644 linker.ld diff --git a/.cargo/config b/.cargo/config index 3c7a0d7..eb2ca7c 100644 --- a/.cargo/config +++ b/.cargo/config @@ -1,5 +1,8 @@ [target.riscv64imac-unknown-none-elf] runner = "qemu-system-riscv64 -S -gdb tcp::10000 -bios none -nographic -machine sifive_u -kernel" +rustflags = [ + "-C", "link-arg=-Tlinker.ld", +] [build] target = "riscv64imac-unknown-none-elf" diff --git a/linker.ld b/linker.ld new file mode 100644 index 0000000..7728761 --- /dev/null +++ b/linker.ld @@ -0,0 +1,38 @@ +OUTPUT_ARCH("riscv") + +ENTRY(__start_rust) +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.*); + } +} diff --git a/src/main.rs b/src/main.rs index 1d6acc3..afefd5b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,23 +3,24 @@ use core::arch::global_asm; -#[link_section = ".boot"] global_asm!( r#" +.option norvc +.section .reset.boot, "ax",@progbits .global _start +.global abort + _start: /* Set up stack pointer. */ - lui sp, %hi(stack_end) - ori sp, sp, %lo(stack_end) - + lui sp, %hi(stacks + 1024) + ori sp, sp, %lo(stacks + 1024) /* Now jump to the rust world; __start_rust. */ j __start_rust .bss -stack_start: +stacks: .skip 1024 -stack_end: "# ); From d4bd3d04ff70b8c9aec89699e1f859c7b326e519 Mon Sep 17 00:00:00 2001 From: Alingof Date: Thu, 13 Jul 2023 23:42:56 +0900 Subject: [PATCH 007/133] [fix] fix assembly --- src/main.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main.rs b/src/main.rs index afefd5b..cbe6932 100644 --- a/src/main.rs +++ b/src/main.rs @@ -12,15 +12,16 @@ global_asm!( _start: /* Set up stack pointer. */ - lui sp, %hi(stacks + 1024) - ori sp, sp, %lo(stacks + 1024) + ld sp, stacks_addr /* Now jump to the rust world; __start_rust. */ j __start_rust .bss - stacks: .skip 1024 + +.data +stacks_addr: .dword stacks "# ); From 12a6a15ee692045ab3b70e1e5aad527aaa1c8cf6 Mon Sep 17 00:00:00 2001 From: Alingof Date: Fri, 14 Jul 2023 00:08:44 +0900 Subject: [PATCH 008/133] [wip][fix] fix rodata section in linker script --- linker.ld | 4 ++-- src/main.rs | 7 +++---- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/linker.ld b/linker.ld index 7728761..3b115b1 100644 --- a/linker.ld +++ b/linker.ld @@ -1,6 +1,6 @@ OUTPUT_ARCH("riscv") -ENTRY(__start_rust) +ENTRY(_start) EXTERN(abort); SECTIONS @@ -21,7 +21,7 @@ SECTIONS /* rodata: Read-only data */ .rodata : { - *(.rdata .rodata. rodata.*); + *(.rdata .rodata. .rodata.*); } /* data: Writable data */ diff --git a/src/main.rs b/src/main.rs index cbe6932..49b454b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -12,16 +12,15 @@ global_asm!( _start: /* Set up stack pointer. */ - ld sp, stacks_addr + lui sp, %hi(stacks + 1024) + ori sp, sp, %lo(stacks + 1024) /* Now jump to the rust world; __start_rust. */ j __start_rust .bss +.global stacks stacks: .skip 1024 - -.data -stacks_addr: .dword stacks "# ); From 99b25ed5bf1f335a1ef287403651da632f10fd75 Mon Sep 17 00:00:00 2001 From: Alingof Date: Sun, 16 Jul 2023 00:00:01 +0900 Subject: [PATCH 009/133] [fix] fix asm --- src/main.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main.rs b/src/main.rs index 49b454b..96e1b18 100644 --- a/src/main.rs +++ b/src/main.rs @@ -12,23 +12,23 @@ global_asm!( _start: /* Set up stack pointer. */ - lui sp, %hi(stacks + 1024) - ori sp, sp, %lo(stacks + 1024) + lla sp, stacks_end /* Now jump to the rust world; __start_rust. */ j __start_rust .bss -.global stacks stacks: .skip 1024 +stacks_end: "# ); #[no_mangle] pub extern "C" fn __start_rust() -> ! { - let uart = 0x1001_1000 as *mut u8; + let uart = 0x1001_0000 as *mut u8; for c in b"Hello from Rust!".iter() { unsafe { + while (*uart as i32) < 0 {} *uart = *c as u8; } } From 5c130ecd71dfd5ecd9842ca8679d5e920e949975 Mon Sep 17 00:00:00 2001 From: Alingof Date: Mon, 17 Jul 2023 23:53:51 +0900 Subject: [PATCH 010/133] [update] update .gitignore to ignore .gdb_history --- .gitignore | 1 + src/main.rs | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 196e176..3d85cc4 100644 --- a/.gitignore +++ b/.gitignore @@ -17,3 +17,4 @@ Cargo.lock # Added by cargo /target +.gdb_history diff --git a/src/main.rs b/src/main.rs index 96e1b18..e0585a9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -25,7 +25,7 @@ stacks_end: #[no_mangle] pub extern "C" fn __start_rust() -> ! { - let uart = 0x1001_0000 as *mut u8; + let uart = 0x1001_3000 as *mut u8; for c in b"Hello from Rust!".iter() { unsafe { while (*uart as i32) < 0 {} From 80944300d810be7b1c34a5f51cf1d21bdd315d62 Mon Sep 17 00:00:00 2001 From: Alingof Date: Tue, 18 Jul 2023 16:51:01 +0900 Subject: [PATCH 011/133] [fix] fix load/store size (u8 -> u32) --- .cargo/config | 3 ++- src/main.rs | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.cargo/config b/.cargo/config index eb2ca7c..c8fbd49 100644 --- a/.cargo/config +++ b/.cargo/config @@ -1,5 +1,6 @@ [target.riscv64imac-unknown-none-elf] -runner = "qemu-system-riscv64 -S -gdb tcp::10000 -bios none -nographic -machine sifive_u -kernel" +# runner = "qemu-system-riscv64 -S -gdb tcp::10000 -bios none -nographic -machine sifive_u -kernel" +runner = "qemu-system-riscv64 -bios none -nographic -machine sifive_u -kernel" rustflags = [ "-C", "link-arg=-Tlinker.ld", ] diff --git a/src/main.rs b/src/main.rs index e0585a9..f50b479 100644 --- a/src/main.rs +++ b/src/main.rs @@ -25,11 +25,11 @@ stacks_end: #[no_mangle] pub extern "C" fn __start_rust() -> ! { - let uart = 0x1001_3000 as *mut u8; + let uart = 0x1001_0000 as *mut u32; for c in b"Hello from Rust!".iter() { unsafe { while (*uart as i32) < 0 {} - *uart = *c as u8; + *uart = *c as u32; } } From 7f07dd8b171d4f7c9af386a8822d4035b5a8e6c1 Mon Sep 17 00:00:00 2001 From: Alingof Date: Tue, 18 Jul 2023 17:46:09 +0900 Subject: [PATCH 012/133] [update] add read/write_volatile --- src/main.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main.rs b/src/main.rs index f50b479..3836215 100644 --- a/src/main.rs +++ b/src/main.rs @@ -26,10 +26,11 @@ stacks_end: #[no_mangle] pub extern "C" fn __start_rust() -> ! { let uart = 0x1001_0000 as *mut u32; - for c in b"Hello from Rust!".iter() { + + for c in b"Hello from Rust!\n".iter() { unsafe { - while (*uart as i32) < 0 {} - *uart = *c as u32; + while (uart.read_volatile() as i32) < 0 {} + uart.write_volatile(*c as u32); } } From 756af7c8c6e06a4f80497d6cfa616daff93cf4c5 Mon Sep 17 00:00:00 2001 From: Alingof Date: Thu, 17 Aug 2023 00:00:09 +0900 Subject: [PATCH 013/133] [add] add riscv-decode --- Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/Cargo.toml b/Cargo.toml index ba64816..623e0ec 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,3 +6,4 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +riscv-decode = "0.2.1" From 9c5c06e2899a1aa6ec8fddd707d87a04b5105917 Mon Sep 17 00:00:00 2001 From: Alingof Date: Fri, 25 Aug 2023 17:22:23 +0900 Subject: [PATCH 014/133] [update] modify .gitignore to ignore linux image --- .gitignore | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 3d85cc4..5d0210b 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,9 @@ Cargo.lock # Added by cargo - /target + +# Added by me .gdb_history +fedora-vmlinux +stage4-disk.img From a1c7c2343b8b9b940b506ee499ea177c0a17c9e8 Mon Sep 17 00:00:00 2001 From: Alingof Date: Sun, 27 Aug 2023 01:37:39 +0900 Subject: [PATCH 015/133] [add] add riscv-rt crate --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 623e0ec..eb90e25 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,4 +6,4 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -riscv-decode = "0.2.1" +riscv-rt = "0.11.0" From 4f71b8210f835d0513f82589981c03c25b4aae23 Mon Sep 17 00:00:00 2001 From: Alingof Date: Sun, 27 Aug 2023 02:08:04 +0900 Subject: [PATCH 016/133] [add] init project by hello world template --- .cargo/config | 8 +++++--- Cargo.toml | 1 + build.rs | 14 ++++++++++++++ memory.x | 15 +++++++++++++++ src/main.rs | 41 ++++++----------------------------------- 5 files changed, 41 insertions(+), 38 deletions(-) create mode 100644 build.rs create mode 100644 memory.x diff --git a/.cargo/config b/.cargo/config index c8fbd49..272ef79 100644 --- a/.cargo/config +++ b/.cargo/config @@ -1,8 +1,10 @@ [target.riscv64imac-unknown-none-elf] -# runner = "qemu-system-riscv64 -S -gdb tcp::10000 -bios none -nographic -machine sifive_u -kernel" -runner = "qemu-system-riscv64 -bios none -nographic -machine sifive_u -kernel" +#runner = "qemu-system-riscv64 -S -gdb tcp::10000 -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=-Tlinker.ld", + "-C", "link-arg=-Tmemory.x", + "-C", "link-arg=-Tlink.x", ] [build] diff --git a/Cargo.toml b/Cargo.toml index eb90e25..4404bab 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,4 +6,5 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +panic-halt = "0.2.0" riscv-rt = "0.11.0" diff --git a/build.rs b/build.rs new file mode 100644 index 0000000..143e014 --- /dev/null +++ b/build.rs @@ -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"); +} diff --git a/memory.x b/memory.x new file mode 100644 index 0000000..eddcf1b --- /dev/null +++ b/memory.x @@ -0,0 +1,15 @@ +MEMORY +{ + L2_LIM : ORIGIN = 0x80300000, LENGTH = 1M + RAM : ORIGIN = 0x80200000, LENGTH = 16K + FLASH : ORIGIN = 0x80000000, 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", L2_LIM); + +_stack_start = ORIGIN(L2_LIM) + LENGTH(L2_LIM); diff --git a/src/main.rs b/src/main.rs index 3836215..49294b2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,31 +1,14 @@ #![no_main] #![no_std] -use core::arch::global_asm; +extern crate panic_halt; -global_asm!( - r#" -.option norvc -.section .reset.boot, "ax",@progbits -.global _start -.global abort +use riscv_rt::entry; -_start: - /* Set up stack pointer. */ - lla sp, stacks_end - /* Now jump to the rust world; __start_rust. */ - j __start_rust - -.bss -stacks: - .skip 1024 -stacks_end: -"# -); - -#[no_mangle] -pub extern "C" fn __start_rust() -> ! { - let uart = 0x1001_0000 as *mut u32; +#[entry] +#[allow(clippy::empty_loop)] +fn main() -> ! { + let uart = 0x1000_0000 as *mut u32; for c in b"Hello from Rust!\n".iter() { unsafe { @@ -36,15 +19,3 @@ pub extern "C" fn __start_rust() -> ! { loop {} } - -use core::panic::PanicInfo; -#[panic_handler] -#[no_mangle] -pub fn panic(_info: &PanicInfo) -> ! { - loop {} -} - -#[no_mangle] -pub extern "C" fn abort() -> ! { - loop {} -} From b7897f1c558b11981b154083fd6b8de2dae48bd5 Mon Sep 17 00:00:00 2001 From: Alingof Date: Sun, 27 Aug 2023 02:08:50 +0900 Subject: [PATCH 017/133] [add] add the rust workflow --- .github/workflows/rust.yml | 39 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 .github/workflows/rust.yml diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml new file mode 100644 index 0000000..cda2c90 --- /dev/null +++ b/.github/workflows/rust.yml @@ -0,0 +1,39 @@ +name: Rust + +on: + push: + branches: + - master + pull_request: + + env: + CARGO_INCREMENTAL: 0 + +jobs: + rust: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + + - uses: dtolnay/rust-toolchain@v1 + 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 + + - name: cache dependencies + uses: Swatinem/rust-cache@v2.4.0 + + - name: reviewdog / clippy + uses: sksat/action-clippy@v0.2.1 + with: + reporter: github-pr-review + clippy_flags: --all-features + + - name: format check + run: cargo fmt --all -- --check + + # no crate for test in no_std + #- name: unit test + # run: cargo test From 3940df257fad304d36171fb26a32439d5e86bc8b Mon Sep 17 00:00:00 2001 From: Alingof Date: Tue, 29 Aug 2023 13:39:36 +0900 Subject: [PATCH 018/133] [add] add init.rs --- src/init.rs | 1 + 1 file changed, 1 insertion(+) create mode 100644 src/init.rs diff --git a/src/init.rs b/src/init.rs new file mode 100644 index 0000000..e9cf21b --- /dev/null +++ b/src/init.rs @@ -0,0 +1 @@ +fn init() {} From 68206c39271fbd6b11b41509cd0558671f0e6c5c Mon Sep 17 00:00:00 2001 From: Alingof Date: Tue, 29 Aug 2023 17:03:32 +0900 Subject: [PATCH 019/133] [wip][add] add init::init() --- src/init.rs | 43 ++++++++++++++++++++++++++++++++++++++++++- src/main.rs | 5 ++++- 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/src/init.rs b/src/init.rs index e9cf21b..67e212c 100644 --- a/src/init.rs +++ b/src/init.rs @@ -1 +1,42 @@ -fn init() {} +use core::arch::asm; + +const DRAM_BASE: u64 = 0x8000_0000; +const PAGE_TABLE_BASE: u64 = 0x8020_0000; +const PAGE_TABLE_SIZE: u64 = 1024; +const STACK_BASE: u64 = 0x8030_0000; +const PA2VA_OFFSET: u64 = 0xffff_ffff_4000_0000; + +/// Initialize CSRs, page tables, stack pointer +pub fn init() { + let hart_id: u64; + unsafe { + // get hart id + asm!("mv {}, a0", out(reg) hart_id); + + // debug output + let uart = 0x1000_0000 as *mut u32; + for c in b"hart_id: ".iter() { + while (uart.read_volatile() as i32) < 0 {} + uart.write_volatile(*c as u32); + } + uart.write_volatile(hart_id as u32 + '0' as u32); + uart.write_volatile('\n' as u32); + } + + // init stack pointer + let stack_pointer = STACK_BASE + PA2VA_OFFSET; + unsafe { + asm!("mv sp, {}", in(reg) stack_pointer); + } + + // init page tables + let offset_from_dram_base = init as *const fn() as u64 - DRAM_BASE; + let offset_from_dram_base_masked = (offset_from_dram_base >> 21) << 19; + let page_table_start = PAGE_TABLE_BASE + offset_from_dram_base + hart_id * PAGE_TABLE_SIZE; + for pt_num in 511..1024 { + let pt_offset = (page_table_start + pt_num * 8) as *mut u64; + unsafe { + pt_offset.write_volatile(pt_offset.read_volatile() + offset_from_dram_base_masked); + } + } +} diff --git a/src/main.rs b/src/main.rs index 49294b2..15027d2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,14 +2,17 @@ #![no_std] extern crate panic_halt; +mod init; use riscv_rt::entry; +/// entry point #[entry] #[allow(clippy::empty_loop)] fn main() -> ! { - let uart = 0x1000_0000 as *mut u32; + init::init(); + let uart = 0x1000_0000 as *mut u32; for c in b"Hello from Rust!\n".iter() { unsafe { while (uart.read_volatile() as i32) < 0 {} From 7e1c6ae1a4ddb05d752d83c1cfa0d3b7f454e2e2 Mon Sep 17 00:00:00 2001 From: Alingof Date: Tue, 29 Aug 2023 17:39:59 +0900 Subject: [PATCH 020/133] [add] add riscv crate --- Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/Cargo.toml b/Cargo.toml index 4404bab..fb31d37 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,4 +7,5 @@ edition = "2021" [dependencies] panic-halt = "0.2.0" +riscv = "0.10.1" riscv-rt = "0.11.0" From 8be05d31b9bb23da58e9b105766e9cb8bf085057 Mon Sep 17 00:00:00 2001 From: Alingof Date: Tue, 29 Aug 2023 17:50:32 +0900 Subject: [PATCH 021/133] [add] implement to init trap vector and set satp --- src/init.rs | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/init.rs b/src/init.rs index 67e212c..aa2c0d0 100644 --- a/src/init.rs +++ b/src/init.rs @@ -1,4 +1,6 @@ use core::arch::asm; +use riscv::asm::sfence_vma; +use riscv::register::{mtvec, satp, stvec}; const DRAM_BASE: u64 = 0x8000_0000; const PAGE_TABLE_BASE: u64 = 0x8020_0000; @@ -33,10 +35,25 @@ pub fn init() { let offset_from_dram_base = init as *const fn() as u64 - DRAM_BASE; let offset_from_dram_base_masked = (offset_from_dram_base >> 21) << 19; let page_table_start = PAGE_TABLE_BASE + offset_from_dram_base + hart_id * PAGE_TABLE_SIZE; - for pt_num in 511..1024 { - let pt_offset = (page_table_start + pt_num * 8) as *mut u64; + for pt_index in 511..1024 { + let pt_offset = (page_table_start + pt_index * 8) as *mut u64; unsafe { pt_offset.write_volatile(pt_offset.read_volatile() + offset_from_dram_base_masked); } } + + unsafe { + // init trap vector + stvec::write(trampoline as *const fn() as usize, mtvec::TrapMode::Direct); + + // set satp(Supervisor Address Translation and Protection) register + satp::set(satp::Mode::Sv39, 0, (page_table_start >> 12) as usize); + + // sfence.vma + sfence_vma(0, 0); + } + + trampoline() } + +pub fn trampoline() {} From 90faf0d40917d1d7b5a7a1066f88aaae3be78d6f Mon Sep 17 00:00:00 2001 From: Alingof Date: Wed, 30 Aug 2023 13:35:37 +0900 Subject: [PATCH 022/133] [update] remove main.rs --- src/main.rs | 24 ------------------------ 1 file changed, 24 deletions(-) delete mode 100644 src/main.rs diff --git a/src/main.rs b/src/main.rs deleted file mode 100644 index 15027d2..0000000 --- a/src/main.rs +++ /dev/null @@ -1,24 +0,0 @@ -#![no_main] -#![no_std] - -extern crate panic_halt; -mod init; - -use riscv_rt::entry; - -/// entry point -#[entry] -#[allow(clippy::empty_loop)] -fn main() -> ! { - init::init(); - - let uart = 0x1000_0000 as *mut u32; - for c in b"Hello from Rust!\n".iter() { - unsafe { - while (uart.read_volatile() as i32) < 0 {} - uart.write_volatile(*c as u32); - } - } - - loop {} -} From 582ad9755cdb01a3c6877df28d2a4286c3ca82a8 Mon Sep 17 00:00:00 2001 From: Alingof Date: Wed, 30 Aug 2023 13:40:21 +0900 Subject: [PATCH 023/133] [update] make the init function an entry point --- Cargo.toml | 4 ++++ src/init.rs | 18 +++++++++++++++--- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index fb31d37..2aaca9d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,6 +5,10 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[[bin]] +name = "hikami" +path = "src/init.rs" + [dependencies] panic-halt = "0.2.0" riscv = "0.10.1" diff --git a/src/init.rs b/src/init.rs index aa2c0d0..a919258 100644 --- a/src/init.rs +++ b/src/init.rs @@ -1,6 +1,11 @@ +#![no_main] +#![no_std] + +extern crate panic_halt; use core::arch::asm; use riscv::asm::sfence_vma; use riscv::register::{mtvec, satp, stvec}; +use riscv_rt::entry; const DRAM_BASE: u64 = 0x8000_0000; const PAGE_TABLE_BASE: u64 = 0x8020_0000; @@ -8,8 +13,10 @@ const PAGE_TABLE_SIZE: u64 = 1024; const STACK_BASE: u64 = 0x8030_0000; const PA2VA_OFFSET: u64 = 0xffff_ffff_4000_0000; +/// entry point /// Initialize CSRs, page tables, stack pointer -pub fn init() { +#[entry] +fn init() -> ! { let hart_id: u64; unsafe { // get hart id @@ -32,7 +39,8 @@ pub fn init() { } // init page tables - let offset_from_dram_base = init as *const fn() as u64 - DRAM_BASE; + let init_func = __risc_v_rt__main; + let offset_from_dram_base = init_func as *const fn() as u64 - DRAM_BASE; let offset_from_dram_base_masked = (offset_from_dram_base >> 21) << 19; let page_table_start = PAGE_TABLE_BASE + offset_from_dram_base + hart_id * PAGE_TABLE_SIZE; for pt_index in 511..1024 { @@ -53,7 +61,11 @@ pub fn init() { sfence_vma(0, 0); } - trampoline() + // jump to trampoline + trampoline(); + + unreachable!() } +/// Jump to start pub fn trampoline() {} From 9103c4a7cb4e271195f12625b0b70b71acbd4909 Mon Sep 17 00:00:00 2001 From: Alingof Date: Wed, 30 Aug 2023 13:48:56 +0900 Subject: [PATCH 024/133] [add] add start.rs --- src/init.rs | 5 ++++- src/start.rs | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 src/start.rs diff --git a/src/init.rs b/src/init.rs index a919258..5295e01 100644 --- a/src/init.rs +++ b/src/init.rs @@ -2,6 +2,7 @@ #![no_std] extern crate panic_halt; +mod start; use core::arch::asm; use riscv::asm::sfence_vma; use riscv::register::{mtvec, satp, stvec}; @@ -68,4 +69,6 @@ fn init() -> ! { } /// Jump to start -pub fn trampoline() {} +pub fn trampoline() { + start::start(); +} diff --git a/src/start.rs b/src/start.rs new file mode 100644 index 0000000..2a0c825 --- /dev/null +++ b/src/start.rs @@ -0,0 +1 @@ +pub fn start() {} From 719eae49bc501ea24b929f393484c95344117646 Mon Sep 17 00:00:00 2001 From: Alingof Date: Wed, 30 Aug 2023 17:45:11 +0900 Subject: [PATCH 025/133] [update] add an arguments to trampoline --- src/init.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/init.rs b/src/init.rs index 5295e01..2fae796 100644 --- a/src/init.rs +++ b/src/init.rs @@ -3,6 +3,7 @@ extern crate panic_halt; mod start; + use core::arch::asm; use riscv::asm::sfence_vma; use riscv::register::{mtvec, satp, stvec}; @@ -19,9 +20,11 @@ const PA2VA_OFFSET: u64 = 0xffff_ffff_4000_0000; #[entry] fn init() -> ! { let hart_id: u64; + let dtb_addr: u64; unsafe { // get hart id asm!("mv {}, a0", out(reg) hart_id); + asm!("mv {}, a1", out(reg) dtb_addr); // debug output let uart = 0x1000_0000 as *mut u32; @@ -63,12 +66,12 @@ fn init() -> ! { } // jump to trampoline - trampoline(); + trampoline(hart_id, dtb_addr); unreachable!() } /// Jump to start -pub fn trampoline() { - start::start(); +pub fn trampoline(hart_id: u64, dtb_addr: u64) { + start::start(hart_id, dtb_addr); } From 0745c0fd2a3aac4fb6a2402ba8842a6f5a8caa24 Mon Sep 17 00:00:00 2001 From: Alingof Date: Wed, 30 Aug 2023 17:45:41 +0900 Subject: [PATCH 026/133] [add] add a functions start and panic_handler --- src/start.rs | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/start.rs b/src/start.rs index 2a0c825..35506b4 100644 --- a/src/start.rs +++ b/src/start.rs @@ -1 +1,15 @@ -pub fn start() {} +use riscv::register::{sstatus, stvec}; + +/// Start function +pub fn start(hart_id: u64, dtb_addr: u64) { + unsafe { + sstatus::clear_sie(); + stvec::write( + panic_handler as *const fn() as usize, + stvec::TrapMode::Direct, + ); + } +} + +/// Panic handler +fn panic_handler() {} From e9a455cc888810fb423e2c9f1677806399958b13 Mon Sep 17 00:00:00 2001 From: Alingof Date: Wed, 30 Aug 2023 22:30:39 +0900 Subject: [PATCH 027/133] [add] add fdt crate --- Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/Cargo.toml b/Cargo.toml index 2aaca9d..a00e007 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,7 @@ name = "hikami" path = "src/init.rs" [dependencies] +fdt = "0.1.5" panic-halt = "0.2.0" riscv = "0.10.1" riscv-rt = "0.11.0" From 07f619307ee2eb578e6cf86f0418c6c78a34f8d9 Mon Sep 17 00:00:00 2001 From: Alingof Date: Thu, 31 Aug 2023 14:30:55 +0900 Subject: [PATCH 028/133] [wip][add] add uart.rs --- src/init.rs | 1 + src/start.rs | 20 ++++++++++++++++++++ src/uart.rs | 11 +++++++++++ 3 files changed, 32 insertions(+) create mode 100644 src/uart.rs diff --git a/src/init.rs b/src/init.rs index 2fae796..51911d2 100644 --- a/src/init.rs +++ b/src/init.rs @@ -3,6 +3,7 @@ extern crate panic_halt; mod start; +mod uart; use core::arch::asm; use riscv::asm::sfence_vma; diff --git a/src/start.rs b/src/start.rs index 35506b4..8ba72a0 100644 --- a/src/start.rs +++ b/src/start.rs @@ -1,13 +1,33 @@ +use crate::uart; use riscv::register::{sstatus, stvec}; /// Start function pub fn start(hart_id: u64, dtb_addr: u64) { unsafe { + // clear sstatus.sie sstatus::clear_sie(); + + // register panic_handler to stvec stvec::write( panic_handler as *const fn() as usize, stvec::TrapMode::Direct, ); + + let device_tree = match fdt::Fdt::from_ptr(dtb_addr as *const u8) { + Ok(fdt) => fdt, + Err(e) => panic!("{}", e), + }; + + let uart_addr = device_tree + .find_node("/soc/uart") + .unwrap() + .reg() + .unwrap() + .next() + .unwrap() + .starting_address; + + let uart = uart::Uart::new(uart_addr as u64); } } diff --git a/src/uart.rs b/src/uart.rs new file mode 100644 index 0000000..92b38bc --- /dev/null +++ b/src/uart.rs @@ -0,0 +1,11 @@ +pub struct Uart { + base_addr: u64, +} + +impl Uart { + pub fn new(uart_addr: u64) -> Self { + Uart { + base_addr: uart_addr, + } + } +} From 5026dc30e2dbadf0e801f564c5c153bbf645e1c0 Mon Sep 17 00:00:00 2001 From: Alingof Date: Thu, 31 Aug 2023 15:22:07 +0900 Subject: [PATCH 029/133] [add] add memmap.rs --- src/init.rs | 8 ++------ src/memmap.rs | 26 ++++++++++++++++++++++++++ src/start.rs | 21 ++++++++------------- 3 files changed, 36 insertions(+), 19 deletions(-) create mode 100644 src/memmap.rs diff --git a/src/init.rs b/src/init.rs index 51911d2..1ed5d62 100644 --- a/src/init.rs +++ b/src/init.rs @@ -2,20 +2,16 @@ #![no_std] extern crate panic_halt; +mod memmap; mod start; mod uart; +use crate::memmap::{DRAM_BASE, PA2VA_OFFSET, PAGE_TABLE_BASE, PAGE_TABLE_SIZE, STACK_BASE}; use core::arch::asm; use riscv::asm::sfence_vma; use riscv::register::{mtvec, satp, stvec}; use riscv_rt::entry; -const DRAM_BASE: u64 = 0x8000_0000; -const PAGE_TABLE_BASE: u64 = 0x8020_0000; -const PAGE_TABLE_SIZE: u64 = 1024; -const STACK_BASE: u64 = 0x8030_0000; -const PA2VA_OFFSET: u64 = 0xffff_ffff_4000_0000; - /// entry point /// Initialize CSRs, page tables, stack pointer #[entry] diff --git a/src/memmap.rs b/src/memmap.rs new file mode 100644 index 0000000..caa1e5d --- /dev/null +++ b/src/memmap.rs @@ -0,0 +1,26 @@ +use fdt::Fdt; + +pub const DRAM_BASE: u64 = 0x8000_0000; +pub const PAGE_TABLE_BASE: u64 = 0x8020_0000; +pub const PAGE_TABLE_SIZE: u64 = 1024; +pub const STACK_BASE: u64 = 0x8030_0000; +pub const PA2VA_OFFSET: u64 = 0xffff_ffff_4000_0000; + +pub struct Memmap { + pub uart_addr: u64, +} + +impl Memmap { + pub fn new(device_tree: Fdt) -> Self { + let uart_addr = device_tree + .find_node("/soc/uart") + .unwrap() + .reg() + .unwrap() + .next() + .unwrap() + .starting_address as u64; + + Memmap { uart_addr } + } +} diff --git a/src/start.rs b/src/start.rs index 8ba72a0..402602c 100644 --- a/src/start.rs +++ b/src/start.rs @@ -1,3 +1,4 @@ +use crate::memmap; use crate::uart; use riscv::register::{sstatus, stvec}; @@ -12,23 +13,17 @@ pub fn start(hart_id: u64, dtb_addr: u64) { panic_handler as *const fn() as usize, stvec::TrapMode::Direct, ); + } - let device_tree = match fdt::Fdt::from_ptr(dtb_addr as *const u8) { + let device_tree = unsafe { + match fdt::Fdt::from_ptr(dtb_addr as *const u8) { Ok(fdt) => fdt, Err(e) => panic!("{}", e), - }; - - let uart_addr = device_tree - .find_node("/soc/uart") - .unwrap() - .reg() - .unwrap() - .next() - .unwrap() - .starting_address; + } + }; - let uart = uart::Uart::new(uart_addr as u64); - } + let mmap = memmap::Memmap::new(device_tree); + let uart = uart::Uart::new(mmap.uart_addr as u64); } /// Panic handler From 417715222a584b3ce1a8a8000bc556c8aa21f09d Mon Sep 17 00:00:00 2001 From: Alingof Date: Thu, 31 Aug 2023 17:03:46 +0900 Subject: [PATCH 030/133] [wip][add] implement Uart::println() --- src/init.rs | 9 --------- src/start.rs | 1 + src/uart.rs | 11 +++++++++++ 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/init.rs b/src/init.rs index 1ed5d62..50842b5 100644 --- a/src/init.rs +++ b/src/init.rs @@ -22,15 +22,6 @@ fn init() -> ! { // get hart id asm!("mv {}, a0", out(reg) hart_id); asm!("mv {}, a1", out(reg) dtb_addr); - - // debug output - let uart = 0x1000_0000 as *mut u32; - for c in b"hart_id: ".iter() { - while (uart.read_volatile() as i32) < 0 {} - uart.write_volatile(*c as u32); - } - uart.write_volatile(hart_id as u32 + '0' as u32); - uart.write_volatile('\n' as u32); } // init stack pointer diff --git a/src/start.rs b/src/start.rs index 402602c..092a7fc 100644 --- a/src/start.rs +++ b/src/start.rs @@ -24,6 +24,7 @@ pub fn start(hart_id: u64, dtb_addr: u64) { let mmap = memmap::Memmap::new(device_tree); let uart = uart::Uart::new(mmap.uart_addr as u64); + uart.println("starting..."); } /// Panic handler diff --git a/src/uart.rs b/src/uart.rs index 92b38bc..5804851 100644 --- a/src/uart.rs +++ b/src/uart.rs @@ -8,4 +8,15 @@ impl Uart { base_addr: uart_addr, } } + + pub fn println(&self, string: &str) { + let uart = self.base_addr as *mut u32; + unsafe { + for c in string.chars() { + while (uart.read_volatile() as i32) < 0 {} + uart.write_volatile(c as u32); + } + uart.write_volatile('\n' as u32); + } + } } From fbd32309654526c3270a3090f7aa43d8ca1d898c Mon Sep 17 00:00:00 2001 From: Alingof Date: Thu, 31 Aug 2023 21:33:25 +0900 Subject: [PATCH 031/133] [mark][fix] fix node name of dtb --- src/memmap.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/memmap.rs b/src/memmap.rs index caa1e5d..1437319 100644 --- a/src/memmap.rs +++ b/src/memmap.rs @@ -13,7 +13,7 @@ pub struct Memmap { impl Memmap { pub fn new(device_tree: Fdt) -> Self { let uart_addr = device_tree - .find_node("/soc/uart") + .find_node("/soc/serial") .unwrap() .reg() .unwrap() From 9a9a895ce6c2b9bdc02bbb53e7a97f8b202af4a4 Mon Sep 17 00:00:00 2001 From: Alingof Date: Thu, 31 Aug 2023 22:47:02 +0900 Subject: [PATCH 032/133] [wip][update] modify entry function (init -> _start) --- Cargo.toml | 2 +- src/init.rs | 10 ---------- 2 files changed, 1 insertion(+), 11 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index a00e007..24ab349 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" [[bin]] name = "hikami" -path = "src/init.rs" +path = "src/start.rs" [dependencies] fdt = "0.1.5" diff --git a/src/init.rs b/src/init.rs index 50842b5..901e671 100644 --- a/src/init.rs +++ b/src/init.rs @@ -1,20 +1,10 @@ -#![no_main] -#![no_std] - -extern crate panic_halt; -mod memmap; -mod start; -mod uart; - use crate::memmap::{DRAM_BASE, PA2VA_OFFSET, PAGE_TABLE_BASE, PAGE_TABLE_SIZE, STACK_BASE}; use core::arch::asm; use riscv::asm::sfence_vma; use riscv::register::{mtvec, satp, stvec}; -use riscv_rt::entry; /// entry point /// Initialize CSRs, page tables, stack pointer -#[entry] fn init() -> ! { let hart_id: u64; let dtb_addr: u64; From d0bc037b1248455a88d22df470c1c58a06d5291d Mon Sep 17 00:00:00 2001 From: Alingof Date: Thu, 31 Aug 2023 22:48:49 +0900 Subject: [PATCH 033/133] [wip][add] add a function _start and mstart --- src/start.rs | 84 ++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 62 insertions(+), 22 deletions(-) diff --git a/src/start.rs b/src/start.rs index 092a7fc..3081f1d 100644 --- a/src/start.rs +++ b/src/start.rs @@ -1,31 +1,71 @@ -use crate::memmap; -use crate::uart; -use riscv::register::{sstatus, stvec}; +#![no_main] +#![no_std] + +extern crate panic_halt; +mod memmap; + +use core::arch::asm; +use memmap::{DRAM_BASE, STACK_BASE, STACK_SIZE_PER_HART}; +use riscv::asm::sfence_vma_all; +use riscv::register::{mcounteren, medeleg, mideleg, mie, mscratch, mstatus, mtvec, satp, stvec}; +use riscv_rt::entry; /// Start function -pub fn start(hart_id: u64, dtb_addr: u64) { +/// - set stack pointer +/// - init mtvec and stvec +/// - jump to mstart +#[entry] +fn _start(hart_id: usize, dtb_addr: usize) -> ! { unsafe { - // clear sstatus.sie - sstatus::clear_sie(); - - // register panic_handler to stvec - stvec::write( - panic_handler as *const fn() as usize, - stvec::TrapMode::Direct, + // set stack pointer + asm!( + "li sp, {} + li t1, {} + mul t0, a0, t1 + add sp, sp, t0", + in(reg) STACK_BASE, + in(reg) STACK_SIZE_PER_HART, ); + + mtvec::write(DRAM_BASE as usize, mtvec::TrapMode::Direct); + stvec::write(DRAM_BASE as usize, mtvec::TrapMode::Direct); } - let device_tree = unsafe { - match fdt::Fdt::from_ptr(dtb_addr as *const u8) { - Ok(fdt) => fdt, - Err(e) => panic!("{}", e), - } - }; + mstart(hart_id, dtb_addr); - let mmap = memmap::Memmap::new(device_tree); - let uart = uart::Uart::new(mmap.uart_addr as u64); - uart.println("starting..."); + unreachable!(); } -/// Panic handler -fn panic_handler() {} +/// 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(); + + mstatus::set_mpp(mstatus::MPP::Supervisor); + mscratch::write(STACK_BASE + STACK_SIZE_PER_HART * hart_id); + satp::set(satp::Mode::Bare, 0, 0); + + mtvec::write(DRAM_BASE as usize, mtvec::TrapMode::Direct); + + sfence_vma_all(); + } +} From 5ef1e01bca0ebc82e3078a391eefe7adc11c88e2 Mon Sep 17 00:00:00 2001 From: Alingof Date: Thu, 31 Aug 2023 22:51:58 +0900 Subject: [PATCH 034/133] [fix] fix a type of constant --- src/memmap.rs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/memmap.rs b/src/memmap.rs index 1437319..b85c568 100644 --- a/src/memmap.rs +++ b/src/memmap.rs @@ -1,10 +1,11 @@ use fdt::Fdt; -pub const DRAM_BASE: u64 = 0x8000_0000; -pub const PAGE_TABLE_BASE: u64 = 0x8020_0000; -pub const PAGE_TABLE_SIZE: u64 = 1024; -pub const STACK_BASE: u64 = 0x8030_0000; -pub const PA2VA_OFFSET: u64 = 0xffff_ffff_4000_0000; +pub const DRAM_BASE: usize = 0x8000_0000; +pub const PAGE_TABLE_BASE: usize = 0x8020_0000; +pub const PAGE_TABLE_SIZE: usize = 1024; +pub const STACK_BASE: usize = 0x8030_0000; +pub const STACK_SIZE_PER_HART: usize = 0x1_0000; +pub const PA2VA_OFFSET: usize = 0xffff_ffff_4000_0000; pub struct Memmap { pub uart_addr: u64, From 63159eb3613af04d814aa0a01141100dbe39a4e4 Mon Sep 17 00:00:00 2001 From: Alingof Date: Thu, 31 Aug 2023 23:14:26 +0900 Subject: [PATCH 035/133] [add] add enter_supervisor_mode() --- src/start.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/start.rs b/src/start.rs index 3081f1d..2920c20 100644 --- a/src/start.rs +++ b/src/start.rs @@ -68,4 +68,14 @@ fn mstart(hart_id: usize, dtb_addr: usize) { sfence_vma_all(); } + + enter_supervisor_mode(hart_id, dtb_addr); +} + +/// enter supervisor (just exec mret) +#[inline(never)] +fn enter_supervisor_mode(_hart_id: usize, _dtb_addr: usize) { + unsafe { + asm!("mret"); + } } From baba3d816f4aaf8b52041ebdade8b2dec87f0e32 Mon Sep 17 00:00:00 2001 From: Alingof Date: Fri, 1 Sep 2023 15:29:57 +0900 Subject: [PATCH 036/133] [wip][add] add trap.S --- src/start.rs | 16 +++-- src/trap.S | 163 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 173 insertions(+), 6 deletions(-) create mode 100644 src/trap.S diff --git a/src/start.rs b/src/start.rs index 2920c20..37cbcac 100644 --- a/src/start.rs +++ b/src/start.rs @@ -4,12 +4,14 @@ extern crate panic_halt; mod memmap; -use core::arch::asm; +use core::arch::{asm, global_asm}; use memmap::{DRAM_BASE, STACK_BASE, STACK_SIZE_PER_HART}; use riscv::asm::sfence_vma_all; -use riscv::register::{mcounteren, medeleg, mideleg, mie, mscratch, mstatus, mtvec, satp, stvec}; +use riscv::register::{medeleg, mideleg, mie, mscratch, mstatus, mtvec, satp, stvec}; use riscv_rt::entry; +global_asm!(include_str!("trap.S")); + /// Start function /// - set stack pointer /// - init mtvec and stvec @@ -19,8 +21,8 @@ fn _start(hart_id: usize, dtb_addr: usize) -> ! { unsafe { // set stack pointer asm!( - "li sp, {} - li t1, {} + "mv sp, {} + mv t1, {} mul t0, a0, t1 add sp, sp, t0", in(reg) STACK_BASE, @@ -64,7 +66,9 @@ fn mstart(hart_id: usize, dtb_addr: usize) { mscratch::write(STACK_BASE + STACK_SIZE_PER_HART * hart_id); satp::set(satp::Mode::Bare, 0, 0); - mtvec::write(DRAM_BASE as usize, mtvec::TrapMode::Direct); + // set trap_vector in trap.S to mtvec + asm!("lla t0, trap_vector"); + asm!("csrw mtvec, t0"); sfence_vma_all(); } @@ -72,7 +76,7 @@ fn mstart(hart_id: usize, dtb_addr: usize) { enter_supervisor_mode(hart_id, dtb_addr); } -/// enter supervisor (just exec mret) +/// Enter supervisor (just exec mret) #[inline(never)] fn enter_supervisor_mode(_hart_id: usize, _dtb_addr: usize) { unsafe { diff --git a/src/trap.S b/src/trap.S new file mode 100644 index 0000000..85e63fc --- /dev/null +++ b/src/trap.S @@ -0,0 +1,163 @@ +.equ SYSCALL_NUM_ECALL, 9 + +trap_vector: + addi sp, sp, -128 + sd ra, 0(sp) + sd t0, 8(sp) + sd t1, 16(sp) + sd t2, 24(sp) + sd t3, 32(sp) + sd t4, 40(sp) + sd t5, 48(sp) + sd t6, 56(sp) + sd a0, 64(sp) + sd a1, 72(sp) + sd a2, 80(sp) + sd a3, 88(sp) + sd a4, 96(sp) + sd a5, 104(sp) + sd a6, 112(sp) + sd a7, 120(sp) + + csrr t0, mcause + bgez t0, exception + j interrupt + +interrupt: + li t1, 0x8000000000000003 + beq t0, t1, machine_software_interrupt + + li t1, 0x8000000000000007 + beq t0, t1, machine_timer_interrupt + + li t1, 0x800000000000000b + beq t0, t1, machine_external_interrupt + +unknown_interrupt: + j unknown_interrupt // loop + +machine_software_interrupt: + csrsi mip, 0x2 // mip.ssip = 1 + + csrr t0, mhartid + slli t0, t0, 2 + li t1, 0x2000000 + add t1, t1, t0 + sw zero, 0(t1) // mtimecmp[hart_id] = 0 + + j return + +machine_timer_interrupt: + li t0, 0x20 + csrs mip, t0 // mip.stip = 1 + + csrr t0, mhartid + slli t0, t0, 2 + li t1, 0x2004000 + add t1, t1, t0 + li t0, 0xffffffffffff + sd zero, 0(t1) // mtimecmp[hart_id] = 0 + + j return + +machine_external_interrupt: + j machine_external_interrupt // loop + +exception: + li t1, SYSCALL_NUM_ECALL + beq t0, t1, ecall_exception + + // other exception + csrw sepc, a2 + csrw scause, a1 + li t0, 0x80 + csrs sstatus, t0 // sstatus.SPP = 1 + csrr t0, stvec + li t1, 0xfffffffffffffffb + and t0, t0, t1 + csrw stvec, t0 + + j return + +ecall_exception: + csrr t0, mepc + addi t0, t0, 4 + csrw mepc, t0 + + beqz a7, sbi_set_timer + + li t1, 3 + beq a7, t1, sbi_clear_ipi + + li t1, 4 + beq a7, t1, sbi_send_ipi + + li t1, 8 + beq a7, t1, sbi_shutdown + + j unknown_exception + +unknown_exception: + j unknown_exception + +sbi_set_timer: + csrr t0, mhartid + slli t0, t0, 3 + li t1, 0x2004000 + add t1, t0, t1 + sd a0, 0(t1) // mtimecmp[hartid] = a0 + + li t0, 0x20 + csrc mip, t0 // mip.stip = 0 + + li a0, 0 + j return_with_value + +sbi_clear_ipi: + csrci mip, 0x2 + li a0, 0 + j return_with_value + +sbi_send_ipi: + li t2, 1 << 17 // t2 = MPRV + csrrs t1, mstatus, t2 + ld t0, 0(a0) + csrw mstatus, t1 + + li t2, (0x02000000 - 4) +1: addi t2, t2, 4 + andi t1, t0, 0x1 + srli t0, t0, 1 + beqz t1, 1b + sw t1, 0(t2) + bnez t0, 1b + + li a0, 0 + j return_with_value + +sbi_shutdown: + j sbi_shutdown + + +return: + ld a0, 64(sp) +return_with_value: + ld ra, 0(sp) + ld t0, 8(sp) + ld t1, 16(sp) + ld t2, 24(sp) + ld t3, 32(sp) + ld t4, 40(sp) + ld t5, 48(sp) + ld t6, 56(sp) + ld a1, 72(sp) + ld a2, 80(sp) + ld a3, 88(sp) + ld a4, 96(sp) + ld a5, 104(sp) + ld a6, 112(sp) + ld a7, 120(sp) + addi sp, sp, 128 + csrrw sp, mscratch, sp + mret + From 168adfc5e9751b02d54b36bda6770a87b687edeb Mon Sep 17 00:00:00 2001 From: Alingof Date: Fri, 1 Sep 2023 17:43:36 +0900 Subject: [PATCH 037/133] [add] add initrd_addr member to Memmap --- src/memmap.rs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/memmap.rs b/src/memmap.rs index b85c568..21474a9 100644 --- a/src/memmap.rs +++ b/src/memmap.rs @@ -9,6 +9,7 @@ pub const PA2VA_OFFSET: usize = 0xffff_ffff_4000_0000; pub struct Memmap { pub uart_addr: u64, + pub initrd_addr: usize, } impl Memmap { @@ -21,7 +22,16 @@ impl Memmap { .next() .unwrap() .starting_address as u64; + let initrd_addr = device_tree + .find_node("/soc/chosen") + .unwrap() + .property("linux,initrd-start") + .unwrap() + .value[0] as usize; - Memmap { uart_addr } + Memmap { + uart_addr, + initrd_addr, + } } } From eadcdef70ed193f4f1a59b3948885d6cd8793d4d Mon Sep 17 00:00:00 2001 From: Alingof Date: Fri, 1 Sep 2023 17:44:29 +0900 Subject: [PATCH 038/133] [wip][update] modify to set initrd_addr to mepc --- .cargo/config | 4 ++-- src/start.rs | 26 ++++++++++++++++++++++---- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/.cargo/config b/.cargo/config index 272ef79..90e66a6 100644 --- a/.cargo/config +++ b/.cargo/config @@ -1,6 +1,6 @@ [target.riscv64imac-unknown-none-elf] -#runner = "qemu-system-riscv64 -S -gdb tcp::10000 -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" +runner = "qemu-system-riscv64 -S -gdb tcp::10000 -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", diff --git a/src/start.rs b/src/start.rs index 37cbcac..a04f54d 100644 --- a/src/start.rs +++ b/src/start.rs @@ -7,7 +7,7 @@ mod memmap; use core::arch::{asm, global_asm}; use memmap::{DRAM_BASE, STACK_BASE, STACK_SIZE_PER_HART}; use riscv::asm::sfence_vma_all; -use riscv::register::{medeleg, mideleg, mie, mscratch, mstatus, mtvec, satp, stvec}; +use riscv::register::{medeleg, mepc, mideleg, mie, mscratch, mstatus, mtvec, satp, stvec}; use riscv_rt::entry; global_asm!(include_str!("trap.S")); @@ -17,18 +17,26 @@ global_asm!(include_str!("trap.S")); /// - init mtvec and stvec /// - jump to mstart #[entry] -fn _start(hart_id: usize, dtb_addr: usize) -> ! { +fn _start(mut hart_id: usize, mut dtb_addr: usize) -> ! { unsafe { // set stack pointer asm!( - "mv sp, {} + " + mv a0, {} + mv a1, {} mv t1, {} mul t0, a0, t1 + mv sp, {} add sp, sp, t0", - in(reg) STACK_BASE, + in(reg) hart_id, + in(reg) dtb_addr, in(reg) STACK_SIZE_PER_HART, + in(reg) STACK_BASE, ); + asm!("mv {}, a0", out(reg) hart_id); + asm!("mv {}, a1", out(reg) dtb_addr); + mtvec::write(DRAM_BASE as usize, mtvec::TrapMode::Direct); stvec::write(DRAM_BASE as usize, mtvec::TrapMode::Direct); } @@ -40,6 +48,14 @@ fn _start(hart_id: usize, dtb_addr: usize) -> ! { /// Machine start function fn mstart(hart_id: usize, dtb_addr: usize) { + let device_tree = unsafe { + match fdt::Fdt::from_ptr(dtb_addr as *const u8) { + Ok(fdt) => fdt, + Err(e) => panic!("{}", e), + } + }; + let mmap = memmap::Memmap::new(device_tree); + unsafe { // mideleg = 0x0222 mideleg::set_sext(); @@ -66,6 +82,8 @@ fn mstart(hart_id: usize, dtb_addr: usize) { mscratch::write(STACK_BASE + STACK_SIZE_PER_HART * hart_id); satp::set(satp::Mode::Bare, 0, 0); + mepc::write(mmap.initrd_addr); + // set trap_vector in trap.S to mtvec asm!("lla t0, trap_vector"); asm!("csrw mtvec, t0"); From 4ddb7cf09ffa4b44490b3edcb8d165dfe4cb270c Mon Sep 17 00:00:00 2001 From: Alingof Date: Sat, 2 Sep 2023 14:21:35 +0900 Subject: [PATCH 039/133] [fix] fix uart path in dtb --- src/memmap.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/memmap.rs b/src/memmap.rs index 21474a9..c4c88b8 100644 --- a/src/memmap.rs +++ b/src/memmap.rs @@ -23,7 +23,7 @@ impl Memmap { .unwrap() .starting_address as u64; let initrd_addr = device_tree - .find_node("/soc/chosen") + .find_node("/chosen") .unwrap() .property("linux,initrd-start") .unwrap() From bf1325bf0cba621b072536cc37bb110f4d6db98b Mon Sep 17 00:00:00 2001 From: Alingof Date: Sat, 2 Sep 2023 14:22:21 +0900 Subject: [PATCH 040/133] [fix] fix _start function --- src/start.rs | 36 +++++++++++++++++------------------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/src/start.rs b/src/start.rs index a04f54d..295b737 100644 --- a/src/start.rs +++ b/src/start.rs @@ -7,7 +7,7 @@ mod memmap; use core::arch::{asm, global_asm}; use memmap::{DRAM_BASE, STACK_BASE, STACK_SIZE_PER_HART}; use riscv::asm::sfence_vma_all; -use riscv::register::{medeleg, mepc, mideleg, mie, mscratch, mstatus, mtvec, satp, stvec}; +use riscv::register::{medeleg, mepc, mideleg, mie, mscratch, mstatus, satp}; use riscv_rt::entry; global_asm!(include_str!("trap.S")); @@ -17,32 +17,30 @@ global_asm!(include_str!("trap.S")); /// - init mtvec and stvec /// - jump to mstart #[entry] -fn _start(mut hart_id: usize, mut dtb_addr: usize) -> ! { +fn _start(hart_id: usize, dtb_addr: usize) -> ! { unsafe { // set stack pointer asm!( " - mv a0, {} - mv a1, {} - mv t1, {} + mv a0, {hart_id} + mv a1, {dtb_addr} + mv t1, {stack_size_per_hart} mul t0, a0, t1 - mv sp, {} - add sp, sp, t0", - in(reg) hart_id, - in(reg) dtb_addr, - in(reg) STACK_SIZE_PER_HART, - in(reg) STACK_BASE, + 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, ); - - asm!("mv {}, a0", out(reg) hart_id); - asm!("mv {}, a1", out(reg) dtb_addr); - - mtvec::write(DRAM_BASE as usize, mtvec::TrapMode::Direct); - stvec::write(DRAM_BASE as usize, mtvec::TrapMode::Direct); } - mstart(hart_id, dtb_addr); - unreachable!(); } From 7ecd05a54a8bc8eb32a7f6587df0ac38a9ecd0e4 Mon Sep 17 00:00:00 2001 From: Alingof Date: Sat, 2 Sep 2023 16:54:03 +0900 Subject: [PATCH 041/133] [wip][add] add sstart() --- .cargo/config | 2 +- src/start.rs | 17 ++++++++--------- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/.cargo/config b/.cargo/config index 90e66a6..096e848 100644 --- a/.cargo/config +++ b/.cargo/config @@ -1,5 +1,5 @@ [target.riscv64imac-unknown-none-elf] -runner = "qemu-system-riscv64 -S -gdb tcp::10000 -machine virt -bios none -nographic -m 2G -initrd fedora-vmlinux -kernel" +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 = [ diff --git a/src/start.rs b/src/start.rs index 295b737..c4e1c20 100644 --- a/src/start.rs +++ b/src/start.rs @@ -46,14 +46,6 @@ fn _start(hart_id: usize, dtb_addr: usize) -> ! { /// Machine start function fn mstart(hart_id: usize, dtb_addr: usize) { - let device_tree = unsafe { - match fdt::Fdt::from_ptr(dtb_addr as *const u8) { - Ok(fdt) => fdt, - Err(e) => panic!("{}", e), - } - }; - let mmap = memmap::Memmap::new(device_tree); - unsafe { // mideleg = 0x0222 mideleg::set_sext(); @@ -80,7 +72,7 @@ fn mstart(hart_id: usize, dtb_addr: usize) { mscratch::write(STACK_BASE + STACK_SIZE_PER_HART * hart_id); satp::set(satp::Mode::Bare, 0, 0); - mepc::write(mmap.initrd_addr); + mepc::write(sstart as *const fn() as usize); // set trap_vector in trap.S to mtvec asm!("lla t0, trap_vector"); @@ -99,3 +91,10 @@ fn enter_supervisor_mode(_hart_id: usize, _dtb_addr: usize) { asm!("mret"); } } + +/// Supervisor start function +fn sstart() { + unsafe { + asm!(""); + } +} From 9b891cc4999bc18a6096dea925def2fbe6280672 Mon Sep 17 00:00:00 2001 From: Alingof Date: Sun, 3 Sep 2023 00:31:17 +0900 Subject: [PATCH 042/133] [add] move sstart.rs to supervisor_init.rs --- src/supervisor_init.rs | 51 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 src/supervisor_init.rs diff --git a/src/supervisor_init.rs b/src/supervisor_init.rs new file mode 100644 index 0000000..e209fb0 --- /dev/null +++ b/src/supervisor_init.rs @@ -0,0 +1,51 @@ +use crate::memmap::{DRAM_BASE, PA2VA_OFFSET, PAGE_TABLE_BASE, PAGE_TABLE_SIZE, STACK_BASE}; +use core::arch::asm; +use riscv::asm::sfence_vma; +use riscv::register::{mtvec, satp, stvec}; + +/// Supervisor start function +pub fn sstart() { + let hart_id: usize; + let dtb_addr: usize; + unsafe { + // get hart id + asm!("mv {}, a0", out(reg) hart_id); + asm!("mv {}, a1", out(reg) dtb_addr); + } + + // init stack pointer + let stack_pointer = STACK_BASE + PA2VA_OFFSET; + unsafe { + asm!("mv sp, {}", in(reg) stack_pointer); + } + + // init page tables + let offset_from_dram_base = sstart as *const fn() as usize - DRAM_BASE; + let offset_from_dram_base_masked = (offset_from_dram_base >> 21) << 19; + let page_table_start = PAGE_TABLE_BASE + offset_from_dram_base + hart_id * PAGE_TABLE_SIZE; + for pt_index in 511..1024 { + let pt_offset = (page_table_start + pt_index * 8) as *mut usize; + unsafe { + pt_offset.write_volatile(pt_offset.read_volatile() + offset_from_dram_base_masked); + } + } + + unsafe { + // init trap vector + stvec::write(trampoline as *const fn() as usize, mtvec::TrapMode::Direct); + + // set satp(Supervisor Address Translation and Protection) register + satp::set(satp::Mode::Sv39, 0, (page_table_start >> 12) as usize); + + // sfence.vma + sfence_vma(0, 0); + } + + // jump to trampoline + trampoline(hart_id, dtb_addr); + + unreachable!() +} + +/// Jump to start +pub fn trampoline(hart_id: usize, dtb_addr: usize) {} From c1a0fe0cab918b9f69b61dd8a7d538c322a6b70d Mon Sep 17 00:00:00 2001 From: Alingof Date: Sun, 3 Sep 2023 00:33:59 +0900 Subject: [PATCH 043/133] [update] rename start.rs to machine_init.rs --- Cargo.toml | 2 +- src/{start.rs => machine_init.rs} | 13 ++++--------- 2 files changed, 5 insertions(+), 10 deletions(-) rename src/{start.rs => machine_init.rs} (92%) diff --git a/Cargo.toml b/Cargo.toml index 24ab349..8bef919 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" [[bin]] name = "hikami" -path = "src/start.rs" +path = "src/machine_init.rs" [dependencies] fdt = "0.1.5" diff --git a/src/start.rs b/src/machine_init.rs similarity index 92% rename from src/start.rs rename to src/machine_init.rs index c4e1c20..f31cbe0 100644 --- a/src/start.rs +++ b/src/machine_init.rs @@ -3,9 +3,10 @@ extern crate panic_halt; mod memmap; +mod supervisor_init; +use crate::memmap::{DRAM_BASE, STACK_BASE, STACK_SIZE_PER_HART}; use core::arch::{asm, global_asm}; -use memmap::{DRAM_BASE, STACK_BASE, STACK_SIZE_PER_HART}; use riscv::asm::sfence_vma_all; use riscv::register::{medeleg, mepc, mideleg, mie, mscratch, mstatus, satp}; use riscv_rt::entry; @@ -72,7 +73,7 @@ fn mstart(hart_id: usize, dtb_addr: usize) { mscratch::write(STACK_BASE + STACK_SIZE_PER_HART * hart_id); satp::set(satp::Mode::Bare, 0, 0); - mepc::write(sstart as *const fn() as usize); + mepc::write(supervisor_init::sstart as *const fn() as usize); // set trap_vector in trap.S to mtvec asm!("lla t0, trap_vector"); @@ -85,16 +86,10 @@ fn mstart(hart_id: usize, dtb_addr: usize) { } /// Enter supervisor (just exec mret) +/// Jump to sstart #[inline(never)] fn enter_supervisor_mode(_hart_id: usize, _dtb_addr: usize) { unsafe { asm!("mret"); } } - -/// Supervisor start function -fn sstart() { - unsafe { - asm!(""); - } -} From 78a7ec69bd857415f9fbd145c2d74a49e6f2ed30 Mon Sep 17 00:00:00 2001 From: Alingof Date: Sun, 3 Sep 2023 01:41:57 +0900 Subject: [PATCH 044/133] [wip][add] add trampoline() and smode_setup() and panic_handler() --- src/supervisor_init.rs | 35 ++++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/src/supervisor_init.rs b/src/supervisor_init.rs index e209fb0..4bece4d 100644 --- a/src/supervisor_init.rs +++ b/src/supervisor_init.rs @@ -1,24 +1,24 @@ use crate::memmap::{DRAM_BASE, PA2VA_OFFSET, PAGE_TABLE_BASE, PAGE_TABLE_SIZE, STACK_BASE}; use core::arch::asm; use riscv::asm::sfence_vma; -use riscv::register::{mtvec, satp, stvec}; +use riscv::register::{mtvec, satp, sstatus, stvec}; /// Supervisor start function pub fn sstart() { + // init stack pointer + let stack_pointer = STACK_BASE + PA2VA_OFFSET; + unsafe { + asm!("mv sp, {}", in(reg) stack_pointer); + } + let hart_id: usize; let dtb_addr: usize; unsafe { - // get hart id + // get an arguments asm!("mv {}, a0", out(reg) hart_id); asm!("mv {}, a1", out(reg) dtb_addr); } - // init stack pointer - let stack_pointer = STACK_BASE + PA2VA_OFFSET; - unsafe { - asm!("mv sp, {}", in(reg) stack_pointer); - } - // init page tables let offset_from_dram_base = sstart as *const fn() as usize - DRAM_BASE; let offset_from_dram_base_masked = (offset_from_dram_base >> 21) << 19; @@ -48,4 +48,21 @@ pub fn sstart() { } /// Jump to start -pub fn trampoline(hart_id: usize, dtb_addr: usize) {} +#[inline(never)] +fn trampoline(hart_id: usize, dtb_addr: usize) { + smode_setup(hart_id, dtb_addr); +} + +fn smode_setup(hart_id: usize, dtb_addr: usize) { + unsafe { + sstatus::clear_sie(); + stvec::write( + panic_handler as *const fn() as usize, + stvec::TrapMode::Direct, + ); + } +} + +fn panic_handler() { + panic!("trap from panic macro") +} From 99739b55126ddf03ad7286b4efd85c2b90f18b34 Mon Sep 17 00:00:00 2001 From: Alingof Date: Mon, 4 Sep 2023 15:06:14 +0900 Subject: [PATCH 045/133] [add] add struct Device and modify Memmap member type --- src/memmap.rs | 66 ++++++++++++++++++++++++++++++------------ src/supervisor_init.rs | 9 ++++++ 2 files changed, 56 insertions(+), 19 deletions(-) diff --git a/src/memmap.rs b/src/memmap.rs index c4c88b8..dcb2139 100644 --- a/src/memmap.rs +++ b/src/memmap.rs @@ -7,31 +7,59 @@ pub const STACK_BASE: usize = 0x8030_0000; pub const STACK_SIZE_PER_HART: usize = 0x1_0000; pub const PA2VA_OFFSET: usize = 0xffff_ffff_4000_0000; -pub struct Memmap { - pub uart_addr: u64, - pub initrd_addr: usize, +pub struct Device { + addr: usize, + size: usize, } -impl Memmap { - pub fn new(device_tree: Fdt) -> Self { - let uart_addr = device_tree - .find_node("/soc/serial") +impl Device { + fn new(device_tree: &Fdt, node_path: &str) -> Self { + let region = device_tree + .find_node(node_path) .unwrap() .reg() .unwrap() - .next() - .unwrap() - .starting_address as u64; - let initrd_addr = device_tree - .find_node("/chosen") - .unwrap() - .property("linux,initrd-start") - .unwrap() - .value[0] as usize; + .nth(0) + .unwrap(); + + Device { + addr: region.starting_address as usize, + size: region.size.unwrap(), + } + } + + fn new_by_property( + device_tree: &Fdt, + node_path: &str, + start_prop: &str, + end_prop: &str, + ) -> Self { + let node = device_tree.find_node(node_path).unwrap(); + let start = node.property(start_prop).unwrap().value[0] as usize; + let end = node.property(end_prop).unwrap().value[0] as usize; - Memmap { - uart_addr, - initrd_addr, + Device { + addr: start, + size: end - start, } } } + +pub struct Memmap { + pub uart: Device, + pub initrd: Device, +} + +impl Memmap { + pub fn new(device_tree: Fdt) -> Self { + let uart = Device::new(&device_tree, "/soc/serial"); + let initrd = Device::new_by_property( + &device_tree, + "/chosen", + "linux,initrd-start", + "linux,initrd-end", + ); + + Memmap { uart, initrd } + } +} diff --git a/src/supervisor_init.rs b/src/supervisor_init.rs index 4bece4d..672cd37 100644 --- a/src/supervisor_init.rs +++ b/src/supervisor_init.rs @@ -1,3 +1,4 @@ +use crate::memmap::Memmap; use crate::memmap::{DRAM_BASE, PA2VA_OFFSET, PAGE_TABLE_BASE, PAGE_TABLE_SIZE, STACK_BASE}; use core::arch::asm; use riscv::asm::sfence_vma; @@ -61,6 +62,14 @@ fn smode_setup(hart_id: usize, dtb_addr: usize) { stvec::TrapMode::Direct, ); } + + let device_tree = unsafe { + match fdt::Fdt::from_ptr(dtb_addr as *const u8) { + Ok(fdt) => fdt, + Err(e) => panic!("{}", e), + } + }; + let mmap = Memmap::new(device_tree); } fn panic_handler() { From a71a7a62ddcd42ad9ff8f196f5971113dd921bf0 Mon Sep 17 00:00:00 2001 From: Alingof Date: Mon, 4 Sep 2023 15:10:09 +0900 Subject: [PATCH 046/133] [add] add the plic member to Memmap --- src/memmap.rs | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/memmap.rs b/src/memmap.rs index dcb2139..a6c3dcb 100644 --- a/src/memmap.rs +++ b/src/memmap.rs @@ -48,18 +48,20 @@ impl Device { pub struct Memmap { pub uart: Device, pub initrd: Device, + pub plic: Device, } impl Memmap { pub fn new(device_tree: Fdt) -> Self { - let uart = Device::new(&device_tree, "/soc/serial"); - let initrd = Device::new_by_property( - &device_tree, - "/chosen", - "linux,initrd-start", - "linux,initrd-end", - ); - - Memmap { uart, initrd } + Memmap { + uart: Device::new(&device_tree, "/soc/serial"), + initrd: Device::new_by_property( + &device_tree, + "/chosen", + "linux,initrd-start", + "linux,initrd-end", + ), + plic: Device::new(&device_tree, "/soc/plic"), + } } } From 86150a38ae8633d1ba613009c18d391301b1c999 Mon Sep 17 00:00:00 2001 From: Alingof Date: Mon, 4 Sep 2023 16:08:26 +0900 Subject: [PATCH 047/133] [add] implement methods paddr() and vaddr() to Device --- src/memmap.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/memmap.rs b/src/memmap.rs index a6c3dcb..468997a 100644 --- a/src/memmap.rs +++ b/src/memmap.rs @@ -1,6 +1,7 @@ use fdt::Fdt; pub const DRAM_BASE: usize = 0x8000_0000; +pub const DRAM_SIZE_PAR_HART: usize = 0x1000_0000; pub const PAGE_TABLE_BASE: usize = 0x8020_0000; pub const PAGE_TABLE_SIZE: usize = 1024; pub const STACK_BASE: usize = 0x8030_0000; @@ -43,6 +44,14 @@ impl Device { size: end - start, } } + + fn paddr(&self) -> usize { + self.addr + } + + pub fn vaddr(&self) -> usize { + self.addr + PA2VA_OFFSET + } } pub struct Memmap { From 57e234b082f8b57e199db1b65c42984544306c7d Mon Sep 17 00:00:00 2001 From: Alingof Date: Mon, 4 Sep 2023 17:28:32 +0900 Subject: [PATCH 048/133] [update] modify to declare trap_vector as extern function --- src/machine_init.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/machine_init.rs b/src/machine_init.rs index f31cbe0..92a9d71 100644 --- a/src/machine_init.rs +++ b/src/machine_init.rs @@ -8,10 +8,13 @@ mod supervisor_init; use crate::memmap::{DRAM_BASE, STACK_BASE, STACK_SIZE_PER_HART}; use core::arch::{asm, global_asm}; use riscv::asm::sfence_vma_all; -use riscv::register::{medeleg, mepc, mideleg, mie, mscratch, mstatus, satp}; +use riscv::register::{medeleg, mepc, mideleg, mie, mscratch, mstatus, mtvec, satp}; use riscv_rt::entry; global_asm!(include_str!("trap.S")); +extern "C" { + fn trap_vector(); +} /// Start function /// - set stack pointer @@ -76,8 +79,7 @@ fn mstart(hart_id: usize, dtb_addr: usize) { mepc::write(supervisor_init::sstart as *const fn() as usize); // set trap_vector in trap.S to mtvec - asm!("lla t0, trap_vector"); - asm!("csrw mtvec, t0"); + mtvec::write(trap_vector as *const fn() as usize, mtvec::TrapMode::Direct); sfence_vma_all(); } From a67400d62aa1e76f99e46bb7d8635f37a08cd491 Mon Sep 17 00:00:00 2001 From: Alingof Date: Mon, 4 Sep 2023 17:29:27 +0900 Subject: [PATCH 049/133] [add] add enter_user_mode() --- src/supervisor_init.rs | 93 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 91 insertions(+), 2 deletions(-) diff --git a/src/supervisor_init.rs b/src/supervisor_init.rs index 672cd37..02b7e47 100644 --- a/src/supervisor_init.rs +++ b/src/supervisor_init.rs @@ -1,8 +1,15 @@ use crate::memmap::Memmap; -use crate::memmap::{DRAM_BASE, PA2VA_OFFSET, PAGE_TABLE_BASE, PAGE_TABLE_SIZE, STACK_BASE}; +use crate::memmap::{ + DRAM_BASE, DRAM_SIZE_PAR_HART, PA2VA_OFFSET, PAGE_TABLE_BASE, PAGE_TABLE_SIZE, STACK_BASE, + STACK_SIZE_PER_HART, +}; use core::arch::asm; use riscv::asm::sfence_vma; -use riscv::register::{mtvec, satp, sstatus, stvec}; +use riscv::register::{mtvec, satp, sie, sstatus, stvec}; + +extern "C" { + fn trap_vector(); +} /// Supervisor start function pub fn sstart() { @@ -63,6 +70,7 @@ fn smode_setup(hart_id: usize, dtb_addr: usize) { ); } + // parse device tree let device_tree = unsafe { match fdt::Fdt::from_ptr(dtb_addr as *const u8) { Ok(fdt) => fdt, @@ -70,6 +78,87 @@ fn smode_setup(hart_id: usize, dtb_addr: usize) { } }; let mmap = Memmap::new(device_tree); + + // set plic priorities + for plic_num in 1..127 { + unsafe { + *((mmap.plic.vaddr() + plic_num * 4) as *mut u32) = 1; + } + } + + unsafe { + // set sie = 0x222 + sie::set_ssoft(); + sie::set_stimer(); + sie::set_sext(); + + // satp = Sv39 | 0x8000_0000 >> 12 + satp::set( + satp::Mode::Sv39, + 0, + (DRAM_BASE + DRAM_SIZE_PAR_HART * hart_id) >> 12, + ); + + let stack_pointer = STACK_BASE + STACK_SIZE_PER_HART * hart_id + PA2VA_OFFSET; + asm!("mv a0, {dtb_addr}", dtb_addr = in(reg) dtb_addr); + asm!("mv sp, {stack_pointer_in_umode}", stack_pointer_in_umode = in(reg) stack_pointer); + asm!("j {enter_user_mode}", enter_user_mode = sym enter_user_mode); + } +} + +fn enter_user_mode(dtb_addr: usize) { + unsafe { + // set sie = 0x222 + sie::set_ssoft(); + sie::set_stimer(); + sie::set_sext(); + + // sstatus.SUM = 1, sstatus.SPP = 0 + sstatus::set_sum(); + sstatus::set_spp(sstatus::SPP::User); + + stvec::write(trap_vector as *const fn() as usize, stvec::TrapMode::Direct); + + asm!( + " + mv a1, {dtb_addr} + + li ra, 0 + li sp, 0 + li gp, 0 + li tp, 0 + li t0, 0 + li t1, 0 + li t2, 0 + li s0, 0 + li s1, 0 + li a0, 0 + li a2, 0 + li a3, 0 + li a4, 0 + li a5, 0 + li a6, 0 + li a7, 0 + li s2, 0 + li s3, 0 + li s4, 0 + li s5, 0 + li s6, 0 + li s7, 0 + li s8, 0 + li s9, 0 + li s10, 0 + li s11, 0 + li t3, 0 + li t4, 0 + li t5, 0 + li t6, 0 + sret + ", + dtb_addr = in(reg) dtb_addr + ); + } + unreachable!(); } fn panic_handler() { From 5e6e7714c2ef90b1accb780db9b9b7417fa421f3 Mon Sep 17 00:00:00 2001 From: Alingof Date: Mon, 4 Sep 2023 17:59:39 +0900 Subject: [PATCH 050/133] [fix] make trap_vector function in trap.S global --- src/supervisor_init.rs | 5 +---- src/trap.S | 1 + 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/supervisor_init.rs b/src/supervisor_init.rs index 02b7e47..2a6831d 100644 --- a/src/supervisor_init.rs +++ b/src/supervisor_init.rs @@ -3,14 +3,11 @@ use crate::memmap::{ DRAM_BASE, DRAM_SIZE_PAR_HART, PA2VA_OFFSET, PAGE_TABLE_BASE, PAGE_TABLE_SIZE, STACK_BASE, STACK_SIZE_PER_HART, }; +use crate::trap_vector; use core::arch::asm; use riscv::asm::sfence_vma; use riscv::register::{mtvec, satp, sie, sstatus, stvec}; -extern "C" { - fn trap_vector(); -} - /// Supervisor start function pub fn sstart() { // init stack pointer diff --git a/src/trap.S b/src/trap.S index 85e63fc..ab1d71e 100644 --- a/src/trap.S +++ b/src/trap.S @@ -1,4 +1,5 @@ .equ SYSCALL_NUM_ECALL, 9 +.globl trap_vector trap_vector: addi sp, sp, -128 From 065837a7252935f23a886bcccb9820d887fd6205 Mon Sep 17 00:00:00 2001 From: Alingof Date: Mon, 4 Sep 2023 18:46:06 +0900 Subject: [PATCH 051/133] [fix] modify to set mcounteren, pmpaddr0, pmpcfg0 CSRs --- src/machine_init.rs | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/src/machine_init.rs b/src/machine_init.rs index 92a9d71..3b1b4ed 100644 --- a/src/machine_init.rs +++ b/src/machine_init.rs @@ -8,7 +8,9 @@ mod supervisor_init; use crate::memmap::{DRAM_BASE, STACK_BASE, STACK_SIZE_PER_HART}; use core::arch::{asm, global_asm}; use riscv::asm::sfence_vma_all; -use riscv::register::{medeleg, mepc, mideleg, mie, mscratch, mstatus, mtvec, satp}; +use riscv::register::{ + mcounteren, medeleg, mepc, mideleg, mie, mscratch, mstatus, mtvec, pmpaddr0, pmpcfg0, satp, +}; use riscv_rt::entry; global_asm!(include_str!("trap.S")); @@ -72,8 +74,43 @@ fn mstart(hart_id: usize, dtb_addr: usize) { 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); From dba3c6d61c708943dc672b503ac015a3157b2f5b Mon Sep 17 00:00:00 2001 From: Alignof Date: Mon, 4 Sep 2023 22:10:25 +0900 Subject: [PATCH 052/133] [fix] fix machine_timer_interrupt in trap.S --- src/trap.S | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/trap.S b/src/trap.S index ab1d71e..0ae1c49 100644 --- a/src/trap.S +++ b/src/trap.S @@ -53,11 +53,11 @@ machine_timer_interrupt: csrs mip, t0 // mip.stip = 1 csrr t0, mhartid - slli t0, t0, 2 - li t1, 0x2004000 + slli t0, t0, 3 + li t1, 0x2004000 // mtimecmp add t1, t1, t0 li t0, 0xffffffffffff - sd zero, 0(t1) // mtimecmp[hart_id] = 0 + sd t0, 0(t1) // mtimecmp[hart_id] = 0 j return From 387db9ea180385e049d6e1d8319064a471d196da Mon Sep 17 00:00:00 2001 From: Alignof Date: Tue, 5 Sep 2023 00:06:02 +0900 Subject: [PATCH 053/133] [fix] rewrite the second half of sstart in assembly --- src/supervisor_init.rs | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/src/supervisor_init.rs b/src/supervisor_init.rs index 2a6831d..72c9479 100644 --- a/src/supervisor_init.rs +++ b/src/supervisor_init.rs @@ -5,17 +5,10 @@ use crate::memmap::{ }; use crate::trap_vector; use core::arch::asm; -use riscv::asm::sfence_vma; use riscv::register::{mtvec, satp, sie, sstatus, stvec}; /// Supervisor start function pub fn sstart() { - // init stack pointer - let stack_pointer = STACK_BASE + PA2VA_OFFSET; - unsafe { - asm!("mv sp, {}", in(reg) stack_pointer); - } - let hart_id: usize; let dtb_addr: usize; unsafe { @@ -31,7 +24,7 @@ pub fn sstart() { for pt_index in 511..1024 { let pt_offset = (page_table_start + pt_index * 8) as *mut usize; unsafe { - pt_offset.write_volatile(pt_offset.read_volatile() + offset_from_dram_base_masked); + pt_offset.write_volatile(offset_from_dram_base_masked + pt_offset.read_volatile()); } } @@ -39,16 +32,26 @@ pub fn sstart() { // init trap vector stvec::write(trampoline as *const fn() as usize, mtvec::TrapMode::Direct); - // set satp(Supervisor Address Translation and Protection) register - satp::set(satp::Mode::Sv39, 0, (page_table_start >> 12) as usize); - - // sfence.vma - sfence_vma(0, 0); + // init stack pointer + let stack_pointer = STACK_BASE + PA2VA_OFFSET; + let satp_config = (0b1000 << 60) | (page_table_start >> 12); + asm!( + " + mv a0, {hart_id} + mv a1, {dtb_addr} + mv sp, {stack_pointer} + csrw satp, {satp_config} + sfence.vma + j {trampoline} + ", + hart_id = in(reg) hart_id, + dtb_addr = in(reg) dtb_addr, + stack_pointer = in(reg) stack_pointer, + satp_config = in(reg) satp_config, + trampoline = sym trampoline + ); } - // jump to trampoline - trampoline(hart_id, dtb_addr); - unreachable!() } From ae8d50e6d0eaf6c08325dcae4e6420ff969850bc Mon Sep 17 00:00:00 2001 From: Alignof Date: Tue, 5 Sep 2023 00:06:55 +0900 Subject: [PATCH 054/133] [add] add forward_exception() to machine_init.rs --- src/machine_init.rs | 29 ++++++++++++++++++++++++++++- src/trap.S | 9 +-------- 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/src/machine_init.rs b/src/machine_init.rs index 3b1b4ed..7d3a1b0 100644 --- a/src/machine_init.rs +++ b/src/machine_init.rs @@ -9,7 +9,8 @@ use crate::memmap::{DRAM_BASE, STACK_BASE, STACK_SIZE_PER_HART}; use core::arch::{asm, global_asm}; use riscv::asm::sfence_vma_all; use riscv::register::{ - mcounteren, medeleg, mepc, mideleg, mie, mscratch, mstatus, mtvec, pmpaddr0, pmpcfg0, satp, + mcause, mcounteren, medeleg, mepc, mideleg, mie, mscratch, mstatus, mtval, mtvec, pmpaddr0, + pmpcfg0, satp, scause, sepc, stval, stvec, }; use riscv_rt::entry; @@ -124,6 +125,32 @@ fn mstart(hart_id: usize, dtb_addr: usize) { enter_supervisor_mode(hart_id, dtb_addr); } +#[no_mangle] +/// Delegate exception to supervisor mode +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 #[inline(never)] diff --git a/src/trap.S b/src/trap.S index 0ae1c49..ad04b08 100644 --- a/src/trap.S +++ b/src/trap.S @@ -69,14 +69,7 @@ exception: beq t0, t1, ecall_exception // other exception - csrw sepc, a2 - csrw scause, a1 - li t0, 0x80 - csrs sstatus, t0 // sstatus.SPP = 1 - csrr t0, stvec - li t1, 0xfffffffffffffffb - and t0, t0, t1 - csrw stvec, t0 + call forward_exception j return From 3f450f0347ca3da913588d633f5d1a66ee05201e Mon Sep 17 00:00:00 2001 From: Alingof Date: Tue, 5 Sep 2023 21:04:59 +0900 Subject: [PATCH 055/133] [wip][fix] fix stvec address --- src/supervisor_init.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/supervisor_init.rs b/src/supervisor_init.rs index 72c9479..0d82ab6 100644 --- a/src/supervisor_init.rs +++ b/src/supervisor_init.rs @@ -5,7 +5,7 @@ use crate::memmap::{ }; use crate::trap_vector; use core::arch::asm; -use riscv::register::{mtvec, satp, sie, sstatus, stvec}; +use riscv::register::{satp, sie, sstatus, stvec}; /// Supervisor start function pub fn sstart() { @@ -30,7 +30,11 @@ pub fn sstart() { unsafe { // init trap vector - stvec::write(trampoline as *const fn() as usize, mtvec::TrapMode::Direct); + stvec::write( + // stvec address must be 4byte aligned. + trampoline as *const fn() as usize + PA2VA_OFFSET & !0b11, + stvec::TrapMode::Direct, + ); // init stack pointer let stack_pointer = STACK_BASE + PA2VA_OFFSET; From 64eccac99ade11a34893e132d11c08a256fb7f4c Mon Sep 17 00:00:00 2001 From: Alingof Date: Tue, 5 Sep 2023 23:57:53 +0900 Subject: [PATCH 056/133] [fix] fix creating page table --- src/memmap.rs | 3 ++- src/supervisor_init.rs | 14 ++++++++------ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/memmap.rs b/src/memmap.rs index 468997a..adb7b8e 100644 --- a/src/memmap.rs +++ b/src/memmap.rs @@ -3,7 +3,8 @@ use fdt::Fdt; pub const DRAM_BASE: usize = 0x8000_0000; pub const DRAM_SIZE_PAR_HART: usize = 0x1000_0000; pub const PAGE_TABLE_BASE: usize = 0x8020_0000; -pub const PAGE_TABLE_SIZE: usize = 1024; +pub const PAGE_SIZE: usize = 4096; +pub const PAGE_TABLE_OFFSET_PER_HART: usize = 1024; pub const STACK_BASE: usize = 0x8030_0000; pub const STACK_SIZE_PER_HART: usize = 0x1_0000; pub const PA2VA_OFFSET: usize = 0xffff_ffff_4000_0000; diff --git a/src/supervisor_init.rs b/src/supervisor_init.rs index 0d82ab6..4349762 100644 --- a/src/supervisor_init.rs +++ b/src/supervisor_init.rs @@ -1,7 +1,7 @@ use crate::memmap::Memmap; use crate::memmap::{ - DRAM_BASE, DRAM_SIZE_PAR_HART, PA2VA_OFFSET, PAGE_TABLE_BASE, PAGE_TABLE_SIZE, STACK_BASE, - STACK_SIZE_PER_HART, + DRAM_BASE, DRAM_SIZE_PAR_HART, PA2VA_OFFSET, PAGE_SIZE, PAGE_TABLE_BASE, + PAGE_TABLE_OFFSET_PER_HART, STACK_BASE, STACK_SIZE_PER_HART, }; use crate::trap_vector; use core::arch::asm; @@ -18,13 +18,15 @@ pub fn sstart() { } // init page tables - let offset_from_dram_base = sstart as *const fn() as usize - DRAM_BASE; - let offset_from_dram_base_masked = (offset_from_dram_base >> 21) << 19; - let page_table_start = PAGE_TABLE_BASE + offset_from_dram_base + hart_id * PAGE_TABLE_SIZE; + let page_table_start = PAGE_TABLE_BASE + hart_id * PAGE_TABLE_OFFSET_PER_HART; for pt_index in 511..1024 { let pt_offset = (page_table_start + pt_index * 8) as *mut usize; unsafe { - pt_offset.write_volatile(offset_from_dram_base_masked + pt_offset.read_volatile()); + pt_offset.write_volatile(match pt_index { + 511 => (PAGE_TABLE_BASE + PAGE_SIZE) >> 2 | 0x01, // v + 512 => 0x2000_0000 | 0xcb, // d, a, x, r, v + 513 | _ => (0x2000_0000 + ((pt_index - 512) << 19)) | 0xc7, // d, a, w, r, v + }); } } From 723be98c2a6e72524f93b827ce4f136a1b7cae75 Mon Sep 17 00:00:00 2001 From: Alingof Date: Wed, 6 Sep 2023 15:39:14 +0900 Subject: [PATCH 057/133] [wip][fix] convert physical address to virtual address by adding PA2VA_OFFSET --- src/supervisor_init.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/supervisor_init.rs b/src/supervisor_init.rs index 4349762..5768877 100644 --- a/src/supervisor_init.rs +++ b/src/supervisor_init.rs @@ -71,14 +71,14 @@ fn smode_setup(hart_id: usize, dtb_addr: usize) { unsafe { sstatus::clear_sie(); stvec::write( - panic_handler as *const fn() as usize, + panic_handler as *const fn() as usize + PA2VA_OFFSET, stvec::TrapMode::Direct, ); } // parse device tree let device_tree = unsafe { - match fdt::Fdt::from_ptr(dtb_addr as *const u8) { + match fdt::Fdt::from_ptr((dtb_addr + PA2VA_OFFSET) as *const u8) { Ok(fdt) => fdt, Err(e) => panic!("{}", e), } From c3ad4d8ed7a6814a9381e30323156b4b6de1852f Mon Sep 17 00:00:00 2001 From: Alingof Date: Wed, 6 Sep 2023 16:05:57 +0900 Subject: [PATCH 058/133] [wip][fix] fix page table --- src/supervisor_init.rs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/supervisor_init.rs b/src/supervisor_init.rs index 5768877..9ce81bc 100644 --- a/src/supervisor_init.rs +++ b/src/supervisor_init.rs @@ -19,13 +19,15 @@ pub fn sstart() { // init page tables let page_table_start = PAGE_TABLE_BASE + hart_id * PAGE_TABLE_OFFSET_PER_HART; - for pt_index in 511..1024 { + for pt_index in 0..1024 { let pt_offset = (page_table_start + pt_index * 8) as *mut usize; unsafe { + // 2 and 511 point to 512 PTE pt_offset.write_volatile(match pt_index { - 511 => (PAGE_TABLE_BASE + PAGE_SIZE) >> 2 | 0x01, // v - 512 => 0x2000_0000 | 0xcb, // d, a, x, r, v - 513 | _ => (0x2000_0000 + ((pt_index - 512) << 19)) | 0xc7, // d, a, w, r, v + 2 | 511 => (PAGE_TABLE_BASE + PAGE_SIZE) >> 2 | 0x01, // v + 512 => 0x2000_0000 | 0xcb, // d, a, x, r, v + 513..=1023 => (0x2000_0000 + ((pt_index - 512) << 19)) | 0xc7, // d, a, w, r, v + _ => 0, }); } } @@ -34,7 +36,8 @@ pub fn sstart() { // init trap vector stvec::write( // stvec address must be 4byte aligned. - trampoline as *const fn() as usize + PA2VA_OFFSET & !0b11, + trampoline as *const fn() as usize & !0b11, + //trampoline as *const fn() as usize + PA2VA_OFFSET & !0b11, stvec::TrapMode::Direct, ); From 2a46f2bfad42dc5080220b2cffa0796f8519f4c1 Mon Sep 17 00:00:00 2001 From: Alingof Date: Wed, 6 Sep 2023 17:03:08 +0900 Subject: [PATCH 059/133] [wip][update] rename PA2VA_OFFSET to PA2VA_DRAM_OFFSET --- src/memmap.rs | 2 +- src/supervisor_init.rs | 18 ++++++++++-------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/memmap.rs b/src/memmap.rs index adb7b8e..2c0e619 100644 --- a/src/memmap.rs +++ b/src/memmap.rs @@ -7,7 +7,7 @@ pub const PAGE_SIZE: usize = 4096; pub const PAGE_TABLE_OFFSET_PER_HART: usize = 1024; pub const STACK_BASE: usize = 0x8030_0000; pub const STACK_SIZE_PER_HART: usize = 0x1_0000; -pub const PA2VA_OFFSET: usize = 0xffff_ffff_4000_0000; +pub const PA2VA_DRAM_OFFSET: usize = 0xffff_ffff_4000_0000; pub struct Device { addr: usize, diff --git a/src/supervisor_init.rs b/src/supervisor_init.rs index 9ce81bc..5590665 100644 --- a/src/supervisor_init.rs +++ b/src/supervisor_init.rs @@ -1,6 +1,6 @@ use crate::memmap::Memmap; use crate::memmap::{ - DRAM_BASE, DRAM_SIZE_PAR_HART, PA2VA_OFFSET, PAGE_SIZE, PAGE_TABLE_BASE, + DRAM_BASE, DRAM_SIZE_PAR_HART, PA2VA_DRAM_OFFSET, PAGE_SIZE, PAGE_TABLE_BASE, PAGE_TABLE_OFFSET_PER_HART, STACK_BASE, STACK_SIZE_PER_HART, }; use crate::trap_vector; @@ -22,10 +22,12 @@ pub fn sstart() { for pt_index in 0..1024 { let pt_offset = (page_table_start + pt_index * 8) as *mut usize; unsafe { - // 2 and 511 point to 512 PTE pt_offset.write_volatile(match pt_index { + // 0x0000_0000_8xxx_xxxx or 0xffff_ffff_cxxx_xxxx 2 | 511 => (PAGE_TABLE_BASE + PAGE_SIZE) >> 2 | 0x01, // v - 512 => 0x2000_0000 | 0xcb, // d, a, x, r, v + // 2 and 511 point to 512 PTE + 512 => 0x2000_0000 | 0xcb, // d, a, x, r, v + // 2nd level 513..=1023 => (0x2000_0000 + ((pt_index - 512) << 19)) | 0xc7, // d, a, w, r, v _ => 0, }); @@ -37,12 +39,12 @@ pub fn sstart() { stvec::write( // stvec address must be 4byte aligned. trampoline as *const fn() as usize & !0b11, - //trampoline as *const fn() as usize + PA2VA_OFFSET & !0b11, + //trampoline as *const fn() as usize + PA2VA_DRAM_OFFSET & !0b11, stvec::TrapMode::Direct, ); // init stack pointer - let stack_pointer = STACK_BASE + PA2VA_OFFSET; + let stack_pointer = STACK_BASE + PA2VA_DRAM_OFFSET; let satp_config = (0b1000 << 60) | (page_table_start >> 12); asm!( " @@ -74,14 +76,14 @@ fn smode_setup(hart_id: usize, dtb_addr: usize) { unsafe { sstatus::clear_sie(); stvec::write( - panic_handler as *const fn() as usize + PA2VA_OFFSET, + panic_handler as *const fn() as usize + PA2VA_DRAM_OFFSET, stvec::TrapMode::Direct, ); } // parse device tree let device_tree = unsafe { - match fdt::Fdt::from_ptr((dtb_addr + PA2VA_OFFSET) as *const u8) { + match fdt::Fdt::from_ptr((dtb_addr + PA2VA_DRAM_OFFSET) as *const u8) { Ok(fdt) => fdt, Err(e) => panic!("{}", e), } @@ -108,7 +110,7 @@ fn smode_setup(hart_id: usize, dtb_addr: usize) { (DRAM_BASE + DRAM_SIZE_PAR_HART * hart_id) >> 12, ); - let stack_pointer = STACK_BASE + STACK_SIZE_PER_HART * hart_id + PA2VA_OFFSET; + let stack_pointer = STACK_BASE + STACK_SIZE_PER_HART * hart_id + PA2VA_DRAM_OFFSET; asm!("mv a0, {dtb_addr}", dtb_addr = in(reg) dtb_addr); asm!("mv sp, {stack_pointer_in_umode}", stack_pointer_in_umode = in(reg) stack_pointer); asm!("j {enter_user_mode}", enter_user_mode = sym enter_user_mode); From 12ff73e3b00f2cf606ce5a5594a3a55825c3980b Mon Sep 17 00:00:00 2001 From: Alingof Date: Wed, 6 Sep 2023 17:07:11 +0900 Subject: [PATCH 060/133] [add] add PA2VA_DEVICE_OFFSET and move const value in memmap.rs to memmap::constant --- src/machine_init.rs | 2 +- src/memmap.rs | 21 ++++++++++++--------- src/supervisor_init.rs | 4 ++-- 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/machine_init.rs b/src/machine_init.rs index 7d3a1b0..ebc1b3d 100644 --- a/src/machine_init.rs +++ b/src/machine_init.rs @@ -5,7 +5,7 @@ extern crate panic_halt; mod memmap; mod supervisor_init; -use crate::memmap::{DRAM_BASE, STACK_BASE, STACK_SIZE_PER_HART}; +use crate::memmap::constant::{DRAM_BASE, STACK_BASE, STACK_SIZE_PER_HART}; use core::arch::{asm, global_asm}; use riscv::asm::sfence_vma_all; use riscv::register::{ diff --git a/src/memmap.rs b/src/memmap.rs index 2c0e619..f69bee4 100644 --- a/src/memmap.rs +++ b/src/memmap.rs @@ -1,13 +1,16 @@ use fdt::Fdt; -pub const DRAM_BASE: usize = 0x8000_0000; -pub const DRAM_SIZE_PAR_HART: usize = 0x1000_0000; -pub const PAGE_TABLE_BASE: usize = 0x8020_0000; -pub const PAGE_SIZE: usize = 4096; -pub const PAGE_TABLE_OFFSET_PER_HART: usize = 1024; -pub const STACK_BASE: usize = 0x8030_0000; -pub const STACK_SIZE_PER_HART: usize = 0x1_0000; -pub const PA2VA_DRAM_OFFSET: usize = 0xffff_ffff_4000_0000; +pub mod constant { + pub const DRAM_BASE: usize = 0x8000_0000; + pub const DRAM_SIZE_PAR_HART: usize = 0x1000_0000; + pub const PAGE_TABLE_BASE: usize = 0x8020_0000; + pub const PAGE_SIZE: usize = 4096; + pub const PAGE_TABLE_OFFSET_PER_HART: usize = 1024; + pub const STACK_BASE: usize = 0x8030_0000; + pub const STACK_SIZE_PER_HART: usize = 0x1_0000; + pub const PA2VA_DRAM_OFFSET: usize = 0xffff_ffff_4000_0000; + pub const PA2VA_DEVICE_OFFSET: usize = 0xffff_fffc_0000_0000; +} pub struct Device { addr: usize, @@ -51,7 +54,7 @@ impl Device { } pub fn vaddr(&self) -> usize { - self.addr + PA2VA_OFFSET + self.addr + constant::PA2VA_DEVICE_OFFSET } } diff --git a/src/supervisor_init.rs b/src/supervisor_init.rs index 5590665..5a2a708 100644 --- a/src/supervisor_init.rs +++ b/src/supervisor_init.rs @@ -1,8 +1,8 @@ -use crate::memmap::Memmap; -use crate::memmap::{ +use crate::memmap::constant::{ DRAM_BASE, DRAM_SIZE_PAR_HART, PA2VA_DRAM_OFFSET, PAGE_SIZE, PAGE_TABLE_BASE, PAGE_TABLE_OFFSET_PER_HART, STACK_BASE, STACK_SIZE_PER_HART, }; +use crate::memmap::Memmap; use crate::trap_vector; use core::arch::asm; use riscv::register::{satp, sie, sstatus, stvec}; From ae67229ab08bafbb012aa2e1d8aec630daa947d7 Mon Sep 17 00:00:00 2001 From: Alingof Date: Wed, 6 Sep 2023 17:24:57 +0900 Subject: [PATCH 061/133] [add] add page table entry for device region --- src/supervisor_init.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/supervisor_init.rs b/src/supervisor_init.rs index 5a2a708..f68b476 100644 --- a/src/supervisor_init.rs +++ b/src/supervisor_init.rs @@ -23,6 +23,8 @@ pub fn sstart() { let pt_offset = (page_table_start + pt_index * 8) as *mut usize; unsafe { pt_offset.write_volatile(match pt_index { + // 0xffff_fffc_0xxx_xxxx ..= 0xffff_ffff_8xxx_xxxx + 496..=503 => (pt_index - 496) << 28 | 0xcf, // a, d, x, w, r, v // 0x0000_0000_8xxx_xxxx or 0xffff_ffff_cxxx_xxxx 2 | 511 => (PAGE_TABLE_BASE + PAGE_SIZE) >> 2 | 0x01, // v // 2 and 511 point to 512 PTE @@ -39,7 +41,6 @@ pub fn sstart() { stvec::write( // stvec address must be 4byte aligned. trampoline as *const fn() as usize & !0b11, - //trampoline as *const fn() as usize + PA2VA_DRAM_OFFSET & !0b11, stvec::TrapMode::Direct, ); From 54ca7f501736488aea23454032932c376016e4fc Mon Sep 17 00:00:00 2001 From: Alingof Date: Thu, 7 Sep 2023 14:28:21 +0900 Subject: [PATCH 062/133] [update] remove src/init.rs --- src/init.rs | 55 ----------------------------------------------------- 1 file changed, 55 deletions(-) delete mode 100644 src/init.rs diff --git a/src/init.rs b/src/init.rs deleted file mode 100644 index 901e671..0000000 --- a/src/init.rs +++ /dev/null @@ -1,55 +0,0 @@ -use crate::memmap::{DRAM_BASE, PA2VA_OFFSET, PAGE_TABLE_BASE, PAGE_TABLE_SIZE, STACK_BASE}; -use core::arch::asm; -use riscv::asm::sfence_vma; -use riscv::register::{mtvec, satp, stvec}; - -/// entry point -/// Initialize CSRs, page tables, stack pointer -fn init() -> ! { - let hart_id: u64; - let dtb_addr: u64; - unsafe { - // get hart id - asm!("mv {}, a0", out(reg) hart_id); - asm!("mv {}, a1", out(reg) dtb_addr); - } - - // init stack pointer - let stack_pointer = STACK_BASE + PA2VA_OFFSET; - unsafe { - asm!("mv sp, {}", in(reg) stack_pointer); - } - - // init page tables - let init_func = __risc_v_rt__main; - let offset_from_dram_base = init_func as *const fn() as u64 - DRAM_BASE; - let offset_from_dram_base_masked = (offset_from_dram_base >> 21) << 19; - let page_table_start = PAGE_TABLE_BASE + offset_from_dram_base + hart_id * PAGE_TABLE_SIZE; - for pt_index in 511..1024 { - let pt_offset = (page_table_start + pt_index * 8) as *mut u64; - unsafe { - pt_offset.write_volatile(pt_offset.read_volatile() + offset_from_dram_base_masked); - } - } - - unsafe { - // init trap vector - stvec::write(trampoline as *const fn() as usize, mtvec::TrapMode::Direct); - - // set satp(Supervisor Address Translation and Protection) register - satp::set(satp::Mode::Sv39, 0, (page_table_start >> 12) as usize); - - // sfence.vma - sfence_vma(0, 0); - } - - // jump to trampoline - trampoline(hart_id, dtb_addr); - - unreachable!() -} - -/// Jump to start -pub fn trampoline(hart_id: u64, dtb_addr: u64) { - start::start(hart_id, dtb_addr); -} From 77b7802142712c570740d8c1401628274d54cc22 Mon Sep 17 00:00:00 2001 From: Alingof Date: Thu, 7 Sep 2023 17:18:08 +0900 Subject: [PATCH 063/133] [update] move constant module to src/memmap/constant.rs --- src/memmap.rs | 12 +----------- src/memmap/constant.rs | 9 +++++++++ 2 files changed, 10 insertions(+), 11 deletions(-) create mode 100644 src/memmap/constant.rs diff --git a/src/memmap.rs b/src/memmap.rs index f69bee4..4c6c368 100644 --- a/src/memmap.rs +++ b/src/memmap.rs @@ -1,16 +1,6 @@ +pub mod constant; use fdt::Fdt; -pub mod constant { - pub const DRAM_BASE: usize = 0x8000_0000; - pub const DRAM_SIZE_PAR_HART: usize = 0x1000_0000; - pub const PAGE_TABLE_BASE: usize = 0x8020_0000; - pub const PAGE_SIZE: usize = 4096; - pub const PAGE_TABLE_OFFSET_PER_HART: usize = 1024; - pub const STACK_BASE: usize = 0x8030_0000; - pub const STACK_SIZE_PER_HART: usize = 0x1_0000; - pub const PA2VA_DRAM_OFFSET: usize = 0xffff_ffff_4000_0000; - pub const PA2VA_DEVICE_OFFSET: usize = 0xffff_fffc_0000_0000; -} pub struct Device { addr: usize, diff --git a/src/memmap/constant.rs b/src/memmap/constant.rs new file mode 100644 index 0000000..5a703ad --- /dev/null +++ b/src/memmap/constant.rs @@ -0,0 +1,9 @@ +pub const DRAM_BASE: usize = 0x8000_0000; +pub const DRAM_SIZE_PAR_HART: usize = 0x1000_0000; +pub const PAGE_TABLE_BASE: usize = 0x8020_0000; +pub const PAGE_SIZE: usize = 4096; +pub const PAGE_TABLE_OFFSET_PER_HART: usize = 1024; +pub const STACK_BASE: usize = 0x8030_0000; +pub const STACK_SIZE_PER_HART: usize = 0x1_0000; +pub const PA2VA_DRAM_OFFSET: usize = 0xffff_ffff_4000_0000; +pub const PA2VA_DEVICE_OFFSET: usize = 0xffff_fffc_0000_0000; From a2ff5ad53d115c7f142172e19fef61ef31f07bbc Mon Sep 17 00:00:00 2001 From: Alingof Date: Thu, 7 Sep 2023 17:18:57 +0900 Subject: [PATCH 064/133] [add] add src/memmap/device/ and move urat.rs to it --- src/memmap/device/uart.rs | 37 +++++++++++++++++++++++++++++++++++++ src/uart.rs | 22 ---------------------- 2 files changed, 37 insertions(+), 22 deletions(-) create mode 100644 src/memmap/device/uart.rs delete mode 100644 src/uart.rs diff --git a/src/memmap/device/uart.rs b/src/memmap/device/uart.rs new file mode 100644 index 0000000..242a1b7 --- /dev/null +++ b/src/memmap/device/uart.rs @@ -0,0 +1,37 @@ +use super::Device; +use crate::memmap::constant; +use fdt::Fdt; + +pub struct Uart { + base_addr: usize, + size: usize, +} + +impl Device for Uart { + fn new(device_tree: &Fdt, node_path: &str) -> Self { + let region = device_tree + .find_node(node_path) + .unwrap() + .reg() + .unwrap() + .nth(0) + .unwrap(); + + Uart { + base_addr: region.starting_address as usize, + size: region.size.unwrap(), + } + } + + fn size(&self) -> usize { + self.size + } + + fn paddr(&self) -> usize { + self.base_addr + } + + fn vaddr(&self) -> usize { + self.base_addr + constant::PA2VA_DEVICE_OFFSET + } +} diff --git a/src/uart.rs b/src/uart.rs deleted file mode 100644 index 5804851..0000000 --- a/src/uart.rs +++ /dev/null @@ -1,22 +0,0 @@ -pub struct Uart { - base_addr: u64, -} - -impl Uart { - pub fn new(uart_addr: u64) -> Self { - Uart { - base_addr: uart_addr, - } - } - - pub fn println(&self, string: &str) { - let uart = self.base_addr as *mut u32; - unsafe { - for c in string.chars() { - while (uart.read_volatile() as i32) < 0 {} - uart.write_volatile(c as u32); - } - uart.write_volatile('\n' as u32); - } - } -} From f21b1a98dd08df803b604f7befa4ef4c1ab5ec44 Mon Sep 17 00:00:00 2001 From: Alingof Date: Thu, 7 Sep 2023 17:20:04 +0900 Subject: [PATCH 065/133] [update] add device module and create struct for each devices --- src/memmap.rs | 68 ++++++------------------------------- src/memmap/device.rs | 13 +++++++ src/memmap/device/initrd.rs | 35 +++++++++++++++++++ src/memmap/device/plic.rs | 37 ++++++++++++++++++++ src/memmap/device/virtio.rs | 38 +++++++++++++++++++++ src/supervisor_init.rs | 1 + 6 files changed, 134 insertions(+), 58 deletions(-) create mode 100644 src/memmap/device.rs create mode 100644 src/memmap/device/initrd.rs create mode 100644 src/memmap/device/plic.rs create mode 100644 src/memmap/device/virtio.rs diff --git a/src/memmap.rs b/src/memmap.rs index 4c6c368..14026c7 100644 --- a/src/memmap.rs +++ b/src/memmap.rs @@ -1,70 +1,22 @@ pub mod constant; +pub mod device; +use device::{initrd, plic, uart, virtio, Device}; use fdt::Fdt; - -pub struct Device { - addr: usize, - size: usize, -} - -impl Device { - fn new(device_tree: &Fdt, node_path: &str) -> Self { - let region = device_tree - .find_node(node_path) - .unwrap() - .reg() - .unwrap() - .nth(0) - .unwrap(); - - Device { - addr: region.starting_address as usize, - size: region.size.unwrap(), - } - } - - fn new_by_property( - device_tree: &Fdt, - node_path: &str, - start_prop: &str, - end_prop: &str, - ) -> Self { - let node = device_tree.find_node(node_path).unwrap(); - let start = node.property(start_prop).unwrap().value[0] as usize; - let end = node.property(end_prop).unwrap().value[0] as usize; - - Device { - addr: start, - size: end - start, - } - } - - fn paddr(&self) -> usize { - self.addr - } - - pub fn vaddr(&self) -> usize { - self.addr + constant::PA2VA_DEVICE_OFFSET - } -} - pub struct Memmap { - pub uart: Device, - pub initrd: Device, - pub plic: Device, + pub uart: uart::Uart, + pub virtio: virtio::VirtIO, + pub initrd: initrd::Initrd, + pub plic: plic::Plic, } impl Memmap { pub fn new(device_tree: Fdt) -> Self { Memmap { - uart: Device::new(&device_tree, "/soc/serial"), - initrd: Device::new_by_property( - &device_tree, - "/chosen", - "linux,initrd-start", - "linux,initrd-end", - ), - plic: Device::new(&device_tree, "/soc/plic"), + uart: uart::Uart::new(&device_tree, "/soc/serial"), + virtio: virtio::VirtIO::new(&device_tree, "/soc/virtio_mmio"), + initrd: initrd::Initrd::new(&device_tree, "/chosen"), + plic: plic::Plic::new(&device_tree, "/soc/plic"), } } } diff --git a/src/memmap/device.rs b/src/memmap/device.rs new file mode 100644 index 0000000..13d8991 --- /dev/null +++ b/src/memmap/device.rs @@ -0,0 +1,13 @@ +pub mod initrd; +pub mod plic; +pub mod uart; +pub mod virtio; + +use fdt::Fdt; + +pub trait Device { + fn new(device_tree: &Fdt, node_path: &str) -> Self; + fn size(&self) -> usize; + fn paddr(&self) -> usize; + fn vaddr(&self) -> usize; +} diff --git a/src/memmap/device/initrd.rs b/src/memmap/device/initrd.rs new file mode 100644 index 0000000..c913412 --- /dev/null +++ b/src/memmap/device/initrd.rs @@ -0,0 +1,35 @@ +use super::Device; +use crate::memmap::constant; +use fdt::Fdt; + +pub struct Initrd { + base_addr: usize, + size: usize, +} + +impl Device for Initrd { + fn new(device_tree: &Fdt, node_path: &str) -> Self { + let start_prop = "linux-initrd-start"; + let end_prop = "linux-initrd-end"; + let node = device_tree.find_node(node_path).unwrap(); + let start = node.property(start_prop).unwrap().value[0] as usize; + let end = node.property(end_prop).unwrap().value[0] as usize; + + Initrd { + base_addr: start, + size: end - start, + } + } + + fn size(&self) -> usize { + self.size + } + + fn paddr(&self) -> usize { + self.base_addr + } + + fn vaddr(&self) -> usize { + self.base_addr + constant::PA2VA_DEVICE_OFFSET + } +} diff --git a/src/memmap/device/plic.rs b/src/memmap/device/plic.rs new file mode 100644 index 0000000..fecd652 --- /dev/null +++ b/src/memmap/device/plic.rs @@ -0,0 +1,37 @@ +use super::Device; +use crate::memmap::constant; +use fdt::Fdt; + +pub struct Plic { + base_addr: usize, + size: usize, +} + +impl Device for Plic { + fn new(device_tree: &Fdt, node_path: &str) -> Self { + let region = device_tree + .find_node(node_path) + .unwrap() + .reg() + .unwrap() + .nth(0) + .unwrap(); + + Plic { + base_addr: region.starting_address as usize, + size: region.size.unwrap(), + } + } + + fn size(&self) -> usize { + self.size + } + + fn paddr(&self) -> usize { + self.base_addr + } + + fn vaddr(&self) -> usize { + self.base_addr + constant::PA2VA_DEVICE_OFFSET + } +} diff --git a/src/memmap/device/virtio.rs b/src/memmap/device/virtio.rs new file mode 100644 index 0000000..34b6729 --- /dev/null +++ b/src/memmap/device/virtio.rs @@ -0,0 +1,38 @@ +use super::Device; +use crate::memmap::constant; +use fdt::Fdt; + +pub struct VirtIO { + base_addr: usize, + size: usize, +} + +impl Device for VirtIO { + fn new(device_tree: &Fdt, node_path: &str) -> Self { + let region = device_tree + .find_all_nodes(node_path) + .next() + .unwrap() + .reg() + .unwrap() + .nth(0) + .unwrap(); + + VirtIO { + base_addr: region.starting_address as usize, + size: region.size.unwrap(), + } + } + + fn size(&self) -> usize { + self.size + } + + fn paddr(&self) -> usize { + self.base_addr + } + + fn vaddr(&self) -> usize { + self.base_addr + constant::PA2VA_DEVICE_OFFSET + } +} diff --git a/src/supervisor_init.rs b/src/supervisor_init.rs index f68b476..db0d2cb 100644 --- a/src/supervisor_init.rs +++ b/src/supervisor_init.rs @@ -2,6 +2,7 @@ use crate::memmap::constant::{ DRAM_BASE, DRAM_SIZE_PAR_HART, PA2VA_DRAM_OFFSET, PAGE_SIZE, PAGE_TABLE_BASE, PAGE_TABLE_OFFSET_PER_HART, STACK_BASE, STACK_SIZE_PER_HART, }; +use crate::memmap::device::Device; use crate::memmap::Memmap; use crate::trap_vector; use core::arch::asm; From a6a49ae18818c272acad5957c1eef5ac65e023e4 Mon Sep 17 00:00:00 2001 From: Alingof Date: Thu, 7 Sep 2023 17:22:15 +0900 Subject: [PATCH 066/133] [refactor] apply cargo fix --- src/memmap/device/plic.rs | 2 +- src/memmap/device/uart.rs | 2 +- src/memmap/device/virtio.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/memmap/device/plic.rs b/src/memmap/device/plic.rs index fecd652..1218a5f 100644 --- a/src/memmap/device/plic.rs +++ b/src/memmap/device/plic.rs @@ -14,7 +14,7 @@ impl Device for Plic { .unwrap() .reg() .unwrap() - .nth(0) + .next() .unwrap(); Plic { diff --git a/src/memmap/device/uart.rs b/src/memmap/device/uart.rs index 242a1b7..f9ac75b 100644 --- a/src/memmap/device/uart.rs +++ b/src/memmap/device/uart.rs @@ -14,7 +14,7 @@ impl Device for Uart { .unwrap() .reg() .unwrap() - .nth(0) + .next() .unwrap(); Uart { diff --git a/src/memmap/device/virtio.rs b/src/memmap/device/virtio.rs index 34b6729..a31c356 100644 --- a/src/memmap/device/virtio.rs +++ b/src/memmap/device/virtio.rs @@ -15,7 +15,7 @@ impl Device for VirtIO { .unwrap() .reg() .unwrap() - .nth(0) + .next() .unwrap(); VirtIO { From ed88289f8fbc890a188d42635a319c3762c9766c Mon Sep 17 00:00:00 2001 From: Alingof Date: Thu, 7 Sep 2023 18:22:49 +0900 Subject: [PATCH 067/133] [refactor][add] add doc comment --- src/machine_init.rs | 13 +++++++------ src/memmap.rs | 2 ++ src/memmap/constant.rs | 11 +++++++++++ src/memmap/device.rs | 10 ++++++++++ src/memmap/device/initrd.rs | 2 ++ src/memmap/device/plic.rs | 2 ++ src/memmap/device/uart.rs | 1 + src/memmap/device/virtio.rs | 2 ++ src/supervisor_init.rs | 14 +++++++++++++- 9 files changed, 50 insertions(+), 7 deletions(-) diff --git a/src/machine_init.rs b/src/machine_init.rs index ebc1b3d..9101297 100644 --- a/src/machine_init.rs +++ b/src/machine_init.rs @@ -16,13 +16,14 @@ use riscv_rt::entry; global_asm!(include_str!("trap.S")); extern "C" { + /// Trap vector for M-mode. This function is in `trap.S`. fn trap_vector(); } -/// Start function -/// - set stack pointer -/// - init mtvec and stvec -/// - jump to mstart +/// 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) -> ! { unsafe { @@ -151,8 +152,8 @@ fn forward_exception() { } } -/// Enter supervisor (just exec mret) -/// Jump to sstart +/// Enter supervisor. (just exec mret) +/// Jump to sstart via mret. #[inline(never)] fn enter_supervisor_mode(_hart_id: usize, _dtb_addr: usize) { unsafe { diff --git a/src/memmap.rs b/src/memmap.rs index 14026c7..d682bc3 100644 --- a/src/memmap.rs +++ b/src/memmap.rs @@ -3,6 +3,8 @@ pub mod device; use device::{initrd, plic, uart, virtio, Device}; use fdt::Fdt; +/// Memmap has memory region data of each devices. +/// Each devices **must** be implemented Device trait. pub struct Memmap { pub uart: uart::Uart, pub virtio: virtio::VirtIO, diff --git a/src/memmap/constant.rs b/src/memmap/constant.rs index 5a703ad..08077c8 100644 --- a/src/memmap/constant.rs +++ b/src/memmap/constant.rs @@ -1,9 +1,20 @@ +//! Constant for memory map. + +/// Base address of dram. pub const DRAM_BASE: usize = 0x8000_0000; +/// Memory region on dram that be allocated each HARTs. pub const DRAM_SIZE_PAR_HART: usize = 0x1000_0000; +/// Base address of page table. pub const PAGE_TABLE_BASE: usize = 0x8020_0000; +/// Size of memory areathat a page can point to. pub const PAGE_SIZE: usize = 4096; +/// Page table offset for each HART. pub const PAGE_TABLE_OFFSET_PER_HART: usize = 1024; +/// Base address of stack. pub const STACK_BASE: usize = 0x8030_0000; +/// Stack size for each HART. pub const STACK_SIZE_PER_HART: usize = 0x1_0000; +/// Offset for converting physical address on dram to virtual address. pub const PA2VA_DRAM_OFFSET: usize = 0xffff_ffff_4000_0000; +/// Offset for converting physical device address to virtual address. pub const PA2VA_DEVICE_OFFSET: usize = 0xffff_fffc_0000_0000; diff --git a/src/memmap/device.rs b/src/memmap/device.rs index 13d8991..d6cd460 100644 --- a/src/memmap/device.rs +++ b/src/memmap/device.rs @@ -1,3 +1,6 @@ +//! A module about device on memory map. +//! This module holds each devices implementation. + pub mod initrd; pub mod plic; pub mod uart; @@ -5,9 +8,16 @@ pub mod virtio; use fdt::Fdt; +/// A struct that implement Device trait **must** has base_addr and size member. pub trait Device { + /// Create self instance. + /// * `device_tree` - struct Fdt + /// * `node_path` - node path in fdt fn new(device_tree: &Fdt, node_path: &str) -> Self; + /// Return size of memory region. fn size(&self) -> usize; + /// Return address of physical memory fn paddr(&self) -> usize; + /// Return address of virtual memory fn vaddr(&self) -> usize; } diff --git a/src/memmap/device/initrd.rs b/src/memmap/device/initrd.rs index c913412..8b2c37d 100644 --- a/src/memmap/device/initrd.rs +++ b/src/memmap/device/initrd.rs @@ -2,6 +2,8 @@ use super::Device; use crate::memmap::constant; use fdt::Fdt; +/// A scheme for loading a temporary root file system into memory, +/// to be used as part of the Linux startup process. pub struct Initrd { base_addr: usize, size: usize, diff --git a/src/memmap/device/plic.rs b/src/memmap/device/plic.rs index 1218a5f..4bf9baa 100644 --- a/src/memmap/device/plic.rs +++ b/src/memmap/device/plic.rs @@ -2,6 +2,8 @@ use super::Device; use crate::memmap::constant; use fdt::Fdt; +/// PLIC: Platform-Level Interrupt Controller +/// Interrupt controller for global interrupts. pub struct Plic { base_addr: usize, size: usize, diff --git a/src/memmap/device/uart.rs b/src/memmap/device/uart.rs index f9ac75b..7b28433 100644 --- a/src/memmap/device/uart.rs +++ b/src/memmap/device/uart.rs @@ -2,6 +2,7 @@ use super::Device; use crate::memmap::constant; use fdt::Fdt; +/// UART: Universal asynchronous receiver-transmitter pub struct Uart { base_addr: usize, size: usize, diff --git a/src/memmap/device/virtio.rs b/src/memmap/device/virtio.rs index a31c356..eae1b58 100644 --- a/src/memmap/device/virtio.rs +++ b/src/memmap/device/virtio.rs @@ -2,6 +2,8 @@ use super::Device; use crate::memmap::constant; use fdt::Fdt; +/// A virtualization standard for network and disk device drivers. +/// Since more than one may be found, we will temporarily use the first one. pub struct VirtIO { base_addr: usize, size: usize, diff --git a/src/supervisor_init.rs b/src/supervisor_init.rs index db0d2cb..8d4c7a8 100644 --- a/src/supervisor_init.rs +++ b/src/supervisor_init.rs @@ -9,6 +9,9 @@ use core::arch::asm; use riscv::register::{satp, sie, sstatus, stvec}; /// Supervisor start function +/// * Init page tables +/// * Init trap vector +/// * Init stack pointer pub fn sstart() { let hart_id: usize; let dtb_addr: usize; @@ -68,12 +71,19 @@ pub fn sstart() { unreachable!() } -/// Jump to start +/// Jump to smode_setup #[inline(never)] fn trampoline(hart_id: usize, dtb_addr: usize) { smode_setup(hart_id, dtb_addr); } +/// Setup for S-mode +/// * parse device tree +/// * Init plic priorities +/// * Set trap vector +/// * Set ppn via setp +/// * Set stack pointer +/// * Jump to enter_user_mode via asm j instruction fn smode_setup(hart_id: usize, dtb_addr: usize) { unsafe { sstatus::clear_sie(); @@ -119,6 +129,7 @@ fn smode_setup(hart_id: usize, dtb_addr: usize) { } } +/// Prepare to enter U-mode and jump to linux kernel fn enter_user_mode(dtb_addr: usize) { unsafe { // set sie = 0x222 @@ -174,6 +185,7 @@ fn enter_user_mode(dtb_addr: usize) { unreachable!(); } +/// Panic handler for S-mode fn panic_handler() { panic!("trap from panic macro") } From 924c9ca5c495700c73b94996015d4d8715d4623a Mon Sep 17 00:00:00 2001 From: Alingof Date: Thu, 7 Sep 2023 21:49:42 +0900 Subject: [PATCH 068/133] [refactor] apply `cargo fix -- -W clippy::pedantic` --- src/machine_init.rs | 4 ++-- src/memmap/device.rs | 2 +- src/supervisor_init.rs | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/machine_init.rs b/src/machine_init.rs index 9101297..bdef9a9 100644 --- a/src/machine_init.rs +++ b/src/machine_init.rs @@ -20,7 +20,7 @@ extern "C" { fn trap_vector(); } -/// Entry function. '__risc_v_rt__main' is alias of `__init` function in machine_init.rs. +/// 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 @@ -126,8 +126,8 @@ fn mstart(hart_id: usize, dtb_addr: usize) { enter_supervisor_mode(hart_id, dtb_addr); } -#[no_mangle] /// Delegate exception to supervisor mode +#[no_mangle] fn forward_exception() { unsafe { sepc::write(mepc::read()); diff --git a/src/memmap/device.rs b/src/memmap/device.rs index d6cd460..0e35b4a 100644 --- a/src/memmap/device.rs +++ b/src/memmap/device.rs @@ -8,7 +8,7 @@ pub mod virtio; use fdt::Fdt; -/// A struct that implement Device trait **must** has base_addr and size member. +/// A struct that implement Device trait **must** has `base_addr` and size member. pub trait Device { /// Create self instance. /// * `device_tree` - struct Fdt diff --git a/src/supervisor_init.rs b/src/supervisor_init.rs index 8d4c7a8..976f674 100644 --- a/src/supervisor_init.rs +++ b/src/supervisor_init.rs @@ -71,7 +71,7 @@ pub fn sstart() { unreachable!() } -/// Jump to smode_setup +/// Jump to `smode_setup` #[inline(never)] fn trampoline(hart_id: usize, dtb_addr: usize) { smode_setup(hart_id, dtb_addr); @@ -83,7 +83,7 @@ fn trampoline(hart_id: usize, dtb_addr: usize) { /// * Set trap vector /// * Set ppn via setp /// * Set stack pointer -/// * Jump to enter_user_mode via asm j instruction +/// * Jump to `enter_user_mode` via asm j instruction fn smode_setup(hart_id: usize, dtb_addr: usize) { unsafe { sstatus::clear_sie(); From 740835c707c72159cea03a2b70b7b6db208f1633 Mon Sep 17 00:00:00 2001 From: Alingof Date: Thu, 7 Sep 2023 22:44:06 +0900 Subject: [PATCH 069/133] [wip][add] add VirtIO::new_all and modify Memmap.virtio type to Vec --- src/memmap.rs | 4 ++-- src/memmap/device/virtio.rs | 15 +++++++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/memmap.rs b/src/memmap.rs index d682bc3..29ca428 100644 --- a/src/memmap.rs +++ b/src/memmap.rs @@ -7,7 +7,7 @@ use fdt::Fdt; /// Each devices **must** be implemented Device trait. pub struct Memmap { pub uart: uart::Uart, - pub virtio: virtio::VirtIO, + pub virtio: Vec, pub initrd: initrd::Initrd, pub plic: plic::Plic, } @@ -16,7 +16,7 @@ impl Memmap { pub fn new(device_tree: Fdt) -> Self { Memmap { uart: uart::Uart::new(&device_tree, "/soc/serial"), - virtio: virtio::VirtIO::new(&device_tree, "/soc/virtio_mmio"), + virtio: virtio::VirtIO::new_all(&device_tree, "/soc/virtio_mmio"), initrd: initrd::Initrd::new(&device_tree, "/chosen"), plic: plic::Plic::new(&device_tree, "/soc/plic"), } diff --git a/src/memmap/device/virtio.rs b/src/memmap/device/virtio.rs index eae1b58..b34b80f 100644 --- a/src/memmap/device/virtio.rs +++ b/src/memmap/device/virtio.rs @@ -9,6 +9,21 @@ pub struct VirtIO { size: usize, } +impl VirtIO { + pub fn new_all(device_tree: &Fdt, node_path: &str) -> Vec { + device_tree + .find_all_nodes(node_path) + .map(|node| { + let region = node.reg().unwrap().next().unwrap(); + VirtIO { + base_addr: region.starting_address as usize, + size: region.size.unwrap(), + } + }) + .collect() + } +} + impl Device for VirtIO { fn new(device_tree: &Fdt, node_path: &str) -> Self { let region = device_tree From c6abd37fa28b9e6ca7037fab9c2cf08b0286ac96 Mon Sep 17 00:00:00 2001 From: Alingof Date: Sun, 10 Sep 2023 15:32:11 +0900 Subject: [PATCH 070/133] [wip][add] add alloc crate but if needs allocator --- src/machine_init.rs | 1 + src/memmap.rs | 2 ++ src/memmap/device/virtio.rs | 1 + src/supervisor_init.rs | 2 ++ 4 files changed, 6 insertions(+) diff --git a/src/machine_init.rs b/src/machine_init.rs index bdef9a9..e4be037 100644 --- a/src/machine_init.rs +++ b/src/machine_init.rs @@ -1,6 +1,7 @@ #![no_main] #![no_std] +extern crate alloc; extern crate panic_halt; mod memmap; mod supervisor_init; diff --git a/src/memmap.rs b/src/memmap.rs index 29ca428..a7b1da6 100644 --- a/src/memmap.rs +++ b/src/memmap.rs @@ -1,5 +1,7 @@ pub mod constant; pub mod device; + +use alloc::vec::Vec; use device::{initrd, plic, uart, virtio, Device}; use fdt::Fdt; diff --git a/src/memmap/device/virtio.rs b/src/memmap/device/virtio.rs index b34b80f..e514b02 100644 --- a/src/memmap/device/virtio.rs +++ b/src/memmap/device/virtio.rs @@ -1,5 +1,6 @@ use super::Device; use crate::memmap::constant; +use alloc::vec::Vec; use fdt::Fdt; /// A virtualization standard for network and disk device drivers. diff --git a/src/supervisor_init.rs b/src/supervisor_init.rs index 976f674..64b138a 100644 --- a/src/supervisor_init.rs +++ b/src/supervisor_init.rs @@ -109,6 +109,8 @@ fn smode_setup(hart_id: usize, dtb_addr: usize) { } } + let irq_mask = mmap.virtio.; + unsafe { // set sie = 0x222 sie::set_ssoft(); From 2ba152d13db51ae694d895de7acaf4c7654ce09f Mon Sep 17 00:00:00 2001 From: Alingof Date: Mon, 11 Sep 2023 17:49:14 +0900 Subject: [PATCH 071/133] [add] add wild-screen-alloc crate as submodule --- .gitmodules | 3 +++ Cargo.toml | 1 + wild-screen-alloc | 1 + 3 files changed, 5 insertions(+) create mode 100644 .gitmodules create mode 160000 wild-screen-alloc diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..20dd4cd --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "wild-screen-alloc"] + path = wild-screen-alloc + url = git@github.com:Alignof/wild-screen-alloc.git diff --git a/Cargo.toml b/Cargo.toml index 8bef919..f9e5721 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,3 +14,4 @@ fdt = "0.1.5" panic-halt = "0.2.0" riscv = "0.10.1" riscv-rt = "0.11.0" +wild_screen_alloc = {path = "wild-screen-alloc"} diff --git a/wild-screen-alloc b/wild-screen-alloc new file mode 160000 index 0000000..6abe81f --- /dev/null +++ b/wild-screen-alloc @@ -0,0 +1 @@ +Subproject commit 6abe81f71d248f11530ccbf21373083b3c3fd2e7 From 7d051d10300c7576241f4e8fc71d49846d241c84 Mon Sep 17 00:00:00 2001 From: Alingof Date: Mon, 11 Sep 2023 18:02:47 +0900 Subject: [PATCH 072/133] [add] add global_allocator and setup in `_start()` --- src/machine_init.rs | 11 ++++++++++- src/memmap/constant.rs | 4 ++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/machine_init.rs b/src/machine_init.rs index e4be037..3bc680a 100644 --- a/src/machine_init.rs +++ b/src/machine_init.rs @@ -6,7 +6,7 @@ extern crate panic_halt; mod memmap; mod supervisor_init; -use crate::memmap::constant::{DRAM_BASE, STACK_BASE, STACK_SIZE_PER_HART}; +use crate::memmap::constant::{DRAM_BASE, HEAP_BASE, HEAP_SIZE, STACK_BASE, STACK_SIZE_PER_HART}; use core::arch::{asm, global_asm}; use riscv::asm::sfence_vma_all; use riscv::register::{ @@ -14,6 +14,10 @@ use riscv::register::{ pmpcfg0, satp, scause, sepc, stval, stvec, }; use riscv_rt::entry; +use wild_screen_alloc::WildScreenAlloc; + +#[global_allocator] +static mut ALLOCATOR: WildScreenAlloc = WildScreenAlloc::empty(); global_asm!(include_str!("trap.S")); extern "C" { @@ -27,6 +31,11 @@ extern "C" { /// * 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!( diff --git a/src/memmap/constant.rs b/src/memmap/constant.rs index 08077c8..125c118 100644 --- a/src/memmap/constant.rs +++ b/src/memmap/constant.rs @@ -14,6 +14,10 @@ pub const PAGE_TABLE_OFFSET_PER_HART: usize = 1024; pub const STACK_BASE: usize = 0x8030_0000; /// Stack size for each HART. pub const STACK_SIZE_PER_HART: usize = 0x1_0000; +/// Base address of heap. +pub const HEAP_BASE: usize = 0x8040_0000; +/// Heap size. +pub const HEAP_SIZE: usize = 0x10_0000; /// Offset for converting physical address on dram to virtual address. pub const PA2VA_DRAM_OFFSET: usize = 0xffff_ffff_4000_0000; /// Offset for converting physical device address to virtual address. From 40dd30ae543df800783b093bcec0ad353e4cf95f Mon Sep 17 00:00:00 2001 From: Alingof Date: Mon, 11 Sep 2023 21:15:27 +0900 Subject: [PATCH 073/133] [add] add irq member to VirtIO --- src/memmap/device/virtio.rs | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/memmap/device/virtio.rs b/src/memmap/device/virtio.rs index e514b02..200d1f1 100644 --- a/src/memmap/device/virtio.rs +++ b/src/memmap/device/virtio.rs @@ -8,6 +8,7 @@ use fdt::Fdt; pub struct VirtIO { base_addr: usize, size: usize, + irq: u8, } impl VirtIO { @@ -16,29 +17,31 @@ impl VirtIO { .find_all_nodes(node_path) .map(|node| { let region = node.reg().unwrap().next().unwrap(); + let irq = node.property("interrupts").unwrap().value[0]; VirtIO { base_addr: region.starting_address as usize, size: region.size.unwrap(), + irq, } }) .collect() } + + pub fn irq(&self) -> u8 { + self.irq + } } impl Device for VirtIO { fn new(device_tree: &Fdt, node_path: &str) -> Self { - let region = device_tree - .find_all_nodes(node_path) - .next() - .unwrap() - .reg() - .unwrap() - .next() - .unwrap(); + let node = device_tree.find_all_nodes(node_path).next().unwrap(); + let region = node.reg().unwrap().next().unwrap(); + let irq = node.property("interrupts").unwrap().value[0]; VirtIO { base_addr: region.starting_address as usize, size: region.size.unwrap(), + irq, } } From b6a6170914282c03c371cf87c09ab5777c6dd604 Mon Sep 17 00:00:00 2001 From: Alingof Date: Mon, 11 Sep 2023 21:53:19 +0900 Subject: [PATCH 074/133] [add] add plic_context to Memmap --- src/memmap.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/memmap.rs b/src/memmap.rs index a7b1da6..d1d8fcb 100644 --- a/src/memmap.rs +++ b/src/memmap.rs @@ -12,6 +12,7 @@ pub struct Memmap { pub virtio: Vec, pub initrd: initrd::Initrd, pub plic: plic::Plic, + pub plic_context: usize, } impl Memmap { @@ -21,6 +22,12 @@ impl Memmap { virtio: virtio::VirtIO::new_all(&device_tree, "/soc/virtio_mmio"), initrd: initrd::Initrd::new(&device_tree, "/chosen"), plic: plic::Plic::new(&device_tree, "/soc/plic"), + plic_context: device_tree + .find_node("/cpus/cpu/interrupt-controller") + .unwrap() + .property("phandle") + .unwrap() + .value[0] as usize, } } } From 090e3307905ca0c41a87a929b4820cab99d87fa4 Mon Sep 17 00:00:00 2001 From: Alingof Date: Mon, 11 Sep 2023 21:54:12 +0900 Subject: [PATCH 075/133] [add] implement setting plic interrupt config --- src/memmap/device/plic.rs | 6 ++++++ src/supervisor_init.rs | 19 ++++++++++++++++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/memmap/device/plic.rs b/src/memmap/device/plic.rs index 4bf9baa..4944b79 100644 --- a/src/memmap/device/plic.rs +++ b/src/memmap/device/plic.rs @@ -2,6 +2,12 @@ use super::Device; use crate::memmap::constant; use fdt::Fdt; +pub const ENABLE_BASE: usize = 0x2000; +pub const ENABLE_PER_HART: usize = 0x80; +pub const CONTEXT_BASE: usize = 0x20_0000; +pub const CONTEXT_PER_HART: usize = 0x1000; +pub const CONTEXT_CLAIM: usize = 0x4; + /// PLIC: Platform-Level Interrupt Controller /// Interrupt controller for global interrupts. pub struct Plic { diff --git a/src/supervisor_init.rs b/src/supervisor_init.rs index 64b138a..1de4b70 100644 --- a/src/supervisor_init.rs +++ b/src/supervisor_init.rs @@ -2,6 +2,9 @@ use crate::memmap::constant::{ DRAM_BASE, DRAM_SIZE_PAR_HART, PA2VA_DRAM_OFFSET, PAGE_SIZE, PAGE_TABLE_BASE, PAGE_TABLE_OFFSET_PER_HART, STACK_BASE, STACK_SIZE_PER_HART, }; +use crate::memmap::device::plic::{ + CONTEXT_BASE, CONTEXT_CLAIM, CONTEXT_PER_HART, ENABLE_BASE, ENABLE_PER_HART, +}; use crate::memmap::device::Device; use crate::memmap::Memmap; use crate::trap_vector; @@ -109,7 +112,21 @@ fn smode_setup(hart_id: usize, dtb_addr: usize) { } } - let irq_mask = mmap.virtio.; + let mut irq_mask = 0; + for vio in mmap.virtio.iter().take(4) { + irq_mask |= 1 << vio.irq(); + } + + // set plic + unsafe { + ((mmap.plic.vaddr() + CONTEXT_BASE + CONTEXT_PER_HART * mmap.plic_context) as *mut u32) + .write_volatile(0); + ((mmap.plic.vaddr() + ENABLE_BASE + ENABLE_PER_HART * mmap.plic_context) as *mut u32) + .write_volatile(irq_mask); + ((mmap.plic.vaddr() + ENABLE_BASE + ENABLE_PER_HART * mmap.plic_context + CONTEXT_CLAIM) + as *mut u32) + .write_volatile(0); + } unsafe { // set sie = 0x222 From fe17a2768b6a5ad4cb7ac9a6d62a53a97e3aea0e Mon Sep 17 00:00:00 2001 From: Alingof Date: Wed, 4 Oct 2023 01:57:14 +0900 Subject: [PATCH 076/133] [fix] fix prop name in Initrd::new --- src/memmap/device/initrd.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/memmap/device/initrd.rs b/src/memmap/device/initrd.rs index 8b2c37d..54492ad 100644 --- a/src/memmap/device/initrd.rs +++ b/src/memmap/device/initrd.rs @@ -11,8 +11,8 @@ pub struct Initrd { impl Device for Initrd { fn new(device_tree: &Fdt, node_path: &str) -> Self { - let start_prop = "linux-initrd-start"; - let end_prop = "linux-initrd-end"; + let start_prop = "linux,initrd-start"; + let end_prop = "linux,initrd-end"; let node = device_tree.find_node(node_path).unwrap(); let start = node.property(start_prop).unwrap().value[0] as usize; let end = node.property(end_prop).unwrap().value[0] as usize; From b9801c1c12a00c5340e7bc3c7702da809cd69b77 Mon Sep 17 00:00:00 2001 From: Alingof Date: Wed, 4 Oct 2023 14:08:53 +0900 Subject: [PATCH 077/133] [wip][fix] fix getting `plic_context` --- src/memmap.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/memmap.rs b/src/memmap.rs index d1d8fcb..b0aff68 100644 --- a/src/memmap.rs +++ b/src/memmap.rs @@ -22,12 +22,23 @@ impl Memmap { virtio: virtio::VirtIO::new_all(&device_tree, "/soc/virtio_mmio"), initrd: initrd::Initrd::new(&device_tree, "/chosen"), plic: plic::Plic::new(&device_tree, "/soc/plic"), + plic_context: device_tree + .find_node("/cpus/cpu") + .unwrap() + .children() + .next() // interrupt-controller + .unwrap() + .property("phandle") + .unwrap() + .value[0] as usize, + /* plic_context: device_tree .find_node("/cpus/cpu/interrupt-controller") .unwrap() .property("phandle") .unwrap() .value[0] as usize, + */ } } } From fd351cdd9fb55d4ead61801971d0dc9d589228c6 Mon Sep 17 00:00:00 2001 From: Alingof Date: Wed, 4 Oct 2023 18:00:07 +0900 Subject: [PATCH 078/133] [add] prepare the boot page tables --- src/supervisor_init.rs | 35 ++++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/src/supervisor_init.rs b/src/supervisor_init.rs index 1de4b70..761e2cd 100644 --- a/src/supervisor_init.rs +++ b/src/supervisor_init.rs @@ -1,6 +1,6 @@ use crate::memmap::constant::{ - DRAM_BASE, DRAM_SIZE_PAR_HART, PA2VA_DRAM_OFFSET, PAGE_SIZE, PAGE_TABLE_BASE, - PAGE_TABLE_OFFSET_PER_HART, STACK_BASE, STACK_SIZE_PER_HART, + DRAM_BASE, DRAM_SIZE_PAR_HART, PA2VA_DEVICE_OFFSET, PA2VA_DRAM_OFFSET, PAGE_SIZE, + PAGE_TABLE_BASE, PAGE_TABLE_OFFSET_PER_HART, STACK_BASE, }; use crate::memmap::device::plic::{ CONTEXT_BASE, CONTEXT_CLAIM, CONTEXT_PER_HART, ENABLE_BASE, ENABLE_PER_HART, @@ -128,20 +128,37 @@ fn smode_setup(hart_id: usize, dtb_addr: usize) { .write_volatile(0); } + // copy fdt to 0x9000_0000 + unsafe { // set sie = 0x222 sie::set_ssoft(); sie::set_stimer(); sie::set_sext(); - // satp = Sv39 | 0x8000_0000 >> 12 - satp::set( - satp::Mode::Sv39, - 0, - (DRAM_BASE + DRAM_SIZE_PAR_HART * hart_id) >> 12, - ); + // boot page tables + let guest_id = hart_id + 1; + let guest_base_addr = DRAM_BASE + guest_id * DRAM_SIZE_PAR_HART; + let page_table_start = guest_base_addr; + for pt_index in 0..1024 { + let pt_offset = (page_table_start + pt_index * 8) as *mut usize; + pt_offset.write_volatile(match pt_index { + // 0xffff_fffc_0xxx_xxxx ..= 0xffff_ffff_8xxx_xxxx + 496..=503 => (pt_index - 496) << 28 | 0xcf, // a, d, x, w, r, v + // 0x0000_0000_8xxx_xxxx or 0xffff_ffff_cxxx_xxxx + 2 | 511 => (PAGE_TABLE_BASE + PAGE_SIZE) >> 2 | 0x01, // v + // 2 and 511 point to 512 PTE + 512 => 0x2000_0000 | 0xcb, // d, a, x, r, v + // 2nd level + 513..=1023 => (0x2000_0000 + ((pt_index - 512) << 19)) | 0xc7, // d, a, w, r, v + _ => 0, + }); + } + + // satp = Sv39 | 0x9000_0000 >> 12 + satp::set(satp::Mode::Sv39, 0, guest_base_addr >> 12); - let stack_pointer = STACK_BASE + STACK_SIZE_PER_HART * hart_id + PA2VA_DRAM_OFFSET; + let stack_pointer = guest_base_addr + 0x20_0000 + PA2VA_DEVICE_OFFSET; asm!("mv a0, {dtb_addr}", dtb_addr = in(reg) dtb_addr); asm!("mv sp, {stack_pointer_in_umode}", stack_pointer_in_umode = in(reg) stack_pointer); asm!("j {enter_user_mode}", enter_user_mode = sym enter_user_mode); From 47b5200c8a7d131d0906d54f7a8c0c60b193d11b Mon Sep 17 00:00:00 2001 From: Alingof Date: Wed, 4 Oct 2023 18:17:25 +0900 Subject: [PATCH 079/133] [add] implement to copy dtb and initrd to guest memory space --- src/supervisor_init.rs | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/src/supervisor_init.rs b/src/supervisor_init.rs index 761e2cd..6dd6257 100644 --- a/src/supervisor_init.rs +++ b/src/supervisor_init.rs @@ -128,17 +128,31 @@ fn smode_setup(hart_id: usize, dtb_addr: usize) { .write_volatile(0); } - // copy fdt to 0x9000_0000 - + let guest_id = hart_id + 1; + let guest_base_addr = DRAM_BASE + guest_id * DRAM_SIZE_PAR_HART; unsafe { + // copy dtb to guest space + let guest_dtb_addr = guest_base_addr + 0x2000 + PA2VA_DEVICE_OFFSET; + core::ptr::copy( + (dtb_addr + PA2VA_DEVICE_OFFSET) as *const u8, + guest_dtb_addr as *mut u8, + device_tree.total_size(), + ); + + // copy initrd to guest space + let heap_offset = 0x40_0000; + core::ptr::copy( + mmap.initrd.vaddr() as *const u8, + (guest_base_addr + heap_offset + PA2VA_DEVICE_OFFSET) as *mut u8, + device_tree.total_size(), + ); + // set sie = 0x222 sie::set_ssoft(); sie::set_stimer(); sie::set_sext(); // boot page tables - let guest_id = hart_id + 1; - let guest_base_addr = DRAM_BASE + guest_id * DRAM_SIZE_PAR_HART; let page_table_start = guest_base_addr; for pt_index in 0..1024 { let pt_offset = (page_table_start + pt_index * 8) as *mut usize; @@ -159,7 +173,7 @@ fn smode_setup(hart_id: usize, dtb_addr: usize) { satp::set(satp::Mode::Sv39, 0, guest_base_addr >> 12); let stack_pointer = guest_base_addr + 0x20_0000 + PA2VA_DEVICE_OFFSET; - asm!("mv a0, {dtb_addr}", dtb_addr = in(reg) dtb_addr); + asm!("mv a0, {dtb_addr}", dtb_addr = in(reg) guest_dtb_addr); asm!("mv sp, {stack_pointer_in_umode}", stack_pointer_in_umode = in(reg) stack_pointer); asm!("j {enter_user_mode}", enter_user_mode = sym enter_user_mode); } From dc8ec5c637b9c18b29d5f848b886d26b94cc87c7 Mon Sep 17 00:00:00 2001 From: Alingof Date: Wed, 4 Oct 2023 21:25:03 +0900 Subject: [PATCH 080/133] [add] add a constance GUEST_HEAP_OFFSET --- src/memmap/constant.rs | 3 +++ src/supervisor_init.rs | 7 +++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/memmap/constant.rs b/src/memmap/constant.rs index 125c118..c08ad12 100644 --- a/src/memmap/constant.rs +++ b/src/memmap/constant.rs @@ -22,3 +22,6 @@ pub const HEAP_SIZE: usize = 0x10_0000; pub const PA2VA_DRAM_OFFSET: usize = 0xffff_ffff_4000_0000; /// Offset for converting physical device address to virtual address. pub const PA2VA_DEVICE_OFFSET: usize = 0xffff_fffc_0000_0000; + +/// Heap offset of guest space +pub const GUEST_HEAP_OFFSET: usize = 0x40_0000; diff --git a/src/supervisor_init.rs b/src/supervisor_init.rs index 6dd6257..124a7ec 100644 --- a/src/supervisor_init.rs +++ b/src/supervisor_init.rs @@ -1,6 +1,6 @@ use crate::memmap::constant::{ - DRAM_BASE, DRAM_SIZE_PAR_HART, PA2VA_DEVICE_OFFSET, PA2VA_DRAM_OFFSET, PAGE_SIZE, - PAGE_TABLE_BASE, PAGE_TABLE_OFFSET_PER_HART, STACK_BASE, + DRAM_BASE, DRAM_SIZE_PAR_HART, GUEST_HEAP_OFFSET, PA2VA_DEVICE_OFFSET, PA2VA_DRAM_OFFSET, + PAGE_SIZE, PAGE_TABLE_BASE, PAGE_TABLE_OFFSET_PER_HART, STACK_BASE, }; use crate::memmap::device::plic::{ CONTEXT_BASE, CONTEXT_CLAIM, CONTEXT_PER_HART, ENABLE_BASE, ENABLE_PER_HART, @@ -140,10 +140,9 @@ fn smode_setup(hart_id: usize, dtb_addr: usize) { ); // copy initrd to guest space - let heap_offset = 0x40_0000; core::ptr::copy( mmap.initrd.vaddr() as *const u8, - (guest_base_addr + heap_offset + PA2VA_DEVICE_OFFSET) as *mut u8, + (guest_base_addr + GUEST_HEAP_OFFSET + PA2VA_DEVICE_OFFSET) as *mut u8, device_tree.total_size(), ); From 81be6c0a8ace0e5373764999da11324a6865ea06 Mon Sep 17 00:00:00 2001 From: Alingof Date: Wed, 4 Oct 2023 22:03:12 +0900 Subject: [PATCH 081/133] [add] add the elf crate --- Cargo.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index f9e5721..53f0836 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,8 +10,9 @@ 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 = {path = "wild-screen-alloc"} +wild_screen_alloc = { path = "wild-screen-alloc" } From a162f51b991f7ca4e9b1baf074371ad822cce50a Mon Sep 17 00:00:00 2001 From: Alingof Date: Wed, 4 Oct 2023 22:03:47 +0900 Subject: [PATCH 082/133] [fix] fix start/end value of Initrd --- src/memmap/device/initrd.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/memmap/device/initrd.rs b/src/memmap/device/initrd.rs index 54492ad..d36f672 100644 --- a/src/memmap/device/initrd.rs +++ b/src/memmap/device/initrd.rs @@ -14,8 +14,10 @@ impl Device for Initrd { let start_prop = "linux,initrd-start"; let end_prop = "linux,initrd-end"; let node = device_tree.find_node(node_path).unwrap(); - let start = node.property(start_prop).unwrap().value[0] as usize; - let end = node.property(end_prop).unwrap().value[0] as usize; + let start = node.property(start_prop).unwrap().value; + let start = u32::from_be_bytes(start.try_into().unwrap()) as usize; + let end = node.property(end_prop).unwrap().value; + let end = u32::from_be_bytes(end.try_into().unwrap()) as usize; Initrd { base_addr: start, From c0391c952496eae6323142b50bcff2d4bbd14802 Mon Sep 17 00:00:00 2001 From: Alingof Date: Wed, 4 Oct 2023 22:10:53 +0900 Subject: [PATCH 083/133] [add] implement to load initrd to guest memory space --- src/supervisor_init.rs | 45 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 39 insertions(+), 6 deletions(-) diff --git a/src/supervisor_init.rs b/src/supervisor_init.rs index 124a7ec..c0bf5b3 100644 --- a/src/supervisor_init.rs +++ b/src/supervisor_init.rs @@ -9,7 +9,9 @@ use crate::memmap::device::Device; use crate::memmap::Memmap; use crate::trap_vector; use core::arch::asm; -use riscv::register::{satp, sie, sstatus, stvec}; +use elf::endian::AnyEndian; +use elf::ElfBytes; +use riscv::register::{satp, sepc, sie, sstatus, stvec}; /// Supervisor start function /// * Init page tables @@ -143,7 +145,7 @@ fn smode_setup(hart_id: usize, dtb_addr: usize) { core::ptr::copy( mmap.initrd.vaddr() as *const u8, (guest_base_addr + GUEST_HEAP_OFFSET + PA2VA_DEVICE_OFFSET) as *mut u8, - device_tree.total_size(), + mmap.initrd.size(), ); // set sie = 0x222 @@ -172,14 +174,35 @@ fn smode_setup(hart_id: usize, dtb_addr: usize) { satp::set(satp::Mode::Sv39, 0, guest_base_addr >> 12); let stack_pointer = guest_base_addr + 0x20_0000 + PA2VA_DEVICE_OFFSET; - asm!("mv a0, {dtb_addr}", dtb_addr = in(reg) guest_dtb_addr); - asm!("mv sp, {stack_pointer_in_umode}", stack_pointer_in_umode = in(reg) stack_pointer); - asm!("j {enter_user_mode}", enter_user_mode = sym enter_user_mode); + asm!( + " + mv a0, {hart_id} + mv a1, {dtb_addr} + mv a2, {guest_base_addr} + mv a3, {guest_id} + mv a4, {guest_initrd_size} + mv sp, {stack_pointer_in_umode} + j {enter_user_mode} + ", + hart_id = in(reg) hart_id, + dtb_addr = in(reg) guest_dtb_addr, + guest_base_addr = in(reg) guest_base_addr, + guest_id = in(reg) guest_id, + guest_initrd_size = in(reg) mmap.initrd.size(), + stack_pointer_in_umode = in(reg) stack_pointer , + enter_user_mode = sym enter_user_mode + ); } } /// Prepare to enter U-mode and jump to linux kernel -fn enter_user_mode(dtb_addr: usize) { +fn enter_user_mode( + _hart_id: usize, + dtb_addr: usize, + guest_base_addr: usize, + _guest_id: usize, + guest_initrd_size: usize, +) { unsafe { // set sie = 0x222 sie::set_ssoft(); @@ -190,6 +213,16 @@ fn enter_user_mode(dtb_addr: usize) { sstatus::set_sum(); sstatus::set_spp(sstatus::SPP::User); + // set initrd entry point to sepc + let guest_elf = ElfBytes::::minimal_parse(core::slice::from_raw_parts( + (guest_base_addr + GUEST_HEAP_OFFSET + PA2VA_DEVICE_OFFSET) as *mut u8, + guest_initrd_size, + )) + .unwrap(); + let entry_point = guest_elf.ehdr.e_entry as usize; + sepc::write(entry_point); + + // stvec = trap_vector stvec::write(trap_vector as *const fn() as usize, stvec::TrapMode::Direct); asm!( From e1d34ce7eeda83742015b247bc2365607fba9bde Mon Sep 17 00:00:00 2001 From: Alignof Date: Thu, 5 Oct 2023 15:52:34 +0900 Subject: [PATCH 084/133] [add] add GUEST_STACK_OFFSET --- src/memmap/constant.rs | 2 ++ src/supervisor_init.rs | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/memmap/constant.rs b/src/memmap/constant.rs index c08ad12..e78f489 100644 --- a/src/memmap/constant.rs +++ b/src/memmap/constant.rs @@ -23,5 +23,7 @@ pub const PA2VA_DRAM_OFFSET: usize = 0xffff_ffff_4000_0000; /// Offset for converting physical device address to virtual address. pub const PA2VA_DEVICE_OFFSET: usize = 0xffff_fffc_0000_0000; +/// Stack offset of guest space +pub const GUEST_STACK_OFFSET: usize = 0x30_0000; /// Heap offset of guest space pub const GUEST_HEAP_OFFSET: usize = 0x40_0000; diff --git a/src/supervisor_init.rs b/src/supervisor_init.rs index c0bf5b3..37a0aee 100644 --- a/src/supervisor_init.rs +++ b/src/supervisor_init.rs @@ -1,6 +1,6 @@ use crate::memmap::constant::{ - DRAM_BASE, DRAM_SIZE_PAR_HART, GUEST_HEAP_OFFSET, PA2VA_DEVICE_OFFSET, PA2VA_DRAM_OFFSET, - PAGE_SIZE, PAGE_TABLE_BASE, PAGE_TABLE_OFFSET_PER_HART, STACK_BASE, + DRAM_BASE, DRAM_SIZE_PAR_HART, GUEST_HEAP_OFFSET, GUEST_STACK_OFFSET, PA2VA_DEVICE_OFFSET, + PA2VA_DRAM_OFFSET, PAGE_SIZE, PAGE_TABLE_BASE, PAGE_TABLE_OFFSET_PER_HART, STACK_BASE, }; use crate::memmap::device::plic::{ CONTEXT_BASE, CONTEXT_CLAIM, CONTEXT_PER_HART, ENABLE_BASE, ENABLE_PER_HART, @@ -173,7 +173,7 @@ fn smode_setup(hart_id: usize, dtb_addr: usize) { // satp = Sv39 | 0x9000_0000 >> 12 satp::set(satp::Mode::Sv39, 0, guest_base_addr >> 12); - let stack_pointer = guest_base_addr + 0x20_0000 + PA2VA_DEVICE_OFFSET; + let stack_pointer = guest_base_addr + GUEST_STACK_OFFSET + PA2VA_DEVICE_OFFSET; asm!( " mv a0, {hart_id} From c6ba4c85184555df70a0080fcc07d75d881d25fd Mon Sep 17 00:00:00 2001 From: Alingof Date: Sat, 7 Oct 2023 23:59:48 +0900 Subject: [PATCH 085/133] [refactor] apply `$ cargo clippy -- -W clippy::pedantic` --- src/supervisor_init.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/supervisor_init.rs b/src/supervisor_init.rs index 37a0aee..1e8606e 100644 --- a/src/supervisor_init.rs +++ b/src/supervisor_init.rs @@ -219,7 +219,8 @@ fn enter_user_mode( guest_initrd_size, )) .unwrap(); - let entry_point = guest_elf.ehdr.e_entry as usize; + let entry_point = + usize::try_from(guest_elf.ehdr.e_entry).expect("casting u64 to usize failed."); sepc::write(entry_point); // stvec = trap_vector From a9501609b4ab3592cc78d1500a3897fba9ff159c Mon Sep 17 00:00:00 2001 From: Alingof Date: Sun, 8 Oct 2023 01:28:54 +0900 Subject: [PATCH 086/133] [wip][add] add load_elf function --- src/supervisor_init.rs | 40 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/src/supervisor_init.rs b/src/supervisor_init.rs index 1e8606e..3a7b539 100644 --- a/src/supervisor_init.rs +++ b/src/supervisor_init.rs @@ -195,6 +195,38 @@ fn smode_setup(hart_id: usize, dtb_addr: usize) { } } +/// Load elf to guest memory. +/// +/// It only load PT_LOAD type segments. +/// Entry address is determined by ... . +/// +/// # Arguments +/// * guest_elf - Elf loading guest space. +/// * guest_base_addr - Base address of loading memory space. +fn load_elf(guest_elf: ElfBytes, elf_addr: *mut u8, guest_base_addr: usize) -> usize { + for prog_header in guest_elf + .segments() + .expect("failed to get segments from elf") + .iter() + { + const PT_LOAD: u32 = 1; + if prog_header.p_type == PT_LOAD { + if prog_header.p_filesz > 0 { + unsafe { + core::ptr::copy( + (guest_base_addr + prog_header.p_offset as usize) as *const u8, + elf_addr.wrapping_add(prog_header.p_offset as usize), + prog_header.p_filesz as usize, + ); + } + } + } + } + + let _debug = guest_elf.ehdr.e_entry; + guest_base_addr +} + /// Prepare to enter U-mode and jump to linux kernel fn enter_user_mode( _hart_id: usize, @@ -213,14 +245,14 @@ fn enter_user_mode( sstatus::set_sum(); sstatus::set_spp(sstatus::SPP::User); - // set initrd entry point to sepc + // copy initrd to guest text space(0x9000_0000-) and set initrd entry point to sepc + let elf_addr = (guest_base_addr + GUEST_HEAP_OFFSET + PA2VA_DEVICE_OFFSET) as *mut u8; let guest_elf = ElfBytes::::minimal_parse(core::slice::from_raw_parts( - (guest_base_addr + GUEST_HEAP_OFFSET + PA2VA_DEVICE_OFFSET) as *mut u8, + elf_addr, guest_initrd_size, )) .unwrap(); - let entry_point = - usize::try_from(guest_elf.ehdr.e_entry).expect("casting u64 to usize failed."); + let entry_point = load_elf(guest_elf, elf_addr, guest_base_addr); sepc::write(entry_point); // stvec = trap_vector From af11e0707ff2b323bd1250d5636ec1fd00364a76 Mon Sep 17 00:00:00 2001 From: Alingof Date: Sun, 8 Oct 2023 17:58:18 +0900 Subject: [PATCH 087/133] [fix] fix the alignment of trap_vector --- src/trap.S | 1 + 1 file changed, 1 insertion(+) diff --git a/src/trap.S b/src/trap.S index ad04b08..f0a8eee 100644 --- a/src/trap.S +++ b/src/trap.S @@ -1,6 +1,7 @@ .equ SYSCALL_NUM_ECALL, 9 .globl trap_vector +.align 4 trap_vector: addi sp, sp, -128 sd ra, 0(sp) From ffa584282a543dfe30d0f891283dd2e7dc327e85 Mon Sep 17 00:00:00 2001 From: Alingof Date: Sun, 8 Oct 2023 17:58:46 +0900 Subject: [PATCH 088/133] [fix] fix loading elf --- src/supervisor_init.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/supervisor_init.rs b/src/supervisor_init.rs index 3a7b539..a003512 100644 --- a/src/supervisor_init.rs +++ b/src/supervisor_init.rs @@ -214,7 +214,7 @@ fn load_elf(guest_elf: ElfBytes, elf_addr: *mut u8, guest_base_addr: if prog_header.p_filesz > 0 { unsafe { core::ptr::copy( - (guest_base_addr + prog_header.p_offset as usize) as *const u8, + (guest_base_addr + prog_header.p_paddr as usize) as *const u8, elf_addr.wrapping_add(prog_header.p_offset as usize), prog_header.p_filesz as usize, ); From 03696329c387b2ccd827075b8765b6fb3fa17fdd Mon Sep 17 00:00:00 2001 From: Alingof Date: Mon, 9 Oct 2023 01:23:12 +0900 Subject: [PATCH 089/133] [update] update guest memory layout --- src/memmap.rs | 2 ++ src/memmap/constant.rs | 25 +++++++++++++++++++++++-- src/supervisor_init.rs | 21 ++++++++++++++------- 3 files changed, 39 insertions(+), 9 deletions(-) diff --git a/src/memmap.rs b/src/memmap.rs index b0aff68..500f8c2 100644 --- a/src/memmap.rs +++ b/src/memmap.rs @@ -1,3 +1,5 @@ +//! See `memmap/constant` module for specefic memmory map. + pub mod constant; pub mod device; diff --git a/src/memmap/constant.rs b/src/memmap/constant.rs index e78f489..ba7cbff 100644 --- a/src/memmap/constant.rs +++ b/src/memmap/constant.rs @@ -1,4 +1,21 @@ //! Constant for memory map. +//! +//! | start | end | region | +//! |-------------|-------------|-----------| +//! | 0x0200_0000 | 0x0210_0000 | QEMU CLINT | +//! | 0x0c00_0000 | 0x0c60_0000 | QEMU PLIC | +//! | 0x1000_0000 | 0x1000_0100 | QEMU UART | +//! | 0x1000_1000 | 0x1000_8000 | QEMU VirtIO | +//! | 0x8000_0000 | 0x8000_xxxx | text data of hikami | +//! | 0x8020_0000 | 0x8020_2000 | hypervisor page table | +//! | 0x8020_4000 | 0x8020_xxxx | hypervisor device tree blob | +//! | 0x8030_0000 | 0x8031_0000 | hypervisor stack | +//! | 0x8040_0000 | 0x8050_0000 | hypervisor heap | +//! | 0x9000_0000 | 0x9000_2000 | hypervisor page table | +//! | 0x9000_2000 | 0x9000_4000 | hypervisor device tree | +//! | 0x9010_0000 | 0x902f_ffff | hypervisor stack | +//! | 0x9030_0000 | 0x93ff_ffff | hypervisor heap | +//! | 0x9400_0000 | ... | text data of hikami | /// Base address of dram. pub const DRAM_BASE: usize = 0x8000_0000; @@ -23,7 +40,11 @@ pub const PA2VA_DRAM_OFFSET: usize = 0xffff_ffff_4000_0000; /// Offset for converting physical device address to virtual address. pub const PA2VA_DEVICE_OFFSET: usize = 0xffff_fffc_0000_0000; +/// loading device tree offset of guest space +pub const GUEST_DEVICE_TREE_OFFSET: usize = 0x2000; /// Stack offset of guest space -pub const GUEST_STACK_OFFSET: usize = 0x30_0000; +pub const GUEST_STACK_OFFSET: usize = 0x10_0000; /// Heap offset of guest space -pub const GUEST_HEAP_OFFSET: usize = 0x40_0000; +pub const GUEST_HEAP_OFFSET: usize = 0x30_0000; +/// Guest Text secion offset +pub const GUEST_TEXT_OFFSET: usize = 0x0400_0000; diff --git a/src/supervisor_init.rs b/src/supervisor_init.rs index a003512..968b742 100644 --- a/src/supervisor_init.rs +++ b/src/supervisor_init.rs @@ -1,6 +1,7 @@ use crate::memmap::constant::{ - DRAM_BASE, DRAM_SIZE_PAR_HART, GUEST_HEAP_OFFSET, GUEST_STACK_OFFSET, PA2VA_DEVICE_OFFSET, - PA2VA_DRAM_OFFSET, PAGE_SIZE, PAGE_TABLE_BASE, PAGE_TABLE_OFFSET_PER_HART, STACK_BASE, + DRAM_BASE, DRAM_SIZE_PAR_HART, GUEST_DEVICE_TREE_OFFSET, GUEST_HEAP_OFFSET, GUEST_STACK_OFFSET, + GUEST_TEXT_OFFSET, PA2VA_DEVICE_OFFSET, PA2VA_DRAM_OFFSET, PAGE_SIZE, PAGE_TABLE_BASE, + PAGE_TABLE_OFFSET_PER_HART, STACK_BASE, }; use crate::memmap::device::plic::{ CONTEXT_BASE, CONTEXT_CLAIM, CONTEXT_PER_HART, ENABLE_BASE, ENABLE_PER_HART, @@ -134,7 +135,7 @@ fn smode_setup(hart_id: usize, dtb_addr: usize) { let guest_base_addr = DRAM_BASE + guest_id * DRAM_SIZE_PAR_HART; unsafe { // copy dtb to guest space - let guest_dtb_addr = guest_base_addr + 0x2000 + PA2VA_DEVICE_OFFSET; + let guest_dtb_addr = guest_base_addr + GUEST_DEVICE_TREE_OFFSET + PA2VA_DEVICE_OFFSET; core::ptr::copy( (dtb_addr + PA2VA_DEVICE_OFFSET) as *const u8, guest_dtb_addr as *mut u8, @@ -164,14 +165,16 @@ fn smode_setup(hart_id: usize, dtb_addr: usize) { 2 | 511 => (PAGE_TABLE_BASE + PAGE_SIZE) >> 2 | 0x01, // v // 2 and 511 point to 512 PTE 512 => 0x2000_0000 | 0xcb, // d, a, x, r, v + // 2 point to 512 PTE(for 0x0000_0000_9xxx_xxxx) + 640 => 0x2000_0000 | 0xcb, // d, a, x, r, v // 2nd level 513..=1023 => (0x2000_0000 + ((pt_index - 512) << 19)) | 0xc7, // d, a, w, r, v _ => 0, }); } - // satp = Sv39 | 0x9000_0000 >> 12 - satp::set(satp::Mode::Sv39, 0, guest_base_addr >> 12); + // satp = Sv39 | 0x9020_0000 >> 12 + satp::set(satp::Mode::Sv39, 0, page_table_start >> 12); let stack_pointer = guest_base_addr + GUEST_STACK_OFFSET + PA2VA_DEVICE_OFFSET; asm!( @@ -214,8 +217,8 @@ fn load_elf(guest_elf: ElfBytes, elf_addr: *mut u8, guest_base_addr: if prog_header.p_filesz > 0 { unsafe { core::ptr::copy( - (guest_base_addr + prog_header.p_paddr as usize) as *const u8, elf_addr.wrapping_add(prog_header.p_offset as usize), + (guest_base_addr + prog_header.p_paddr as usize) as *mut u8, prog_header.p_filesz as usize, ); } @@ -252,7 +255,11 @@ fn enter_user_mode( guest_initrd_size, )) .unwrap(); - let entry_point = load_elf(guest_elf, elf_addr, guest_base_addr); + let entry_point = load_elf( + guest_elf, + elf_addr, + guest_base_addr + GUEST_TEXT_OFFSET + PA2VA_DEVICE_OFFSET, + ); sepc::write(entry_point); // stvec = trap_vector From 7c2bb8f3180aec19d8af702ba1ddba28e28e0db6 Mon Sep 17 00:00:00 2001 From: Alingof Date: Tue, 10 Oct 2023 18:57:52 +0900 Subject: [PATCH 090/133] [wip][fix] fix address transrating --- src/supervisor_init.rs | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/src/supervisor_init.rs b/src/supervisor_init.rs index 968b742..4ab274b 100644 --- a/src/supervisor_init.rs +++ b/src/supervisor_init.rs @@ -1,7 +1,7 @@ use crate::memmap::constant::{ DRAM_BASE, DRAM_SIZE_PAR_HART, GUEST_DEVICE_TREE_OFFSET, GUEST_HEAP_OFFSET, GUEST_STACK_OFFSET, - GUEST_TEXT_OFFSET, PA2VA_DEVICE_OFFSET, PA2VA_DRAM_OFFSET, PAGE_SIZE, PAGE_TABLE_BASE, - PAGE_TABLE_OFFSET_PER_HART, STACK_BASE, + GUEST_TEXT_OFFSET, PA2VA_DRAM_OFFSET, PAGE_SIZE, PAGE_TABLE_BASE, PAGE_TABLE_OFFSET_PER_HART, + STACK_BASE, }; use crate::memmap::device::plic::{ CONTEXT_BASE, CONTEXT_CLAIM, CONTEXT_PER_HART, ENABLE_BASE, ENABLE_PER_HART, @@ -36,7 +36,7 @@ pub fn sstart() { // 0xffff_fffc_0xxx_xxxx ..= 0xffff_ffff_8xxx_xxxx 496..=503 => (pt_index - 496) << 28 | 0xcf, // a, d, x, w, r, v // 0x0000_0000_8xxx_xxxx or 0xffff_ffff_cxxx_xxxx - 2 | 511 => (PAGE_TABLE_BASE + PAGE_SIZE) >> 2 | 0x01, // v + 2 | 511 => (page_table_start + PAGE_SIZE) >> 2 | 0x01, // v // 2 and 511 point to 512 PTE 512 => 0x2000_0000 | 0xcb, // d, a, x, r, v // 2nd level @@ -135,9 +135,9 @@ fn smode_setup(hart_id: usize, dtb_addr: usize) { let guest_base_addr = DRAM_BASE + guest_id * DRAM_SIZE_PAR_HART; unsafe { // copy dtb to guest space - let guest_dtb_addr = guest_base_addr + GUEST_DEVICE_TREE_OFFSET + PA2VA_DEVICE_OFFSET; + let guest_dtb_addr = guest_base_addr + GUEST_DEVICE_TREE_OFFSET + PA2VA_DRAM_OFFSET; core::ptr::copy( - (dtb_addr + PA2VA_DEVICE_OFFSET) as *const u8, + (dtb_addr + PA2VA_DRAM_OFFSET) as *const u8, guest_dtb_addr as *mut u8, device_tree.total_size(), ); @@ -145,7 +145,7 @@ fn smode_setup(hart_id: usize, dtb_addr: usize) { // copy initrd to guest space core::ptr::copy( mmap.initrd.vaddr() as *const u8, - (guest_base_addr + GUEST_HEAP_OFFSET + PA2VA_DEVICE_OFFSET) as *mut u8, + (guest_base_addr + GUEST_HEAP_OFFSET + PA2VA_DRAM_OFFSET) as *mut u8, mmap.initrd.size(), ); @@ -162,7 +162,7 @@ fn smode_setup(hart_id: usize, dtb_addr: usize) { // 0xffff_fffc_0xxx_xxxx ..= 0xffff_ffff_8xxx_xxxx 496..=503 => (pt_index - 496) << 28 | 0xcf, // a, d, x, w, r, v // 0x0000_0000_8xxx_xxxx or 0xffff_ffff_cxxx_xxxx - 2 | 511 => (PAGE_TABLE_BASE + PAGE_SIZE) >> 2 | 0x01, // v + 2 | 511 => (page_table_start + PAGE_SIZE) >> 2 | 0x01, // v // 2 and 511 point to 512 PTE 512 => 0x2000_0000 | 0xcb, // d, a, x, r, v // 2 point to 512 PTE(for 0x0000_0000_9xxx_xxxx) @@ -173,10 +173,10 @@ fn smode_setup(hart_id: usize, dtb_addr: usize) { }); } - // satp = Sv39 | 0x9020_0000 >> 12 + // satp = Sv39 | 0x9000_0000 >> 12 satp::set(satp::Mode::Sv39, 0, page_table_start >> 12); - let stack_pointer = guest_base_addr + GUEST_STACK_OFFSET + PA2VA_DEVICE_OFFSET; + let stack_pointer = guest_base_addr + GUEST_STACK_OFFSET + PA2VA_DRAM_OFFSET; asm!( " mv a0, {hart_id} @@ -226,7 +226,6 @@ fn load_elf(guest_elf: ElfBytes, elf_addr: *mut u8, guest_base_addr: } } - let _debug = guest_elf.ehdr.e_entry; guest_base_addr } @@ -249,7 +248,7 @@ fn enter_user_mode( sstatus::set_spp(sstatus::SPP::User); // copy initrd to guest text space(0x9000_0000-) and set initrd entry point to sepc - let elf_addr = (guest_base_addr + GUEST_HEAP_OFFSET + PA2VA_DEVICE_OFFSET) as *mut u8; + let elf_addr = (guest_base_addr + GUEST_HEAP_OFFSET + PA2VA_DRAM_OFFSET) as *mut u8; let guest_elf = ElfBytes::::minimal_parse(core::slice::from_raw_parts( elf_addr, guest_initrd_size, @@ -258,7 +257,7 @@ fn enter_user_mode( let entry_point = load_elf( guest_elf, elf_addr, - guest_base_addr + GUEST_TEXT_OFFSET + PA2VA_DEVICE_OFFSET, + guest_base_addr + GUEST_TEXT_OFFSET + PA2VA_DRAM_OFFSET, ); sepc::write(entry_point); From aa76ce010a986c3dd3e0b16bcaab84d054a3b614 Mon Sep 17 00:00:00 2001 From: Alingof Date: Wed, 11 Oct 2023 01:58:09 +0900 Subject: [PATCH 091/133] [fix] fix the page table for translating 0xffff_ffff_dxxx_xxxx --- src/supervisor_init.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/supervisor_init.rs b/src/supervisor_init.rs index 4ab274b..a7da682 100644 --- a/src/supervisor_init.rs +++ b/src/supervisor_init.rs @@ -162,11 +162,12 @@ fn smode_setup(hart_id: usize, dtb_addr: usize) { // 0xffff_fffc_0xxx_xxxx ..= 0xffff_ffff_8xxx_xxxx 496..=503 => (pt_index - 496) << 28 | 0xcf, // a, d, x, w, r, v // 0x0000_0000_8xxx_xxxx or 0xffff_ffff_cxxx_xxxx + // 0x0000_0000_9xxx_xxxx or 0xffff_ffff_dxxx_xxxx 2 | 511 => (page_table_start + PAGE_SIZE) >> 2 | 0x01, // v - // 2 and 511 point to 512 PTE + // 2 and 511 point to 512 PTE(for 0xffff_ffff_cxxx_xxxx -> 0x0000_0000_8xxx_xxxx) 512 => 0x2000_0000 | 0xcb, // d, a, x, r, v - // 2 point to 512 PTE(for 0x0000_0000_9xxx_xxxx) - 640 => 0x2000_0000 | 0xcb, // d, a, x, r, v + // 2 and 511 point to 640 PTE(for 0xffff_ffff_dxxx_xxxx -> 0x0000_0000_9xxx_xxxx) + 640 => 0x2400_0000 | 0xcf, // d, a, x, r, v // 2nd level 513..=1023 => (0x2000_0000 + ((pt_index - 512) << 19)) | 0xc7, // d, a, w, r, v _ => 0, From 49d8f937524b7f8b40ed942b1be8dbcf793031f6 Mon Sep 17 00:00:00 2001 From: Alignof Date: Sat, 14 Oct 2023 00:57:34 +0900 Subject: [PATCH 092/133] [wip][add] add src/trap.rs --- src/trap.rs | 187 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 187 insertions(+) create mode 100644 src/trap.rs diff --git a/src/trap.rs b/src/trap.rs new file mode 100644 index 0000000..458fbc1 --- /dev/null +++ b/src/trap.rs @@ -0,0 +1,187 @@ +use crate::memmap::constant::STACK_BASE; +use core::arch::asm; +use riscv::register::mcause; +use riscv::register::mcause::Trap; +use riscv::register::mcause::{Exception, Interrupt}; +use riscv::register::{mepc, mhartid, mip, mstatus, mtval, scause, sepc, stval, stvec}; + +#[no_mangle] +unsafe fn mtrap() { + asm!( + ".align 4 + csrrw mscratch, sp + li sp, {stack_base} + + addi sp, sp, -240 + sd ra, 0(sp) + sd t0, 8(sp) + sd t1, 16(sp) + sd t2, 24(sp) + sd t3, 32(sp) + sd t4, 40(sp) + sd t5, 48(sp) + sd t6, 56(sp) + sd a0, 64(sp) + sd a1, 72(sp) + sd a2, 80(sp) + sd a3, 88(sp) + sd a4, 96(sp) + sd a5, 104(sp) + sd a6, 112(sp) + sd a7, 120(sp) + sd s2, 128(sp) + sd s3, 136(sp) + sd s4, 144(sp) + sd s5, 152(sp) + sd s6, 160(sp) + sd s7, 168(sp) + sd s8, 176(sp) + sd s9, 184(sp) + sd s10, 192(sp) + sd s11, 200(sp) + sd t3, 208(sp) + sd t4, 216(sp) + sd t5, 224(sp) + sd t6, 232(sp) + ", + stack_base = in(reg) STACK_BASE + ); + + const MTIMECMP_ADDR: usize = 0x200_4000; + let trap_cause = mcause::read(); + match trap_cause.cause() { + Trap::Interrupt(inter) => match inter { + Interrupt::MachineSoft => { + mip::set_ssoft(); + const CLINT_ADDR: usize = 0x200_0000; + let interrupt_addr = (CLINT_ADDR + mhartid::read() * 4) as *mut u64; + interrupt_addr.write_volatile(0); + } + Interrupt::MachineTimer => { + mip::set_stimer(); + let mtimecmp_addr = (MTIMECMP_ADDR + mhartid::read() * 8) as *mut u64; + mtimecmp_addr.write_volatile(u64::MAX); + } + Interrupt::MachineExternal => loop {}, + _ => panic!("unknown interrupt type"), + }, + Trap::Exception(except) => match except { + // https://doxygen.coreboot.org/d6/dfc/sbi_8c_source.html + Exception::UserEnvCall => { + mepc::write(mepc::read() + 4); + + // ecall_number = a7 + let ecall_number: i64 = 0; + asm!("ld {ecall_number}, 120(sp)", ecall_number = in(reg) ecall_number); + match ecall_number { + // sbi_set_timer + 0 => { + // timer_value = a0 + let timer_value: u64 = 0; + asm!("ld {timer_value}, 64(sp)", timer_value = in(reg) timer_value); + + let mtimecmp_addr = (MTIMECMP_ADDR + mhartid::read() * 8) as *mut u64; + mtimecmp_addr.write_volatile(timer_value); + asm!("li a0, 0"); + } + // sbi_clear_ipi + 3 => { + mip::clear_ssoft(); + asm!("li a0, 0"); + } + // sbi_send_ipi + 4 => { + // mask_addr = a0 + let mask_addr: *mut u64 = core::ptr::null_mut(); + asm!("ld {mask_addr}, 64(sp)", mask_addr = in(reg) mask_addr); + + let mut mask = if mstatus::read().mprv() { + mask_addr.read_volatile() + } else { + mstatus::set_mprv(); + let mask = mask_addr.read_volatile(); + mstatus::clear_mprv(); + mask + }; + + let mut clint_addr: *mut u8 = 0x200_0000 as *mut u8; + while mask != 0 { + if mask & 1 == 1 { + clint_addr.write_volatile(1); + } + clint_addr = clint_addr.add(4); + mask >>= 1; + } + asm!("li a0, 0"); + } + // sbi_shutdown + 8 => panic!("sbi shutdown"), + // other + _ => panic!("unknown ecall number"), + } + } + // other exception + _ => { + 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); + } + }, + } + + asm!(" + sd ra, 0(sp) + sd t0, 8(sp) + sd t1, 16(sp) + sd t2, 24(sp) + sd t3, 32(sp) + sd t4, 40(sp) + sd t5, 48(sp) + sd t6, 56(sp) + sd a0, 64(sp) + sd a1, 72(sp) + sd a2, 80(sp) + sd a3, 88(sp) + sd a4, 96(sp) + sd a5, 104(sp) + sd a6, 112(sp) + sd a7, 120(sp) + sd s2, 128(sp) + sd s3, 136(sp) + sd s4, 144(sp) + sd s5, 152(sp) + sd s6, 160(sp) + sd s7, 168(sp) + sd s8, 176(sp) + sd s9, 184(sp) + sd s10, 192(sp) + sd s11, 200(sp) + sd t3, 208(sp) + sd t4, 216(sp) + sd t5, 224(sp) + sd t6, 232(sp) + + csrrw mscratch, sp + li sp, {stack_base} + + mret + ", + stack_base = in(reg) STACK_BASE + ); +} From 29b5567da9f4ab2694940a5f727771e1518f6e0d Mon Sep 17 00:00:00 2001 From: Alignof Date: Sat, 14 Oct 2023 01:27:15 +0900 Subject: [PATCH 093/133] [add] add `trap_exception` and `trap_interrupt` to trap.rs --- src/trap.rs | 249 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 153 insertions(+), 96 deletions(-) diff --git a/src/trap.rs b/src/trap.rs index 458fbc1..eb1c093 100644 --- a/src/trap.rs +++ b/src/trap.rs @@ -5,6 +5,8 @@ use riscv::register::mcause::Trap; use riscv::register::mcause::{Exception, Interrupt}; use riscv::register::{mepc, mhartid, mip, mstatus, mtval, scause, sepc, stval, stvec}; +const MTIMECMP_ADDR: usize = 0x200_4000; + #[no_mangle] unsafe fn mtrap() { asm!( @@ -47,102 +49,13 @@ unsafe fn mtrap() { stack_base = in(reg) STACK_BASE ); - const MTIMECMP_ADDR: usize = 0x200_4000; - let trap_cause = mcause::read(); - match trap_cause.cause() { - Trap::Interrupt(inter) => match inter { - Interrupt::MachineSoft => { - mip::set_ssoft(); - const CLINT_ADDR: usize = 0x200_0000; - let interrupt_addr = (CLINT_ADDR + mhartid::read() * 4) as *mut u64; - interrupt_addr.write_volatile(0); - } - Interrupt::MachineTimer => { - mip::set_stimer(); - let mtimecmp_addr = (MTIMECMP_ADDR + mhartid::read() * 8) as *mut u64; - mtimecmp_addr.write_volatile(u64::MAX); - } - Interrupt::MachineExternal => loop {}, - _ => panic!("unknown interrupt type"), - }, - Trap::Exception(except) => match except { - // https://doxygen.coreboot.org/d6/dfc/sbi_8c_source.html - Exception::UserEnvCall => { - mepc::write(mepc::read() + 4); - - // ecall_number = a7 - let ecall_number: i64 = 0; - asm!("ld {ecall_number}, 120(sp)", ecall_number = in(reg) ecall_number); - match ecall_number { - // sbi_set_timer - 0 => { - // timer_value = a0 - let timer_value: u64 = 0; - asm!("ld {timer_value}, 64(sp)", timer_value = in(reg) timer_value); - - let mtimecmp_addr = (MTIMECMP_ADDR + mhartid::read() * 8) as *mut u64; - mtimecmp_addr.write_volatile(timer_value); - asm!("li a0, 0"); - } - // sbi_clear_ipi - 3 => { - mip::clear_ssoft(); - asm!("li a0, 0"); - } - // sbi_send_ipi - 4 => { - // mask_addr = a0 - let mask_addr: *mut u64 = core::ptr::null_mut(); - asm!("ld {mask_addr}, 64(sp)", mask_addr = in(reg) mask_addr); - - let mut mask = if mstatus::read().mprv() { - mask_addr.read_volatile() - } else { - mstatus::set_mprv(); - let mask = mask_addr.read_volatile(); - mstatus::clear_mprv(); - mask - }; - - let mut clint_addr: *mut u8 = 0x200_0000 as *mut u8; - while mask != 0 { - if mask & 1 == 1 { - clint_addr.write_volatile(1); - } - clint_addr = clint_addr.add(4); - mask >>= 1; - } - asm!("li a0, 0"); - } - // sbi_shutdown - 8 => panic!("sbi shutdown"), - // other - _ => panic!("unknown ecall number"), - } - } - // other exception - _ => { - 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); - } - }, + let a0: u64 = 0; + let a7: u64 = 0; + asm!("ld {a0_reg}, 64(sp)", a0_reg = in(reg) a0); + asm!("ld {a7_reg}, 64(sp)", a7_reg = in(reg) a7); + match mcause::read().cause() { + Trap::Interrupt(interrupt_cause) => trap_interrupt(interrupt_cause), + Trap::Exception(exception_cause) => trap_exception(a0, a7, exception_cause), } asm!(" @@ -185,3 +98,147 @@ unsafe fn mtrap() { stack_base = in(reg) STACK_BASE ); } + +unsafe fn trap_exception(a0: u64, a7: u64, exception_cause: Exception) { + let ret_with_value = |ret_value: u64| { + asm!(" + sd ra, 0(sp) + sd t0, 8(sp) + sd t1, 16(sp) + sd t2, 24(sp) + sd t3, 32(sp) + sd t4, 40(sp) + sd t5, 48(sp) + sd t6, 56(sp) + sd a0, {ret_value} + sd a1, 72(sp) + sd a2, 80(sp) + sd a3, 88(sp) + sd a4, 96(sp) + sd a5, 104(sp) + sd a6, 112(sp) + sd a7, 120(sp) + sd s2, 128(sp) + sd s3, 136(sp) + sd s4, 144(sp) + sd s5, 152(sp) + sd s6, 160(sp) + sd s7, 168(sp) + sd s8, 176(sp) + sd s9, 184(sp) + sd s10, 192(sp) + sd s11, 200(sp) + sd t3, 208(sp) + sd t4, 216(sp) + sd t5, 224(sp) + sd t6, 232(sp) + + csrrw mscratch, sp + li sp, {stack_base} + + mret + ", + stack_base = in(reg) STACK_BASE, + ret_value = in(reg) ret_value, + ) + }; + + match exception_cause { + // https://doxygen.coreboot.org/d6/dfc/sbi_8c_source.html + Exception::UserEnvCall => { + mepc::write(mepc::read() + 4); + + // ecall_number = a7 + let ecall_number: i64 = a7 as i64; + match ecall_number { + // sbi_set_timer + 0 => { + // timer_value = a0 + let timer_value: u64 = a0 as u64; + + let mtimecmp_addr = (MTIMECMP_ADDR + mhartid::read() * 8) as *mut u64; + mtimecmp_addr.write_volatile(timer_value); + + ret_with_value(0); + unreachable!(); + } + // sbi_clear_ipi + 3 => { + mip::clear_ssoft(); + + ret_with_value(0); + unreachable!(); + } + // sbi_send_ipi + 4 => { + // mask_addr = a0 + let mask_addr: *mut u64 = a0 as *mut u64; + let mut mask = if mstatus::read().mprv() { + mask_addr.read_volatile() + } else { + mstatus::set_mprv(); + let mask = mask_addr.read_volatile(); + mstatus::clear_mprv(); + mask + }; + + let mut clint_addr: *mut u8 = 0x200_0000 as *mut u8; + while mask != 0 { + if mask & 1 == 1 { + clint_addr.write_volatile(1); + } + clint_addr = clint_addr.add(4); + mask >>= 1; + } + + ret_with_value(0); + unreachable!(); + } + // sbi_shutdown + 8 => panic!("sbi shutdown"), + // other + _ => panic!("unknown ecall number"), + } + } + // other exception + _ => { + 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); + } + } +} + +unsafe fn trap_interrupt(interrupt_cause: Interrupt) { + match interrupt_cause { + Interrupt::MachineSoft => { + mip::set_ssoft(); + const CLINT_ADDR: usize = 0x200_0000; + let interrupt_addr = (CLINT_ADDR + mhartid::read() * 4) as *mut u64; + interrupt_addr.write_volatile(0); + } + Interrupt::MachineTimer => { + mip::set_stimer(); + let mtimecmp_addr = (MTIMECMP_ADDR + mhartid::read() * 8) as *mut u64; + mtimecmp_addr.write_volatile(u64::MAX); + } + Interrupt::MachineExternal => loop {}, + _ => panic!("unknown interrupt type"), + } +} From d0fe87765da8aa7f32d0bb2936c4059b8d0ce8ad Mon Sep 17 00:00:00 2001 From: Alignof Date: Sat, 14 Oct 2023 01:37:21 +0900 Subject: [PATCH 094/133] [update] rename `mtrap` to `mtrap_vector` and move it to `trap/machine.rs` --- src/trap.rs | 95 +------------------------------------------- src/trap/machine.rs | 97 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 99 insertions(+), 93 deletions(-) create mode 100644 src/trap/machine.rs diff --git a/src/trap.rs b/src/trap.rs index eb1c093..e649f18 100644 --- a/src/trap.rs +++ b/src/trap.rs @@ -1,104 +1,13 @@ +mod machine; + use crate::memmap::constant::STACK_BASE; use core::arch::asm; use riscv::register::mcause; -use riscv::register::mcause::Trap; use riscv::register::mcause::{Exception, Interrupt}; use riscv::register::{mepc, mhartid, mip, mstatus, mtval, scause, sepc, stval, stvec}; const MTIMECMP_ADDR: usize = 0x200_4000; -#[no_mangle] -unsafe fn mtrap() { - asm!( - ".align 4 - csrrw mscratch, sp - li sp, {stack_base} - - addi sp, sp, -240 - sd ra, 0(sp) - sd t0, 8(sp) - sd t1, 16(sp) - sd t2, 24(sp) - sd t3, 32(sp) - sd t4, 40(sp) - sd t5, 48(sp) - sd t6, 56(sp) - sd a0, 64(sp) - sd a1, 72(sp) - sd a2, 80(sp) - sd a3, 88(sp) - sd a4, 96(sp) - sd a5, 104(sp) - sd a6, 112(sp) - sd a7, 120(sp) - sd s2, 128(sp) - sd s3, 136(sp) - sd s4, 144(sp) - sd s5, 152(sp) - sd s6, 160(sp) - sd s7, 168(sp) - sd s8, 176(sp) - sd s9, 184(sp) - sd s10, 192(sp) - sd s11, 200(sp) - sd t3, 208(sp) - sd t4, 216(sp) - sd t5, 224(sp) - sd t6, 232(sp) - ", - stack_base = in(reg) STACK_BASE - ); - - let a0: u64 = 0; - let a7: u64 = 0; - asm!("ld {a0_reg}, 64(sp)", a0_reg = in(reg) a0); - asm!("ld {a7_reg}, 64(sp)", a7_reg = in(reg) a7); - match mcause::read().cause() { - Trap::Interrupt(interrupt_cause) => trap_interrupt(interrupt_cause), - Trap::Exception(exception_cause) => trap_exception(a0, a7, exception_cause), - } - - asm!(" - sd ra, 0(sp) - sd t0, 8(sp) - sd t1, 16(sp) - sd t2, 24(sp) - sd t3, 32(sp) - sd t4, 40(sp) - sd t5, 48(sp) - sd t6, 56(sp) - sd a0, 64(sp) - sd a1, 72(sp) - sd a2, 80(sp) - sd a3, 88(sp) - sd a4, 96(sp) - sd a5, 104(sp) - sd a6, 112(sp) - sd a7, 120(sp) - sd s2, 128(sp) - sd s3, 136(sp) - sd s4, 144(sp) - sd s5, 152(sp) - sd s6, 160(sp) - sd s7, 168(sp) - sd s8, 176(sp) - sd s9, 184(sp) - sd s10, 192(sp) - sd s11, 200(sp) - sd t3, 208(sp) - sd t4, 216(sp) - sd t5, 224(sp) - sd t6, 232(sp) - - csrrw mscratch, sp - li sp, {stack_base} - - mret - ", - stack_base = in(reg) STACK_BASE - ); -} - unsafe fn trap_exception(a0: u64, a7: u64, exception_cause: Exception) { let ret_with_value = |ret_value: u64| { asm!(" diff --git a/src/trap/machine.rs b/src/trap/machine.rs new file mode 100644 index 0000000..78a8c71 --- /dev/null +++ b/src/trap/machine.rs @@ -0,0 +1,97 @@ +use super::{trap_exception, trap_interrupt}; +use crate::memmap::constant::STACK_BASE; +use core::arch::asm; +use riscv::register::mcause; +use riscv::register::mcause::Trap; + +#[no_mangle] +unsafe fn mtrap_vector() { + asm!( + ".align 4 + csrrw mscratch, sp + li sp, {stack_base} + + addi sp, sp, -240 + sd ra, 0(sp) + sd t0, 8(sp) + sd t1, 16(sp) + sd t2, 24(sp) + sd t3, 32(sp) + sd t4, 40(sp) + sd t5, 48(sp) + sd t6, 56(sp) + sd a0, 64(sp) + sd a1, 72(sp) + sd a2, 80(sp) + sd a3, 88(sp) + sd a4, 96(sp) + sd a5, 104(sp) + sd a6, 112(sp) + sd a7, 120(sp) + sd s2, 128(sp) + sd s3, 136(sp) + sd s4, 144(sp) + sd s5, 152(sp) + sd s6, 160(sp) + sd s7, 168(sp) + sd s8, 176(sp) + sd s9, 184(sp) + sd s10, 192(sp) + sd s11, 200(sp) + sd t3, 208(sp) + sd t4, 216(sp) + sd t5, 224(sp) + sd t6, 232(sp) + ", + stack_base = in(reg) STACK_BASE + ); + + let a0: u64 = 0; + let a7: u64 = 0; + asm!("ld {a0_reg}, 64(sp)", a0_reg = in(reg) a0); + asm!("ld {a7_reg}, 64(sp)", a7_reg = in(reg) a7); + match mcause::read().cause() { + Trap::Interrupt(interrupt_cause) => trap_interrupt(interrupt_cause), + Trap::Exception(exception_cause) => trap_exception(a0, a7, exception_cause), + } + + asm!(" + sd ra, 0(sp) + sd t0, 8(sp) + sd t1, 16(sp) + sd t2, 24(sp) + sd t3, 32(sp) + sd t4, 40(sp) + sd t5, 48(sp) + sd t6, 56(sp) + sd a0, 64(sp) + sd a1, 72(sp) + sd a2, 80(sp) + sd a3, 88(sp) + sd a4, 96(sp) + sd a5, 104(sp) + sd a6, 112(sp) + sd a7, 120(sp) + sd s2, 128(sp) + sd s3, 136(sp) + sd s4, 144(sp) + sd s5, 152(sp) + sd s6, 160(sp) + sd s7, 168(sp) + sd s8, 176(sp) + sd s9, 184(sp) + sd s10, 192(sp) + sd s11, 200(sp) + sd t3, 208(sp) + sd t4, 216(sp) + sd t5, 224(sp) + sd t6, 232(sp) + + csrrw mscratch, sp + li sp, {stack_base} + + mret + ", + stack_base = in(reg) STACK_BASE + ); +} From e1088ebaca24c18c65d772fc0ad49c0cdcfe8e4f Mon Sep 17 00:00:00 2001 From: Alignof Date: Sat, 14 Oct 2023 01:39:05 +0900 Subject: [PATCH 095/133] [add] add `trap/supervisor.rs` --- src/trap.rs | 1 + src/trap/supervisor.rs | 97 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 98 insertions(+) create mode 100644 src/trap/supervisor.rs diff --git a/src/trap.rs b/src/trap.rs index e649f18..da351c4 100644 --- a/src/trap.rs +++ b/src/trap.rs @@ -1,4 +1,5 @@ mod machine; +mod supervisor; use crate::memmap::constant::STACK_BASE; use core::arch::asm; diff --git a/src/trap/supervisor.rs b/src/trap/supervisor.rs new file mode 100644 index 0000000..5e91ad2 --- /dev/null +++ b/src/trap/supervisor.rs @@ -0,0 +1,97 @@ +use super::{trap_exception, trap_interrupt}; +use crate::memmap::constant::STACK_BASE; +use core::arch::asm; +use riscv::register::mcause; +use riscv::register::mcause::Trap; + +#[no_mangle] +unsafe fn strap_vector() { + asm!( + ".align 4 + csrrw sscratch, sp + li sp, {stack_base} + + addi sp, sp, -240 + sd ra, 0(sp) + sd t0, 8(sp) + sd t1, 16(sp) + sd t2, 24(sp) + sd t3, 32(sp) + sd t4, 40(sp) + sd t5, 48(sp) + sd t6, 56(sp) + sd a0, 64(sp) + sd a1, 72(sp) + sd a2, 80(sp) + sd a3, 88(sp) + sd a4, 96(sp) + sd a5, 104(sp) + sd a6, 112(sp) + sd a7, 120(sp) + sd s2, 128(sp) + sd s3, 136(sp) + sd s4, 144(sp) + sd s5, 152(sp) + sd s6, 160(sp) + sd s7, 168(sp) + sd s8, 176(sp) + sd s9, 184(sp) + sd s10, 192(sp) + sd s11, 200(sp) + sd t3, 208(sp) + sd t4, 216(sp) + sd t5, 224(sp) + sd t6, 232(sp) + ", + stack_base = in(reg) STACK_BASE + ); + + let a0: u64 = 0; + let a7: u64 = 0; + asm!("ld {a0_reg}, 64(sp)", a0_reg = in(reg) a0); + asm!("ld {a7_reg}, 64(sp)", a7_reg = in(reg) a7); + match mcause::read().cause() { + Trap::Interrupt(interrupt_cause) => trap_interrupt(interrupt_cause), + Trap::Exception(exception_cause) => trap_exception(a0, a7, exception_cause), + } + + asm!(" + sd ra, 0(sp) + sd t0, 8(sp) + sd t1, 16(sp) + sd t2, 24(sp) + sd t3, 32(sp) + sd t4, 40(sp) + sd t5, 48(sp) + sd t6, 56(sp) + sd a0, 64(sp) + sd a1, 72(sp) + sd a2, 80(sp) + sd a3, 88(sp) + sd a4, 96(sp) + sd a5, 104(sp) + sd a6, 112(sp) + sd a7, 120(sp) + sd s2, 128(sp) + sd s3, 136(sp) + sd s4, 144(sp) + sd s5, 152(sp) + sd s6, 160(sp) + sd s7, 168(sp) + sd s8, 176(sp) + sd s9, 184(sp) + sd s10, 192(sp) + sd s11, 200(sp) + sd t3, 208(sp) + sd t4, 216(sp) + sd t5, 224(sp) + sd t6, 232(sp) + + csrrw sscratch, sp + li sp, {stack_base} + + sret + ", + stack_base = in(reg) STACK_BASE + ); +} From 6255087e948161bd8764d169a11015bdc3afa116 Mon Sep 17 00:00:00 2001 From: Alignof Date: Sat, 14 Oct 2023 01:51:55 +0900 Subject: [PATCH 096/133] [fix] fix some assembly code --- src/machine_init.rs | 15 +++++++-------- src/supervisor_init.rs | 7 +++++-- src/trap.rs | 13 +++++-------- src/trap/machine.rs | 15 +++++++-------- src/trap/supervisor.rs | 15 +++++++-------- 5 files changed, 31 insertions(+), 34 deletions(-) diff --git a/src/machine_init.rs b/src/machine_init.rs index 3bc680a..dccd55c 100644 --- a/src/machine_init.rs +++ b/src/machine_init.rs @@ -5,9 +5,11 @@ extern crate alloc; extern crate panic_halt; mod memmap; mod supervisor_init; +mod trap; use crate::memmap::constant::{DRAM_BASE, HEAP_BASE, HEAP_SIZE, STACK_BASE, STACK_SIZE_PER_HART}; -use core::arch::{asm, global_asm}; +use crate::trap::machine::mtrap_vector; +use core::arch::asm; use riscv::asm::sfence_vma_all; use riscv::register::{ mcause, mcounteren, medeleg, mepc, mideleg, mie, mscratch, mstatus, mtval, mtvec, pmpaddr0, @@ -19,12 +21,6 @@ use wild_screen_alloc::WildScreenAlloc; #[global_allocator] static mut ALLOCATOR: WildScreenAlloc = WildScreenAlloc::empty(); -global_asm!(include_str!("trap.S")); -extern "C" { - /// Trap vector for M-mode. This function is in `trap.S`. - fn trap_vector(); -} - /// Entry function. `__risc_v_rt__main` is alias of `__init` function in machine_init.rs. /// * set stack pointer /// * init mtvec and stvec @@ -128,7 +124,10 @@ fn mstart(hart_id: usize, dtb_addr: usize) { mepc::write(supervisor_init::sstart as *const fn() as usize); // set trap_vector in trap.S to mtvec - mtvec::write(trap_vector as *const fn() as usize, mtvec::TrapMode::Direct); + mtvec::write( + mtrap_vector as *const fn() as usize, + mtvec::TrapMode::Direct, + ); sfence_vma_all(); } diff --git a/src/supervisor_init.rs b/src/supervisor_init.rs index a7da682..90db1fd 100644 --- a/src/supervisor_init.rs +++ b/src/supervisor_init.rs @@ -8,7 +8,7 @@ use crate::memmap::device::plic::{ }; use crate::memmap::device::Device; use crate::memmap::Memmap; -use crate::trap_vector; +use crate::trap::supervisor::strap_vector; use core::arch::asm; use elf::endian::AnyEndian; use elf::ElfBytes; @@ -263,7 +263,10 @@ fn enter_user_mode( sepc::write(entry_point); // stvec = trap_vector - stvec::write(trap_vector as *const fn() as usize, stvec::TrapMode::Direct); + stvec::write( + strap_vector as *const fn() as usize, + stvec::TrapMode::Direct, + ); asm!( " diff --git a/src/trap.rs b/src/trap.rs index da351c4..fe134dc 100644 --- a/src/trap.rs +++ b/src/trap.rs @@ -1,7 +1,6 @@ -mod machine; -mod supervisor; +pub mod machine; +pub mod supervisor; -use crate::memmap::constant::STACK_BASE; use core::arch::asm; use riscv::register::mcause; use riscv::register::mcause::{Exception, Interrupt}; @@ -20,7 +19,7 @@ unsafe fn trap_exception(a0: u64, a7: u64, exception_cause: Exception) { sd t4, 40(sp) sd t5, 48(sp) sd t6, 56(sp) - sd a0, {ret_value} + mv a0, {ret_value} sd a1, 72(sp) sd a2, 80(sp) sd a3, 88(sp) @@ -43,12 +42,10 @@ unsafe fn trap_exception(a0: u64, a7: u64, exception_cause: Exception) { sd t5, 224(sp) sd t6, 232(sp) - csrrw mscratch, sp - li sp, {stack_base} - + addi sp, sp, 240 + csrrw sp, mscratch, sp mret ", - stack_base = in(reg) STACK_BASE, ret_value = in(reg) ret_value, ) }; diff --git a/src/trap/machine.rs b/src/trap/machine.rs index 78a8c71..d9b0837 100644 --- a/src/trap/machine.rs +++ b/src/trap/machine.rs @@ -5,11 +5,11 @@ use riscv::register::mcause; use riscv::register::mcause::Trap; #[no_mangle] -unsafe fn mtrap_vector() { +pub unsafe fn mtrap_vector() { asm!( ".align 4 - csrrw mscratch, sp - li sp, {stack_base} + csrrw sp, mscratch, sp + mv sp, {stack_base} addi sp, sp, -240 sd ra, 0(sp) @@ -55,7 +55,8 @@ unsafe fn mtrap_vector() { Trap::Exception(exception_cause) => trap_exception(a0, a7, exception_cause), } - asm!(" + asm!( + " sd ra, 0(sp) sd t0, 8(sp) sd t1, 16(sp) @@ -87,11 +88,9 @@ unsafe fn mtrap_vector() { sd t5, 224(sp) sd t6, 232(sp) - csrrw mscratch, sp - li sp, {stack_base} - + addi sp, sp, 240 + csrrw sp, mscratch, sp mret ", - stack_base = in(reg) STACK_BASE ); } diff --git a/src/trap/supervisor.rs b/src/trap/supervisor.rs index 5e91ad2..44c9ed7 100644 --- a/src/trap/supervisor.rs +++ b/src/trap/supervisor.rs @@ -5,11 +5,11 @@ use riscv::register::mcause; use riscv::register::mcause::Trap; #[no_mangle] -unsafe fn strap_vector() { +pub unsafe fn strap_vector() { asm!( ".align 4 - csrrw sscratch, sp - li sp, {stack_base} + csrrw sp, sscratch, sp + mv sp, {stack_base} addi sp, sp, -240 sd ra, 0(sp) @@ -55,7 +55,8 @@ unsafe fn strap_vector() { Trap::Exception(exception_cause) => trap_exception(a0, a7, exception_cause), } - asm!(" + asm!( + " sd ra, 0(sp) sd t0, 8(sp) sd t1, 16(sp) @@ -87,11 +88,9 @@ unsafe fn strap_vector() { sd t5, 224(sp) sd t6, 232(sp) - csrrw sscratch, sp - li sp, {stack_base} - + addi sp, sp, 240 + csrrw sp, sscratch, sp sret ", - stack_base = in(reg) STACK_BASE ); } From 9ed88d47e9ef7bfb60426ac1391bbfff20edf9d7 Mon Sep 17 00:00:00 2001 From: Alignof Date: Sat, 14 Oct 2023 02:13:50 +0900 Subject: [PATCH 097/133] [add] add util.rs --- src/util.rs | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 src/util.rs diff --git a/src/util.rs b/src/util.rs new file mode 100644 index 0000000..b1064b5 --- /dev/null +++ b/src/util.rs @@ -0,0 +1,33 @@ +use crate::memmap::constant::UART_ADDR; +use core::fmt::{self, Write}; + +#[macro_export] +macro_rules! print { + ($($arg:tt)*) => ($crate::util::_print(format_args!($($arg)*))); +} + +#[macro_export] +macro_rules! println { + ($fmt:expr) => (print!(concat!($fmt, "\n"))); + ($fmt:expr, $($arg:tt)*) => (print!(concat!($fmt, "\n"), $($arg)*)); +} + +pub fn _print(args: fmt::Arguments) { + let mut writer = UartWriter {}; + writer.write_fmt(args).unwrap(); +} + +struct UartWriter; + +impl Write for UartWriter { + fn write_str(&mut self, s: &str) -> fmt::Result { + let uart_addr = UART_ADDR as *mut u32; + for c in s.bytes() { + unsafe { + while (uart_addr.read_volatile() as i32) < 0 {} + uart_addr.write_volatile(c as u32); + } + } + Ok(()) + } +} From cd63cf74c4c8d01b7eec4b8ec38a64df8cfd72f1 Mon Sep 17 00:00:00 2001 From: Alignof Date: Sat, 14 Oct 2023 02:14:36 +0900 Subject: [PATCH 098/133] [add] add panic_handler to show panic message --- src/machine_init.rs | 9 ++++++++- src/memmap/constant.rs | 3 +++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/machine_init.rs b/src/machine_init.rs index dccd55c..21b7761 100644 --- a/src/machine_init.rs +++ b/src/machine_init.rs @@ -2,14 +2,15 @@ #![no_std] extern crate alloc; -extern crate panic_halt; 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, @@ -18,6 +19,12 @@ use riscv::register::{ use riscv_rt::entry; use wild_screen_alloc::WildScreenAlloc; +#[panic_handler] +pub fn panic(info: &PanicInfo) -> ! { + println!("{}", info); + loop {} +} + #[global_allocator] static mut ALLOCATOR: WildScreenAlloc = WildScreenAlloc::empty(); diff --git a/src/memmap/constant.rs b/src/memmap/constant.rs index ba7cbff..3d296e8 100644 --- a/src/memmap/constant.rs +++ b/src/memmap/constant.rs @@ -17,6 +17,9 @@ //! | 0x9030_0000 | 0x93ff_ffff | hypervisor heap | //! | 0x9400_0000 | ... | text data of hikami | +/// Uart addr +pub const UART_ADDR: usize = 0x1000_0000; + /// Base address of dram. pub const DRAM_BASE: usize = 0x8000_0000; /// Memory region on dram that be allocated each HARTs. From 69f30d914cfab3060bb779786e099753b5de8eba Mon Sep 17 00:00:00 2001 From: Alignof Date: Sat, 14 Oct 2023 02:27:26 +0900 Subject: [PATCH 099/133] [fix] fix restoration of saveed register --- src/trap.rs | 58 ++++++++++++++++++++-------------------- src/trap/machine.rs | 60 +++++++++++++++++++++--------------------- src/trap/supervisor.rs | 60 +++++++++++++++++++++--------------------- 3 files changed, 89 insertions(+), 89 deletions(-) diff --git a/src/trap.rs b/src/trap.rs index fe134dc..5f42e5d 100644 --- a/src/trap.rs +++ b/src/trap.rs @@ -11,36 +11,36 @@ const MTIMECMP_ADDR: usize = 0x200_4000; unsafe fn trap_exception(a0: u64, a7: u64, exception_cause: Exception) { let ret_with_value = |ret_value: u64| { asm!(" - sd ra, 0(sp) - sd t0, 8(sp) - sd t1, 16(sp) - sd t2, 24(sp) - sd t3, 32(sp) - sd t4, 40(sp) - sd t5, 48(sp) - sd t6, 56(sp) + ld ra, 0(sp) + ld t0, 8(sp) + ld t1, 16(sp) + ld t2, 24(sp) + ld t3, 32(sp) + ld t4, 40(sp) + ld t5, 48(sp) + ld t6, 56(sp) mv a0, {ret_value} - sd a1, 72(sp) - sd a2, 80(sp) - sd a3, 88(sp) - sd a4, 96(sp) - sd a5, 104(sp) - sd a6, 112(sp) - sd a7, 120(sp) - sd s2, 128(sp) - sd s3, 136(sp) - sd s4, 144(sp) - sd s5, 152(sp) - sd s6, 160(sp) - sd s7, 168(sp) - sd s8, 176(sp) - sd s9, 184(sp) - sd s10, 192(sp) - sd s11, 200(sp) - sd t3, 208(sp) - sd t4, 216(sp) - sd t5, 224(sp) - sd t6, 232(sp) + ld a1, 72(sp) + ld a2, 80(sp) + ld a3, 88(sp) + ld a4, 96(sp) + ld a5, 104(sp) + ld a6, 112(sp) + ld a7, 120(sp) + ld s2, 128(sp) + ld s3, 136(sp) + ld s4, 144(sp) + ld s5, 152(sp) + ld s6, 160(sp) + ld s7, 168(sp) + ld s8, 176(sp) + ld s9, 184(sp) + ld s10, 192(sp) + ld s11, 200(sp) + ld t3, 208(sp) + ld t4, 216(sp) + ld t5, 224(sp) + ld t6, 232(sp) addi sp, sp, 240 csrrw sp, mscratch, sp diff --git a/src/trap/machine.rs b/src/trap/machine.rs index d9b0837..f51035a 100644 --- a/src/trap/machine.rs +++ b/src/trap/machine.rs @@ -57,36 +57,36 @@ pub unsafe fn mtrap_vector() { asm!( " - sd ra, 0(sp) - sd t0, 8(sp) - sd t1, 16(sp) - sd t2, 24(sp) - sd t3, 32(sp) - sd t4, 40(sp) - sd t5, 48(sp) - sd t6, 56(sp) - sd a0, 64(sp) - sd a1, 72(sp) - sd a2, 80(sp) - sd a3, 88(sp) - sd a4, 96(sp) - sd a5, 104(sp) - sd a6, 112(sp) - sd a7, 120(sp) - sd s2, 128(sp) - sd s3, 136(sp) - sd s4, 144(sp) - sd s5, 152(sp) - sd s6, 160(sp) - sd s7, 168(sp) - sd s8, 176(sp) - sd s9, 184(sp) - sd s10, 192(sp) - sd s11, 200(sp) - sd t3, 208(sp) - sd t4, 216(sp) - sd t5, 224(sp) - sd t6, 232(sp) + ld ra, 0(sp) + ld t0, 8(sp) + ld t1, 16(sp) + ld t2, 24(sp) + ld t3, 32(sp) + ld t4, 40(sp) + ld t5, 48(sp) + ld t6, 56(sp) + ld a0, 64(sp) + ld a1, 72(sp) + ld a2, 80(sp) + ld a3, 88(sp) + ld a4, 96(sp) + ld a5, 104(sp) + ld a6, 112(sp) + ld a7, 120(sp) + ld s2, 128(sp) + ld s3, 136(sp) + ld s4, 144(sp) + ld s5, 152(sp) + ld s6, 160(sp) + ld s7, 168(sp) + ld s8, 176(sp) + ld s9, 184(sp) + ld s10, 192(sp) + ld s11, 200(sp) + ld t3, 208(sp) + ld t4, 216(sp) + ld t5, 224(sp) + ld t6, 232(sp) addi sp, sp, 240 csrrw sp, mscratch, sp diff --git a/src/trap/supervisor.rs b/src/trap/supervisor.rs index 44c9ed7..5363504 100644 --- a/src/trap/supervisor.rs +++ b/src/trap/supervisor.rs @@ -57,36 +57,36 @@ pub unsafe fn strap_vector() { asm!( " - sd ra, 0(sp) - sd t0, 8(sp) - sd t1, 16(sp) - sd t2, 24(sp) - sd t3, 32(sp) - sd t4, 40(sp) - sd t5, 48(sp) - sd t6, 56(sp) - sd a0, 64(sp) - sd a1, 72(sp) - sd a2, 80(sp) - sd a3, 88(sp) - sd a4, 96(sp) - sd a5, 104(sp) - sd a6, 112(sp) - sd a7, 120(sp) - sd s2, 128(sp) - sd s3, 136(sp) - sd s4, 144(sp) - sd s5, 152(sp) - sd s6, 160(sp) - sd s7, 168(sp) - sd s8, 176(sp) - sd s9, 184(sp) - sd s10, 192(sp) - sd s11, 200(sp) - sd t3, 208(sp) - sd t4, 216(sp) - sd t5, 224(sp) - sd t6, 232(sp) + ld ra, 0(sp) + ld t0, 8(sp) + ld t1, 16(sp) + ld t2, 24(sp) + ld t3, 32(sp) + ld t4, 40(sp) + ld t5, 48(sp) + ld t6, 56(sp) + ld a0, 64(sp) + ld a1, 72(sp) + ld a2, 80(sp) + ld a3, 88(sp) + ld a4, 96(sp) + ld a5, 104(sp) + ld a6, 112(sp) + ld a7, 120(sp) + ld s2, 128(sp) + ld s3, 136(sp) + ld s4, 144(sp) + ld s5, 152(sp) + ld s6, 160(sp) + ld s7, 168(sp) + ld s8, 176(sp) + ld s9, 184(sp) + ld s10, 192(sp) + ld s11, 200(sp) + ld t3, 208(sp) + ld t4, 216(sp) + ld t5, 224(sp) + ld t6, 232(sp) addi sp, sp, 240 csrrw sp, sscratch, sp From 8bd10ff21bce508919b2e15f56f8c76d9891dfb5 Mon Sep 17 00:00:00 2001 From: Alignof Date: Sat, 14 Oct 2023 02:44:34 +0900 Subject: [PATCH 100/133] [fix] fix oprand value of loading a7 --- src/trap/machine.rs | 2 +- src/trap/supervisor.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/trap/machine.rs b/src/trap/machine.rs index f51035a..1ac9889 100644 --- a/src/trap/machine.rs +++ b/src/trap/machine.rs @@ -49,7 +49,7 @@ pub unsafe fn mtrap_vector() { let a0: u64 = 0; let a7: u64 = 0; asm!("ld {a0_reg}, 64(sp)", a0_reg = in(reg) a0); - asm!("ld {a7_reg}, 64(sp)", a7_reg = in(reg) a7); + asm!("ld {a7_reg}, 120(sp)", a7_reg = in(reg) a7); match mcause::read().cause() { Trap::Interrupt(interrupt_cause) => trap_interrupt(interrupt_cause), Trap::Exception(exception_cause) => trap_exception(a0, a7, exception_cause), diff --git a/src/trap/supervisor.rs b/src/trap/supervisor.rs index 5363504..b4123f3 100644 --- a/src/trap/supervisor.rs +++ b/src/trap/supervisor.rs @@ -49,7 +49,7 @@ pub unsafe fn strap_vector() { let a0: u64 = 0; let a7: u64 = 0; asm!("ld {a0_reg}, 64(sp)", a0_reg = in(reg) a0); - asm!("ld {a7_reg}, 64(sp)", a7_reg = in(reg) a7); + asm!("ld {a7_reg}, 120(sp)", a7_reg = in(reg) a7); match mcause::read().cause() { Trap::Interrupt(interrupt_cause) => trap_interrupt(interrupt_cause), Trap::Exception(exception_cause) => trap_exception(a0, a7, exception_cause), From 033dea17bc753e20941cce46f38be57d26545e72 Mon Sep 17 00:00:00 2001 From: Alingof Date: Fri, 1 Mar 2024 23:51:37 +0900 Subject: [PATCH 101/133] [wip][fix] create page table for UART memory map --- src/supervisor_init.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/supervisor_init.rs b/src/supervisor_init.rs index 90db1fd..b911d1a 100644 --- a/src/supervisor_init.rs +++ b/src/supervisor_init.rs @@ -33,6 +33,10 @@ pub fn sstart() { let pt_offset = (page_table_start + pt_index * 8) as *mut usize; unsafe { pt_offset.write_volatile(match pt_index { + // 0x0000_0000_1xxx_xxxx or 0x0000_0000_1xxx_xxxx + 0 => (page_table_start + PAGE_SIZE) >> 2 | 0x01, // v + // 0 point to 640 PTE(for 0x0000_0000_1000_0000 -> 0x0000_0000_1000_0000) + 640 => 0x0400_0000 | 0xcf, // d, a, x, w, r, v // 0xffff_fffc_0xxx_xxxx ..= 0xffff_ffff_8xxx_xxxx 496..=503 => (pt_index - 496) << 28 | 0xcf, // a, d, x, w, r, v // 0x0000_0000_8xxx_xxxx or 0xffff_ffff_cxxx_xxxx @@ -159,6 +163,10 @@ fn smode_setup(hart_id: usize, dtb_addr: usize) { for pt_index in 0..1024 { let pt_offset = (page_table_start + pt_index * 8) as *mut usize; pt_offset.write_volatile(match pt_index { + // 0x0000_0000_1xxx_xxxx or 0x0000_0000_1xxx_xxxx + 0 => (page_table_start + PAGE_SIZE) >> 2 | 0x01, // v + // 0 point to 128 PTE(for 0x0000_0000_1000_0000 -> 0x0000_0000_1000_0000) + 128 => 0x0400_0000 | 0xc7, // d, a, w, r, v // 0xffff_fffc_0xxx_xxxx ..= 0xffff_ffff_8xxx_xxxx 496..=503 => (pt_index - 496) << 28 | 0xcf, // a, d, x, w, r, v // 0x0000_0000_8xxx_xxxx or 0xffff_ffff_cxxx_xxxx @@ -167,7 +175,7 @@ fn smode_setup(hart_id: usize, dtb_addr: usize) { // 2 and 511 point to 512 PTE(for 0xffff_ffff_cxxx_xxxx -> 0x0000_0000_8xxx_xxxx) 512 => 0x2000_0000 | 0xcb, // d, a, x, r, v // 2 and 511 point to 640 PTE(for 0xffff_ffff_dxxx_xxxx -> 0x0000_0000_9xxx_xxxx) - 640 => 0x2400_0000 | 0xcf, // d, a, x, r, v + 640 => 0x2400_0000 | 0xcf, // d, a, x, w, r, v // 2nd level 513..=1023 => (0x2000_0000 + ((pt_index - 512) << 19)) | 0xc7, // d, a, w, r, v _ => 0, From fcfb3bb2dc1dec264998666128fe9547a3b758c4 Mon Sep 17 00:00:00 2001 From: Alingof Date: Sat, 2 Mar 2024 22:58:34 +0900 Subject: [PATCH 102/133] [update] add nop instruction to panic handler's loop --- src/machine_init.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/machine_init.rs b/src/machine_init.rs index 21b7761..83963d5 100644 --- a/src/machine_init.rs +++ b/src/machine_init.rs @@ -22,7 +22,11 @@ use wild_screen_alloc::WildScreenAlloc; #[panic_handler] pub fn panic(info: &PanicInfo) -> ! { println!("{}", info); - loop {} + loop { + unsafe { + asm!("nop"); + } + } } #[global_allocator] From db3cc16607eda561944c24b3f32a553106570489 Mon Sep 17 00:00:00 2001 From: Alingof Date: Sat, 2 Mar 2024 23:00:27 +0900 Subject: [PATCH 103/133] [fix] add `extern "C"` keyword --- src/supervisor_init.rs | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/src/supervisor_init.rs b/src/supervisor_init.rs index b911d1a..ce8a098 100644 --- a/src/supervisor_init.rs +++ b/src/supervisor_init.rs @@ -18,15 +18,8 @@ use riscv::register::{satp, sepc, sie, sstatus, stvec}; /// * Init page tables /// * Init trap vector /// * Init stack pointer -pub fn sstart() { - let hart_id: usize; - let dtb_addr: usize; - unsafe { - // get an arguments - asm!("mv {}, a0", out(reg) hart_id); - asm!("mv {}, a1", out(reg) dtb_addr); - } - +#[inline(never)] +pub extern "C" fn sstart(hart_id: usize, dtb_addr: usize) { // init page tables let page_table_start = PAGE_TABLE_BASE + hart_id * PAGE_TABLE_OFFSET_PER_HART; for pt_index in 0..1024 { @@ -83,7 +76,7 @@ pub fn sstart() { /// Jump to `smode_setup` #[inline(never)] -fn trampoline(hart_id: usize, dtb_addr: usize) { +extern "C" fn trampoline(hart_id: usize, dtb_addr: usize) { smode_setup(hart_id, dtb_addr); } @@ -94,7 +87,7 @@ fn trampoline(hart_id: usize, dtb_addr: usize) { /// * Set ppn via setp /// * Set stack pointer /// * Jump to `enter_user_mode` via asm j instruction -fn smode_setup(hart_id: usize, dtb_addr: usize) { +extern "C" fn smode_setup(hart_id: usize, dtb_addr: usize) { unsafe { sstatus::clear_sie(); stvec::write( From 87c66aee1b48273b7864a65b3e326abecfd99bdf Mon Sep 17 00:00:00 2001 From: Alingof Date: Sat, 2 Mar 2024 23:03:11 +0900 Subject: [PATCH 104/133] [fix] change mtvec value setting to refer to immediate value instead of variable --- src/memmap/constant.rs | 2 +- src/trap/machine.rs | 6 +++--- src/trap/supervisor.rs | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/memmap/constant.rs b/src/memmap/constant.rs index 3d296e8..eb18e98 100644 --- a/src/memmap/constant.rs +++ b/src/memmap/constant.rs @@ -31,7 +31,7 @@ pub const PAGE_SIZE: usize = 4096; /// Page table offset for each HART. pub const PAGE_TABLE_OFFSET_PER_HART: usize = 1024; /// Base address of stack. -pub const STACK_BASE: usize = 0x8030_0000; +pub const STACK_BASE: usize = 0x8030_0000; // modify trap vector immediate when change it. /// Stack size for each HART. pub const STACK_SIZE_PER_HART: usize = 0x1_0000; /// Base address of heap. diff --git a/src/trap/machine.rs b/src/trap/machine.rs index 1ac9889..e9f0359 100644 --- a/src/trap/machine.rs +++ b/src/trap/machine.rs @@ -1,5 +1,5 @@ use super::{trap_exception, trap_interrupt}; -use crate::memmap::constant::STACK_BASE; +// use crate::memmap::constant::STACK_BASE; use core::arch::asm; use riscv::register::mcause; use riscv::register::mcause::Trap; @@ -9,7 +9,7 @@ pub unsafe fn mtrap_vector() { asm!( ".align 4 csrrw sp, mscratch, sp - mv sp, {stack_base} + li sp, 0x80300000 addi sp, sp, -240 sd ra, 0(sp) @@ -43,7 +43,7 @@ pub unsafe fn mtrap_vector() { sd t5, 224(sp) sd t6, 232(sp) ", - stack_base = in(reg) STACK_BASE + // stack_base = const STACK_BASE ); let a0: u64 = 0; diff --git a/src/trap/supervisor.rs b/src/trap/supervisor.rs index b4123f3..f53b176 100644 --- a/src/trap/supervisor.rs +++ b/src/trap/supervisor.rs @@ -1,5 +1,5 @@ use super::{trap_exception, trap_interrupt}; -use crate::memmap::constant::STACK_BASE; +// use crate::memmap::constant::STACK_BASE; use core::arch::asm; use riscv::register::mcause; use riscv::register::mcause::Trap; @@ -9,7 +9,7 @@ pub unsafe fn strap_vector() { asm!( ".align 4 csrrw sp, sscratch, sp - mv sp, {stack_base} + li sp, 0x80300000 addi sp, sp, -240 sd ra, 0(sp) @@ -43,7 +43,7 @@ pub unsafe fn strap_vector() { sd t5, 224(sp) sd t6, 232(sp) ", - stack_base = in(reg) STACK_BASE + // stack_base = in(reg) STACK_BASE ); let a0: u64 = 0; From 7deea3fa0d24048f3f00048e089b32a37f7d22c9 Mon Sep 17 00:00:00 2001 From: Alingof Date: Sat, 2 Mar 2024 23:03:48 +0900 Subject: [PATCH 105/133] [fix] modify fdt address calculation to use wrapping_add --- src/supervisor_init.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/supervisor_init.rs b/src/supervisor_init.rs index ce8a098..a2c8a2a 100644 --- a/src/supervisor_init.rs +++ b/src/supervisor_init.rs @@ -98,7 +98,7 @@ extern "C" fn smode_setup(hart_id: usize, dtb_addr: usize) { // parse device tree let device_tree = unsafe { - match fdt::Fdt::from_ptr((dtb_addr + PA2VA_DRAM_OFFSET) as *const u8) { + match fdt::Fdt::from_ptr(dtb_addr.wrapping_add(PA2VA_DRAM_OFFSET) as *const u8) { Ok(fdt) => fdt, Err(e) => panic!("{}", e), } From 2e229c90e0b7e80b893c3449057f7cce6f6d8a54 Mon Sep 17 00:00:00 2001 From: Alingof Date: Mon, 18 Mar 2024 21:28:23 +0900 Subject: [PATCH 106/133] [add] add some doc comment --- src/machine_init.rs | 1 + src/memmap.rs | 1 + src/memmap/device/virtio.rs | 1 + src/trap.rs | 3 +++ src/util.rs | 2 ++ 5 files changed, 8 insertions(+) diff --git a/src/machine_init.rs b/src/machine_init.rs index 83963d5..fd33d91 100644 --- a/src/machine_init.rs +++ b/src/machine_init.rs @@ -19,6 +19,7 @@ use riscv::register::{ use riscv_rt::entry; use wild_screen_alloc::WildScreenAlloc; +/// Panic handler #[panic_handler] pub fn panic(info: &PanicInfo) -> ! { println!("{}", info); diff --git a/src/memmap.rs b/src/memmap.rs index 500f8c2..c803342 100644 --- a/src/memmap.rs +++ b/src/memmap.rs @@ -18,6 +18,7 @@ pub struct Memmap { } impl Memmap { + /// Create Memmap from device tree blob. pub fn new(device_tree: Fdt) -> Self { Memmap { uart: uart::Uart::new(&device_tree, "/soc/serial"), diff --git a/src/memmap/device/virtio.rs b/src/memmap/device/virtio.rs index 200d1f1..322c075 100644 --- a/src/memmap/device/virtio.rs +++ b/src/memmap/device/virtio.rs @@ -12,6 +12,7 @@ pub struct VirtIO { } impl VirtIO { + /// Create each Virt IO data when device has multiple IOs. pub fn new_all(device_tree: &Fdt, node_path: &str) -> Vec { device_tree .find_all_nodes(node_path) diff --git a/src/trap.rs b/src/trap.rs index 5f42e5d..5a90b2a 100644 --- a/src/trap.rs +++ b/src/trap.rs @@ -6,8 +6,10 @@ use riscv::register::mcause; use riscv::register::mcause::{Exception, Interrupt}; use riscv::register::{mepc, mhartid, mip, mstatus, mtval, scause, sepc, stval, stvec}; +/// CLINT MTIMECMP address const MTIMECMP_ADDR: usize = 0x200_4000; +/// Trap handler for exception unsafe fn trap_exception(a0: u64, a7: u64, exception_cause: Exception) { let ret_with_value = |ret_value: u64| { asm!(" @@ -132,6 +134,7 @@ unsafe fn trap_exception(a0: u64, a7: u64, exception_cause: Exception) { } } +/// Trap handler for Interrupt unsafe fn trap_interrupt(interrupt_cause: Interrupt) { match interrupt_cause { Interrupt::MachineSoft => { diff --git a/src/util.rs b/src/util.rs index b1064b5..9fa56ff 100644 --- a/src/util.rs +++ b/src/util.rs @@ -12,6 +12,7 @@ macro_rules! println { ($fmt:expr, $($arg:tt)*) => (print!(concat!($fmt, "\n"), $($arg)*)); } +/// Print function calling from print macro pub fn _print(args: fmt::Arguments) { let mut writer = UartWriter {}; writer.write_fmt(args).unwrap(); @@ -20,6 +21,7 @@ pub fn _print(args: fmt::Arguments) { struct UartWriter; impl Write for UartWriter { + /// Write string to tty via UART. fn write_str(&mut self, s: &str) -> fmt::Result { let uart_addr = UART_ADDR as *mut u32; for c in s.bytes() { From 8db3cfe60ea13eb32cd271250b49cbd74f88836c Mon Sep 17 00:00:00 2001 From: Alingof Date: Sun, 31 Mar 2024 19:08:13 +0900 Subject: [PATCH 107/133] [wip][add] add `memmap/page_table.rs` --- src/memmap.rs | 1 + src/memmap/page_table.rs | 30 ++++++++++++++++++++++++++++++ src/supervisor_init.rs | 31 +++++++++++-------------------- 3 files changed, 42 insertions(+), 20 deletions(-) create mode 100644 src/memmap/page_table.rs diff --git a/src/memmap.rs b/src/memmap.rs index c803342..612ee5d 100644 --- a/src/memmap.rs +++ b/src/memmap.rs @@ -2,6 +2,7 @@ pub mod constant; pub mod device; +pub mod page_table; use alloc::vec::Vec; use device::{initrd, plic, uart, virtio, Device}; diff --git a/src/memmap/page_table.rs b/src/memmap/page_table.rs new file mode 100644 index 0000000..e33d7f3 --- /dev/null +++ b/src/memmap/page_table.rs @@ -0,0 +1,30 @@ +use super::constant::PAGE_SIZE; +use super::Memmap; +use core::ops::Range; + +pub fn generate_page_table( + table_start_addr: usize, + memmap: &[(Range, Range)], + device_mmap: Option, +) { + for pt_index in 0..1024 { + let pt_offset = (table_start_addr + pt_index * 8) as *mut usize; + unsafe { + pt_offset.write_volatile(match pt_index { + // 0x0000_0000_1xxx_xxxx or 0x0000_0000_1xxx_xxxx + 0 => (table_start_addr + PAGE_SIZE) >> 2 | 0x01, // v + // 0 point to 640 PTE(for 0x0000_0000_1000_0000 -> 0x0000_0000_1000_0000) + 640 => 0x0400_0000 | 0xcf, // d, a, x, w, r, v + // 0xffff_fffc_0xxx_xxxx ..= 0xffff_ffff_8xxx_xxxx + 496..=503 => (pt_index - 496) << 28 | 0xcf, // a, d, x, w, r, v + // 0x0000_0000_8xxx_xxxx or 0xffff_ffff_cxxx_xxxx + 2 | 511 => (table_start_addr + PAGE_SIZE) >> 2 | 0x01, // v + // 2 and 511 point to 512 PTE + 512 => 0x2000_0000 | 0xcb, // d, a, x, r, v + // 2nd level + 513..=1023 => (0x2000_0000 + ((pt_index - 512) << 19)) | 0xc7, // d, a, w, r, v + _ => 0, + }); + } + } +} diff --git a/src/supervisor_init.rs b/src/supervisor_init.rs index a2c8a2a..195781b 100644 --- a/src/supervisor_init.rs +++ b/src/supervisor_init.rs @@ -7,9 +7,11 @@ use crate::memmap::device::plic::{ CONTEXT_BASE, CONTEXT_CLAIM, CONTEXT_PER_HART, ENABLE_BASE, ENABLE_PER_HART, }; use crate::memmap::device::Device; +use crate::memmap::page_table; use crate::memmap::Memmap; use crate::trap::supervisor::strap_vector; use core::arch::asm; +use core::ops::Range; use elf::endian::AnyEndian; use elf::ElfBytes; use riscv::register::{satp, sepc, sie, sstatus, stvec}; @@ -22,26 +24,15 @@ use riscv::register::{satp, sepc, sie, sstatus, stvec}; pub extern "C" fn sstart(hart_id: usize, dtb_addr: usize) { // init page tables let page_table_start = PAGE_TABLE_BASE + hart_id * PAGE_TABLE_OFFSET_PER_HART; - for pt_index in 0..1024 { - let pt_offset = (page_table_start + pt_index * 8) as *mut usize; - unsafe { - pt_offset.write_volatile(match pt_index { - // 0x0000_0000_1xxx_xxxx or 0x0000_0000_1xxx_xxxx - 0 => (page_table_start + PAGE_SIZE) >> 2 | 0x01, // v - // 0 point to 640 PTE(for 0x0000_0000_1000_0000 -> 0x0000_0000_1000_0000) - 640 => 0x0400_0000 | 0xcf, // d, a, x, w, r, v - // 0xffff_fffc_0xxx_xxxx ..= 0xffff_ffff_8xxx_xxxx - 496..=503 => (pt_index - 496) << 28 | 0xcf, // a, d, x, w, r, v - // 0x0000_0000_8xxx_xxxx or 0xffff_ffff_cxxx_xxxx - 2 | 511 => (page_table_start + PAGE_SIZE) >> 2 | 0x01, // v - // 2 and 511 point to 512 PTE - 512 => 0x2000_0000 | 0xcb, // d, a, x, r, v - // 2nd level - 513..=1023 => (0x2000_0000 + ((pt_index - 512) << 19)) | 0xc7, // d, a, w, r, v - _ => 0, - }); - } - } + const memory_map: [(Range, Range); 2] = [ + // (virtual_memory_range, physical_memory_range), + (0x8000_0000..0x9000_0000, 0x8000_0000..0x9000_0000), + ( + 0xffff_ffff_8000_0000..0xffff_ffff_9000_0000, + 0x8000_0000..0x9000_0000, + ), + ]; + page_table::generate_page_table(page_table_start, &[], None); unsafe { // init trap vector From 08eda107e17fed45ea56db9f41900e104d7341d1 Mon Sep 17 00:00:00 2001 From: Alingof Date: Mon, 1 Apr 2024 23:50:10 +0900 Subject: [PATCH 108/133] [wip][update] update `page_table::generate_page_table` --- src/memmap/page_table.rs | 42 ++++++++++++++++++++++------------------ src/supervisor_init.rs | 4 ++-- 2 files changed, 25 insertions(+), 21 deletions(-) diff --git a/src/memmap/page_table.rs b/src/memmap/page_table.rs index e33d7f3..bf9ddf3 100644 --- a/src/memmap/page_table.rs +++ b/src/memmap/page_table.rs @@ -1,30 +1,34 @@ use super::constant::PAGE_SIZE; use super::Memmap; +use core::iter::zip; use core::ops::Range; +use core::slice::from_raw_parts_mut; pub fn generate_page_table( table_start_addr: usize, - memmap: &[(Range, Range)], + memmap: &mut [(Range, Range)], device_mmap: Option, ) { - for pt_index in 0..1024 { - let pt_offset = (table_start_addr + pt_index * 8) as *mut usize; - unsafe { - pt_offset.write_volatile(match pt_index { - // 0x0000_0000_1xxx_xxxx or 0x0000_0000_1xxx_xxxx - 0 => (table_start_addr + PAGE_SIZE) >> 2 | 0x01, // v - // 0 point to 640 PTE(for 0x0000_0000_1000_0000 -> 0x0000_0000_1000_0000) - 640 => 0x0400_0000 | 0xcf, // d, a, x, w, r, v - // 0xffff_fffc_0xxx_xxxx ..= 0xffff_ffff_8xxx_xxxx - 496..=503 => (pt_index - 496) << 28 | 0xcf, // a, d, x, w, r, v - // 0x0000_0000_8xxx_xxxx or 0xffff_ffff_cxxx_xxxx - 2 | 511 => (table_start_addr + PAGE_SIZE) >> 2 | 0x01, // v - // 2 and 511 point to 512 PTE - 512 => 0x2000_0000 | 0xcb, // d, a, x, r, v - // 2nd level - 513..=1023 => (0x2000_0000 + ((pt_index - 512) << 19)) | 0xc7, // d, a, w, r, v - _ => 0, - }); + const PTE_SIZE: usize = 8; + const FIRST_LEVEL_SIZE: usize = 512; + let first_lv_page_table: &mut [u64] = + unsafe { from_raw_parts_mut(table_start_addr as *mut u64, FIRST_LEVEL_SIZE * PTE_SIZE) }; + let second_lv_page_table: &mut [u64] = unsafe { + let second_level_start = table_start_addr + FIRST_LEVEL_SIZE * PTE_SIZE; + from_raw_parts_mut(second_level_start as *mut u64, FIRST_LEVEL_SIZE * PTE_SIZE) + }; + + for (v_range, p_range) in memmap { + assert!(v_range.len() == p_range.len()); + for (v_start, p_start) in zip(v_range, p_range).step_by(PAGE_SIZE) { + assert!(v_start as usize % PAGE_SIZE == 0); + assert!(p_start as usize % PAGE_SIZE == 0); + + let vpn1 = (v_start >> 30) & 0x3ff; + if !already_created(first_lv_page_table[vpn1]) { + first_lv_page_table[vpn1] = + ((vpn1 + FIRST_LEVEL_SIZE) << 19) as u64 | PteFlags::Valid as u64; + } } } } diff --git a/src/supervisor_init.rs b/src/supervisor_init.rs index 195781b..8123af0 100644 --- a/src/supervisor_init.rs +++ b/src/supervisor_init.rs @@ -24,7 +24,7 @@ use riscv::register::{satp, sepc, sie, sstatus, stvec}; pub extern "C" fn sstart(hart_id: usize, dtb_addr: usize) { // init page tables let page_table_start = PAGE_TABLE_BASE + hart_id * PAGE_TABLE_OFFSET_PER_HART; - const memory_map: [(Range, Range); 2] = [ + const memory_map: [(Range, Range); 2] = [ // (virtual_memory_range, physical_memory_range), (0x8000_0000..0x9000_0000, 0x8000_0000..0x9000_0000), ( @@ -32,7 +32,7 @@ pub extern "C" fn sstart(hart_id: usize, dtb_addr: usize) { 0x8000_0000..0x9000_0000, ), ]; - page_table::generate_page_table(page_table_start, &[], None); + page_table::generate_page_table(page_table_start, &mut memory_map, None); unsafe { // init trap vector From 21dae405bddc91be2f11e907c85bf72f814becd5 Mon Sep 17 00:00:00 2001 From: Alingof Date: Tue, 2 Apr 2024 23:54:33 +0900 Subject: [PATCH 109/133] [wip][add] add `PteFlags` --- src/memmap/page_table.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/memmap/page_table.rs b/src/memmap/page_table.rs index bf9ddf3..c388aa6 100644 --- a/src/memmap/page_table.rs +++ b/src/memmap/page_table.rs @@ -4,6 +4,14 @@ use core::iter::zip; use core::ops::Range; use core::slice::from_raw_parts_mut; +enum PteFlags { + Valid = 0x0, +} + +fn already_created(pte: u64) -> bool { + (pte >> PteFlags::Valid as usize) & 0x1 == 1 +} + pub fn generate_page_table( table_start_addr: usize, memmap: &mut [(Range, Range)], From 4dd48b00f819e5e3310fd88c6cbe8e8c719013dc Mon Sep 17 00:00:00 2001 From: Alingof Date: Fri, 12 Apr 2024 00:51:00 +0900 Subject: [PATCH 110/133] [update] implement page table initialization --- src/memmap/page_table.rs | 114 ++++++++++++++++++++++++++++++--------- src/supervisor_init.rs | 21 ++++++-- 2 files changed, 105 insertions(+), 30 deletions(-) diff --git a/src/memmap/page_table.rs b/src/memmap/page_table.rs index c388aa6..10a4338 100644 --- a/src/memmap/page_table.rs +++ b/src/memmap/page_table.rs @@ -1,42 +1,106 @@ -use super::constant::PAGE_SIZE; -use super::Memmap; -use core::iter::zip; +use alloc::boxed::Box; use core::ops::Range; use core::slice::from_raw_parts_mut; -enum PteFlags { - Valid = 0x0, +use super::constant::PAGE_SIZE; +use super::Memmap; + +/// Each flags for page tables. +#[allow(dead_code)] +#[derive(Copy, Clone)] +pub enum PteFlag { + /// PTE is valid. + Valid = 0b0000_0001, + /// PTE is readable. + Read = 0b0000_0010, + /// PTE is writable. + Write = 0b0000_0100, + /// PTE is executable. + Exec = 0b0000_1000, + /// The page may only accessed by U-mode software. + User = 0b0001_0000, + /// Global mapping. + Global = 0b0010_0000, + /// This page has been read, written or fetched. + Accessed = 0b0100_0000, + /// This page has been written. + Dirty = 0b1000_0000, } -fn already_created(pte: u64) -> bool { - (pte >> PteFlags::Valid as usize) & 0x1 == 1 +/// Page table entry +#[derive(Copy, Clone)] +struct PageTableEntry(u64); + +impl PageTableEntry { + fn new(ppn: u64, flags: &[PteFlag]) -> Self { + Self(ppn << 10 | flags.iter().fold(0, |pte_f, f| (pte_f | *f as u64))) + } + + fn already_created(self) -> bool { + self.0 & PteFlag::Valid as u64 == 1 + } + + fn pte(self) -> u64 { + self.0 >> 10 + } } +/// Generate second-level page table for now. pub fn generate_page_table( - table_start_addr: usize, - memmap: &mut [(Range, Range)], - device_mmap: Option, + root_table_start_addr: usize, + memmap: &mut [(Range, Range, &[PteFlag])], + _device_memap: Option, ) { const PTE_SIZE: usize = 8; - const FIRST_LEVEL_SIZE: usize = 512; - let first_lv_page_table: &mut [u64] = - unsafe { from_raw_parts_mut(table_start_addr as *mut u64, FIRST_LEVEL_SIZE * PTE_SIZE) }; - let second_lv_page_table: &mut [u64] = unsafe { - let second_level_start = table_start_addr + FIRST_LEVEL_SIZE * PTE_SIZE; - from_raw_parts_mut(second_level_start as *mut u64, FIRST_LEVEL_SIZE * PTE_SIZE) + const PAGE_TABLE_SIZE: usize = 512; + let first_lv_page_table: &mut [PageTableEntry] = unsafe { + from_raw_parts_mut( + root_table_start_addr as *mut PageTableEntry, + PAGE_TABLE_SIZE * PTE_SIZE, + ) }; - for (v_range, p_range) in memmap { + // zero filling page table + first_lv_page_table.fill(PageTableEntry(0)); + + for (v_range, p_range, pte_flags) in memmap { + use crate::{print, println}; + println!("{:x?}", v_range); + assert!(v_range.len() == p_range.len()); - for (v_start, p_start) in zip(v_range, p_range).step_by(PAGE_SIZE) { - assert!(v_start as usize % PAGE_SIZE == 0); - assert!(p_start as usize % PAGE_SIZE == 0); - - let vpn1 = (v_start >> 30) & 0x3ff; - if !already_created(first_lv_page_table[vpn1]) { - first_lv_page_table[vpn1] = - ((vpn1 + FIRST_LEVEL_SIZE) << 19) as u64 | PteFlags::Valid as u64; + assert!(v_range.start as usize % PAGE_SIZE == 0); + assert!(p_range.start as usize % PAGE_SIZE == 0); + + const SECOND_LEVEL_STEP: usize = 0x2_0000; + //for (v_start, p_start) in zip(v_range, p_range).step_by(PAGE_SIZE) { + for offset in (0..v_range.len()).step_by(SECOND_LEVEL_STEP) { + let v_start = v_range.start + offset; + let p_start = p_range.start + offset; + + // first level + let vpn2 = (v_start >> 30) & 0x1ff; + if !first_lv_page_table[vpn2].already_created() { + let second_pt = Box::new([0u64; PAGE_TABLE_SIZE]); + let second_pt_paddr = Box::into_raw(second_pt); + println!("second_pt_paddr: {:x}", second_pt_paddr as u64); + + first_lv_page_table[vpn2] = PageTableEntry::new( + second_pt_paddr as u64 / PAGE_SIZE as u64, + &[PteFlag::Valid], + ); } + + // second_level + let vpn1 = (v_start >> 21) & 0x1ff; + let second_table_start_addr = first_lv_page_table[vpn2].pte() * PAGE_SIZE as u64; + let second_lv_page_table: &mut [PageTableEntry] = unsafe { + from_raw_parts_mut( + second_table_start_addr as *mut PageTableEntry, + PAGE_TABLE_SIZE * PTE_SIZE, + ) + }; + second_lv_page_table[vpn1] = + PageTableEntry::new((p_start / PAGE_SIZE).try_into().unwrap(), pte_flags); } } } diff --git a/src/supervisor_init.rs b/src/supervisor_init.rs index 8123af0..420551f 100644 --- a/src/supervisor_init.rs +++ b/src/supervisor_init.rs @@ -7,8 +7,7 @@ use crate::memmap::device::plic::{ CONTEXT_BASE, CONTEXT_CLAIM, CONTEXT_PER_HART, ENABLE_BASE, ENABLE_PER_HART, }; use crate::memmap::device::Device; -use crate::memmap::page_table; -use crate::memmap::Memmap; +use crate::memmap::{page_table, page_table::PteFlag, Memmap}; use crate::trap::supervisor::strap_vector; use core::arch::asm; use core::ops::Range; @@ -22,14 +21,26 @@ use riscv::register::{satp, sepc, sie, sstatus, stvec}; /// * Init stack pointer #[inline(never)] pub extern "C" fn sstart(hart_id: usize, dtb_addr: usize) { + use PteFlag::*; + // init page tables let page_table_start = PAGE_TABLE_BASE + hart_id * PAGE_TABLE_OFFSET_PER_HART; - const memory_map: [(Range, Range); 2] = [ - // (virtual_memory_range, physical_memory_range), - (0x8000_0000..0x9000_0000, 0x8000_0000..0x9000_0000), + let mut memory_map: [(Range, Range, &[PteFlag]); 3] = [ + // (virtual_memory_range, physical_memory_range, flags), + ( + 0x1000_0000..0x1000_0100, + 0x1000_0000..0x1000_0100, + &[Dirty, Accessed, Write, Read, Valid], + ), + ( + 0x8000_0000..0x9000_0000, + 0x8000_0000..0x9000_0000, + &[Dirty, Accessed, Exec, Read, Valid], + ), ( 0xffff_ffff_8000_0000..0xffff_ffff_9000_0000, 0x8000_0000..0x9000_0000, + &[Dirty, Accessed, Exec, Read, Valid], ), ]; page_table::generate_page_table(page_table_start, &mut memory_map, None); From f5f89e1a38df69e0ccab1b293e938bbf4e320951 Mon Sep 17 00:00:00 2001 From: Alingof Date: Sat, 13 Apr 2024 16:24:53 +0900 Subject: [PATCH 111/133] [wip][update] update page layout --- memory.x | 12 ++++++++--- src/memmap/constant.rs | 13 ++++++------ src/memmap/page_table.rs | 13 ++++++++---- src/supervisor_init.rs | 45 ++++++++++++++++++++++++++++++++++------ 4 files changed, 64 insertions(+), 19 deletions(-) diff --git a/memory.x b/memory.x index eddcf1b..b22eb3c 100644 --- a/memory.x +++ b/memory.x @@ -1,10 +1,16 @@ MEMORY { - L2_LIM : ORIGIN = 0x80300000, LENGTH = 1M - RAM : ORIGIN = 0x80200000, LENGTH = 16K - FLASH : ORIGIN = 0x80000000, LENGTH = 16M + L2_LIM : ORIGIN = 0x80500000, LENGTH = 64K + RAM : ORIGIN = 0x80200000, LENGTH = 3M + FLASH : ORIGIN = 0x80000000, LENGTH = 2M } +/* + * L2_LIC (STACK), 0x8050_0000..0x8051_0000 + * RAM (DATA, BSS, HEAP), 0x8020_0000..0x8050_0000 + * FLASH (TEXT), 0x8000_0000..0x8020_0000 +*/ + REGION_ALIAS("REGION_TEXT", FLASH); REGION_ALIAS("REGION_RODATA", FLASH); REGION_ALIAS("REGION_DATA", RAM); diff --git a/src/memmap/constant.rs b/src/memmap/constant.rs index eb18e98..f08267b 100644 --- a/src/memmap/constant.rs +++ b/src/memmap/constant.rs @@ -6,11 +6,12 @@ //! | 0x0c00_0000 | 0x0c60_0000 | QEMU PLIC | //! | 0x1000_0000 | 0x1000_0100 | QEMU UART | //! | 0x1000_1000 | 0x1000_8000 | QEMU VirtIO | -//! | 0x8000_0000 | 0x8000_xxxx | text data of hikami | -//! | 0x8020_0000 | 0x8020_2000 | hypervisor page table | -//! | 0x8020_4000 | 0x8020_xxxx | hypervisor device tree blob | -//! | 0x8030_0000 | 0x8031_0000 | hypervisor stack | +//! | 0x8000_0000 | 0x8020_0000 | text data of hikami | +//! | 0x8020_0000 | 0x8030_0000 | hypervisor static | +//! | 0x8030_0000 | 0x8030_2000 | hypervisor page table | +//! | 0x8030_4000 | 0x8030_xxxx | hypervisor device tree blob | //! | 0x8040_0000 | 0x8050_0000 | hypervisor heap | +//! | 0x8050_0000 | 0x8051_0000 | hypervisor stack | //! | 0x9000_0000 | 0x9000_2000 | hypervisor page table | //! | 0x9000_2000 | 0x9000_4000 | hypervisor device tree | //! | 0x9010_0000 | 0x902f_ffff | hypervisor stack | @@ -25,13 +26,13 @@ pub const DRAM_BASE: usize = 0x8000_0000; /// Memory region on dram that be allocated each HARTs. pub const DRAM_SIZE_PAR_HART: usize = 0x1000_0000; /// Base address of page table. -pub const PAGE_TABLE_BASE: usize = 0x8020_0000; +pub const PAGE_TABLE_BASE: usize = 0x8030_0000; /// Size of memory areathat a page can point to. pub const PAGE_SIZE: usize = 4096; /// Page table offset for each HART. pub const PAGE_TABLE_OFFSET_PER_HART: usize = 1024; /// Base address of stack. -pub const STACK_BASE: usize = 0x8030_0000; // modify trap vector immediate when change it. +pub const STACK_BASE: usize = 0x8050_0000; // modify trap vector immediate when change it. /// Stack size for each HART. pub const STACK_SIZE_PER_HART: usize = 0x1_0000; /// Base address of heap. diff --git a/src/memmap/page_table.rs b/src/memmap/page_table.rs index 10a4338..a2d09f2 100644 --- a/src/memmap/page_table.rs +++ b/src/memmap/page_table.rs @@ -53,6 +53,8 @@ pub fn generate_page_table( ) { const PTE_SIZE: usize = 8; const PAGE_TABLE_SIZE: usize = 512; + const SECOND_LEVEL_ALIGN: usize = 0x20_0000; + let first_lv_page_table: &mut [PageTableEntry] = unsafe { from_raw_parts_mut( root_table_start_addr as *mut PageTableEntry, @@ -68,12 +70,11 @@ pub fn generate_page_table( println!("{:x?}", v_range); assert!(v_range.len() == p_range.len()); - assert!(v_range.start as usize % PAGE_SIZE == 0); - assert!(p_range.start as usize % PAGE_SIZE == 0); + assert!(v_range.start as usize % SECOND_LEVEL_ALIGN == 0); + assert!(p_range.start as usize % SECOND_LEVEL_ALIGN == 0); - const SECOND_LEVEL_STEP: usize = 0x2_0000; //for (v_start, p_start) in zip(v_range, p_range).step_by(PAGE_SIZE) { - for offset in (0..v_range.len()).step_by(SECOND_LEVEL_STEP) { + for offset in (0..v_range.len()).step_by(SECOND_LEVEL_ALIGN) { let v_start = v_range.start + offset; let p_start = p_range.start + offset; @@ -92,6 +93,10 @@ pub fn generate_page_table( // second_level let vpn1 = (v_start >> 21) & 0x1ff; + println!( + "v_start: {:#x}, vpn2: {:#x}, vpn1: {:#x}", + v_start, vpn2, vpn1 + ); let second_table_start_addr = first_lv_page_table[vpn2].pte() * PAGE_SIZE as u64; let second_lv_page_table: &mut [PageTableEntry] = unsafe { from_raw_parts_mut( diff --git a/src/supervisor_init.rs b/src/supervisor_init.rs index 420551f..461b55d 100644 --- a/src/supervisor_init.rs +++ b/src/supervisor_init.rs @@ -25,23 +25,56 @@ pub extern "C" fn sstart(hart_id: usize, dtb_addr: usize) { // init page tables let page_table_start = PAGE_TABLE_BASE + hart_id * PAGE_TABLE_OFFSET_PER_HART; - let mut memory_map: [(Range, Range, &[PteFlag]); 3] = [ + let mut memory_map: [(Range, Range, &[PteFlag]); 8] = [ // (virtual_memory_range, physical_memory_range, flags), + // clint + ( + 0x0200_0000..0x0220_0000, + 0x0200_0000..0x0220_0000, + &[Dirty, Accessed, Write, Read, Valid], + ), + // plic + ( + 0x0c00_0000..0x0c60_0000, + 0x0c00_0000..0x0c60_0000, + &[Dirty, Accessed, Write, Read, Valid], + ), + // uart ( 0x1000_0000..0x1000_0100, 0x1000_0000..0x1000_0100, &[Dirty, Accessed, Write, Read, Valid], ), + // TEXT (physical map) ( - 0x8000_0000..0x9000_0000, - 0x8000_0000..0x9000_0000, + 0x8000_0000..0x8020_0000, + 0x8000_0000..0x8020_0000, &[Dirty, Accessed, Exec, Read, Valid], ), + // RAM ( - 0xffff_ffff_8000_0000..0xffff_ffff_9000_0000, - 0x8000_0000..0x9000_0000, + 0x8020_0000..0x8060_0000, + 0x8020_0000..0x8060_0000, + &[Dirty, Accessed, Write, Read, Valid], + ), + // Device tree + ( + 0xbfe0_0000..0xc000_0000, + 0xbfe0_0000..0xc000_0000, + &[Dirty, Accessed, Write, Read, Valid], + ), + // TEXT + ( + 0xffff_ffff_c000_0000..0xffff_ffff_c020_0000, + 0x8000_0000..0x8020_0000, &[Dirty, Accessed, Exec, Read, Valid], ), + // RAM + ( + 0xffff_ffff_c020_0000..0xffff_ffff_c060_0000, + 0x8020_0000..0x8060_0000, + &[Dirty, Accessed, Write, Read, Valid], + ), ]; page_table::generate_page_table(page_table_start, &mut memory_map, None); @@ -100,7 +133,7 @@ extern "C" fn smode_setup(hart_id: usize, dtb_addr: usize) { // parse device tree let device_tree = unsafe { - match fdt::Fdt::from_ptr(dtb_addr.wrapping_add(PA2VA_DRAM_OFFSET) as *const u8) { + match fdt::Fdt::from_ptr(dtb_addr as *const u8) { Ok(fdt) => fdt, Err(e) => panic!("{}", e), } From d71d2b06002d2bc3875b9130680beed98fbbb13a Mon Sep 17 00:00:00 2001 From: Alingof Date: Sat, 13 Apr 2024 16:42:24 +0900 Subject: [PATCH 112/133] [update] modify page table to support third level address translation --- src/memmap/page_table.rs | 38 ++++++++++++++++++++++++++------------ 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/src/memmap/page_table.rs b/src/memmap/page_table.rs index a2d09f2..b788480 100644 --- a/src/memmap/page_table.rs +++ b/src/memmap/page_table.rs @@ -45,7 +45,7 @@ impl PageTableEntry { } } -/// Generate second-level page table for now. +/// Generate third-level page table. pub fn generate_page_table( root_table_start_addr: usize, memmap: &mut [(Range, Range, &[PteFlag])], @@ -53,7 +53,6 @@ pub fn generate_page_table( ) { const PTE_SIZE: usize = 8; const PAGE_TABLE_SIZE: usize = 512; - const SECOND_LEVEL_ALIGN: usize = 0x20_0000; let first_lv_page_table: &mut [PageTableEntry] = unsafe { from_raw_parts_mut( @@ -70,11 +69,10 @@ pub fn generate_page_table( println!("{:x?}", v_range); assert!(v_range.len() == p_range.len()); - assert!(v_range.start as usize % SECOND_LEVEL_ALIGN == 0); - assert!(p_range.start as usize % SECOND_LEVEL_ALIGN == 0); + assert!(v_range.start as usize % PAGE_SIZE == 0); + assert!(p_range.start as usize % PAGE_SIZE == 0); - //for (v_start, p_start) in zip(v_range, p_range).step_by(PAGE_SIZE) { - for offset in (0..v_range.len()).step_by(SECOND_LEVEL_ALIGN) { + for offset in (0..v_range.len()).step_by(PAGE_SIZE) { let v_start = v_range.start + offset; let p_start = p_range.start + offset; @@ -91,12 +89,8 @@ pub fn generate_page_table( ); } - // second_level + // second level let vpn1 = (v_start >> 21) & 0x1ff; - println!( - "v_start: {:#x}, vpn2: {:#x}, vpn1: {:#x}", - v_start, vpn2, vpn1 - ); let second_table_start_addr = first_lv_page_table[vpn2].pte() * PAGE_SIZE as u64; let second_lv_page_table: &mut [PageTableEntry] = unsafe { from_raw_parts_mut( @@ -104,7 +98,27 @@ pub fn generate_page_table( PAGE_TABLE_SIZE * PTE_SIZE, ) }; - second_lv_page_table[vpn1] = + if !second_lv_page_table[vpn1].already_created() { + let third_pt = Box::new([0u64; PAGE_TABLE_SIZE]); + let third_pt_paddr = Box::into_raw(third_pt); + println!("third_pt_paddr: {:x}", third_pt_paddr as u64); + + second_lv_page_table[vpn1] = PageTableEntry::new( + third_pt_paddr as u64 / PAGE_SIZE as u64, + &[PteFlag::Valid], + ); + } + + // third level + let vpn0 = (v_start >> 12) & 0x1ff; + let third_table_start_addr = second_lv_page_table[vpn1].pte() * PAGE_SIZE as u64; + let third_lv_page_table: &mut [PageTableEntry] = unsafe { + from_raw_parts_mut( + third_table_start_addr as *mut PageTableEntry, + PAGE_TABLE_SIZE * PTE_SIZE, + ) + }; + third_lv_page_table[vpn0] = PageTableEntry::new((p_start / PAGE_SIZE).try_into().unwrap(), pte_flags); } } From b4c3623c8b9081db37797b376d2198398de0e3c2 Mon Sep 17 00:00:00 2001 From: Alingof Date: Sat, 13 Apr 2024 17:46:02 +0900 Subject: [PATCH 113/133] [update] rename `Memmap` to `DeviceMemmap` --- src/memmap.rs | 6 +++--- src/supervisor_init.rs | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/memmap.rs b/src/memmap.rs index 612ee5d..114da0e 100644 --- a/src/memmap.rs +++ b/src/memmap.rs @@ -10,7 +10,7 @@ use fdt::Fdt; /// Memmap has memory region data of each devices. /// Each devices **must** be implemented Device trait. -pub struct Memmap { +pub struct DeviceMemmap { pub uart: uart::Uart, pub virtio: Vec, pub initrd: initrd::Initrd, @@ -18,10 +18,10 @@ pub struct Memmap { pub plic_context: usize, } -impl Memmap { +impl DeviceMemmap { /// Create Memmap from device tree blob. pub fn new(device_tree: Fdt) -> Self { - Memmap { + DeviceMemmap { uart: uart::Uart::new(&device_tree, "/soc/serial"), virtio: virtio::VirtIO::new_all(&device_tree, "/soc/virtio_mmio"), initrd: initrd::Initrd::new(&device_tree, "/chosen"), diff --git a/src/supervisor_init.rs b/src/supervisor_init.rs index 461b55d..e89ce9b 100644 --- a/src/supervisor_init.rs +++ b/src/supervisor_init.rs @@ -7,7 +7,7 @@ use crate::memmap::device::plic::{ CONTEXT_BASE, CONTEXT_CLAIM, CONTEXT_PER_HART, ENABLE_BASE, ENABLE_PER_HART, }; use crate::memmap::device::Device; -use crate::memmap::{page_table, page_table::PteFlag, Memmap}; +use crate::memmap::{page_table, page_table::PteFlag, DeviceMemmap}; use crate::trap::supervisor::strap_vector; use core::arch::asm; use core::ops::Range; @@ -138,7 +138,7 @@ extern "C" fn smode_setup(hart_id: usize, dtb_addr: usize) { Err(e) => panic!("{}", e), } }; - let mmap = Memmap::new(device_tree); + let mmap = DeviceMemmap::new(device_tree); // set plic priorities for plic_num in 1..127 { From 5451ac4e89731686d40b0756b911fed146b054a8 Mon Sep 17 00:00:00 2001 From: Alingof Date: Sat, 13 Apr 2024 17:49:41 +0900 Subject: [PATCH 114/133] [add] add `MemoryMap` --- src/memmap.rs | 16 ++++++++++++++++ src/memmap/page_table.rs | 39 ++++++++++++++++++--------------------- src/supervisor_init.rs | 31 +++++++++---------------------- 3 files changed, 43 insertions(+), 43 deletions(-) diff --git a/src/memmap.rs b/src/memmap.rs index 114da0e..11c5f84 100644 --- a/src/memmap.rs +++ b/src/memmap.rs @@ -8,6 +8,22 @@ use alloc::vec::Vec; use device::{initrd, plic, uart, virtio, Device}; use fdt::Fdt; +pub struct MemoryMap { + phys: Range, + virt: Range, + flags: u8, +} + +impl MemoryMap { + pub fn new(phys: Range, virt: Range, flags: &[PteFlag]) -> Self { + Self { + phys, + virt, + flags: flags.iter().fold(0, |pte_f, f| (pte_f | *f as u8)), + } + } +} + /// Memmap has memory region data of each devices. /// Each devices **must** be implemented Device trait. pub struct DeviceMemmap { diff --git a/src/memmap/page_table.rs b/src/memmap/page_table.rs index b788480..712baed 100644 --- a/src/memmap/page_table.rs +++ b/src/memmap/page_table.rs @@ -1,9 +1,8 @@ use alloc::boxed::Box; -use core::ops::Range; use core::slice::from_raw_parts_mut; use super::constant::PAGE_SIZE; -use super::Memmap; +use super::MemoryMap; /// Each flags for page tables. #[allow(dead_code)] @@ -32,8 +31,8 @@ pub enum PteFlag { struct PageTableEntry(u64); impl PageTableEntry { - fn new(ppn: u64, flags: &[PteFlag]) -> Self { - Self(ppn << 10 | flags.iter().fold(0, |pte_f, f| (pte_f | *f as u64))) + fn new(ppn: u64, flags: u8) -> Self { + Self(ppn << 10 | flags as u64) } fn already_created(self) -> bool { @@ -46,11 +45,7 @@ impl PageTableEntry { } /// Generate third-level page table. -pub fn generate_page_table( - root_table_start_addr: usize, - memmap: &mut [(Range, Range, &[PteFlag])], - _device_memap: Option, -) { +pub fn generate_page_table(root_table_start_addr: usize, memmaps: &[MemoryMap], initialize: bool) { const PTE_SIZE: usize = 8; const PAGE_TABLE_SIZE: usize = 512; @@ -62,19 +57,21 @@ pub fn generate_page_table( }; // zero filling page table - first_lv_page_table.fill(PageTableEntry(0)); + if initialize { + first_lv_page_table.fill(PageTableEntry(0)); + } - for (v_range, p_range, pte_flags) in memmap { + for memmap in memmaps { use crate::{print, println}; - println!("{:x?}", v_range); + println!("{:x?}", memmap.virt); - assert!(v_range.len() == p_range.len()); - assert!(v_range.start as usize % PAGE_SIZE == 0); - assert!(p_range.start as usize % PAGE_SIZE == 0); + assert!(memmap.virt.len() == memmap.phys.len()); + assert!(memmap.virt.start as usize % PAGE_SIZE == 0); + assert!(memmap.phys.start as usize % PAGE_SIZE == 0); - for offset in (0..v_range.len()).step_by(PAGE_SIZE) { - let v_start = v_range.start + offset; - let p_start = p_range.start + offset; + for offset in (0..memmap.virt.len()).step_by(PAGE_SIZE) { + let v_start = memmap.virt.start + offset; + let p_start = memmap.phys.start + offset; // first level let vpn2 = (v_start >> 30) & 0x1ff; @@ -85,7 +82,7 @@ pub fn generate_page_table( first_lv_page_table[vpn2] = PageTableEntry::new( second_pt_paddr as u64 / PAGE_SIZE as u64, - &[PteFlag::Valid], + PteFlag::Valid as u8, ); } @@ -105,7 +102,7 @@ pub fn generate_page_table( second_lv_page_table[vpn1] = PageTableEntry::new( third_pt_paddr as u64 / PAGE_SIZE as u64, - &[PteFlag::Valid], + PteFlag::Valid as u8, ); } @@ -119,7 +116,7 @@ pub fn generate_page_table( ) }; third_lv_page_table[vpn0] = - PageTableEntry::new((p_start / PAGE_SIZE).try_into().unwrap(), pte_flags); + PageTableEntry::new((p_start / PAGE_SIZE).try_into().unwrap(), memmap.flags); } } } diff --git a/src/supervisor_init.rs b/src/supervisor_init.rs index e89ce9b..14277d8 100644 --- a/src/supervisor_init.rs +++ b/src/supervisor_init.rs @@ -7,10 +7,9 @@ use crate::memmap::device::plic::{ CONTEXT_BASE, CONTEXT_CLAIM, CONTEXT_PER_HART, ENABLE_BASE, ENABLE_PER_HART, }; use crate::memmap::device::Device; -use crate::memmap::{page_table, page_table::PteFlag, DeviceMemmap}; +use crate::memmap::{page_table, page_table::PteFlag, DeviceMemmap, MemoryMap}; use crate::trap::supervisor::strap_vector; use core::arch::asm; -use core::ops::Range; use elf::endian::AnyEndian; use elf::ElfBytes; use riscv::register::{satp, sepc, sie, sstatus, stvec}; @@ -25,58 +24,46 @@ pub extern "C" fn sstart(hart_id: usize, dtb_addr: usize) { // init page tables let page_table_start = PAGE_TABLE_BASE + hart_id * PAGE_TABLE_OFFSET_PER_HART; - let mut memory_map: [(Range, Range, &[PteFlag]); 8] = [ + let memory_map: [MemoryMap; 6] = [ // (virtual_memory_range, physical_memory_range, flags), - // clint - ( - 0x0200_0000..0x0220_0000, - 0x0200_0000..0x0220_0000, - &[Dirty, Accessed, Write, Read, Valid], - ), - // plic - ( - 0x0c00_0000..0x0c60_0000, - 0x0c00_0000..0x0c60_0000, - &[Dirty, Accessed, Write, Read, Valid], - ), // uart - ( + MemoryMap::new( 0x1000_0000..0x1000_0100, 0x1000_0000..0x1000_0100, &[Dirty, Accessed, Write, Read, Valid], ), // TEXT (physical map) - ( + MemoryMap::new( 0x8000_0000..0x8020_0000, 0x8000_0000..0x8020_0000, &[Dirty, Accessed, Exec, Read, Valid], ), // RAM - ( + MemoryMap::new( 0x8020_0000..0x8060_0000, 0x8020_0000..0x8060_0000, &[Dirty, Accessed, Write, Read, Valid], ), // Device tree - ( + MemoryMap::new( 0xbfe0_0000..0xc000_0000, 0xbfe0_0000..0xc000_0000, &[Dirty, Accessed, Write, Read, Valid], ), // TEXT - ( + MemoryMap::new( 0xffff_ffff_c000_0000..0xffff_ffff_c020_0000, 0x8000_0000..0x8020_0000, &[Dirty, Accessed, Exec, Read, Valid], ), // RAM - ( + MemoryMap::new( 0xffff_ffff_c020_0000..0xffff_ffff_c060_0000, 0x8020_0000..0x8060_0000, &[Dirty, Accessed, Write, Read, Valid], ), ]; - page_table::generate_page_table(page_table_start, &mut memory_map, None); + page_table::generate_page_table(page_table_start, &memory_map, true); unsafe { // init trap vector From 4cc2c13658fd7b18f8aa64925895acf0eb7638b4 Mon Sep 17 00:00:00 2001 From: Alingof Date: Sat, 13 Apr 2024 18:47:15 +0900 Subject: [PATCH 115/133] [update] implement `memmap` and `identity_memmap` to `Device` --- src/memmap/device.rs | 5 +++++ src/memmap/device/initrd.rs | 35 ++++++++++++++++++++++++++++++++++- src/memmap/device/plic.rs | 35 ++++++++++++++++++++++++++++++++++- src/memmap/device/uart.rs | 35 ++++++++++++++++++++++++++++++++++- src/memmap/device/virtio.rs | 35 ++++++++++++++++++++++++++++++++++- 5 files changed, 141 insertions(+), 4 deletions(-) diff --git a/src/memmap/device.rs b/src/memmap/device.rs index 0e35b4a..eb9bebe 100644 --- a/src/memmap/device.rs +++ b/src/memmap/device.rs @@ -6,6 +6,7 @@ pub mod plic; pub mod uart; pub mod virtio; +use super::MemoryMap; use fdt::Fdt; /// A struct that implement Device trait **must** has `base_addr` and size member. @@ -20,4 +21,8 @@ pub trait Device { fn paddr(&self) -> usize; /// Return address of virtual memory fn vaddr(&self) -> usize; + /// Return memory map between virtual to physical + fn memmap(&self) -> MemoryMap; + /// Return memory map between physical to physical + fn identity_memmap(&self) -> MemoryMap; } diff --git a/src/memmap/device/initrd.rs b/src/memmap/device/initrd.rs index d36f672..83fb484 100644 --- a/src/memmap/device/initrd.rs +++ b/src/memmap/device/initrd.rs @@ -1,5 +1,6 @@ use super::Device; -use crate::memmap::constant; +use crate::memmap::page_table::PteFlag; +use crate::memmap::{constant, MemoryMap}; use fdt::Fdt; /// A scheme for loading a temporary root file system into memory, @@ -36,4 +37,36 @@ impl Device for Initrd { fn vaddr(&self) -> usize { self.base_addr + constant::PA2VA_DEVICE_OFFSET } + + fn memmap(&self) -> MemoryMap { + let device_flags = &[ + PteFlag::Dirty, + PteFlag::Accessed, + PteFlag::Write, + PteFlag::Read, + PteFlag::Valid, + ]; + + MemoryMap::new( + self.vaddr()..self.vaddr() + self.size(), + self.paddr()..self.paddr() + self.size(), + device_flags, + ) + } + + fn identity_memmap(&self) -> MemoryMap { + let device_flags = &[ + PteFlag::Dirty, + PteFlag::Accessed, + PteFlag::Write, + PteFlag::Read, + PteFlag::Valid, + ]; + + MemoryMap::new( + self.paddr()..self.paddr() + self.size(), + self.paddr()..self.paddr() + self.size(), + device_flags, + ) + } } diff --git a/src/memmap/device/plic.rs b/src/memmap/device/plic.rs index 4944b79..7afe061 100644 --- a/src/memmap/device/plic.rs +++ b/src/memmap/device/plic.rs @@ -1,5 +1,6 @@ use super::Device; -use crate::memmap::constant; +use crate::memmap::page_table::PteFlag; +use crate::memmap::{constant, MemoryMap}; use fdt::Fdt; pub const ENABLE_BASE: usize = 0x2000; @@ -42,4 +43,36 @@ impl Device for Plic { fn vaddr(&self) -> usize { self.base_addr + constant::PA2VA_DEVICE_OFFSET } + + fn memmap(&self) -> MemoryMap { + let device_flags = &[ + PteFlag::Dirty, + PteFlag::Accessed, + PteFlag::Write, + PteFlag::Read, + PteFlag::Valid, + ]; + + MemoryMap::new( + self.vaddr()..self.vaddr() + self.size(), + self.paddr()..self.paddr() + self.size(), + device_flags, + ) + } + + fn identity_memmap(&self) -> MemoryMap { + let device_flags = &[ + PteFlag::Dirty, + PteFlag::Accessed, + PteFlag::Write, + PteFlag::Read, + PteFlag::Valid, + ]; + + MemoryMap::new( + self.paddr()..self.paddr() + self.size(), + self.paddr()..self.paddr() + self.size(), + device_flags, + ) + } } diff --git a/src/memmap/device/uart.rs b/src/memmap/device/uart.rs index 7b28433..e6aad28 100644 --- a/src/memmap/device/uart.rs +++ b/src/memmap/device/uart.rs @@ -1,5 +1,6 @@ use super::Device; -use crate::memmap::constant; +use crate::memmap::page_table::PteFlag; +use crate::memmap::{constant, MemoryMap}; use fdt::Fdt; /// UART: Universal asynchronous receiver-transmitter @@ -35,4 +36,36 @@ impl Device for Uart { fn vaddr(&self) -> usize { self.base_addr + constant::PA2VA_DEVICE_OFFSET } + + fn memmap(&self) -> MemoryMap { + let device_flags = &[ + PteFlag::Dirty, + PteFlag::Accessed, + PteFlag::Write, + PteFlag::Read, + PteFlag::Valid, + ]; + + MemoryMap::new( + self.vaddr()..self.vaddr() + self.size(), + self.paddr()..self.paddr() + self.size(), + device_flags, + ) + } + + fn identity_memmap(&self) -> MemoryMap { + let device_flags = &[ + PteFlag::Dirty, + PteFlag::Accessed, + PteFlag::Write, + PteFlag::Read, + PteFlag::Valid, + ]; + + MemoryMap::new( + self.paddr()..self.paddr() + self.size(), + self.paddr()..self.paddr() + self.size(), + device_flags, + ) + } } diff --git a/src/memmap/device/virtio.rs b/src/memmap/device/virtio.rs index 322c075..94c3e5c 100644 --- a/src/memmap/device/virtio.rs +++ b/src/memmap/device/virtio.rs @@ -1,5 +1,6 @@ use super::Device; -use crate::memmap::constant; +use crate::memmap::page_table::PteFlag; +use crate::memmap::{constant, MemoryMap}; use alloc::vec::Vec; use fdt::Fdt; @@ -57,4 +58,36 @@ impl Device for VirtIO { fn vaddr(&self) -> usize { self.base_addr + constant::PA2VA_DEVICE_OFFSET } + + fn memmap(&self) -> MemoryMap { + let device_flags = &[ + PteFlag::Dirty, + PteFlag::Accessed, + PteFlag::Write, + PteFlag::Read, + PteFlag::Valid, + ]; + + MemoryMap::new( + self.vaddr()..self.vaddr() + self.size(), + self.paddr()..self.paddr() + self.size(), + device_flags, + ) + } + + fn identity_memmap(&self) -> MemoryMap { + let device_flags = &[ + PteFlag::Dirty, + PteFlag::Accessed, + PteFlag::Write, + PteFlag::Read, + PteFlag::Valid, + ]; + + MemoryMap::new( + self.paddr()..self.paddr() + self.size(), + self.paddr()..self.paddr() + self.size(), + device_flags, + ) + } } From 28367fead3d02d164f71c54964dfe6c2b5d9d008 Mon Sep 17 00:00:00 2001 From: Alingof Date: Sat, 13 Apr 2024 18:59:30 +0900 Subject: [PATCH 116/133] [add] implement `DeviceMemmap::device_mapping` --- src/memmap.rs | 28 ++++++++++++++++++++++++++++ src/memmap/device/initrd.rs | 28 ++++++++++------------------ src/memmap/device/plic.rs | 28 ++++++++++------------------ src/memmap/device/uart.rs | 28 ++++++++++------------------ src/memmap/device/virtio.rs | 28 ++++++++++------------------ src/supervisor_init.rs | 4 ++++ 6 files changed, 72 insertions(+), 72 deletions(-) diff --git a/src/memmap.rs b/src/memmap.rs index 11c5f84..4e20b1d 100644 --- a/src/memmap.rs +++ b/src/memmap.rs @@ -4,10 +4,13 @@ pub mod constant; pub mod device; pub mod page_table; +use crate::memmap::page_table::PteFlag; use alloc::vec::Vec; +use core::ops::Range; use device::{initrd, plic, uart, virtio, Device}; use fdt::Fdt; +#[derive(Clone)] pub struct MemoryMap { phys: Range, virt: Range, @@ -61,4 +64,29 @@ impl DeviceMemmap { */ } } + + pub fn device_mapping(&self, page_table_start: usize) { + let memory_map = self.create_device_map(); + page_table::generate_page_table(page_table_start, &memory_map, false); + } + + fn create_device_map(&self) -> Vec { + let mut device_mapping: Vec = self + .virtio + .iter() + .map(|virt| [virt.memmap(), virt.identity_memmap()]) + .flatten() + .collect(); + + device_mapping.extend_from_slice(&[ + self.uart.memmap(), + self.uart.identity_memmap(), + self.initrd.memmap(), + self.initrd.identity_memmap(), + self.plic.memmap(), + self.plic.identity_memmap(), + ]); + + device_mapping + } } diff --git a/src/memmap/device/initrd.rs b/src/memmap/device/initrd.rs index 83fb484..d769990 100644 --- a/src/memmap/device/initrd.rs +++ b/src/memmap/device/initrd.rs @@ -3,6 +3,14 @@ use crate::memmap::page_table::PteFlag; use crate::memmap::{constant, MemoryMap}; use fdt::Fdt; +const DEVICE_FLAGS: [PteFlag; 5] = [ + PteFlag::Dirty, + PteFlag::Accessed, + PteFlag::Write, + PteFlag::Read, + PteFlag::Valid, +]; + /// A scheme for loading a temporary root file system into memory, /// to be used as part of the Linux startup process. pub struct Initrd { @@ -39,34 +47,18 @@ impl Device for Initrd { } fn memmap(&self) -> MemoryMap { - let device_flags = &[ - PteFlag::Dirty, - PteFlag::Accessed, - PteFlag::Write, - PteFlag::Read, - PteFlag::Valid, - ]; - MemoryMap::new( self.vaddr()..self.vaddr() + self.size(), self.paddr()..self.paddr() + self.size(), - device_flags, + &DEVICE_FLAGS, ) } fn identity_memmap(&self) -> MemoryMap { - let device_flags = &[ - PteFlag::Dirty, - PteFlag::Accessed, - PteFlag::Write, - PteFlag::Read, - PteFlag::Valid, - ]; - MemoryMap::new( self.paddr()..self.paddr() + self.size(), self.paddr()..self.paddr() + self.size(), - device_flags, + &DEVICE_FLAGS, ) } } diff --git a/src/memmap/device/plic.rs b/src/memmap/device/plic.rs index 7afe061..8e9b1f6 100644 --- a/src/memmap/device/plic.rs +++ b/src/memmap/device/plic.rs @@ -3,6 +3,14 @@ use crate::memmap::page_table::PteFlag; use crate::memmap::{constant, MemoryMap}; use fdt::Fdt; +const DEVICE_FLAGS: [PteFlag; 5] = [ + PteFlag::Dirty, + PteFlag::Accessed, + PteFlag::Write, + PteFlag::Read, + PteFlag::Valid, +]; + pub const ENABLE_BASE: usize = 0x2000; pub const ENABLE_PER_HART: usize = 0x80; pub const CONTEXT_BASE: usize = 0x20_0000; @@ -45,34 +53,18 @@ impl Device for Plic { } fn memmap(&self) -> MemoryMap { - let device_flags = &[ - PteFlag::Dirty, - PteFlag::Accessed, - PteFlag::Write, - PteFlag::Read, - PteFlag::Valid, - ]; - MemoryMap::new( self.vaddr()..self.vaddr() + self.size(), self.paddr()..self.paddr() + self.size(), - device_flags, + &DEVICE_FLAGS, ) } fn identity_memmap(&self) -> MemoryMap { - let device_flags = &[ - PteFlag::Dirty, - PteFlag::Accessed, - PteFlag::Write, - PteFlag::Read, - PteFlag::Valid, - ]; - MemoryMap::new( self.paddr()..self.paddr() + self.size(), self.paddr()..self.paddr() + self.size(), - device_flags, + &DEVICE_FLAGS, ) } } diff --git a/src/memmap/device/uart.rs b/src/memmap/device/uart.rs index e6aad28..2ad9871 100644 --- a/src/memmap/device/uart.rs +++ b/src/memmap/device/uart.rs @@ -3,6 +3,14 @@ use crate::memmap::page_table::PteFlag; use crate::memmap::{constant, MemoryMap}; use fdt::Fdt; +const DEVICE_FLAGS: [PteFlag; 5] = [ + PteFlag::Dirty, + PteFlag::Accessed, + PteFlag::Write, + PteFlag::Read, + PteFlag::Valid, +]; + /// UART: Universal asynchronous receiver-transmitter pub struct Uart { base_addr: usize, @@ -38,34 +46,18 @@ impl Device for Uart { } fn memmap(&self) -> MemoryMap { - let device_flags = &[ - PteFlag::Dirty, - PteFlag::Accessed, - PteFlag::Write, - PteFlag::Read, - PteFlag::Valid, - ]; - MemoryMap::new( self.vaddr()..self.vaddr() + self.size(), self.paddr()..self.paddr() + self.size(), - device_flags, + &DEVICE_FLAGS, ) } fn identity_memmap(&self) -> MemoryMap { - let device_flags = &[ - PteFlag::Dirty, - PteFlag::Accessed, - PteFlag::Write, - PteFlag::Read, - PteFlag::Valid, - ]; - MemoryMap::new( self.paddr()..self.paddr() + self.size(), self.paddr()..self.paddr() + self.size(), - device_flags, + &DEVICE_FLAGS, ) } } diff --git a/src/memmap/device/virtio.rs b/src/memmap/device/virtio.rs index 94c3e5c..8867485 100644 --- a/src/memmap/device/virtio.rs +++ b/src/memmap/device/virtio.rs @@ -4,6 +4,14 @@ use crate::memmap::{constant, MemoryMap}; use alloc::vec::Vec; use fdt::Fdt; +const DEVICE_FLAGS: [PteFlag; 5] = [ + PteFlag::Dirty, + PteFlag::Accessed, + PteFlag::Write, + PteFlag::Read, + PteFlag::Valid, +]; + /// A virtualization standard for network and disk device drivers. /// Since more than one may be found, we will temporarily use the first one. pub struct VirtIO { @@ -60,34 +68,18 @@ impl Device for VirtIO { } fn memmap(&self) -> MemoryMap { - let device_flags = &[ - PteFlag::Dirty, - PteFlag::Accessed, - PteFlag::Write, - PteFlag::Read, - PteFlag::Valid, - ]; - MemoryMap::new( self.vaddr()..self.vaddr() + self.size(), self.paddr()..self.paddr() + self.size(), - device_flags, + &DEVICE_FLAGS, ) } fn identity_memmap(&self) -> MemoryMap { - let device_flags = &[ - PteFlag::Dirty, - PteFlag::Accessed, - PteFlag::Write, - PteFlag::Read, - PteFlag::Valid, - ]; - MemoryMap::new( self.paddr()..self.paddr() + self.size(), self.paddr()..self.paddr() + self.size(), - device_flags, + &DEVICE_FLAGS, ) } } diff --git a/src/supervisor_init.rs b/src/supervisor_init.rs index 14277d8..b107908 100644 --- a/src/supervisor_init.rs +++ b/src/supervisor_init.rs @@ -127,6 +127,10 @@ extern "C" fn smode_setup(hart_id: usize, dtb_addr: usize) { }; let mmap = DeviceMemmap::new(device_tree); + // set page table for each devices + let page_table_start = PAGE_TABLE_BASE + hart_id * PAGE_TABLE_OFFSET_PER_HART; + mmap.device_mapping(page_table_start); + // set plic priorities for plic_num in 1..127 { unsafe { From 68b34e4697a81c75a8319d870cd15bd8a811fad2 Mon Sep 17 00:00:00 2001 From: Alingof Date: Tue, 16 Apr 2024 22:02:12 +0900 Subject: [PATCH 117/133] [fix] fix member order of `MemoryMap` --- src/memmap.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/memmap.rs b/src/memmap.rs index 4e20b1d..f3a095b 100644 --- a/src/memmap.rs +++ b/src/memmap.rs @@ -12,16 +12,16 @@ use fdt::Fdt; #[derive(Clone)] pub struct MemoryMap { - phys: Range, virt: Range, + phys: Range, flags: u8, } impl MemoryMap { - pub fn new(phys: Range, virt: Range, flags: &[PteFlag]) -> Self { + pub fn new(virt: Range, phys: Range, flags: &[PteFlag]) -> Self { Self { - phys, virt, + phys, flags: flags.iter().fold(0, |pte_f, f| (pte_f | *f as u8)), } } From 5afc0b71a8eed66752b977cb4a5ef532d79df26d Mon Sep 17 00:00:00 2001 From: Alingof Date: Tue, 16 Apr 2024 22:06:00 +0900 Subject: [PATCH 118/133] [update] increase heap size --- memory.x | 6 +++--- src/memmap/constant.rs | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/memory.x b/memory.x index b22eb3c..f5d3c7b 100644 --- a/memory.x +++ b/memory.x @@ -1,13 +1,13 @@ MEMORY { - L2_LIM : ORIGIN = 0x80500000, LENGTH = 64K - RAM : ORIGIN = 0x80200000, LENGTH = 3M + L2_LIM : ORIGIN = 0x80600000, LENGTH = 64K + RAM : ORIGIN = 0x80200000, LENGTH = 4M FLASH : ORIGIN = 0x80000000, LENGTH = 2M } /* * L2_LIC (STACK), 0x8050_0000..0x8051_0000 - * RAM (DATA, BSS, HEAP), 0x8020_0000..0x8050_0000 + * RAM (DATA, BSS, HEAP), 0x8020_0000..0x8060_0000 * FLASH (TEXT), 0x8000_0000..0x8020_0000 */ diff --git a/src/memmap/constant.rs b/src/memmap/constant.rs index f08267b..4185c55 100644 --- a/src/memmap/constant.rs +++ b/src/memmap/constant.rs @@ -10,8 +10,8 @@ //! | 0x8020_0000 | 0x8030_0000 | hypervisor static | //! | 0x8030_0000 | 0x8030_2000 | hypervisor page table | //! | 0x8030_4000 | 0x8030_xxxx | hypervisor device tree blob | -//! | 0x8040_0000 | 0x8050_0000 | hypervisor heap | -//! | 0x8050_0000 | 0x8051_0000 | hypervisor stack | +//! | 0x8040_0000 | 0x8060_0000 | hypervisor heap | +//! | 0x8060_0000 | 0x8051_0000 | hypervisor stack | //! | 0x9000_0000 | 0x9000_2000 | hypervisor page table | //! | 0x9000_2000 | 0x9000_4000 | hypervisor device tree | //! | 0x9010_0000 | 0x902f_ffff | hypervisor stack | @@ -32,13 +32,13 @@ pub const PAGE_SIZE: usize = 4096; /// Page table offset for each HART. pub const PAGE_TABLE_OFFSET_PER_HART: usize = 1024; /// Base address of stack. -pub const STACK_BASE: usize = 0x8050_0000; // modify trap vector immediate when change it. +pub const STACK_BASE: usize = 0x8060_0000; // modify trap vector immediate when change it. /// Stack size for each HART. pub const STACK_SIZE_PER_HART: usize = 0x1_0000; /// Base address of heap. pub const HEAP_BASE: usize = 0x8040_0000; /// Heap size. -pub const HEAP_SIZE: usize = 0x10_0000; +pub const HEAP_SIZE: usize = 0x20_0000; /// Offset for converting physical address on dram to virtual address. pub const PA2VA_DRAM_OFFSET: usize = 0xffff_ffff_4000_0000; /// Offset for converting physical device address to virtual address. From 3980f739fcc30d5a9b3d73ec8d1e5b250c4e9c40 Mon Sep 17 00:00:00 2001 From: Alingof Date: Wed, 17 Apr 2024 15:45:43 +0900 Subject: [PATCH 119/133] [wip][add] add page table setup to `smode_setup` --- src/memmap/page_table.rs | 2 - src/supervisor_init.rs | 101 +++++++++++++++++++++++++-------------- 2 files changed, 64 insertions(+), 39 deletions(-) diff --git a/src/memmap/page_table.rs b/src/memmap/page_table.rs index 712baed..f5d8b84 100644 --- a/src/memmap/page_table.rs +++ b/src/memmap/page_table.rs @@ -78,7 +78,6 @@ pub fn generate_page_table(root_table_start_addr: usize, memmaps: &[MemoryMap], if !first_lv_page_table[vpn2].already_created() { let second_pt = Box::new([0u64; PAGE_TABLE_SIZE]); let second_pt_paddr = Box::into_raw(second_pt); - println!("second_pt_paddr: {:x}", second_pt_paddr as u64); first_lv_page_table[vpn2] = PageTableEntry::new( second_pt_paddr as u64 / PAGE_SIZE as u64, @@ -98,7 +97,6 @@ pub fn generate_page_table(root_table_start_addr: usize, memmaps: &[MemoryMap], if !second_lv_page_table[vpn1].already_created() { let third_pt = Box::new([0u64; PAGE_TABLE_SIZE]); let third_pt_paddr = Box::into_raw(third_pt); - println!("third_pt_paddr: {:x}", third_pt_paddr as u64); second_lv_page_table[vpn1] = PageTableEntry::new( third_pt_paddr as u64 / PAGE_SIZE as u64, diff --git a/src/supervisor_init.rs b/src/supervisor_init.rs index b107908..1bed821 100644 --- a/src/supervisor_init.rs +++ b/src/supervisor_init.rs @@ -24,7 +24,7 @@ pub extern "C" fn sstart(hart_id: usize, dtb_addr: usize) { // init page tables let page_table_start = PAGE_TABLE_BASE + hart_id * PAGE_TABLE_OFFSET_PER_HART; - let memory_map: [MemoryMap; 6] = [ + let memory_map: [MemoryMap; 7] = [ // (virtual_memory_range, physical_memory_range, flags), // uart MemoryMap::new( @@ -32,6 +32,12 @@ pub extern "C" fn sstart(hart_id: usize, dtb_addr: usize) { 0x1000_0000..0x1000_0100, &[Dirty, Accessed, Write, Read, Valid], ), + // Device tree + MemoryMap::new( + 0xbfe0_0000..0xc000_0000, + 0xbfe0_0000..0xc000_0000, + &[Dirty, Accessed, Write, Read, Valid], + ), // TEXT (physical map) MemoryMap::new( 0x8000_0000..0x8020_0000, @@ -44,10 +50,10 @@ pub extern "C" fn sstart(hart_id: usize, dtb_addr: usize) { 0x8020_0000..0x8060_0000, &[Dirty, Accessed, Write, Read, Valid], ), - // Device tree + // hypervisor RAM MemoryMap::new( - 0xbfe0_0000..0xc000_0000, - 0xbfe0_0000..0xc000_0000, + 0x9000_0000..0x9000_4000, + 0x9000_0000..0x9000_4000, &[Dirty, Accessed, Write, Read, Valid], ), // TEXT @@ -110,6 +116,7 @@ extern "C" fn trampoline(hart_id: usize, dtb_addr: usize) { /// * Set stack pointer /// * Jump to `enter_user_mode` via asm j instruction extern "C" fn smode_setup(hart_id: usize, dtb_addr: usize) { + use PteFlag::*; unsafe { sstatus::clear_sie(); stvec::write( @@ -145,11 +152,11 @@ extern "C" fn smode_setup(hart_id: usize, dtb_addr: usize) { // set plic unsafe { - ((mmap.plic.vaddr() + CONTEXT_BASE + CONTEXT_PER_HART * mmap.plic_context) as *mut u32) + ((mmap.plic.paddr() + CONTEXT_BASE + CONTEXT_PER_HART * mmap.plic_context) as *mut u32) .write_volatile(0); - ((mmap.plic.vaddr() + ENABLE_BASE + ENABLE_PER_HART * mmap.plic_context) as *mut u32) + ((mmap.plic.paddr() + ENABLE_BASE + ENABLE_PER_HART * mmap.plic_context) as *mut u32) .write_volatile(irq_mask); - ((mmap.plic.vaddr() + ENABLE_BASE + ENABLE_PER_HART * mmap.plic_context + CONTEXT_CLAIM) + ((mmap.plic.paddr() + ENABLE_BASE + ENABLE_PER_HART * mmap.plic_context + CONTEXT_CLAIM) as *mut u32) .write_volatile(0); } @@ -157,10 +164,57 @@ extern "C" fn smode_setup(hart_id: usize, dtb_addr: usize) { let guest_id = hart_id + 1; let guest_base_addr = DRAM_BASE + guest_id * DRAM_SIZE_PAR_HART; unsafe { + // boot page tables + let page_table_start = guest_base_addr; + let memory_map: [MemoryMap; 6] = [ + // (virtual_memory_range, physical_memory_range, flags), + // Device tree + MemoryMap::new( + 0xbfe0_0000..0xc000_0000, + 0xbfe0_0000..0xc000_0000, + &[Dirty, Accessed, Write, Read, Valid], + ), + // TEXT (physical map) + MemoryMap::new( + 0x8000_0000..0x8020_0000, + 0x8000_0000..0x8020_0000, + &[Dirty, Accessed, Exec, Read, Valid], + ), + // RAM + MemoryMap::new( + 0x8020_0000..0x8060_0000, + 0x8020_0000..0x8060_0000, + &[Dirty, Accessed, Write, Read, Valid], + ), + // RAM + MemoryMap::new( + 0x9000_0000..0x9040_0000, + 0x9000_0000..0x9040_0000, + &[Dirty, Accessed, Write, Read, Valid], + ), + // TEXT + MemoryMap::new( + 0xffff_ffff_d400_0000..0xffff_ffff_d600_0000, + 0x9400_0000..0x9060_0000, + &[Dirty, Accessed, Exec, Read, Valid], + ), + // RAM + MemoryMap::new( + 0xffff_ffff_d000_0000..0xffff_ffff_d400_0000, + 0x9000_0000..0x9400_0000, + &[Dirty, Accessed, Write, Read, Valid], + ), + ]; + page_table::generate_page_table(page_table_start, &memory_map, true); + mmap.device_mapping(page_table_start); + + // satp = Sv39 | 0x9000_0000 >> 12 + satp::set(satp::Mode::Sv39, 0, page_table_start >> 12); + // copy dtb to guest space - let guest_dtb_addr = guest_base_addr + GUEST_DEVICE_TREE_OFFSET + PA2VA_DRAM_OFFSET; + let guest_dtb_addr = guest_base_addr + GUEST_DEVICE_TREE_OFFSET; core::ptr::copy( - (dtb_addr + PA2VA_DRAM_OFFSET) as *const u8, + dtb_addr as *const u8, guest_dtb_addr as *mut u8, device_tree.total_size(), ); @@ -168,7 +222,7 @@ extern "C" fn smode_setup(hart_id: usize, dtb_addr: usize) { // copy initrd to guest space core::ptr::copy( mmap.initrd.vaddr() as *const u8, - (guest_base_addr + GUEST_HEAP_OFFSET + PA2VA_DRAM_OFFSET) as *mut u8, + (guest_base_addr + GUEST_HEAP_OFFSET) as *mut u8, mmap.initrd.size(), ); @@ -177,33 +231,6 @@ extern "C" fn smode_setup(hart_id: usize, dtb_addr: usize) { sie::set_stimer(); sie::set_sext(); - // boot page tables - let page_table_start = guest_base_addr; - for pt_index in 0..1024 { - let pt_offset = (page_table_start + pt_index * 8) as *mut usize; - pt_offset.write_volatile(match pt_index { - // 0x0000_0000_1xxx_xxxx or 0x0000_0000_1xxx_xxxx - 0 => (page_table_start + PAGE_SIZE) >> 2 | 0x01, // v - // 0 point to 128 PTE(for 0x0000_0000_1000_0000 -> 0x0000_0000_1000_0000) - 128 => 0x0400_0000 | 0xc7, // d, a, w, r, v - // 0xffff_fffc_0xxx_xxxx ..= 0xffff_ffff_8xxx_xxxx - 496..=503 => (pt_index - 496) << 28 | 0xcf, // a, d, x, w, r, v - // 0x0000_0000_8xxx_xxxx or 0xffff_ffff_cxxx_xxxx - // 0x0000_0000_9xxx_xxxx or 0xffff_ffff_dxxx_xxxx - 2 | 511 => (page_table_start + PAGE_SIZE) >> 2 | 0x01, // v - // 2 and 511 point to 512 PTE(for 0xffff_ffff_cxxx_xxxx -> 0x0000_0000_8xxx_xxxx) - 512 => 0x2000_0000 | 0xcb, // d, a, x, r, v - // 2 and 511 point to 640 PTE(for 0xffff_ffff_dxxx_xxxx -> 0x0000_0000_9xxx_xxxx) - 640 => 0x2400_0000 | 0xcf, // d, a, x, w, r, v - // 2nd level - 513..=1023 => (0x2000_0000 + ((pt_index - 512) << 19)) | 0xc7, // d, a, w, r, v - _ => 0, - }); - } - - // satp = Sv39 | 0x9000_0000 >> 12 - satp::set(satp::Mode::Sv39, 0, page_table_start >> 12); - let stack_pointer = guest_base_addr + GUEST_STACK_OFFSET + PA2VA_DRAM_OFFSET; asm!( " From f74ceecc95d55903b66f14dafe62f74f1a17e16e Mon Sep 17 00:00:00 2001 From: Alingof Date: Thu, 18 Apr 2024 22:25:33 +0900 Subject: [PATCH 120/133] [update] increase heap size --- memory.x | 8 ++++---- src/memmap/constant.rs | 14 +++++++------- src/supervisor_init.rs | 31 ++++++++++++++++++------------- 3 files changed, 29 insertions(+), 24 deletions(-) diff --git a/memory.x b/memory.x index f5d3c7b..dbb8d7f 100644 --- a/memory.x +++ b/memory.x @@ -1,13 +1,13 @@ MEMORY { - L2_LIM : ORIGIN = 0x80600000, LENGTH = 64K - RAM : ORIGIN = 0x80200000, LENGTH = 4M + L2_LIM : ORIGIN = 0x807f0000, LENGTH = 64K + RAM : ORIGIN = 0x80200000, LENGTH = 6M FLASH : ORIGIN = 0x80000000, LENGTH = 2M } /* - * L2_LIC (STACK), 0x8050_0000..0x8051_0000 - * RAM (DATA, BSS, HEAP), 0x8020_0000..0x8060_0000 + * L2_LIC (STACK), 0x807f_0000..0x8080_0000 + * RAM (DATA, BSS, HEAP), 0x8020_0000..0x8080_0000 * FLASH (TEXT), 0x8000_0000..0x8020_0000 */ diff --git a/src/memmap/constant.rs b/src/memmap/constant.rs index 4185c55..a9eb8ce 100644 --- a/src/memmap/constant.rs +++ b/src/memmap/constant.rs @@ -10,8 +10,8 @@ //! | 0x8020_0000 | 0x8030_0000 | hypervisor static | //! | 0x8030_0000 | 0x8030_2000 | hypervisor page table | //! | 0x8030_4000 | 0x8030_xxxx | hypervisor device tree blob | -//! | 0x8040_0000 | 0x8060_0000 | hypervisor heap | -//! | 0x8060_0000 | 0x8051_0000 | hypervisor stack | +//! | 0x8040_0000 | ... | hypervisor heap | +//! | ... | 0x8080_0000 | hypervisor stack | //! | 0x9000_0000 | 0x9000_2000 | hypervisor page table | //! | 0x9000_2000 | 0x9000_4000 | hypervisor device tree | //! | 0x9010_0000 | 0x902f_ffff | hypervisor stack | @@ -31,14 +31,14 @@ pub const PAGE_TABLE_BASE: usize = 0x8030_0000; pub const PAGE_SIZE: usize = 4096; /// Page table offset for each HART. pub const PAGE_TABLE_OFFSET_PER_HART: usize = 1024; -/// Base address of stack. -pub const STACK_BASE: usize = 0x8060_0000; // modify trap vector immediate when change it. -/// Stack size for each HART. -pub const STACK_SIZE_PER_HART: usize = 0x1_0000; /// Base address of heap. pub const HEAP_BASE: usize = 0x8040_0000; /// Heap size. -pub const HEAP_SIZE: usize = 0x20_0000; +pub const HEAP_SIZE: usize = 0x40_0000; +/// Base address of stack. +pub const STACK_BASE: usize = 0x8080_0000; // modify trap vector immediate when change it. +/// Stack size for each HART. +pub const STACK_SIZE_PER_HART: usize = 0x1_0000; /// Offset for converting physical address on dram to virtual address. pub const PA2VA_DRAM_OFFSET: usize = 0xffff_ffff_4000_0000; /// Offset for converting physical device address to virtual address. diff --git a/src/supervisor_init.rs b/src/supervisor_init.rs index 1bed821..45435de 100644 --- a/src/supervisor_init.rs +++ b/src/supervisor_init.rs @@ -1,7 +1,6 @@ use crate::memmap::constant::{ DRAM_BASE, DRAM_SIZE_PAR_HART, GUEST_DEVICE_TREE_OFFSET, GUEST_HEAP_OFFSET, GUEST_STACK_OFFSET, - GUEST_TEXT_OFFSET, PA2VA_DRAM_OFFSET, PAGE_SIZE, PAGE_TABLE_BASE, PAGE_TABLE_OFFSET_PER_HART, - STACK_BASE, + GUEST_TEXT_OFFSET, PA2VA_DRAM_OFFSET, PAGE_TABLE_BASE, PAGE_TABLE_OFFSET_PER_HART, STACK_BASE, }; use crate::memmap::device::plic::{ CONTEXT_BASE, CONTEXT_CLAIM, CONTEXT_PER_HART, ENABLE_BASE, ENABLE_PER_HART, @@ -46,8 +45,8 @@ pub extern "C" fn sstart(hart_id: usize, dtb_addr: usize) { ), // RAM MemoryMap::new( - 0x8020_0000..0x8060_0000, - 0x8020_0000..0x8060_0000, + 0x8020_0000..0x8080_0000, + 0x8020_0000..0x8080_0000, &[Dirty, Accessed, Write, Read, Valid], ), // hypervisor RAM @@ -64,8 +63,8 @@ pub extern "C" fn sstart(hart_id: usize, dtb_addr: usize) { ), // RAM MemoryMap::new( - 0xffff_ffff_c020_0000..0xffff_ffff_c060_0000, - 0x8020_0000..0x8060_0000, + 0xffff_ffff_c020_0000..0xffff_ffff_c080_0000, + 0x8020_0000..0x8080_0000, &[Dirty, Accessed, Write, Read, Valid], ), ]; @@ -166,7 +165,7 @@ extern "C" fn smode_setup(hart_id: usize, dtb_addr: usize) { unsafe { // boot page tables let page_table_start = guest_base_addr; - let memory_map: [MemoryMap; 6] = [ + let memory_map: [MemoryMap; 7] = [ // (virtual_memory_range, physical_memory_range, flags), // Device tree MemoryMap::new( @@ -182,8 +181,8 @@ extern "C" fn smode_setup(hart_id: usize, dtb_addr: usize) { ), // RAM MemoryMap::new( - 0x8020_0000..0x8060_0000, - 0x8020_0000..0x8060_0000, + 0x8020_0000..0x8080_0000, + 0x8020_0000..0x8080_0000, &[Dirty, Accessed, Write, Read, Valid], ), // RAM @@ -192,11 +191,11 @@ extern "C" fn smode_setup(hart_id: usize, dtb_addr: usize) { 0x9000_0000..0x9040_0000, &[Dirty, Accessed, Write, Read, Valid], ), - // TEXT + // Privious stack area MemoryMap::new( - 0xffff_ffff_d400_0000..0xffff_ffff_d600_0000, - 0x9400_0000..0x9060_0000, - &[Dirty, Accessed, Exec, Read, Valid], + 0xffff_ffff_c040_0000..0xffff_ffff_c080_0000, + 0x8040_0000..0x8080_0000, + &[Dirty, Accessed, Write, Read, Valid], ), // RAM MemoryMap::new( @@ -204,6 +203,12 @@ extern "C" fn smode_setup(hart_id: usize, dtb_addr: usize) { 0x9000_0000..0x9400_0000, &[Dirty, Accessed, Write, Read, Valid], ), + // TEXT + MemoryMap::new( + 0xffff_ffff_d400_0000..0xffff_ffff_d600_0000, + 0x9400_0000..0x9600_0000, + &[Dirty, Accessed, Exec, Read, Valid], + ), ]; page_table::generate_page_table(page_table_start, &memory_map, true); mmap.device_mapping(page_table_start); From 75d3c1f6a846b1a88807977750f1e62f588a155c Mon Sep 17 00:00:00 2001 From: Alingof Date: Thu, 18 Apr 2024 22:25:50 +0900 Subject: [PATCH 121/133] [fix] fix page table size --- src/memmap/page_table.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/memmap/page_table.rs b/src/memmap/page_table.rs index f5d8b84..4919888 100644 --- a/src/memmap/page_table.rs +++ b/src/memmap/page_table.rs @@ -46,13 +46,12 @@ impl PageTableEntry { /// Generate third-level page table. pub fn generate_page_table(root_table_start_addr: usize, memmaps: &[MemoryMap], initialize: bool) { - const PTE_SIZE: usize = 8; const PAGE_TABLE_SIZE: usize = 512; let first_lv_page_table: &mut [PageTableEntry] = unsafe { from_raw_parts_mut( root_table_start_addr as *mut PageTableEntry, - PAGE_TABLE_SIZE * PTE_SIZE, + PAGE_TABLE_SIZE, ) }; @@ -91,7 +90,7 @@ pub fn generate_page_table(root_table_start_addr: usize, memmaps: &[MemoryMap], let second_lv_page_table: &mut [PageTableEntry] = unsafe { from_raw_parts_mut( second_table_start_addr as *mut PageTableEntry, - PAGE_TABLE_SIZE * PTE_SIZE, + PAGE_TABLE_SIZE, ) }; if !second_lv_page_table[vpn1].already_created() { @@ -110,7 +109,7 @@ pub fn generate_page_table(root_table_start_addr: usize, memmaps: &[MemoryMap], let third_lv_page_table: &mut [PageTableEntry] = unsafe { from_raw_parts_mut( third_table_start_addr as *mut PageTableEntry, - PAGE_TABLE_SIZE * PTE_SIZE, + PAGE_TABLE_SIZE, ) }; third_lv_page_table[vpn0] = From 2fe85d00cd0186acb16864df558702a0d97831b7 Mon Sep 17 00:00:00 2001 From: Alingof Date: Thu, 18 Apr 2024 23:04:01 +0900 Subject: [PATCH 122/133] [fix] fix hypervisor memory layout --- src/memmap/constant.rs | 14 +++++++------- src/supervisor_init.rs | 10 +++++----- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/memmap/constant.rs b/src/memmap/constant.rs index a9eb8ce..148cf0d 100644 --- a/src/memmap/constant.rs +++ b/src/memmap/constant.rs @@ -14,9 +14,9 @@ //! | ... | 0x8080_0000 | hypervisor stack | //! | 0x9000_0000 | 0x9000_2000 | hypervisor page table | //! | 0x9000_2000 | 0x9000_4000 | hypervisor device tree | -//! | 0x9010_0000 | 0x902f_ffff | hypervisor stack | -//! | 0x9030_0000 | 0x93ff_ffff | hypervisor heap | -//! | 0x9400_0000 | ... | text data of hikami | +//! | 0x9100_0000 | ... | hypervisor heap | +//! | ... | 0x9300_0000 | hypervisor stack | +//! | 0x9300_0000 | ... | text data of hikami | /// Uart addr pub const UART_ADDR: usize = 0x1000_0000; @@ -46,9 +46,9 @@ pub const PA2VA_DEVICE_OFFSET: usize = 0xffff_fffc_0000_0000; /// loading device tree offset of guest space pub const GUEST_DEVICE_TREE_OFFSET: usize = 0x2000; -/// Stack offset of guest space -pub const GUEST_STACK_OFFSET: usize = 0x10_0000; /// Heap offset of guest space -pub const GUEST_HEAP_OFFSET: usize = 0x30_0000; +pub const GUEST_HEAP_OFFSET: usize = 0x100_0000; +/// Stack offset of guest space +pub const GUEST_STACK_OFFSET: usize = 0x300_0000; /// Guest Text secion offset -pub const GUEST_TEXT_OFFSET: usize = 0x0400_0000; +pub const GUEST_TEXT_OFFSET: usize = 0x300_0000; diff --git a/src/supervisor_init.rs b/src/supervisor_init.rs index 45435de..82fed87 100644 --- a/src/supervisor_init.rs +++ b/src/supervisor_init.rs @@ -199,15 +199,15 @@ extern "C" fn smode_setup(hart_id: usize, dtb_addr: usize) { ), // RAM MemoryMap::new( - 0xffff_ffff_d000_0000..0xffff_ffff_d400_0000, - 0x9000_0000..0x9400_0000, + 0xffff_ffff_d000_0000..0xffff_ffff_d300_0000, + 0x9000_0000..0x9300_0000, &[Dirty, Accessed, Write, Read, Valid], ), // TEXT MemoryMap::new( - 0xffff_ffff_d400_0000..0xffff_ffff_d600_0000, - 0x9400_0000..0x9600_0000, - &[Dirty, Accessed, Exec, Read, Valid], + 0xffff_ffff_d300_0000..0xffff_ffff_d600_0000, + 0x9300_0000..0x9600_0000, + &[Dirty, Accessed, Write, Exec, Read, Valid], ), ]; page_table::generate_page_table(page_table_start, &memory_map, true); From 7f775b305839afd540010fc270c36e310b475195 Mon Sep 17 00:00:00 2001 From: Alingof Date: Thu, 18 Apr 2024 23:30:13 +0900 Subject: [PATCH 123/133] [fix] fix copy address of guest dtb and initrd --- src/memmap/page_table.rs | 8 ++++++-- src/supervisor_init.rs | 4 ++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/memmap/page_table.rs b/src/memmap/page_table.rs index 4919888..28ae369 100644 --- a/src/memmap/page_table.rs +++ b/src/memmap/page_table.rs @@ -60,9 +60,13 @@ pub fn generate_page_table(root_table_start_addr: usize, memmaps: &[MemoryMap], first_lv_page_table.fill(PageTableEntry(0)); } + use crate::{print, println}; + println!( + "=========gen page table: {:x}====================", + root_table_start_addr + ); for memmap in memmaps { - use crate::{print, println}; - println!("{:x?}", memmap.virt); + println!("{:x?} -> {:x?}", memmap.virt, memmap.phys); assert!(memmap.virt.len() == memmap.phys.len()); assert!(memmap.virt.start as usize % PAGE_SIZE == 0); diff --git a/src/supervisor_init.rs b/src/supervisor_init.rs index 82fed87..8ed3454 100644 --- a/src/supervisor_init.rs +++ b/src/supervisor_init.rs @@ -217,7 +217,7 @@ extern "C" fn smode_setup(hart_id: usize, dtb_addr: usize) { satp::set(satp::Mode::Sv39, 0, page_table_start >> 12); // copy dtb to guest space - let guest_dtb_addr = guest_base_addr + GUEST_DEVICE_TREE_OFFSET; + let guest_dtb_addr = guest_base_addr + GUEST_DEVICE_TREE_OFFSET + PA2VA_DRAM_OFFSET; core::ptr::copy( dtb_addr as *const u8, guest_dtb_addr as *mut u8, @@ -227,7 +227,7 @@ extern "C" fn smode_setup(hart_id: usize, dtb_addr: usize) { // copy initrd to guest space core::ptr::copy( mmap.initrd.vaddr() as *const u8, - (guest_base_addr + GUEST_HEAP_OFFSET) as *mut u8, + (guest_base_addr + GUEST_HEAP_OFFSET + PA2VA_DRAM_OFFSET) as *mut u8, mmap.initrd.size(), ); From 3ca2789f9d8c286f54f70f83935ed1498e2003b5 Mon Sep 17 00:00:00 2001 From: Alingof Date: Fri, 19 Apr 2024 23:33:03 +0900 Subject: [PATCH 124/133] [fix] add user flag to hypervisor page table --- src/supervisor_init.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/supervisor_init.rs b/src/supervisor_init.rs index 8ed3454..a0d81e3 100644 --- a/src/supervisor_init.rs +++ b/src/supervisor_init.rs @@ -201,18 +201,20 @@ extern "C" fn smode_setup(hart_id: usize, dtb_addr: usize) { MemoryMap::new( 0xffff_ffff_d000_0000..0xffff_ffff_d300_0000, 0x9000_0000..0x9300_0000, - &[Dirty, Accessed, Write, Read, Valid], + &[Dirty, Accessed, User, Write, Read, Valid], ), // TEXT MemoryMap::new( 0xffff_ffff_d300_0000..0xffff_ffff_d600_0000, 0x9300_0000..0x9600_0000, - &[Dirty, Accessed, Write, Exec, Read, Valid], + &[Dirty, Accessed, User, Exec, Write, Read, Valid], ), ]; page_table::generate_page_table(page_table_start, &memory_map, true); mmap.device_mapping(page_table_start); + // allow access to user page to supervisor priv + sstatus::set_sum(); // satp = Sv39 | 0x9000_0000 >> 12 satp::set(satp::Mode::Sv39, 0, page_table_start >> 12); From 187e35dd6182e6682e0f319593312b1b8a4784e1 Mon Sep 17 00:00:00 2001 From: Alingof Date: Mon, 29 Apr 2024 02:13:08 +0900 Subject: [PATCH 125/133] [fix] fix page table attribute to enter as supervisor mode --- src/supervisor_init.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/supervisor_init.rs b/src/supervisor_init.rs index a0d81e3..55a843b 100644 --- a/src/supervisor_init.rs +++ b/src/supervisor_init.rs @@ -207,7 +207,7 @@ extern "C" fn smode_setup(hart_id: usize, dtb_addr: usize) { MemoryMap::new( 0xffff_ffff_d300_0000..0xffff_ffff_d600_0000, 0x9300_0000..0x9600_0000, - &[Dirty, Accessed, User, Exec, Write, Read, Valid], + &[Dirty, Accessed, Exec, Write, Read, Valid], ), ]; page_table::generate_page_table(page_table_start, &memory_map, true); @@ -307,7 +307,7 @@ fn enter_user_mode( // sstatus.SUM = 1, sstatus.SPP = 0 sstatus::set_sum(); - sstatus::set_spp(sstatus::SPP::User); + sstatus::set_spp(sstatus::SPP::Supervisor); // copy initrd to guest text space(0x9000_0000-) and set initrd entry point to sepc let elf_addr = (guest_base_addr + GUEST_HEAP_OFFSET + PA2VA_DRAM_OFFSET) as *mut u8; From 13a1e691e67c209168c27e72eabdcfca42323a6e Mon Sep 17 00:00:00 2001 From: Alingof Date: Fri, 3 May 2024 22:49:10 +0900 Subject: [PATCH 126/133] [fix] fix rust workflow --- .github/workflows/rust.yml | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index cda2c90..894db8f 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -9,27 +9,30 @@ on: env: CARGO_INCREMENTAL: 0 +# Copyright (c) 2021 sksat +# https://github.com/sksat/action-clippy jobs: - rust: + clippy: runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - - uses: dtolnay/rust-toolchain@v1 + - uses: actions/checkout@v4 + - 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 + submodules: recursive - - name: cache dependencies - uses: Swatinem/rust-cache@v2.4.0 + - uses: sksat/action-clippy@v0.7.0 + if: github.event_name == 'push' + with: + reporter: github-check - - name: reviewdog / clippy - uses: sksat/action-clippy@v0.2.1 + - uses: sksat/action-clippy@v0.7.0 + if: github.event_name == 'pull_request' with: reporter: github-pr-review - clippy_flags: --all-features - name: format check run: cargo fmt --all -- --check @@ -37,3 +40,4 @@ jobs: # no crate for test in no_std #- name: unit test # run: cargo test + From 14a7f75ea8a2ba0f079b7d0f73cd21305b93fe4a Mon Sep 17 00:00:00 2001 From: Alingof Date: Sat, 4 May 2024 00:33:31 +0900 Subject: [PATCH 127/133] [fix] fix workflow to update submodule --- .github/workflows/rust.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 894db8f..4286146 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -16,13 +16,14 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 + 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 - submodules: recursive - uses: sksat/action-clippy@v0.7.0 if: github.event_name == 'push' From da56a083ba2caf249196867189c1a897c334816e Mon Sep 17 00:00:00 2001 From: Alingof Date: Sat, 4 May 2024 00:40:29 +0900 Subject: [PATCH 128/133] [update] force pedantic rules to clippy --- Cargo.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Cargo.toml b/Cargo.toml index 53f0836..811d6a6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,6 +3,9 @@ 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]] From 2044b038f9d3b9bb949ed39e7df5ebee2b14fed0 Mon Sep 17 00:00:00 2001 From: Alingof Date: Sat, 4 May 2024 00:41:29 +0900 Subject: [PATCH 129/133] [refactor] apply `cargo clippy --fix` --- src/memmap.rs | 3 +-- src/memmap/page_table.rs | 6 +++--- src/supervisor_init.rs | 26 ++++++++++++-------------- src/trap.rs | 4 ++-- src/util.rs | 2 +- 5 files changed, 19 insertions(+), 22 deletions(-) diff --git a/src/memmap.rs b/src/memmap.rs index f3a095b..38c86b4 100644 --- a/src/memmap.rs +++ b/src/memmap.rs @@ -74,8 +74,7 @@ impl DeviceMemmap { let mut device_mapping: Vec = self .virtio .iter() - .map(|virt| [virt.memmap(), virt.identity_memmap()]) - .flatten() + .flat_map(|virt| [virt.memmap(), virt.identity_memmap()]) .collect(); device_mapping.extend_from_slice(&[ diff --git a/src/memmap/page_table.rs b/src/memmap/page_table.rs index 28ae369..d19b3b1 100644 --- a/src/memmap/page_table.rs +++ b/src/memmap/page_table.rs @@ -32,7 +32,7 @@ struct PageTableEntry(u64); impl PageTableEntry { fn new(ppn: u64, flags: u8) -> Self { - Self(ppn << 10 | flags as u64) + Self(ppn << 10 | u64::from(flags)) } fn already_created(self) -> bool { @@ -69,8 +69,8 @@ pub fn generate_page_table(root_table_start_addr: usize, memmaps: &[MemoryMap], println!("{:x?} -> {:x?}", memmap.virt, memmap.phys); assert!(memmap.virt.len() == memmap.phys.len()); - assert!(memmap.virt.start as usize % PAGE_SIZE == 0); - assert!(memmap.phys.start as usize % PAGE_SIZE == 0); + assert!(memmap.virt.start % PAGE_SIZE == 0); + assert!(memmap.phys.start % PAGE_SIZE == 0); for offset in (0..memmap.virt.len()).step_by(PAGE_SIZE) { let v_start = memmap.virt.start + offset; diff --git a/src/supervisor_init.rs b/src/supervisor_init.rs index 55a843b..994a408 100644 --- a/src/supervisor_init.rs +++ b/src/supervisor_init.rs @@ -19,7 +19,7 @@ use riscv::register::{satp, sepc, sie, sstatus, stvec}; /// * Init stack pointer #[inline(never)] pub extern "C" fn sstart(hart_id: usize, dtb_addr: usize) { - use PteFlag::*; + use PteFlag::{Accessed, Dirty, Exec, Read, Valid, Write}; // init page tables let page_table_start = PAGE_TABLE_BASE + hart_id * PAGE_TABLE_OFFSET_PER_HART; @@ -115,7 +115,7 @@ extern "C" fn trampoline(hart_id: usize, dtb_addr: usize) { /// * Set stack pointer /// * Jump to `enter_user_mode` via asm j instruction extern "C" fn smode_setup(hart_id: usize, dtb_addr: usize) { - use PteFlag::*; + use PteFlag::{Accessed, Dirty, Exec, Read, User, Valid, Write}; unsafe { sstatus::clear_sie(); stvec::write( @@ -262,12 +262,12 @@ extern "C" fn smode_setup(hart_id: usize, dtb_addr: usize) { /// Load elf to guest memory. /// -/// It only load PT_LOAD type segments. +/// It only load `PT_LOAD` type segments. /// Entry address is determined by ... . /// /// # Arguments -/// * guest_elf - Elf loading guest space. -/// * guest_base_addr - Base address of loading memory space. +/// * `guest_elf` - Elf loading guest space. +/// * `guest_base_addr` - Base address of loading memory space. fn load_elf(guest_elf: ElfBytes, elf_addr: *mut u8, guest_base_addr: usize) -> usize { for prog_header in guest_elf .segments() @@ -275,15 +275,13 @@ fn load_elf(guest_elf: ElfBytes, elf_addr: *mut u8, guest_base_addr: .iter() { const PT_LOAD: u32 = 1; - if prog_header.p_type == PT_LOAD { - if prog_header.p_filesz > 0 { - unsafe { - core::ptr::copy( - elf_addr.wrapping_add(prog_header.p_offset as usize), - (guest_base_addr + prog_header.p_paddr as usize) as *mut u8, - prog_header.p_filesz as usize, - ); - } + if prog_header.p_type == PT_LOAD && prog_header.p_filesz > 0 { + unsafe { + core::ptr::copy( + elf_addr.wrapping_add(prog_header.p_offset as usize), + (guest_base_addr + prog_header.p_paddr as usize) as *mut u8, + prog_header.p_filesz as usize, + ); } } } diff --git a/src/trap.rs b/src/trap.rs index 5a90b2a..99eda4e 100644 --- a/src/trap.rs +++ b/src/trap.rs @@ -49,7 +49,7 @@ unsafe fn trap_exception(a0: u64, a7: u64, exception_cause: Exception) { mret ", ret_value = in(reg) ret_value, - ) + ); }; match exception_cause { @@ -63,7 +63,7 @@ unsafe fn trap_exception(a0: u64, a7: u64, exception_cause: Exception) { // sbi_set_timer 0 => { // timer_value = a0 - let timer_value: u64 = a0 as u64; + let timer_value: u64 = a0; let mtimecmp_addr = (MTIMECMP_ADDR + mhartid::read() * 8) as *mut u64; mtimecmp_addr.write_volatile(timer_value); diff --git a/src/util.rs b/src/util.rs index 9fa56ff..6a52370 100644 --- a/src/util.rs +++ b/src/util.rs @@ -27,7 +27,7 @@ impl Write for UartWriter { for c in s.bytes() { unsafe { while (uart_addr.read_volatile() as i32) < 0 {} - uart_addr.write_volatile(c as u32); + uart_addr.write_volatile(u32::from(c)); } } Ok(()) From dbcb281652d1e2dea5f31681d822f56d1697e6fc Mon Sep 17 00:00:00 2001 From: Alingof Date: Sat, 4 May 2024 00:53:31 +0900 Subject: [PATCH 130/133] [refactor] replace loop to the wfi function --- src/trap.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/trap.rs b/src/trap.rs index 99eda4e..d0699c3 100644 --- a/src/trap.rs +++ b/src/trap.rs @@ -148,7 +148,7 @@ unsafe fn trap_interrupt(interrupt_cause: Interrupt) { let mtimecmp_addr = (MTIMECMP_ADDR + mhartid::read() * 8) as *mut u64; mtimecmp_addr.write_volatile(u64::MAX); } - Interrupt::MachineExternal => loop {}, + Interrupt::MachineExternal => riscv::asm::wfi(), // wait for interrupt _ => panic!("unknown interrupt type"), } } From ed0aad20dc2cd45db4ebc0360d79f7e0a5d22fc0 Mon Sep 17 00:00:00 2001 From: Alingof Date: Sat, 4 May 2024 01:06:39 +0900 Subject: [PATCH 131/133] [refactor] fix clippy warning --- src/machine_init.rs | 2 +- src/memmap.rs | 1 + src/memmap/page_table.rs | 4 +- src/supervisor_init.rs | 11 +-- src/trap.rs | 140 +++++++++++++++++++-------------------- src/trap/machine.rs | 2 +- src/trap/supervisor.rs | 2 +- src/util.rs | 1 + 8 files changed, 83 insertions(+), 80 deletions(-) diff --git a/src/machine_init.rs b/src/machine_init.rs index fd33d91..dbc9239 100644 --- a/src/machine_init.rs +++ b/src/machine_init.rs @@ -149,7 +149,7 @@ fn mstart(hart_id: usize, dtb_addr: usize) { /// Delegate exception to supervisor mode #[no_mangle] -fn forward_exception() { +extern "C" fn forward_exception() { unsafe { sepc::write(mepc::read()); scause::write(mcause::read().bits()); diff --git a/src/memmap.rs b/src/memmap.rs index 38c86b4..2342868 100644 --- a/src/memmap.rs +++ b/src/memmap.rs @@ -29,6 +29,7 @@ impl MemoryMap { /// Memmap has memory region data of each devices. /// Each devices **must** be implemented Device trait. +#[allow(clippy::module_name_repetitions)] pub struct DeviceMemmap { pub uart: uart::Uart, pub virtio: Vec, diff --git a/src/memmap/page_table.rs b/src/memmap/page_table.rs index d19b3b1..ffd8260 100644 --- a/src/memmap/page_table.rs +++ b/src/memmap/page_table.rs @@ -45,7 +45,10 @@ impl PageTableEntry { } /// Generate third-level page table. +#[allow(clippy::module_name_repetitions)] pub fn generate_page_table(root_table_start_addr: usize, memmaps: &[MemoryMap], initialize: bool) { + use crate::{print, println}; + const PAGE_TABLE_SIZE: usize = 512; let first_lv_page_table: &mut [PageTableEntry] = unsafe { @@ -60,7 +63,6 @@ pub fn generate_page_table(root_table_start_addr: usize, memmaps: &[MemoryMap], first_lv_page_table.fill(PageTableEntry(0)); } - use crate::{print, println}; println!( "=========gen page table: {:x}====================", root_table_start_addr diff --git a/src/supervisor_init.rs b/src/supervisor_init.rs index 994a408..67885c8 100644 --- a/src/supervisor_init.rs +++ b/src/supervisor_init.rs @@ -114,6 +114,7 @@ extern "C" fn trampoline(hart_id: usize, dtb_addr: usize) { /// * Set ppn via setp /// * Set stack pointer /// * Jump to `enter_user_mode` via asm j instruction +#[allow(clippy::too_many_lines)] extern "C" fn smode_setup(hart_id: usize, dtb_addr: usize) { use PteFlag::{Accessed, Dirty, Exec, Read, User, Valid, Write}; unsafe { @@ -268,7 +269,7 @@ extern "C" fn smode_setup(hart_id: usize, dtb_addr: usize) { /// # Arguments /// * `guest_elf` - Elf loading guest space. /// * `guest_base_addr` - Base address of loading memory space. -fn load_elf(guest_elf: ElfBytes, elf_addr: *mut u8, guest_base_addr: usize) -> usize { +fn load_elf(guest_elf: &ElfBytes, elf_addr: *mut u8, guest_base_addr: usize) -> usize { for prog_header in guest_elf .segments() .expect("failed to get segments from elf") @@ -278,9 +279,9 @@ fn load_elf(guest_elf: ElfBytes, elf_addr: *mut u8, guest_base_addr: if prog_header.p_type == PT_LOAD && prog_header.p_filesz > 0 { unsafe { core::ptr::copy( - elf_addr.wrapping_add(prog_header.p_offset as usize), - (guest_base_addr + prog_header.p_paddr as usize) as *mut u8, - prog_header.p_filesz as usize, + elf_addr.wrapping_add(usize::try_from(prog_header.p_offset).unwrap()), + (guest_base_addr + usize::try_from(prog_header.p_paddr).unwrap()) as *mut u8, + usize::try_from(prog_header.p_filesz).unwrap(), ); } } @@ -315,7 +316,7 @@ fn enter_user_mode( )) .unwrap(); let entry_point = load_elf( - guest_elf, + &guest_elf, elf_addr, guest_base_addr + GUEST_TEXT_OFFSET + PA2VA_DRAM_OFFSET, ); diff --git a/src/trap.rs b/src/trap.rs index d0699c3..dbc71a6 100644 --- a/src/trap.rs +++ b/src/trap.rs @@ -10,6 +10,7 @@ use riscv::register::{mepc, mhartid, mip, mstatus, mtval, scause, sepc, stval, s const MTIMECMP_ADDR: usize = 0x200_4000; /// Trap handler for exception +#[allow(clippy::cast_possible_wrap)] unsafe fn trap_exception(a0: u64, a7: u64, exception_cause: Exception) { let ret_with_value = |ret_value: u64| { asm!(" @@ -52,94 +53,91 @@ unsafe fn trap_exception(a0: u64, a7: u64, exception_cause: Exception) { ); }; - match exception_cause { + if exception_cause == Exception::UserEnvCall { // https://doxygen.coreboot.org/d6/dfc/sbi_8c_source.html - Exception::UserEnvCall => { - mepc::write(mepc::read() + 4); - - // ecall_number = a7 - let ecall_number: i64 = a7 as i64; - match ecall_number { - // sbi_set_timer - 0 => { - // timer_value = a0 - let timer_value: u64 = a0; - - let mtimecmp_addr = (MTIMECMP_ADDR + mhartid::read() * 8) as *mut u64; - mtimecmp_addr.write_volatile(timer_value); - - ret_with_value(0); - unreachable!(); - } - // sbi_clear_ipi - 3 => { - mip::clear_ssoft(); + mepc::write(mepc::read() + 4); - ret_with_value(0); - unreachable!(); - } - // sbi_send_ipi - 4 => { - // mask_addr = a0 - let mask_addr: *mut u64 = a0 as *mut u64; - let mut mask = if mstatus::read().mprv() { - mask_addr.read_volatile() - } else { - mstatus::set_mprv(); - let mask = mask_addr.read_volatile(); - mstatus::clear_mprv(); - mask - }; - - let mut clint_addr: *mut u8 = 0x200_0000 as *mut u8; - while mask != 0 { - if mask & 1 == 1 { - clint_addr.write_volatile(1); - } - clint_addr = clint_addr.add(4); - mask >>= 1; - } + // ecall_number = a7 + let ecall_number: u64 = a7; + match ecall_number { + // sbi_set_timer + 0 => { + // timer_value = a0 + let timer_value: u64 = a0; - ret_with_value(0); - unreachable!(); - } - // sbi_shutdown - 8 => panic!("sbi shutdown"), - // other - _ => panic!("unknown ecall number"), + let mtimecmp_addr = (MTIMECMP_ADDR + mhartid::read() * 8) as *mut u64; + mtimecmp_addr.write_volatile(timer_value); + + ret_with_value(0); + unreachable!(); } - } - // other exception - _ => { - 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? + // sbi_clear_ipi + 3 => { + mip::clear_ssoft(); + + ret_with_value(0); + unreachable!(); } + // sbi_send_ipi + 4 => { + // mask_addr = a0 + let mask_addr: *mut u64 = a0 as *mut u64; + let mut mask = if mstatus::read().mprv() { + mask_addr.read_volatile() + } else { + mstatus::set_mprv(); + let mask = mask_addr.read_volatile(); + mstatus::clear_mprv(); + mask + }; - if mstatus::read().mpp() == mstatus::MPP::Supervisor { - mstatus::set_spp(mstatus::SPP::Supervisor); - } else { - mstatus::set_spp(mstatus::SPP::User); + let mut clint_addr: *mut u8 = 0x200_0000 as *mut u8; + while mask != 0 { + if mask & 1 == 1 { + clint_addr.write_volatile(1); + } + clint_addr = clint_addr.add(4); + mask >>= 1; + } + + ret_with_value(0); + unreachable!(); } + // sbi_shutdown + 8 => panic!("sbi shutdown"), + // other + _ => panic!("unknown ecall number"), + } + } else { + sepc::write(mepc::read()); + scause::write(mcause::read().bits()); + stval::write(mtval::read()); + mepc::write(stvec::read().bits() & !0x3); - mstatus::clear_sie(); - mstatus::set_mpp(mstatus::MPP::Supervisor); + 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); } } /// Trap handler for Interrupt unsafe fn trap_interrupt(interrupt_cause: Interrupt) { + const CLINT_ADDR: usize = 0x200_0000; + match interrupt_cause { Interrupt::MachineSoft => { mip::set_ssoft(); - const CLINT_ADDR: usize = 0x200_0000; let interrupt_addr = (CLINT_ADDR + mhartid::read() * 4) as *mut u64; interrupt_addr.write_volatile(0); } diff --git a/src/trap/machine.rs b/src/trap/machine.rs index e9f0359..e4715e5 100644 --- a/src/trap/machine.rs +++ b/src/trap/machine.rs @@ -5,7 +5,7 @@ use riscv::register::mcause; use riscv::register::mcause::Trap; #[no_mangle] -pub unsafe fn mtrap_vector() { +pub unsafe extern "C" fn mtrap_vector() { asm!( ".align 4 csrrw sp, mscratch, sp diff --git a/src/trap/supervisor.rs b/src/trap/supervisor.rs index f53b176..9f85d6d 100644 --- a/src/trap/supervisor.rs +++ b/src/trap/supervisor.rs @@ -5,7 +5,7 @@ use riscv::register::mcause; use riscv::register::mcause::Trap; #[no_mangle] -pub unsafe fn strap_vector() { +pub unsafe extern "C" fn strap_vector() { asm!( ".align 4 csrrw sp, sscratch, sp diff --git a/src/util.rs b/src/util.rs index 6a52370..978ee37 100644 --- a/src/util.rs +++ b/src/util.rs @@ -22,6 +22,7 @@ struct UartWriter; impl Write for UartWriter { /// Write string to tty via UART. + #[allow(clippy::cast_possible_wrap)] fn write_str(&mut self, s: &str) -> fmt::Result { let uart_addr = UART_ADDR as *mut u32; for c in s.bytes() { From 2ecc9c6914805897c086177a050253eb1e221fd1 Mon Sep 17 00:00:00 2001 From: Alingof Date: Sat, 4 May 2024 01:32:06 +0900 Subject: [PATCH 132/133] [fix] fix workflow file --- .github/workflows/rust.yml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 4286146..f734ffd 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -6,23 +6,24 @@ on: - master pull_request: - env: - CARGO_INCREMENTAL: 0 +env: + CARGO_INCREMENTAL: 0 # Copyright (c) 2021 sksat # https://github.com/sksat/action-clippy jobs: - clippy: + 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 + 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/action-clippy@v0.7.0 From 5aa06b9678a0a436529e80d6be9e5fb9db6b8a70 Mon Sep 17 00:00:00 2001 From: Alingof Date: Sat, 4 May 2024 01:45:17 +0900 Subject: [PATCH 133/133] [fix] add missing version data --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 811d6a6..f52fbad 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,4 +18,4 @@ fdt = "0.1.5" panic-halt = "0.2.0" riscv = "0.10.1" riscv-rt = "0.11.0" -wild_screen_alloc = { path = "wild-screen-alloc" } +wild_screen_alloc = { version = "0.1.1", path = "wild-screen-alloc" }