1
0
mirror of https://github.com/rcore-os/rCore.git synced 2024-11-21 15:46:17 +04:00

fix serial interrupt on HiFiveU

This commit is contained in:
WangRunji 2019-03-19 18:23:10 +08:00
parent c4df7cd3af
commit f6352b2688
7 changed files with 42 additions and 10 deletions

View File

@ -318,7 +318,7 @@ ifeq ($(board), u540)
.PHONY:
install: $(kernel_img)
@$(objcopy) -S -O binary --change-addresses -0x80000000 $< $(build_path)/bin
@sudo sh ../tools/u540/mkimg.sh $(build_path)/bin $(build_path)/sd.img
@../tools/u540/mkimg.sh $(build_path)/bin $(build_path)/sd.img
endif
.PHONY:

View File

@ -0,0 +1,18 @@
use super::consts::KERNEL_OFFSET;
/// Mask all external interrupt except serial.
pub unsafe fn init_external_interrupt() {
const HART1_S_MODE_INTERRUPT_ENABLES: *mut u64 = (KERNEL_OFFSET + 0x0C00_2100) as *mut u64;
const SERIAL: u64 = 4;
HART1_S_MODE_INTERRUPT_ENABLES.write(1 << SERIAL);
}
/// Claim and complete external interrupt by reading and writing to
/// PLIC Interrupt Claim/Complete Register.
pub unsafe fn handle_external_interrupt() {
const HART1_S_MODE_INTERRUPT_CLAIM_COMPLETE: *mut u32 = (KERNEL_OFFSET + 0x0C20_2004) as *mut u32;
// claim
let source = HART1_S_MODE_INTERRUPT_CLAIM_COMPLETE.read();
// complete
HART1_S_MODE_INTERRUPT_CLAIM_COMPLETE.write(source);
}

View File

@ -34,14 +34,16 @@ pub fn init() {
xtvec::write(trap_entry as usize, xtvec::TrapMode::Direct);
// Enable IPI
sie::set_ssoft();
// Enable serial interrupt
#[cfg(feature = "m_mode")]
mie::set_mext();
#[cfg(not(feature = "m_mode"))]
sie::set_sext();
// NOTE: In M-mode: mie.MSIE is set by BBL.
// mie.MEIE can not be set in QEMU v3.0
// (seems like a bug)
// Enable external interrupt
if super::cpu::id() == super::BOOT_HART_ID {
#[cfg(feature = "m_mode")]
mie::set_mext();
#[cfg(not(feature = "m_mode"))]
sie::set_sext();
// NOTE: In M-mode: mie.MSIE is set by BBL.
// mie.MEIE can not be set in QEMU v3.0
// (seems like a bug)
}
}
info!("interrupt: init end");
}
@ -130,6 +132,9 @@ fn sbi(tf: &mut TrapFrame) {
}
fn external() {
#[cfg(feature = "board_u540")]
unsafe { super::board::handle_external_interrupt(); }
// true means handled, false otherwise
let handlers = [try_process_serial, try_process_drivers];
for handler in handlers.iter() {

View File

@ -79,6 +79,10 @@ fn remap_the_kernel(dtb: usize) {
ms.push(bootstack as usize, bootstacktop as usize, MemoryAttr::default(), Linear::new(offset), "stack");
ms.push(sbss as usize, ebss as usize, MemoryAttr::default(), Linear::new(offset), "bss");
ms.push(dtb, dtb + super::consts::MAX_DTB_SIZE, MemoryAttr::default().readonly(), Linear::new(offset), "dts");
// map PLIC for HiFiveU
let offset = -(KERNEL_OFFSET as isize);
ms.push(KERNEL_OFFSET + 0x0C00_2000, KERNEL_OFFSET + 0x0C00_2000 + PAGE_SIZE, MemoryAttr::default(), Linear::new(offset), "plic0");
ms.push(KERNEL_OFFSET + 0x0C20_2000, KERNEL_OFFSET + 0x0C20_2000 + PAGE_SIZE, MemoryAttr::default(), Linear::new(offset), "plic1");
unsafe { ms.activate(); }
unsafe { SATP = ms.token(); }
mem::forget(ms);

View File

@ -7,6 +7,9 @@ pub mod compiler_rt;
pub mod consts;
pub mod cpu;
pub mod syscall;
#[cfg(feature = "board_u540")]
#[path = "board/u540/mod.rs"]
mod board;
mod sbi;
use log::*;
@ -36,6 +39,8 @@ pub extern fn rust_main(hartid: usize, dtb: usize, hart_mask: usize, functions:
// FIXME: init driver on u540
#[cfg(not(feature = "board_u540"))]
crate::drivers::init(dtb);
#[cfg(feature = "board_u540")]
unsafe { board::init_external_interrupt(); }
crate::process::init();
unsafe { cpu::start_others(hart_mask); }

@ -1 +1 @@
Subproject commit 2829915ea12fba2e5fd4db2879e23311043a55b4
Subproject commit 405ea59dd7dd2762c5883822f21d9995bea32b0c

0
tools/u540/mkimg.sh Normal file → Executable file
View File