mirror of
https://github.com/panpaul/tiny_os
synced 2024-09-20 09:45:19 +08:00
feat: use cfg_if! to avoid conflicting features
This commit is contained in:
parent
e7c1a7a656
commit
f1735dc1c0
@ -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 {
|
19
kernel/src/arch/riscv/board/default/lowlevel.rs
Normal file
19
kernel/src/arch/riscv/board/default/lowlevel.rs
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
5
kernel/src/arch/riscv/board/default/mod.rs
Normal file
5
kernel/src/arch/riscv/board/default/mod.rs
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
pub const BOOT_HART_ID: usize = 0;
|
||||||
|
pub const TIMER_TICKS: u64 = 100_000; // 100ms
|
||||||
|
|
||||||
|
mod io;
|
||||||
|
mod lowlevel;
|
16
kernel/src/arch/riscv/board/virt/lowlevel.rs
Normal file
16
kernel/src/arch/riscv/board/virt/lowlevel.rs
Normal 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) }
|
||||||
|
}
|
||||||
|
}
|
@ -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;
|
||||||
|
@ -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]
|
||||||
|
@ -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]
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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: {:?}",
|
||||||
|
@ -1,49 +1,52 @@
|
|||||||
#[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);
|
||||||
static ref ALLOCATOR: SpinMutex<FreeList> = {
|
} else { // fallback to freelist
|
||||||
let mut list = FreeList::new();
|
use lazy_static::lazy_static;
|
||||||
|
use crate::mm::freelist::FreeList;
|
||||||
|
|
||||||
for i in 0..1024 {
|
lazy_static! {
|
||||||
let addr = PhysAddr((i * PAGE_SIZE) + KERNEL_MEM_START);
|
static ref ALLOCATOR: SpinMutex<FreeList> = {
|
||||||
list.push(addr.into());
|
let mut list = FreeList::new();
|
||||||
|
|
||||||
|
for i in 0..1024 {
|
||||||
|
let addr = PhysAddr((i * PAGE_SIZE) + KERNEL_MEM_START);
|
||||||
|
list.push(addr.into());
|
||||||
|
}
|
||||||
|
|
||||||
|
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 {
|
||||||
|
let addr = ALLOCATOR.lock().pop().map(|addr| addr.into());
|
||||||
#[cfg(feature = "frame_freelist")]
|
}
|
||||||
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,17 +58,19 @@ 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());
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user