mirror of
https://github.com/rcore-os/rCore.git
synced 2024-11-22 16:16:16 +04:00
Fix Rocket Chip serial interrupt
This commit is contained in:
parent
2fb09109bb
commit
2e599b0bab
@ -75,7 +75,7 @@ board := raspi3
|
||||
need_bootloader := true
|
||||
endif
|
||||
|
||||
# currently only mipsel architecture and rocket-chip needs DTB linked to the kernel
|
||||
# currently only mipsel architecture and rocket-chip need DTB linked to the kernel
|
||||
ifeq ($(arch), mipsel)
|
||||
dtb := src/arch/$(arch)/board/$(board)/device.dtb
|
||||
endif
|
||||
|
@ -91,16 +91,16 @@
|
||||
|
||||
serial0: serial@60000000 {
|
||||
compatible = "xlnx,xps-uartlite-1.00.a";
|
||||
reg = <0x0 0x6000000 0x1000>;
|
||||
interrupt-parent = <&L10>;
|
||||
reg = <0x6000000 0x1000>;
|
||||
interrupt-parent = <&axi_intc>;
|
||||
interrupts = <1>;
|
||||
};
|
||||
|
||||
serial_net: serial@60010000 {
|
||||
compatible = "xlnx,xps-uartlite-1.00.a";
|
||||
reg = <0x0 0x60010000 0x1000>;
|
||||
axi_intc: axi_intc@61200000 {
|
||||
compatible = "xlnx,xps-intc-1.00.a";
|
||||
reg = <0x61200000 0x1000>;
|
||||
interrupt-parent = <&L10>;
|
||||
interrupts = <2>;
|
||||
interrupts = <1>;
|
||||
};
|
||||
};
|
||||
L9: rom@10000 {
|
||||
|
@ -4,15 +4,43 @@ use super::consts::KERNEL_OFFSET;
|
||||
pub unsafe fn init_external_interrupt() {
|
||||
const HART0_S_MODE_INTERRUPT_ENABLES: *mut u64 = (KERNEL_OFFSET + 0x0C00_2080) as *mut u64;
|
||||
HART0_S_MODE_INTERRUPT_ENABLES.write_volatile(0xf);
|
||||
|
||||
// mask interrupts first
|
||||
const AXI_INTC_IER: *mut u32 = (KERNEL_OFFSET + 0x1900_0008) as *mut u32;
|
||||
AXI_INTC_IER.write_volatile(0x0);
|
||||
|
||||
// acknowledge all interrupts
|
||||
const AXI_INTC_IAR: *mut u32 = (KERNEL_OFFSET + 0x1900_000C) as *mut u32;
|
||||
AXI_INTC_IAR.write_volatile(0xffffffff);
|
||||
|
||||
const AXI_INTC_MER: *mut u32 = (KERNEL_OFFSET + 0x1900_001C) as *mut u32;
|
||||
// Hardware Interrupt enable | Enable irq output
|
||||
AXI_INTC_MER.write_volatile(0b11);
|
||||
|
||||
// enable all interrupts
|
||||
AXI_INTC_IER.write_volatile(0xffffffff);
|
||||
|
||||
}
|
||||
|
||||
/// Claim and complete external interrupt by reading and writing to
|
||||
/// PLIC Interrupt Claim/Complete Register.
|
||||
pub unsafe fn handle_external_interrupt() {
|
||||
const HART0_S_MODE_INTERRUPT_CLAIM_COMPLETE: *mut u32 =
|
||||
(KERNEL_OFFSET + 0x0C20_2000) as *mut u32;
|
||||
(KERNEL_OFFSET + 0x0C20_1004) as *mut u32;
|
||||
// claim
|
||||
let source = HART0_S_MODE_INTERRUPT_CLAIM_COMPLETE.read_volatile();
|
||||
// complete
|
||||
HART0_S_MODE_INTERRUPT_CLAIM_COMPLETE.write_volatile(source);
|
||||
|
||||
// acknowledge all interrupts
|
||||
const AXI_INTC_IAR: *mut u32 = (KERNEL_OFFSET + 0x1900_000C) as *mut u32;
|
||||
AXI_INTC_IAR.write_volatile(0xffffffff);
|
||||
}
|
||||
|
||||
pub unsafe fn enable_serial_interrupt() {
|
||||
const SERIAL_BASE: *mut u32 = (KERNEL_OFFSET + 0x18000000) as *mut u32;
|
||||
const UART_CTRL_REG: usize = 3;
|
||||
// Intr enable | rx reset | tx reset
|
||||
const UART_IE: u32 = 0x13;
|
||||
SERIAL_BASE.add(UART_CTRL_REG).write_volatile(UART_IE);
|
||||
}
|
@ -74,7 +74,7 @@ pub extern "C" fn rust_trap(tf: &mut TrapFrame) {
|
||||
}
|
||||
|
||||
fn external() {
|
||||
#[cfg(feature = "board_u540")]
|
||||
#[cfg(any(feature = "board_u540", feature = "board_rocket_chip"))]
|
||||
unsafe {
|
||||
super::board::handle_external_interrupt();
|
||||
}
|
||||
|
@ -133,6 +133,33 @@ fn remap_the_kernel(dtb: usize) {
|
||||
Linear::new(offset),
|
||||
"uart16550",
|
||||
);
|
||||
// map PLIC for Rocket Chip
|
||||
#[cfg(feature = "board_rocket_chip")]
|
||||
ms.push(
|
||||
KERNEL_OFFSET + 0x0C20_1000,
|
||||
KERNEL_OFFSET + 0x0C20_1000 + PAGE_SIZE,
|
||||
MemoryAttr::default(),
|
||||
Linear::new(offset),
|
||||
"plic2",
|
||||
);
|
||||
// map UART for Rocket Chip
|
||||
#[cfg(feature = "board_rocket_chip")]
|
||||
ms.push(
|
||||
KERNEL_OFFSET + 0x18000000,
|
||||
KERNEL_OFFSET + 0x18000000 + PAGE_SIZE,
|
||||
MemoryAttr::default(),
|
||||
Linear::new(-(KERNEL_OFFSET as isize + 0x18000000 - 0x60000000)),
|
||||
"uartlite",
|
||||
);
|
||||
// map AXI INTC for Rocket Chip
|
||||
#[cfg(feature = "board_rocket_chip")]
|
||||
ms.push(
|
||||
KERNEL_OFFSET + 0x19000000,
|
||||
KERNEL_OFFSET + 0x19000000 + PAGE_SIZE,
|
||||
MemoryAttr::default(),
|
||||
Linear::new(-(KERNEL_OFFSET as isize + 0x19000000 - 0x61200000)),
|
||||
"axi_intc",
|
||||
);
|
||||
unsafe {
|
||||
ms.activate();
|
||||
}
|
||||
|
@ -70,7 +70,6 @@ pub extern "C" fn rust_main(hartid: usize, device_tree_paddr: usize) -> ! {
|
||||
crate::drivers::init(device_tree_vaddr);
|
||||
#[cfg(not(feature = "board_k210"))]
|
||||
unsafe {
|
||||
#[cfg(not(feature = "board_rocket_chip"))]
|
||||
board::enable_serial_interrupt();
|
||||
board::init_external_interrupt();
|
||||
}
|
||||
|
@ -29,14 +29,7 @@ impl Stdin {
|
||||
return c;
|
||||
}
|
||||
}
|
||||
#[cfg(feature = "board_rocket_chip")]
|
||||
loop {
|
||||
let c = crate::arch::io::getchar();
|
||||
if c != '\0' && c as u8 != 254 {
|
||||
return c;
|
||||
}
|
||||
}
|
||||
#[cfg(not(any(feature = "board_k210", feature = "board_rocket_chip")))]
|
||||
#[cfg(not(feature = "board_k210"))]
|
||||
loop {
|
||||
let mut buf_lock = self.buf.lock();
|
||||
match buf_lock.pop_front() {
|
||||
@ -48,11 +41,6 @@ impl Stdin {
|
||||
}
|
||||
}
|
||||
pub fn can_read(&self) -> bool {
|
||||
// Currently, rocket-chip implementation rely on htif interface, the serial interrupt DO
|
||||
// NOT work, so return true always
|
||||
#[cfg(feature = "board_rocket_chip")]
|
||||
return true;
|
||||
#[cfg(not(feature = "board_rocket_chip"))]
|
||||
return self.buf.lock().len() > 0;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user