Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions driver/src/uart/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@ pub mod dumb;
pub mod gd32e5x_uart;
#[cfg(target_chip = "gd32vw55x")]
pub mod gd32vw55x;
pub mod ns16550a;
pub mod ns16650;
pub mod ns16x50;

#[derive(Debug, Clone, PartialEq, Eq)]
#[repr(C)]
Expand Down
101 changes: 0 additions & 101 deletions driver/src/uart/ns16550a.rs

This file was deleted.

113 changes: 66 additions & 47 deletions driver/src/uart/ns16650.rs → driver/src/uart/ns16x50.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2025 vivo Mobile Communication Co., Ltd.
// Copyright (c) 2026 vivo Mobile Communication Co., Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand All @@ -24,6 +24,26 @@ use tock_registers::{

use crate::static_ref::StaticRef;

#[cfg(not(target_board = "rk3568"))]
// qemu virt platform uses NS16550 UART
// NS16550 uses 8-bit registers, and the register offset is 1 byte.
register_structs! {
UartRegisters {
/// Get or Put Register.
(0x00 => rbr: ReadWrite<u8>),
(0x01 => ier: ReadWrite<u8, IER::Register>),
(0x02 => fcr: ReadWrite<u8>),
(0x03 => lcr: ReadWrite<u8>),
(0x04 => mcr: ReadWrite<u8>),
(0x05 => lsr: ReadOnly<u8, LSR::Register>),
(0x06 => msr: ReadOnly<u8>),
(0x07 => @END),
}
}

#[cfg(target_board = "rk3568")]
// rk3568 uses NS16650 UART
// NS16650 uses 32-bit registers, and the register offset is 4 bytes.
register_structs! {
UartRegisters {
/// Get or Put Register.
Expand All @@ -47,49 +67,59 @@ register_structs! {
}
}

register_bitfields! [u32,
LSR [
DATA_READY OFFSET(0) NUMBITS(1) [],
OVERRUN_ERROR OFFSET(1) NUMBITS(1) [],
PARITY_ERROR OFFSET(2) NUMBITS(1) [],
FRAMING_ERROR OFFSET(3) NUMBITS(1) [],
BREAK_INTERRUPT OFFSET(4) NUMBITS(1) [],
TRANS_HOLD_REG_EMPTY OFFSET(5) NUMBITS(1) [],
TRANS_EMPTY OFFSET(6) NUMBITS(1) [],
RECV_FIFO_ERROR OFFSET(7) NUMBITS(1) [],
],

IER [
RECV_DATA_AVAILABLE OFFSET(0) NUMBITS(1) [],
TRANS_HOLD_EMPTY OFFSET(1) NUMBITS(1) [],
RECV_LINE_STATUS OFFSET(2) NUMBITS(1) [],
MODEM_STATUS OFFSET(3) NUMBITS(1) [],
PROG_THRE OFFSET(5) NUMBITS(1) [],
]
];

pub struct Ns16650 {
macro_rules! define_ns16x50_registers {
($base:ident) => {
register_bitfields! [$base,
LSR [
DATA_READY OFFSET(0) NUMBITS(1) [],
OVERRUN_ERROR OFFSET(1) NUMBITS(1) [],
PARITY_ERROR OFFSET(2) NUMBITS(1) [],
FRAMING_ERROR OFFSET(3) NUMBITS(1) [],
BREAK_INTERRUPT OFFSET(4) NUMBITS(1) [],
TRANS_HOLD_REG_EMPTY OFFSET(5) NUMBITS(1) [],
TRANS_EMPTY OFFSET(6) NUMBITS(1) [],
RECV_FIFO_ERROR OFFSET(7) NUMBITS(1) [],
],

IER [
RECV_DATA_AVAILABLE OFFSET(0) NUMBITS(1) [],
TRANS_HOLD_EMPTY OFFSET(1) NUMBITS(1) [],
RECV_LINE_STATUS OFFSET(2) NUMBITS(1) [],
MODEM_STATUS OFFSET(3) NUMBITS(1) [],
PROG_THRE OFFSET(5) NUMBITS(1) [],
]
];
}
}

#[cfg(not(target_board = "rk3568"))]
define_ns16x50_registers!(u8);

#[cfg(target_board = "rk3568")]
define_ns16x50_registers!(u32);

pub struct Ns16x50 {
registers: StaticRef<UartRegisters>,
}

impl Ns16650 {
impl Ns16x50 {
pub const fn new(base: usize) -> Self {
Self {
registers: unsafe { StaticRef::new(base as *const UartRegisters) },
}
}
}

impl Configuration<super::UartConfig> for Ns16650 {
impl Configuration<super::UartConfig> for Ns16x50 {
type Target = ();
fn configure(&self, para: &super::UartConfig) -> blueos_hal::err::Result<()> {
Ok(())
}
}

impl Uart<super::UartConfig, (), super::InterruptType, super::UartCtrlStatus> for Ns16650 {}
impl Uart<super::UartConfig, (), super::InterruptType, super::UartCtrlStatus> for Ns16x50 {}

impl Has8bitDataReg for Ns16650 {
impl Has8bitDataReg for Ns16x50 {
fn read_data8(&self) -> Result<u8> {
let er_bits = self.registers.ier.get();
if LSR::FRAMING_ERROR.is_set(er_bits)
Expand All @@ -104,6 +134,9 @@ impl Has8bitDataReg for Ns16650 {
}

fn write_data8(&self, data: u8) {
#[cfg(not(target_board = "rk3568"))]
self.registers.rbr.set(data as u8);
#[cfg(target_board = "rk3568")]
self.registers.rbr.set(data as u32);
}

Expand All @@ -112,13 +145,13 @@ impl Has8bitDataReg for Ns16650 {
}
}

impl HasLineStatusReg for Ns16650 {
impl HasLineStatusReg for Ns16x50 {
fn is_bus_busy(&self) -> bool {
!self.registers.lsr.is_set(LSR::TRANS_EMPTY)
}
}

impl HasFifo for Ns16650 {
impl HasFifo for Ns16x50 {
fn enable_fifo(&self, num: u8) -> blueos_hal::err::Result<()> {
todo!()
}
Expand All @@ -132,13 +165,9 @@ impl HasFifo for Ns16650 {
}
}

impl HasInterruptReg for Ns16650 {
impl HasInterruptReg for Ns16x50 {
type InterruptType = super::InterruptType;

fn enable_interrupt(&self, int_type: Self::InterruptType) {}

fn disable_interrupt(&self, int_type: Self::InterruptType) {}

fn clear_interrupt(&self, int_type: Self::InterruptType) {
match int_type {
super::InterruptType::Rx => {}
Expand All @@ -150,19 +179,9 @@ impl HasInterruptReg for Ns16650 {
fn get_interrupt(&self) -> Self::InterruptType {
todo!()
}

fn set_interrupt_handler(&self, handler: &'static dyn Fn()) {}

fn get_irq_nums(&self) -> &[u32] {
&[]
}
}

unsafe impl Sync for Ns16650 {}
unsafe impl Send for Ns16650 {}
unsafe impl Sync for Ns16x50 {}
unsafe impl Send for Ns16x50 {}

impl PlatPeri for Ns16650 {
fn enable(&self) {}

fn disable(&self) {}
}
impl PlatPeri for Ns16x50 {}
4 changes: 2 additions & 2 deletions kernel/src/boards/qemu_riscv32/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,5 @@
use crate::arch::irq::IrqNumber;

pub const PLIC_BASE: usize = 0x0c00_0000;
pub const NS16550A_UART0_BASE: u32 = 0x1000_0000;
pub const NS16550A_UART0_IRQNUM: IrqNumber = IrqNumber::new(10);
pub const NS16550_UART0_BASE: u32 = 0x1000_0000;
pub const NS16550_UART0_IRQNUM: IrqNumber = IrqNumber::new(10);
10 changes: 5 additions & 5 deletions kernel/src/boards/qemu_riscv32/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,21 +67,21 @@ pub(crate) fn init() {
// Enable UART0 in PLIC.
PLIC.enable(
arch::current_cpu_id(),
u32::try_from(usize::from(config::NS16550A_UART0_IRQNUM))
u32::try_from(usize::from(config::NS16550_UART0_IRQNUM))
.expect("usize(64 bits) converts to u32 failed"),
);
// Set UART0 priority in PLIC.
PLIC.set_priority(
u32::try_from(usize::from(config::NS16550A_UART0_IRQNUM))
u32::try_from(usize::from(config::NS16550_UART0_IRQNUM))
.expect("usize(64 bits) converts to u32 failed"),
1,
);
}

crate::define_peripheral! {
(console_uart, blueos_driver::uart::ns16550a::Ns16550a<'static>,
blueos_driver::uart::ns16550a::Ns16550a::<'static>::new(
config::NS16550A_UART0_BASE as _,
(console_uart, blueos_driver::uart::ns16x50::Ns16x50,
blueos_driver::uart::ns16x50::Ns16x50::new(
config::NS16550_UART0_BASE as _,
)),
}

Expand Down
4 changes: 2 additions & 2 deletions kernel/src/boards/qemu_riscv64/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,5 @@
use crate::arch::irq::IrqNumber;

pub const PLIC_BASE: usize = 0x0c00_0000;
pub const NS16550A_UART0_BASE: u32 = 0x1000_0000;
pub const NS16550A_UART0_IRQNUM: IrqNumber = IrqNumber::new(10);
pub const NS16550_UART0_BASE: u32 = 0x1000_0000;
pub const NS16550_UART0_IRQNUM: IrqNumber = IrqNumber::new(10);
10 changes: 5 additions & 5 deletions kernel/src/boards/qemu_riscv64/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,21 +67,21 @@ pub(crate) fn init() {
// Enable UART0 in PLIC.
PLIC.enable(
arch::current_cpu_id(),
u32::try_from(usize::from(config::NS16550A_UART0_IRQNUM))
u32::try_from(usize::from(config::NS16550_UART0_IRQNUM))
.expect("usize(64 bits) converts to u32 failed"),
);
// Set UART0 priority in PLIC.
PLIC.set_priority(
u32::try_from(usize::from(config::NS16550A_UART0_IRQNUM))
u32::try_from(usize::from(config::NS16550_UART0_IRQNUM))
.expect("usize(64 bits) converts to u32 failed"),
1,
);
}

crate::define_peripheral! {
(console_uart, blueos_driver::uart::ns16550a::Ns16550a<'static>,
blueos_driver::uart::ns16550a::Ns16550a::<'static>::new(
config::NS16550A_UART0_BASE as _,
(console_uart, blueos_driver::uart::ns16x50::Ns16x50,
blueos_driver::uart::ns16x50::Ns16x50::new(
config::NS16550_UART0_BASE as _,
)),
}

Expand Down
4 changes: 2 additions & 2 deletions kernel/src/boards/rk3568/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ pub(crate) fn init() {
}

crate::define_peripheral! {
(console_uart, blueos_driver::uart::ns16650::Ns16650,
blueos_driver::uart::ns16650::Ns16650::new(
(console_uart, blueos_driver::uart::ns16x50::Ns16x50,
blueos_driver::uart::ns16x50::Ns16x50::new(
0xFE660000,
)),
}
Expand Down