Merge riscv for QEMU & FPGA

master
WangRunji 6 years ago
parent ff8930a36c
commit cbe7affc5d

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

@ -1,19 +1,26 @@
# Examples:
# make run Run in debug
# make justrun Run in debug without build
# make run int=1 Run with interrupt info by QEMU
# make run mode=release Run in release
# make run LOG=error Run with log level: error
# LOG = off | error | warn | info | debug | trace
# Commands:
# make build Build
# make run Build and run in QEMU
# make justrun Run the last build
# make doc Generate docs
# make asm Open the deassemble file of the last build
# make elf-h Open 'objdump -h' of the last build
# 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
mode ?= debug
LOG ?= debug
kernel := build/$(arch)/kernel.bin
iso := build/$(arch)/os.iso
target ?= $(arch)-blog_os
mode ?= debug
target := $(arch)-blog_os
rust_lib := target/$(target)/$(mode)/ucore
boot_src := src/arch/$(arch)/boot
@ -34,7 +41,9 @@ qemu_opts := -machine virt -kernel $(iso) -nographic
endif
features := use_apic
LOG ?= debug
ifdef board
features := $(features) no_bbl
endif
# Link user binaries at ../user
ifdef link_user
@ -111,8 +120,23 @@ build/x86_64/os.iso: $(kernel) $(grub_cfg)
@rm -r build/isofiles
build/riscv32/os.iso: kernel
@cp $(rust_lib) $@
@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)
@$(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
.global _start
.section .text.entry
.globl _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)
addi sp, sp, %lo(bootstacktop)
mret
call rust_main
.section .bss
.align 12 #PGSHIFT

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

@ -39,12 +39,12 @@ pub unsafe fn restore(flags: usize) {
#[no_mangle]
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());
match tf.scause.cause() {
Trap::Interrupt(SupervisorTimer) => timer(),
Trap::Exception(IllegalInstruction) => illegal_inst(tf),
Trap::Exception(UserEnvCall) => syscall(tf),
Trap::Interrupt(I::SupervisorTimer) => timer(),
Trap::Exception(E::IllegalInstruction) => illegal_inst(tf),
Trap::Exception(E::UserEnvCall) => syscall(tf),
_ => ::trap::error(tf),
}
::trap::before_return();

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

@ -1,4 +1,5 @@
extern crate riscv;
extern crate bbl;
pub mod io;
pub mod interrupt;
@ -14,5 +15,7 @@ pub fn 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/trap.asm"));

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