Merge riscv for QEMU & FPGA

master
WangRunji 6 years ago
parent ff8930a36c
commit cbe7affc5d

@ -9,6 +9,7 @@ crate-type = ["staticlib", "rlib"]
[features] [features]
use_apic = [] use_apic = []
link_user_program = [] link_user_program = []
no_bbl = []
[profile.dev] [profile.dev]
# MUST >= 1 : Enable RVO to avoid stack overflow # MUST >= 1 : Enable RVO to avoid stack overflow

@ -1,19 +1,26 @@
# Examples: # Commands:
# make run Run in debug # make build Build
# make justrun Run in debug without build # make run Build and run in QEMU
# make run int=1 Run with interrupt info by QEMU # make justrun Run the last build
# make run mode=release Run in release
# make run LOG=error Run with log level: error
# LOG = off | error | warn | info | debug | trace
# make doc Generate docs # make doc Generate docs
# make asm Open the deassemble file of the last build # make asm Open the deassemble file of the last build
# make elf-h Open 'objdump -h' of the last build
# make clean Clean # make clean Clean
#
# Options:
# arch = x86_64 | riscv32
# d = int | in_asm | ... QEMU debug info
# mode = debug | release
# LOG = off | error | warn | info | debug | trace
# board Only available on riscv32, build without bbl, run on board
arch ?= riscv32 arch ?= riscv32
mode ?= debug
LOG ?= debug
kernel := build/$(arch)/kernel.bin kernel := build/$(arch)/kernel.bin
iso := build/$(arch)/os.iso iso := build/$(arch)/os.iso
target ?= $(arch)-blog_os target := $(arch)-blog_os
mode ?= debug
rust_lib := target/$(target)/$(mode)/ucore rust_lib := target/$(target)/$(mode)/ucore
boot_src := src/arch/$(arch)/boot boot_src := src/arch/$(arch)/boot
@ -34,7 +41,9 @@ qemu_opts := -machine virt -kernel $(iso) -nographic
endif endif
features := use_apic features := use_apic
LOG ?= debug ifdef board
features := $(features) no_bbl
endif
# Link user binaries at ../user # Link user binaries at ../user
ifdef link_user ifdef link_user
@ -111,8 +120,23 @@ build/x86_64/os.iso: $(kernel) $(grub_cfg)
@rm -r build/isofiles @rm -r build/isofiles
build/riscv32/os.iso: kernel build/riscv32/os.iso: kernel
@cp $(rust_lib) $@
@cp $(rust_lib) $(kernel) @cp $(rust_lib) $(kernel)
ifdef board
@cp $(rust_lib) $@
else
@mkdir -p build/riscv32
@cd ../riscv-pk && \
mkdir -p build && \
cd build && \
../configure \
--enable-32bit \
--enable-logo \
--disable-fp-emulation \
--host=riscv64-unknown-elf \
--with-payload=$(abspath $(rust_lib)) && \
make && \
cp bbl ../../kernel/$@
endif
$(kernel): kernel $(assembly_object_files) $(linker_script) $(kernel): kernel $(assembly_object_files) $(linker_script)
@$(ld) -n --gc-sections -T $(linker_script) -o $(kernel) \ @$(ld) -n --gc-sections -T $(linker_script) -o $(kernel) \

@ -0,0 +1,16 @@
.section .text.boot
boot:
csrwi 0x304, 0 # mie
csrwi 0x344, 0 # mip
csrwi 0x340, 0 # mscratch
csrwi 0x180, 0 # satp
li t0, -1
csrw 0x302, t0 # medeleg
csrw 0x303, t0 # mideleg
csrw 0x306, t0 # mcounteren
csrw 0x106, t0 # scounteren
li t0, 1 << 11 # MPP = S
csrw 0x300, t0 # mstatus
lui t0, 0x80020
csrw 0x341, t0 # mepc
mret

@ -1,23 +1,9 @@
.section .entry .section .text.entry
.global _start .globl _start
_start: _start:
csrwi 0x304, 0 # mie
csrwi 0x344, 0 # mip
csrwi 0x340, 0 # mscratch
csrwi 0x180, 0 # satp
li t0, -1
csrw 0x302, t0 # medeleg
csrw 0x303, t0 # mideleg
csrw 0x306, t0 # mcounteren
csrw 0x106, t0 # scounteren
li t0, 1 << 11 # MPP = S
csrw 0x300, t0 # mstatus
lui t0, %hi(rust_main)
addi t0, t0, %lo(rust_main)
csrw 0x341, t0 # mepc
lui sp, %hi(bootstacktop) lui sp, %hi(bootstacktop)
addi sp, sp, %lo(bootstacktop) addi sp, sp, %lo(bootstacktop)
mret call rust_main
.section .bss .section .bss
.align 12 #PGSHIFT .align 12 #PGSHIFT

@ -6,17 +6,22 @@
OUTPUT_ARCH(riscv) OUTPUT_ARCH(riscv)
ENTRY(_start) ENTRY(_start)
BASE_ADDRESS = 0x80000000; BASE_ADDRESS = 0x80020000;
SECTIONS SECTIONS
{ {
. = 0x80000000;
.boot : {
KEEP(*(.text.boot))
}
/* Load the kernel at this address: "." means the current address */ /* Load the kernel at this address: "." means the current address */
. = BASE_ADDRESS; . = BASE_ADDRESS;
start = .; start = .;
.text : { .text : {
stext = .; stext = .;
*(.entry) *(.text.entry)
*(.text .stub .text.* .gnu.linkonce.t.*) *(.text .stub .text.* .gnu.linkonce.t.*)
. = ALIGN(4K); . = ALIGN(4K);
etext = .; etext = .;

@ -39,12 +39,12 @@ pub unsafe fn restore(flags: usize) {
#[no_mangle] #[no_mangle]
pub extern fn rust_trap(tf: &mut TrapFrame) { pub extern fn rust_trap(tf: &mut TrapFrame) {
use super::riscv::register::scause::{Trap, Interrupt, Exception}; use super::riscv::register::scause::{Trap, Interrupt as I, Exception as E};
trace!("Interrupt: {:?}", tf.scause.cause()); trace!("Interrupt: {:?}", tf.scause.cause());
match tf.scause.cause() { match tf.scause.cause() {
Trap::Interrupt(SupervisorTimer) => timer(), Trap::Interrupt(I::SupervisorTimer) => timer(),
Trap::Exception(IllegalInstruction) => illegal_inst(tf), Trap::Exception(E::IllegalInstruction) => illegal_inst(tf),
Trap::Exception(UserEnvCall) => syscall(tf), Trap::Exception(E::UserEnvCall) => syscall(tf),
_ => ::trap::error(tf), _ => ::trap::error(tf),
} }
::trap::before_return(); ::trap::before_return();

@ -1,5 +1,6 @@
use core::fmt::{Write, Result, Arguments}; use core::fmt::{Write, Result, Arguments};
use core::ptr::{read_volatile, write_volatile}; use core::ptr::{read_volatile, write_volatile};
use super::bbl::sbi;
struct SerialPort; struct SerialPort;
@ -11,7 +12,7 @@ impl Write for SerialPort {
putchar(b' '); putchar(b' ');
putchar(8); putchar(8);
} else { } else {
putchar(c as u8); putchar(c);
} }
} }
Ok(()) Ok(())
@ -19,21 +20,29 @@ impl Write for SerialPort {
} }
fn putchar(c: u8) { fn putchar(c: u8) {
#[cfg(feature = "no_bbl")]
unsafe { unsafe {
while read_volatile(STATUS) & CAN_WRITE == 0 {} while read_volatile(STATUS) & CAN_WRITE == 0 {}
write_volatile(DATA, c as u8); write_volatile(DATA, c as u8);
} }
#[cfg(not(feature = "no_bbl"))]
sbi::console_putchar(c as usize);
} }
pub fn getchar() -> char { pub fn getchar() -> char {
unsafe { #[cfg(feature = "no_bbl")]
let c = unsafe {
while read_volatile(STATUS) & CAN_READ == 0 {} while read_volatile(STATUS) & CAN_READ == 0 {}
match read_volatile(DATA) { read_volatile(DATA)
};
#[cfg(not(feature = "no_bbl"))]
let c = sbi::console_getchar() as u8;
match c {
255 => '\0', // null 255 => '\0', // null
c => c as char, c => c as char,
} }
} }
}
pub fn putfmt(fmt: Arguments) { pub fn putfmt(fmt: Arguments) {
SerialPort.write_fmt(fmt).unwrap(); SerialPort.write_fmt(fmt).unwrap();

@ -1,4 +1,5 @@
extern crate riscv; extern crate riscv;
extern crate bbl;
pub mod io; pub mod io;
pub mod interrupt; pub mod interrupt;
@ -14,5 +15,7 @@ pub fn init() {
timer::init(); timer::init();
} }
#[cfg(feature = "no_bbl")]
global_asm!(include_str!("boot/boot.asm"));
global_asm!(include_str!("boot/entry.asm")); global_asm!(include_str!("boot/entry.asm"));
global_asm!(include_str!("boot/trap.asm")); global_asm!(include_str!("boot/trap.asm"));

@ -1,4 +1,5 @@
use super::riscv::register::*; use super::riscv::register::*;
use super::bbl::sbi;
#[cfg(target_pointer_width = "64")] #[cfg(target_pointer_width = "64")]
pub fn get_cycle() -> u64 { pub fn get_cycle() -> u64 {
@ -32,8 +33,11 @@ pub fn set_next() {
} }
fn set_timer(t: u64) { fn set_timer(t: u64) {
#[cfg(feature = "no_bbl")]
unsafe { unsafe {
asm!("csrw 0x321, $0; csrw 0x322, $1" asm!("csrw 0x321, $0; csrw 0x322, $1"
: : "r"(t as u32), "r"((t >> 32) as u32) : : "volatile"); : : "r"(t as u32), "r"((t >> 32) as u32) : : "volatile");
} }
#[cfg(not(feature = "no_bbl"))]
sbi::set_timer(t);
} }
Loading…
Cancel
Save