feat: use cfg_if! to avoid conflicting features

This commit is contained in:
Paul Pan 2024-02-16 21:00:08 +08:00
parent e7c1a7a656
commit f1735dc1c0
14 changed files with 130 additions and 104 deletions

View File

@ -1,7 +1,5 @@
#[allow(unused_imports)]
use crate::plat::io::{Printer, RawConsole, Reader}; use crate::plat::io::{Printer, RawConsole, Reader};
#[cfg(feature = "board_default")]
impl Printer for RawConsole { impl Printer for RawConsole {
fn put_char(c: char) { fn put_char(c: char) {
#[allow(deprecated)] #[allow(deprecated)]
@ -9,7 +7,6 @@ impl Printer for RawConsole {
} }
} }
#[cfg(feature = "board_default")]
impl Reader for RawConsole { impl Reader for RawConsole {
fn get_char() -> char { fn get_char() -> char {
loop { loop {

View File

@ -0,0 +1,19 @@
use super::super::lowlevel::{ArchLL, ArchLLOps};
impl ArchLLOps for ArchLL {
fn board_shutdown(failure: bool) {
if failure {
sbi_rt::system_reset(sbi_rt::Shutdown, sbi_rt::SystemFailure);
} else {
sbi_rt::system_reset(sbi_rt::Shutdown, sbi_rt::NoReason);
}
}
fn board_reset(failure: bool) {
if failure {
sbi_rt::system_reset(sbi_rt::ColdReboot, sbi_rt::SystemFailure);
} else {
sbi_rt::system_reset(sbi_rt::WarmReboot, sbi_rt::NoReason);
}
}
}

View File

@ -0,0 +1,5 @@
pub const BOOT_HART_ID: usize = 0;
pub const TIMER_TICKS: u64 = 100_000; // 100ms
mod io;
mod lowlevel;

View File

@ -0,0 +1,16 @@
use super::super::lowlevel::{ArchLL, ArchLLOps};
use super::TEST_DEVICE;
impl ArchLLOps for ArchLL {
fn board_shutdown(failure: bool) {
if failure {
unsafe { TEST_DEVICE.write_volatile(0x0001_3333) }
} else {
unsafe { TEST_DEVICE.write_volatile(0x0000_5555) }
}
}
fn board_reset(_failure: bool) {
unsafe { TEST_DEVICE.write_volatile(0x0042_7777) }
}
}

View File

@ -1,10 +1,11 @@
pub const BOOT_HART_ID: usize = 0; pub const BOOT_HART_ID: usize = 0;
pub const TIMER_TICKS: u64 = 100_000; // 100ms
// devices
pub const UART0_BASE: usize = 0x1000_0000; pub const UART0_BASE: usize = 0x1000_0000;
pub const UART0_LSR: usize = 0x1000_0005; pub const UART0_LSR: usize = 0x1000_0005;
pub const TEST_DEVICE: *mut u32 = 0x10_0000 as *mut u32; pub const TEST_DEVICE: *mut u32 = 0x10_0000 as *mut u32;
pub const TIMER_TICKS: u64 = 100_000; // 100ms
pub mod printer; mod lowlevel;
pub mod reader; mod printer;
pub mod timer; mod reader;

View File

@ -1,10 +1,6 @@
use crate::plat::io::{Printer, RawConsole}; use crate::plat::io::{Printer, RawConsole};
/* // Theoretically, we should wait until "THR Empty" bit (1<<5 in LSR) is set before writing to UART.
Theoretically, we should wait until
"THR Empty" bit (1<<5 in LSR) is set
before writing to UART.
*/
impl Printer for RawConsole { impl Printer for RawConsole {
#[inline] #[inline]

View File

@ -1,6 +1,6 @@
use core::ptr::addr_of_mut; use core::ptr::addr_of_mut;
use crate::arch::cpu::set_hart_id; use super::cpu::set_hart_id;
#[naked] #[naked]
#[no_mangle] #[no_mangle]

View File

@ -2,9 +2,6 @@ pub use super::mm::page::PAGE_SIZE;
pub const KERNEL_MEM_START: usize = 0x8030_0000; pub const KERNEL_MEM_START: usize = 0x8030_0000;
// TODO: currently a dummy value, figure out our memory layout
pub const TRAPFRAME: usize = 0x8000_0000;
extern "C" { extern "C" {
static __kernel_end: u8; static __kernel_end: u8;
} }

View File

@ -2,8 +2,13 @@ use log::error;
use crate::plat::lowlevel::{Hardware, LowLevel}; use crate::plat::lowlevel::{Hardware, LowLevel};
#[cfg(feature = "board_virt")] pub struct ArchLL
use super::board::TEST_DEVICE; where ArchLL: ArchLLOps;
pub trait ArchLLOps {
fn board_shutdown(failure: bool);
fn board_reset(failure: bool);
}
impl LowLevel for Hardware { impl LowLevel for Hardware {
#[inline] #[inline]
@ -14,25 +19,7 @@ impl LowLevel for Hardware {
#[inline] #[inline]
fn shutdown(failure: bool) -> ! { fn shutdown(failure: bool) -> ! {
Self::disable_interrupt(); Self::disable_interrupt();
ArchLL::board_shutdown(failure);
if failure {
#[cfg(not(feature = "board_virt"))]
sbi_rt::system_reset(sbi_rt::Shutdown, sbi_rt::SystemFailure);
#[cfg(feature = "board_virt")]
unsafe {
TEST_DEVICE.write_volatile(0x0001_3333)
}
} else {
#[cfg(not(feature = "board_virt"))]
sbi_rt::system_reset(sbi_rt::Shutdown, sbi_rt::NoReason);
#[cfg(feature = "board_virt")]
unsafe {
TEST_DEVICE.write_volatile(0x0000_5555)
}
}
loop { loop {
// in case system_reset failed // in case system_reset failed
Self::halt() Self::halt()
@ -40,19 +27,8 @@ impl LowLevel for Hardware {
} }
#[inline] #[inline]
fn reset(#[allow(unused_variables)] failure: bool) -> ! { fn reset(failure: bool) -> ! {
#[cfg(not(feature = "board_virt"))] ArchLL::board_reset(failure);
if failure {
sbi_rt::system_reset(sbi_rt::ColdReboot, sbi_rt::SystemFailure);
} else {
sbi_rt::system_reset(sbi_rt::WarmReboot, sbi_rt::NoReason);
}
#[cfg(feature = "board_virt")]
unsafe {
TEST_DEVICE.write_volatile(0x0042_7777)
}
error!("[riscv/lowlevel] system_reset failed, shutdown instead"); error!("[riscv/lowlevel] system_reset failed, shutdown instead");
Self::shutdown(true); Self::shutdown(true);
} }

View File

@ -4,7 +4,6 @@ use crate::mm::addr::{AddressOps, PhysAddr};
use crate::mm::page; use crate::mm::page;
pub const PAGE_SIZE: usize = 4096; pub const PAGE_SIZE: usize = 4096;
const PAGE_TABLE_ENTRIES: usize = 512;
const PG_OFFSET: u64 = 12; const PG_OFFSET: u64 = 12;
const PPN_OFFSET: u64 = 10; const PPN_OFFSET: u64 = 10;
@ -119,16 +118,19 @@ impl page::PageTableEntry for PTE {
// we'll implement sv39 paging scheme // we'll implement sv39 paging scheme
pub struct Size4KiB; pub struct Size4KiB;
impl page::PageSize for Size4KiB { impl page::PageSize for Size4KiB {
const SIZE: usize = 1 << 12; // 4KiB const SIZE: usize = 1 << 12; // 4KiB
} }
pub struct Size2MiB; pub struct Size2MiB;
impl page::PageSize for Size2MiB { impl page::PageSize for Size2MiB {
const SIZE: usize = 1 << 21; // 2MiB const SIZE: usize = 1 << 21; // 2MiB
} }
pub struct Size1GiB; pub struct Size1GiB;
impl page::PageSize for Size1GiB { impl page::PageSize for Size1GiB {
const SIZE: usize = 1 << 30; // 1GiB const SIZE: usize = 1 << 30; // 1GiB
} }

View File

@ -1,13 +1,21 @@
use cfg_if::cfg_if;
pub use board::BOOT_HART_ID; pub use board::BOOT_HART_ID;
#[cfg(feature = "board_virt")] cfg_if! {
#[path = "board/virt/mod.rs"] if #[cfg(feature = "board_virt")] {
mod board; #[path = "board/virt/mod.rs"]
mod board;
} else {
#[path = "board/default/mod.rs"]
mod board;
}
}
pub mod cpu; mod cpu;
pub mod entry; mod entry;
pub mod io;
pub mod layout; pub mod layout;
pub mod lowlevel; mod lowlevel;
pub mod mm; mod mm;
mod timer;
pub mod trap; pub mod trap;

View File

@ -1,5 +1,6 @@
use log::info; use log::info;
use super::board::TIMER_TICKS;
use crate::plat::timer::{Timer, TimerOps}; use crate::plat::timer::{Timer, TimerOps};
impl TimerOps for Timer { impl TimerOps for Timer {
@ -21,6 +22,6 @@ impl TimerOps for Timer {
} }
fn tick() { fn tick() {
sbi_rt::set_timer(Self::read_cycle() + super::TIMER_TICKS); sbi_rt::set_timer(Self::read_cycle() + TIMER_TICKS);
} }
} }

View File

@ -1,15 +1,18 @@
use cfg_if::cfg_if;
use log::trace; use log::trace;
use riscv::register::scause::{Interrupt as I, Trap as T}; use riscv::register::scause::{Interrupt as I, Trap as T};
use crate::arch::cpu::get_hart_id; use super::cpu::get_hart_id;
use crate::plat::timer::{Timer, TimerOps}; use crate::plat::timer::{Timer, TimerOps};
use crate::plat::trap::{Trap, TrapContextOps, TrapOps}; use crate::plat::trap::{Trap, TrapContextOps, TrapOps};
#[cfg(feature = "arch_riscv64")] cfg_if! {
core::arch::global_asm!(include_str!("./asm/trap64.S")); if #[cfg(feature = "arch_riscv64")] {
core::arch::global_asm!(include_str!("./asm/trap64.S"));
#[cfg(feature = "arch_riscv32")] } else if #[cfg(feature = "arch_riscv32")] {
core::arch::global_asm!(include_str!("./asm/trap32.S")); core::arch::global_asm!(include_str!("./asm/trap32.S"));
}
}
core::arch::global_asm!(include_str!("./asm/trap_common.S")); core::arch::global_asm!(include_str!("./asm/trap_common.S"));
@ -19,7 +22,7 @@ extern "C" {
} }
#[no_mangle] #[no_mangle]
pub extern "C" fn trap_handler(tf: &mut TrapContext) { extern "C" fn trap_handler(_tf: &mut TrapContext) {
let scause = riscv::register::scause::read(); let scause = riscv::register::scause::read();
trace!( trace!(
"[Interrupt] cpu@{} scause: {:?}", "[Interrupt] cpu@{} scause: {:?}",

View File

@ -1,21 +1,21 @@
#[allow(unused_imports)] use cfg_if::cfg_if;
use lazy_static::lazy_static;
use log::trace; use log::trace;
use spin::mutex::SpinMutex; use spin::mutex::SpinMutex;
use crate::arch::layout::*; use crate::arch::layout::*;
use crate::mm::addr::{AddressOps, PhysAddr}; use crate::mm::addr::{AddressOps, PhysAddr};
#[allow(unused_imports)]
use crate::mm::bitmap::{Bitmap1K, BitmapOps};
#[allow(unused_imports)]
use crate::mm::freelist::FreeList;
// 1k * 4k = 4MB, currently enough for kernel data cfg_if! {
#[cfg(feature = "frame_bitmap")] if #[cfg(feature = "frame_bitmap")] {
static ALLOCATOR: SpinMutex<Bitmap1K> = SpinMutex::new(Bitmap1K::DEFAULT); use crate::mm::bitmap::{Bitmap1K, BitmapOps};
#[cfg(feature = "frame_freelist")] // 1k * 4k = 4MB, currently enough for kernel data
lazy_static! { static ALLOCATOR: SpinMutex<Bitmap1K> = SpinMutex::new(Bitmap1K::DEFAULT);
} else { // fallback to freelist
use lazy_static::lazy_static;
use crate::mm::freelist::FreeList;
lazy_static! {
static ref ALLOCATOR: SpinMutex<FreeList> = { static ref ALLOCATOR: SpinMutex<FreeList> = {
let mut list = FreeList::new(); let mut list = FreeList::new();
@ -26,24 +26,27 @@ lazy_static! {
SpinMutex::new(list) SpinMutex::new(list)
}; };
}
}
} }
pub struct FrameAllocator; pub struct FrameAllocator;
impl FrameAllocator { impl FrameAllocator {
pub fn alloc(&self) -> Option<PhysAddr> { pub fn alloc(&self) -> Option<PhysAddr> {
#[cfg(feature = "frame_bitmap")] cfg_if! {
let addr = crate::mm::frame::ALLOCATOR.lock().alloc().map(|i| { if #[cfg(feature = "frame_bitmap")] {
crate::mm::addr::PhysAddr( let addr = ALLOCATOR
(i * crate::arch::arch::mm::page::PAGE_SIZE) .lock()
+ crate::arch::arch::layout::KERNEL_MEM_START, .alloc()
) .map(|i| PhysAddr((i * PAGE_SIZE) + KERNEL_MEM_START));
}); } else {
#[cfg(feature = "frame_freelist")]
let addr = ALLOCATOR.lock().pop().map(|addr| addr.into()); let addr = ALLOCATOR.lock().pop().map(|addr| addr.into());
}
}
trace!("[mm/frame] alloc frame: {:?}", addr); trace!("[mm/frame] alloc frame: {:?}", addr);
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
fill_page(addr, 0xaa); fill_page(addr, 0xaa);
@ -55,18 +58,20 @@ impl FrameAllocator {
debug_assert!(addr.as_usize() >= KERNEL_MEM_START); debug_assert!(addr.as_usize() >= KERNEL_MEM_START);
trace!("[mm/frame] dealloc frame: {:?}", addr); trace!("[mm/frame] dealloc frame: {:?}", addr);
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
fill_page(Some(addr), 0x55); fill_page(Some(addr), 0x55);
#[cfg(feature = "frame_bitmap")] cfg_if! {
crate::mm::frame::ALLOCATOR.lock().dealloc( if #[cfg(feature = "frame_bitmap")] {
(addr.as_usize() - crate::arch::arch::layout::KERNEL_MEM_START) ALLOCATOR
/ crate::arch::arch::mm::page::PAGE_SIZE, .lock()
); .dealloc((addr.as_usize() - KERNEL_MEM_START) / PAGE_SIZE);
} else {
#[cfg(feature = "frame_freelist")]
ALLOCATOR.lock().push(addr.into()); ALLOCATOR.lock().push(addr.into());
} }
}
}
} }
fn fill_page(addr: Option<PhysAddr>, val: u8) { fn fill_page(addr: Option<PhysAddr>, val: u8) {