forked from rcore-os/zCore
Add more docs to kernel-hal
This commit is contained in:
parent
67a0468df0
commit
91d57d4409
|
@ -69,7 +69,7 @@ jobs:
|
|||
with:
|
||||
command: build
|
||||
use-cross: true
|
||||
args: -p zircon-loader --target aarch64-unknown-linux-gnu --workspace --exclude linux-syscall --exclude linux-loader --exclude zcore
|
||||
args: --target aarch64-unknown-linux-gnu --workspace --exclude linux-syscall --exclude linux-loader --exclude zcore
|
||||
|
||||
build-user:
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
/// Configuration of HAL.
|
||||
//! Kernel configuration.
|
||||
|
||||
/// Kernel configuration passed by kernel when calls [`crate::primary_init_early()`].
|
||||
#[derive(Debug)]
|
||||
pub struct KernelConfig {
|
||||
pub phys_mem_start: usize,
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
//! Context switch.
|
||||
|
||||
use riscv::register::scause::{Exception, Trap};
|
||||
use riscv::register::{scause, stval};
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
//! CPU information.
|
||||
|
||||
hal_fn_impl! {
|
||||
impl mod crate::hal_fn::cpu {
|
||||
fn cpu_frequency() -> u16 {
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
//! Interrupts management.
|
||||
|
||||
use riscv::{asm, register::sstatus};
|
||||
|
||||
hal_fn_impl! {
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
//! Virutal memory operations.
|
||||
|
||||
use core::fmt::{Debug, Formatter, Result};
|
||||
use core::slice;
|
||||
|
||||
|
@ -124,7 +126,7 @@ hal_fn_impl! {
|
|||
|
||||
bitflags::bitflags! {
|
||||
/// Possible flags for a page table entry.
|
||||
pub struct PTF: usize {
|
||||
struct PTF: usize {
|
||||
const VALID = 1 << 0;
|
||||
const READABLE = 1 << 1;
|
||||
const WRITABLE = 1 << 2;
|
||||
|
@ -181,6 +183,7 @@ impl From<PTF> for MMUFlags {
|
|||
|
||||
const PHYS_ADDR_MASK: u64 = 0x003f_ffff_ffff_fc00; // 10..54
|
||||
|
||||
/// Sv39 and Sv48 page table entry.
|
||||
#[derive(Clone, Copy)]
|
||||
#[repr(transparent)]
|
||||
pub struct Rv64PTE(u64);
|
||||
|
@ -228,5 +231,5 @@ impl Debug for Rv64PTE {
|
|||
}
|
||||
}
|
||||
|
||||
/// Sv39: Page-Based 39-bit Virtual-Memory System
|
||||
/// Sv39: Page-Based 39-bit Virtual-Memory System.
|
||||
pub type PageTable = PageTableImpl<PageTableLevel3, Rv64PTE>;
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
//! Kernel configuration.
|
||||
|
||||
use uefi::proto::console::gop::ModeInfo;
|
||||
use uefi::table::boot::MemoryDescriptor;
|
||||
|
||||
/// Configuration of HAL.
|
||||
/// Kernel configuration passed by kernel when calls [`crate::primary_init_early()`].
|
||||
#[derive(Debug)]
|
||||
pub struct KernelConfig {
|
||||
pub cmdline: &'static str,
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
//! Context switch.
|
||||
|
||||
use bitflags::bitflags;
|
||||
use x86_64::registers::control::Cr2;
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
//! CPU information.
|
||||
|
||||
use raw_cpuid::CpuId;
|
||||
|
||||
lazy_static! {
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
//! Interrupts management.
|
||||
|
||||
use core::ops::Range;
|
||||
|
||||
use crate::drivers::all_irq;
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
//! Functions only available on x86 platforms.
|
||||
|
||||
use x86_64::instructions::port::Port;
|
||||
|
||||
/// IO Port in instruction
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
//! Virutal memory operations.
|
||||
|
||||
use core::fmt::{Debug, Formatter, Result};
|
||||
use core::{convert::TryFrom, slice};
|
||||
|
||||
|
@ -105,6 +107,7 @@ impl From<PTF> for MMUFlags {
|
|||
|
||||
const PHYS_ADDR_MASK: u64 = 0x000f_ffff_ffff_f000; // 12..52
|
||||
|
||||
/// Page table entry on x86.
|
||||
#[derive(Clone, Copy)]
|
||||
#[repr(transparent)]
|
||||
pub struct X86PTE(u64);
|
||||
|
@ -155,4 +158,5 @@ impl Debug for X86PTE {
|
|||
}
|
||||
}
|
||||
|
||||
/// The 4-level page table on x86.
|
||||
pub type PageTable = PageTableImpl<PageTableLevel4, X86PTE>;
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
//! Bootstrap and initialization.
|
||||
|
||||
use crate::{KernelConfig, KernelHandler, KCONFIG, KHANDLER};
|
||||
|
||||
hal_fn_impl! {
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
//! Physical memory operations.
|
||||
|
||||
use alloc::vec::Vec;
|
||||
use core::ops::Range;
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
//! Thread spawning.
|
||||
|
||||
use alloc::boxed::Box;
|
||||
use core::task::{Context, Poll};
|
||||
use core::{future::Future, pin::Pin};
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
//! Time and clock functions.
|
||||
|
||||
use alloc::boxed::Box;
|
||||
use core::time::Duration;
|
||||
|
||||
|
|
|
@ -2,8 +2,13 @@
|
|||
|
||||
use crate::PAGE_SIZE;
|
||||
|
||||
/// Physical address.
|
||||
pub type PhysAddr = usize;
|
||||
|
||||
/// Virtual address.
|
||||
pub type VirtAddr = usize;
|
||||
|
||||
/// Device address.
|
||||
pub type DevVAddr = usize;
|
||||
|
||||
pub const fn align_down(addr: usize) -> usize {
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
//! Console input and output.
|
||||
|
||||
use crate::drivers;
|
||||
use core::fmt::{Arguments, Result, Write};
|
||||
use spin::Mutex;
|
||||
|
@ -41,17 +43,26 @@ cfg_if! {
|
|||
}
|
||||
}
|
||||
|
||||
/// Print format string and its arguments to serial.
|
||||
/// Writes a string slice into the serial.
|
||||
pub fn serial_write_str(s: &str) {
|
||||
SERIAL_WRITER.lock().write_str(s).unwrap();
|
||||
}
|
||||
|
||||
/// Writes formatted data into the serial.
|
||||
pub fn serial_write_fmt(fmt: Arguments) {
|
||||
SERIAL_WRITER.lock().write_fmt(fmt).unwrap();
|
||||
}
|
||||
|
||||
/// Print format string and its arguments to serial.
|
||||
pub fn serial_write(s: &str) {
|
||||
SERIAL_WRITER.lock().write_str(s).unwrap();
|
||||
/// Writes a string slice into the graphic console.
|
||||
#[allow(unused_variables)]
|
||||
pub fn graphic_console_write_str(s: &str) {
|
||||
#[cfg(feature = "graphic")]
|
||||
if let Some(cons) = GRAPHIC_CONSOLE.try_get() {
|
||||
cons.lock().write_str(s).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
/// Print format string and its arguments to graphic console.
|
||||
/// Writes formatted data into the graphic console.
|
||||
#[allow(unused_variables)]
|
||||
pub fn graphic_console_write_fmt(fmt: Arguments) {
|
||||
#[cfg(feature = "graphic")]
|
||||
|
@ -60,32 +71,24 @@ pub fn graphic_console_write_fmt(fmt: Arguments) {
|
|||
}
|
||||
}
|
||||
|
||||
/// Print format string and its arguments to graphic console.
|
||||
#[allow(unused_variables)]
|
||||
pub fn graphic_console_write(s: &str) {
|
||||
#[cfg(feature = "graphic")]
|
||||
if let Some(cons) = GRAPHIC_CONSOLE.try_get() {
|
||||
cons.lock().write_str(s).unwrap();
|
||||
}
|
||||
/// Writes a string slice into the serial, and the graphic console if it exists.
|
||||
pub fn console_write_str(s: &str) {
|
||||
serial_write_str(s);
|
||||
graphic_console_write_str(s);
|
||||
}
|
||||
|
||||
/// Print format string and its arguments to serial and graphic console (if exists).
|
||||
/// Writes formatted data into the serial, and the graphic console if it exists.
|
||||
pub fn console_write_fmt(fmt: Arguments) {
|
||||
serial_write_fmt(fmt);
|
||||
graphic_console_write_fmt(fmt);
|
||||
}
|
||||
|
||||
/// Print a string to serial and graphic console (if exists).
|
||||
pub fn console_write(s: &str) {
|
||||
serial_write(s);
|
||||
graphic_console_write(s);
|
||||
}
|
||||
|
||||
/// Read buffer data from console (serial).
|
||||
pub async fn console_read(buf: &mut [u8]) -> usize {
|
||||
super::future::SerialReadFuture::new(buf).await
|
||||
}
|
||||
|
||||
/// The POSIX `winsize` structure.
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy, Default)]
|
||||
pub struct ConsoleWinSize {
|
||||
|
|
|
@ -10,6 +10,7 @@ pub struct HalError;
|
|||
pub type HalResult<T = ()> = core::result::Result<T, HalError>;
|
||||
|
||||
bitflags! {
|
||||
/// Generic memory flags.
|
||||
pub struct MMUFlags: usize {
|
||||
#[allow(clippy::identity_op)]
|
||||
const CACHE_1 = 1 << 0;
|
||||
|
@ -25,6 +26,7 @@ bitflags! {
|
|||
numeric_enum! {
|
||||
#[repr(u32)]
|
||||
#[derive(Debug, PartialEq, Clone, Copy)]
|
||||
/// Generic cache policy.
|
||||
pub enum CachePolicy {
|
||||
Cached = 0,
|
||||
Uncached = 1,
|
||||
|
@ -32,8 +34,8 @@ numeric_enum! {
|
|||
WriteCombining = 3,
|
||||
}
|
||||
}
|
||||
pub const CACHE_POLICY_MASK: u32 = 3;
|
||||
|
||||
/// The smallest size of a page (4K).
|
||||
pub const PAGE_SIZE: usize = super::vm::PageSize::Size4K as usize;
|
||||
|
||||
pub use super::addr::{DevVAddr, PhysAddr, VirtAddr};
|
||||
|
|
|
@ -2,6 +2,7 @@ use alloc::vec::Vec;
|
|||
|
||||
use crate::{PhysAddr, KHANDLER, PAGE_SIZE};
|
||||
|
||||
/// A 4K size physical frame.
|
||||
#[derive(Debug)]
|
||||
pub struct PhysFrame {
|
||||
paddr: PhysAddr,
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
//! Read/write user space pointer.
|
||||
|
||||
use alloc::string::String;
|
||||
use alloc::vec::Vec;
|
||||
use core::fmt::{Debug, Formatter};
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use crate::{addr::is_aligned, MMUFlags, PhysAddr, VirtAddr};
|
||||
|
||||
/// Errors may occur during address translation.
|
||||
#[derive(Debug)]
|
||||
pub enum PagingError {
|
||||
NoMemory,
|
||||
|
@ -7,9 +8,13 @@ pub enum PagingError {
|
|||
AlreadyMapped,
|
||||
}
|
||||
|
||||
/// Address translation result.
|
||||
pub type PagingResult<T = ()> = Result<T, PagingError>;
|
||||
|
||||
/// The [`PagingError::NotMapped`] can be ignored.
|
||||
pub trait IgnoreNotMappedErr {
|
||||
/// If self is `Err(PagingError::NotMapped`, ignores the error and returns
|
||||
/// `Ok(())`, otherwise remain unchanged.
|
||||
fn ignore(self) -> PagingResult;
|
||||
}
|
||||
|
||||
|
@ -22,6 +27,7 @@ impl<T> IgnoreNotMappedErr for PagingResult<T> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Possible page size (4K, 2M, 1G).
|
||||
#[repr(usize)]
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
||||
pub enum PageSize {
|
||||
|
@ -30,6 +36,7 @@ pub enum PageSize {
|
|||
Size1G = 0x4000_0000,
|
||||
}
|
||||
|
||||
/// A 4K, 2M or 1G size page.
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct Page {
|
||||
pub vaddr: VirtAddr,
|
||||
|
@ -61,6 +68,7 @@ impl Page {
|
|||
}
|
||||
}
|
||||
|
||||
/// A generic page table abstraction.
|
||||
pub trait GenericPageTable: Sync + Send {
|
||||
/// Get the physical address of root page table.
|
||||
fn table_phys(&self) -> PhysAddr;
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
//! Device drivers.
|
||||
|
||||
use alloc::{sync::Arc, vec::Vec};
|
||||
use core::convert::From;
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ use crate::drivers::prelude::{IrqHandler, IrqPolarity, IrqTriggerMode};
|
|||
use crate::{common, HalResult, KernelConfig, KernelHandler, MMUFlags, PhysAddr, VirtAddr};
|
||||
|
||||
hal_fn_def! {
|
||||
/// Bootstrap and initialization.
|
||||
pub mod boot {
|
||||
/// The kernel command line.
|
||||
pub fn cmdline() -> String { "".into() }
|
||||
|
@ -27,6 +28,7 @@ hal_fn_def! {
|
|||
pub fn secondary_init() {}
|
||||
}
|
||||
|
||||
/// CPU information.
|
||||
pub mod cpu {
|
||||
/// Current CPU ID.
|
||||
pub fn cpu_id() -> u8 { 0 }
|
||||
|
@ -35,6 +37,7 @@ hal_fn_def! {
|
|||
pub fn cpu_frequency() -> u16 { 3000 }
|
||||
}
|
||||
|
||||
/// Physical memory operations.
|
||||
pub mod mem: common::mem {
|
||||
/// Convert physical address to virtual address.
|
||||
pub(crate) fn phys_to_virt(paddr: PhysAddr) -> VirtAddr;
|
||||
|
@ -58,6 +61,7 @@ hal_fn_def! {
|
|||
pub fn frame_flush(target: PhysAddr);
|
||||
}
|
||||
|
||||
/// Virutal memory operations.
|
||||
pub mod vm: common::vm {
|
||||
/// Read current VM token. (e.g. CR3, SATP, ...)
|
||||
pub fn current_vmtoken() -> PhysAddr;
|
||||
|
@ -72,6 +76,7 @@ hal_fn_def! {
|
|||
pub(crate) fn pt_clone_kernel_space(dst_pt_root: PhysAddr, src_pt_root: PhysAddr);
|
||||
}
|
||||
|
||||
/// Interrupts management.
|
||||
pub mod interrupt {
|
||||
/// Suspend the CPU (also enable interrupts) and wait for an interrupt
|
||||
/// to occurs, then disable interrupts.
|
||||
|
@ -119,6 +124,7 @@ hal_fn_def! {
|
|||
pub(crate) fn console_write_early(_s: &str) {}
|
||||
}
|
||||
|
||||
/// Context switch.
|
||||
pub mod context: common::context {
|
||||
/// Enter user mode.
|
||||
pub fn context_run(context: &mut UserContext) {
|
||||
|
@ -139,6 +145,7 @@ hal_fn_def! {
|
|||
pub fn fetch_page_fault_info(info_reg: usize) -> (VirtAddr, MMUFlags);
|
||||
}
|
||||
|
||||
/// Thread spawning.
|
||||
pub mod thread: common::thread {
|
||||
/// Spawn a new thread.
|
||||
pub fn spawn(future: Pin<Box<dyn Future<Output = ()> + Send + 'static>>, vmtoken: usize);
|
||||
|
@ -146,10 +153,11 @@ hal_fn_def! {
|
|||
/// Set tid and pid of current task.
|
||||
pub fn set_tid(tid: u64, pid: u64);
|
||||
|
||||
/// Get tid and pid of current task.]
|
||||
/// Get tid and pid of current task.
|
||||
pub fn get_tid() -> (u64, u64);
|
||||
}
|
||||
|
||||
/// Time and clock functions.
|
||||
pub mod timer {
|
||||
/// Get current time.
|
||||
/// TODO: use `Instant` as return type.
|
||||
|
@ -168,6 +176,7 @@ hal_fn_def! {
|
|||
pub(crate) fn timer_tick();
|
||||
}
|
||||
|
||||
/// Random number generator.
|
||||
pub mod rand {
|
||||
/// Fill random bytes to the buffer
|
||||
#[allow(unused_variables)]
|
||||
|
@ -194,6 +203,7 @@ hal_fn_def! {
|
|||
}
|
||||
}
|
||||
|
||||
/// VDSO constants.
|
||||
pub mod vdso: common::vdso {
|
||||
/// Get platform specific information.
|
||||
pub fn vdso_constants() -> VdsoConstants {
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
use crate::{utils::init_once::InitOnce, MMUFlags, PhysAddr, VirtAddr};
|
||||
|
||||
/// Functions implemented in the kernel and used by HAL funtions.
|
||||
pub trait KernelHandler: Send + Sync + 'static {
|
||||
/// Allocate one physical frame.
|
||||
fn frame_alloc(&self) -> Option<PhysAddr> {
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
//! Bootstrap and initialization.
|
||||
|
||||
use crate::{KernelConfig, KernelHandler, KCONFIG, KHANDLER};
|
||||
|
||||
hal_fn_impl! {
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
/// Configuration of HAL.
|
||||
//! Kernel configuration.
|
||||
|
||||
/// Kernel configuration passed by kernel when calls [`crate::primary_init_early()`].
|
||||
#[derive(Debug)]
|
||||
pub struct KernelConfig;
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
//! Physical memory operations.
|
||||
|
||||
use alloc::vec::Vec;
|
||||
use core::ops::Range;
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
//! Functions only available on the libos mode.
|
||||
|
||||
#[cfg(feature = "graphic")]
|
||||
pub fn run_graphic_service() {
|
||||
use crate::drivers::{all_display, all_input};
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
//! Thread spawning.
|
||||
|
||||
use async_std::task_local;
|
||||
use core::{cell::Cell, future::Future, pin::Pin};
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
//! Time and clock functions.
|
||||
|
||||
use async_std::task;
|
||||
use std::time::{Duration, SystemTime};
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
//! VDSO constants.
|
||||
|
||||
hal_fn_impl! {
|
||||
impl mod crate::hal_fn::vdso {
|
||||
fn vdso_constants() -> VdsoConstants {
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
//! Virutal memory operations.
|
||||
|
||||
use super::mem::{MOCK_PHYS_MEM, PMEM_MAP_VADDR, PMEM_SIZE};
|
||||
use crate::{addr::is_aligned, MMUFlags, PhysAddr, VirtAddr, PAGE_SIZE};
|
||||
|
||||
|
@ -9,7 +11,7 @@ hal_fn_impl! {
|
|||
}
|
||||
}
|
||||
|
||||
/// Page Table
|
||||
/// Dummy page table implemented by `mmap`, `munmap`, and `mprotect`.
|
||||
pub struct PageTable;
|
||||
|
||||
impl PageTable {
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
macro_rules! hal_fn_def {
|
||||
(
|
||||
$(
|
||||
$(#[$inner:ident $($args:tt)*])*
|
||||
$vis:vis mod $mod_name:ident $( : $base:path )? {
|
||||
$($fn:tt)*
|
||||
}
|
||||
)+
|
||||
) => {
|
||||
$(
|
||||
$(#[$inner $($args)*])*
|
||||
$vis mod $mod_name {
|
||||
#![allow(unused_imports)]
|
||||
$( pub use $base::*; )?
|
||||
|
|
|
@ -152,7 +152,7 @@ impl INode for Stdout {
|
|||
fn write_at(&self, _offset: usize, buf: &[u8]) -> Result<usize> {
|
||||
// we do not care the utf-8 things, we just want to print it!
|
||||
let s = unsafe { core::str::from_utf8_unchecked(buf) };
|
||||
kernel_hal::console::console_write(s);
|
||||
kernel_hal::console::console_write_str(s);
|
||||
Ok(buf.len())
|
||||
}
|
||||
fn poll(&self) -> Result<PollStatus> {
|
||||
|
|
|
@ -6,7 +6,7 @@ impl Syscall<'_> {
|
|||
pub fn sys_debug_write(&self, buf: UserInPtr<u8>, len: usize) -> ZxResult {
|
||||
info!("debug.write: buf=({:?}; {:#x})", buf, len);
|
||||
let data = buf.read_array(len)?;
|
||||
kernel_hal::console::console_write(core::str::from_utf8(&data).unwrap());
|
||||
kernel_hal::console::console_write_str(core::str::from_utf8(&data).unwrap());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
|
@ -54,9 +54,9 @@ impl Syscall<'_> {
|
|||
let dlog = proc.get_object_with_rights::<DebugLog>(handle_value, Rights::WRITE)?;
|
||||
dlog.write(Severity::Info, options, self.thread.id(), proc.id(), &data);
|
||||
// print to kernel console
|
||||
kernel_hal::console::console_write(&data);
|
||||
kernel_hal::console::console_write_str(&data);
|
||||
if data.as_bytes().last() != Some(&b'\n') {
|
||||
kernel_hal::console::console_write("\n");
|
||||
kernel_hal::console::console_write_str("\n");
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue