Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Riscv64 paging mraerino #25

Draft
wants to merge 27 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
9a1951c
initial boot page table
Apr 16, 2023
1c6fe9f
riscv: remove unnecessary cast in virt devcons
orangecms Apr 29, 2023
aaebad2
riscv: reduce change in uart16550
orangecms Apr 25, 2023
200106e
riscv: print in platform init
orangecms Apr 25, 2023
4e2c972
riscv: linker script cleanup
orangecms Apr 25, 2023
f8a3548
riscv: DT/regblock/MMIO tests
orangecms Apr 28, 2023
cd76e73
riscv: rework, add address mapping debug helper
orangecms Apr 29, 2023
becc92b
riscv64: elaborate on SATP
orangecms Apr 29, 2023
ddc1c2a
WIP: riscv: try initializing UART natively
orangecms Apr 29, 2023
6ab6651
riscv: reduce UART MMIO debug prints
orangecms Apr 29, 2023
1ca9843
riscv: document PTE
orangecms Apr 29, 2023
a658d52
riscv: factor out walk_dt, print binary sections
orangecms May 1, 2023
d3fe2d7
riscv: dump start of text region
orangecms May 1, 2023
a12713e
riscv/memory: debug print address translation
orangecms May 2, 2023
1684254
riscv/platform/virt: fix up memory address offset
orangecms May 2, 2023
1435e83
port/fdt: debug DT parsing
orangecms May 2, 2023
c2abf9c
riscv: rework again, debug more...
orangecms May 2, 2023
cbc0bfa
I KNOW KUNG FU (kinda)
orangecms May 2, 2023
a86c953
BACK TO NATIVE UART
orangecms May 2, 2023
94025c7
awesome ASCII art
orangecms May 2, 2023
6e0312b
rework logo
orangecms May 2, 2023
8ec24ac
riscv/platform/virt/devcons: remove unnecessary mut
orangecms May 2, 2023
1da42ba
Implement page table reading and writing
mraerino Sep 9, 2023
ca70a11
Ensure cargo checks works for the workspace without flags
mraerino Sep 10, 2023
9c52cb5
Move mem handling into module
mraerino Sep 10, 2023
f072d8f
Check page table bounds
mraerino Sep 10, 2023
9b59755
Refactor to integer with access methods
mraerino Sep 10, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions aarch64/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
cargo-features = ["per-package-target"]

[package]
name = "aarch64"
version = "0.1.0"
edition = "2021"
default-target = "aarch64-unknown-none-softfloat"

[dependencies]
bitstruct = "0.1"
Expand Down
12 changes: 11 additions & 1 deletion port/src/fdt.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
use crate::println;
use core::{
ffi::CStr,
mem::{self, MaybeUninit},
};

const DEBUG_DT_PARSING: bool = false;

#[derive(Debug)]
pub enum ParseError {
InvalidHeader,
Expand Down Expand Up @@ -66,6 +69,9 @@ impl<'a> DeviceTree<'a> {
/// Given a pointer to the dtb as a u64, return a DeviceTree struct.
pub unsafe fn from_u64(ptr: u64) -> Result<Self> {
let u8ptr = ptr as *const mem::MaybeUninit<u8>;
if DEBUG_DT_PARSING {
println!(" DT @ {u8ptr:x?}");
}

// Extract the real length from the header
let dtb_buf_for_header: &[mem::MaybeUninit<u8>] =
Expand All @@ -77,7 +83,11 @@ impl<'a> DeviceTree<'a> {
// Extract the buffer for real
let dtb_buf: &[mem::MaybeUninit<u8>] =
unsafe { core::slice::from_raw_parts(u8ptr as *const MaybeUninit<u8>, len) };
FdtHeader::new(dtb_buf, false).map(|header| Self { data: dtb_buf, header })
let h = FdtHeader::new(dtb_buf, false);
if DEBUG_DT_PARSING {
println!(" DT header {:#x?}", h);
}
h.map(|header| Self { data: dtb_buf, header })
}

/// Return slice containing `structs` area in FDT
Expand Down
5 changes: 5 additions & 0 deletions riscv64/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
cargo-features = ["per-package-target"]

[package]
name = "riscv64"
version = "0.1.0"
edition = "2021"
default-target = "riscv64imac-unknown-none-elf"

[dependencies]
port = { path = "../port" }
bitflags = "2.3.3"
bit_field = "0.10.2"

[features]
opensbi = []
2 changes: 1 addition & 1 deletion riscv64/lib/config_default.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ buildflags = [
[link]
arch = 'riscv'
script = 'riscv64/lib/kernel.ld'
load-address = '0x80200000'
load-address = '0xffffffffc0200000'

[config]
platform = "virt"
18 changes: 10 additions & 8 deletions riscv64/lib/kernel.ld
Original file line number Diff line number Diff line change
Expand Up @@ -3,36 +3,38 @@ ENTRY(start)

SECTIONS {
. = ${LOAD-ADDRESS};

text = .;
.text : ALIGN(4096) {
*(.text.entry)
*(.text*)
. = ALIGN(2097152);
PROVIDE(etext = .);
etext = .;
}

rodata = .;
.rodata : ALIGN(4096) {
*(.rodata*)
*(.srodata*)
. = ALIGN(2097152);
PROVIDE(erodata = .);
erodata = .;
}

data = .;
.data : ALIGN(4096) {
*(.data*)
*(.sdata*)
. = ALIGN(2097152);
PROVIDE(edata = .);
edata = .;
}

bss = .;
.bss : ALIGN(4096) {
*(.bss*)
*(.sbss*)
*(COMMON)
. = ALIGN(2097152);
PROVIDE(end = .);
}
end = .;

/DISCARD/ : {
*(.eh_frame)
*(.eh_frame .note.GNU-stack)
}
}
88 changes: 80 additions & 8 deletions riscv64/src/l.S
Original file line number Diff line number Diff line change
@@ -1,15 +1,87 @@
.section .text.entry
.globl start
start:
bnez a0, 1f
la sp, stack // set the stack pointer
li t0, 4096 * 4
add sp, sp, t0 // add stack length
call main9
// a0 == hartid
// pc == 0x80200000
// sp == 0x800xxxxx

// 1. set sp
// sp = bootstack + (hartid + 1) * 0x10000
add t0, a0, 1
slli t0, t0, 16 // ??? this is * 0x4000, not 0x10000
lui sp, %hi(bootstack)
add sp, sp, t0 // add stack length

// enable paging
// satp = (8 << 60) | PPN(boot_page_table)
// SATP = Supervisor Address Translation and Protection
// Register definition:
// | MODE | ASID | PPN |
// |[63..60]|[59..44]|[43..0]|
// PPN = Physical Page Number (of root page table)
// ASID = Address Space Identifier
// Volume II: RISC-V Privileged Architectures V20211203 p75
// SXLEN 64, MODE 8: Sv39 aka Page-based 39-bit virtual addressing
lui t0, %hi(boot_page_table)
li t1, 0xffffffffc0000000 - 0x80000000
sub t0, t0, t1
srli t0, t0, 12 // page size 4k (2^12)
li t1, 8 << 60 // mode Sv39
or t0, t0, t1
csrw satp, t0
sfence.vma

// 3. jump to main9 (absolute address)
lui t0, %hi(main9)
addi t0, t0, %lo(main9)
jr t0

1:
wfi
j 1b

.bss
.balign 4096
stack: .space 4096 * 4
/* STACK */
.section .bss.stack
.align 12 # page align
.global bootstack

bootstack:
.space 4096 * 4 * 8
.global bootstacktop

bootstacktop:
.section .data
.align 12 // page align

/* PAGING */
boot_page_table:
// PTE (Page Table Entry) definition (SV39)
// NOTE: A page table entry is 8 bytes; 256 entries are 512*8=4k.
//
// N is reserved for Svnapot, PBMT is Page-based Memory Types
// | N | PBMT | Rsvd. |
// |[63]|[62..61]|[60..54]|
// The Physical Page Number (PPN) is 9+9+26 bits long,
// mapped to a 9+9+9 bit Virtual Page Number (VPN).
// | PPN[2] | PPN[1] | PPN[0] |
// |[53..28]|[27..19]|[18..10]|
// RSW is reserved for supervisor software control.
// D - dirty, A - accessed, G - global mapping, U - user mode access,
// XWR - exec/write/read (table 4.5, p80), V - entry is valid
// | RSW | D | A | G | U | X | W | R | V |
// |[9..8]|[7]|[6]|[5]|[4]|[3]|[2]|[1]|[0]|
//
// NOTE: quad = 4 words = 4 double bytes = 8 bytes
// https://ftp.gnu.org/old-gnu/Manuals/gas-2.9.1/html_chapter/as_7.html#SEC115
.quad (0x00000 << 10) | 0xcf // VRWXAD
.quad (0x40000 << 10) | 0xcf // VRWXAD
// 3rd page: 0x00000000_c0000000 -> 0x80000000 (1G)
.quad (0x80000 << 10) | 0xcf // VRWXAD
// 504 empty entries
.zero 506 * 8
// 3rd last page: 0xffffffff_00000000 -> 0x00000000 (1G)
.quad (0x00000 << 10) | 0xcf // VRWXAD
// 2nd last page: 0xffffffff_80000000 -> 0x40000000 (1G)
.quad (0x40000 << 10) | 0xcf // VRWXAD
// last page: 0xffffffff_c0000000 -> 0x80000000 (1G)
.quad (0x80000 << 10) | 0xcf // VRWXAD
Loading