diff --git a/kernel/Makefile b/kernel/Makefile index faba997..b0ccb2a 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -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 diff --git a/kernel/src/arch/riscv32/board/rocket_chip/device.dts b/kernel/src/arch/riscv32/board/rocket_chip/device.dts index 774c238..42cf330 100644 --- a/kernel/src/arch/riscv32/board/rocket_chip/device.dts +++ b/kernel/src/arch/riscv32/board/rocket_chip/device.dts @@ -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 { diff --git a/kernel/src/arch/riscv32/board/rocket_chip/mod.rs b/kernel/src/arch/riscv32/board/rocket_chip/mod.rs index 0e2ac03..7e996b6 100644 --- a/kernel/src/arch/riscv32/board/rocket_chip/mod.rs +++ b/kernel/src/arch/riscv32/board/rocket_chip/mod.rs @@ -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); } \ No newline at end of file diff --git a/kernel/src/arch/riscv32/interrupt.rs b/kernel/src/arch/riscv32/interrupt.rs index b498e65..12735f6 100644 --- a/kernel/src/arch/riscv32/interrupt.rs +++ b/kernel/src/arch/riscv32/interrupt.rs @@ -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(); } diff --git a/kernel/src/arch/riscv32/memory.rs b/kernel/src/arch/riscv32/memory.rs index 04a3388..304e9f6 100644 --- a/kernel/src/arch/riscv32/memory.rs +++ b/kernel/src/arch/riscv32/memory.rs @@ -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(); } diff --git a/kernel/src/arch/riscv32/mod.rs b/kernel/src/arch/riscv32/mod.rs index e34c2ea..028d666 100644 --- a/kernel/src/arch/riscv32/mod.rs +++ b/kernel/src/arch/riscv32/mod.rs @@ -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(); } diff --git a/kernel/src/fs/stdio.rs b/kernel/src/fs/stdio.rs index d13520a..57e242c 100644 --- a/kernel/src/fs/stdio.rs +++ b/kernel/src/fs/stdio.rs @@ -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; } }