forked from rcore-os/zCore
kernel_hal: add macros to generate default functions automatically
This commit is contained in:
parent
937c86f01d
commit
3b0e3296e8
|
@ -413,7 +413,7 @@ pub fn serial_read(buf: &mut [u8]) -> usize {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[export_name = "hal_serial_write"]
|
#[export_name = "hal_serial_write"]
|
||||||
pub fn serial_write(s: &str) {
|
pub fn print_str(s: &str) {
|
||||||
//putfmt(format_args!("{}", s));
|
//putfmt(format_args!("{}", s));
|
||||||
putfmt_uart(format_args!("{}", s));
|
putfmt_uart(format_args!("{}", s));
|
||||||
}
|
}
|
||||||
|
@ -631,8 +631,8 @@ pub fn init_framebuffer(width: u32, height: u32, addr: usize, size: usize) {
|
||||||
*FRAME_BUFFER.write() = Some(fb_info);
|
*FRAME_BUFFER.write() = Some(fb_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[export_name = "hal_mice_set_callback"]
|
#[export_name = "hal_mouse_set_callback"]
|
||||||
pub fn mice_set_callback(_callback: Box<dyn Fn([u8; 3]) + Send + Sync>) {
|
pub fn mouse_set_callback(_callback: Box<dyn Fn([u8; 3]) + Send + Sync>) {
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,8 +22,8 @@ lazy_static! {
|
||||||
Mutex::new(Vec::new());
|
Mutex::new(Vec::new());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[export_name = "hal_mice_set_callback"]
|
#[export_name = "hal_mouse_set_callback"]
|
||||||
pub fn mice_set_callback(callback: Box<dyn Fn([u8; 3]) + Send + Sync>) {
|
pub fn mouse_set_callback(callback: Box<dyn Fn([u8; 3]) + Send + Sync>) {
|
||||||
MOUSE_CALLBACK.lock().push(callback);
|
MOUSE_CALLBACK.lock().push(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -324,7 +324,7 @@ pub fn serial_read(buf: &mut [u8]) -> usize {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[export_name = "hal_serial_write"]
|
#[export_name = "hal_serial_write"]
|
||||||
pub fn serial_write(s: &str) {
|
pub fn print_str(s: &str) {
|
||||||
putfmt(format_args!("{}", s));
|
putfmt(format_args!("{}", s));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
//! Definition of phyical, virtual addresses and helper functions.
|
||||||
|
|
||||||
|
use crate::PAGE_SIZE;
|
||||||
|
|
||||||
|
pub type PhysAddr = usize;
|
||||||
|
pub type VirtAddr = usize;
|
||||||
|
pub type DevVAddr = usize;
|
||||||
|
|
||||||
|
pub const fn align_down(addr: usize) -> usize {
|
||||||
|
addr & !(PAGE_SIZE - 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const fn align_up(addr: usize) -> usize {
|
||||||
|
(addr + PAGE_SIZE - 1) & !(PAGE_SIZE - 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const fn is_aligned(addr: usize) -> bool {
|
||||||
|
page_offset(addr) == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const fn page_count(size: usize) -> usize {
|
||||||
|
align_up(size) / PAGE_SIZE
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const fn page_offset(addr: usize) -> usize {
|
||||||
|
addr & (PAGE_SIZE - 1)
|
||||||
|
}
|
|
@ -6,7 +6,7 @@ use numeric_enum_macro::numeric_enum;
|
||||||
pub struct HalError;
|
pub struct HalError;
|
||||||
|
|
||||||
/// The result type returned by HAL functions.
|
/// The result type returned by HAL functions.
|
||||||
pub type HalResult<T> = core::result::Result<T, HalError>;
|
pub type HalResult<T = ()> = core::result::Result<T, HalError>;
|
||||||
|
|
||||||
bitflags! {
|
bitflags! {
|
||||||
pub struct MMUFlags: usize {
|
pub struct MMUFlags: usize {
|
||||||
|
@ -32,7 +32,6 @@ numeric_enum! {
|
||||||
}
|
}
|
||||||
pub const CACHE_POLICY_MASK: u32 = 3;
|
pub const CACHE_POLICY_MASK: u32 = 3;
|
||||||
|
|
||||||
pub type PhysAddr = usize;
|
|
||||||
pub type VirtAddr = usize;
|
|
||||||
pub type DevVAddr = usize;
|
|
||||||
pub const PAGE_SIZE: usize = 0x1000;
|
pub const PAGE_SIZE: usize = 0x1000;
|
||||||
|
|
||||||
|
pub use super::addr::{DevVAddr, PhysAddr, VirtAddr};
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
pub(super) mod defs;
|
pub(super) mod defs;
|
||||||
pub(super) mod fb;
|
pub(super) mod fb;
|
||||||
|
|
||||||
|
pub mod addr;
|
||||||
pub mod context;
|
pub mod context;
|
||||||
pub mod future;
|
pub mod future;
|
||||||
pub mod memory;
|
pub mod memory;
|
||||||
pub mod paging;
|
pub mod paging;
|
||||||
pub mod user;
|
pub mod user;
|
||||||
pub mod vdso;
|
pub mod vdso;
|
||||||
|
|
||||||
pub use defs::*;
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use super::{HalResult, MMUFlags, PhysAddr, VirtAddr, PAGE_SIZE};
|
use crate::{HalResult, MMUFlags, PhysAddr, VirtAddr, PAGE_SIZE};
|
||||||
|
|
||||||
pub trait PageTableTrait: Sync + Send {
|
pub trait PageTableTrait: Sync + Send {
|
||||||
/// Map the page of `vaddr` to the frame of `paddr` with `flags`.
|
/// Map the page of `vaddr` to the frame of `paddr` with `flags`.
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use core::fmt::{Debug, Error, Formatter};
|
use core::fmt::{Debug, Error, Formatter};
|
||||||
|
use git_version::git_version;
|
||||||
|
|
||||||
/// This struct contains constants that are initialized by the kernel
|
/// This struct contains constants that are initialized by the kernel
|
||||||
/// once at boot time. From the vDSO code's perspective, they are
|
/// once at boot time. From the vDSO code's perspective, they are
|
||||||
|
@ -69,3 +70,28 @@ impl Debug for VersionString {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn vdso_constants_template() -> VdsoConstants {
|
||||||
|
let frequency = crate::cpu::cpu_frequency();
|
||||||
|
let mut constants = VdsoConstants {
|
||||||
|
max_num_cpus: 1,
|
||||||
|
features: Features {
|
||||||
|
cpu: 0,
|
||||||
|
hw_breakpoint_count: 0,
|
||||||
|
hw_watchpoint_count: 0,
|
||||||
|
},
|
||||||
|
dcache_line_size: 0,
|
||||||
|
icache_line_size: 0,
|
||||||
|
ticks_per_second: frequency as u64 * 1_000_000,
|
||||||
|
ticks_to_mono_numerator: 1000,
|
||||||
|
ticks_to_mono_denominator: frequency as u32,
|
||||||
|
physmem: 0,
|
||||||
|
version_string_len: 0,
|
||||||
|
version_string: Default::default(),
|
||||||
|
};
|
||||||
|
constants.set_version_string(git_version!(
|
||||||
|
prefix = "git-",
|
||||||
|
args = ["--always", "--abbrev=40", "--dirty=-dirty"]
|
||||||
|
));
|
||||||
|
constants
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,178 @@
|
||||||
|
use alloc::boxed::Box;
|
||||||
|
use core::{fmt::Arguments, future::Future, pin::Pin, time::Duration};
|
||||||
|
|
||||||
|
use crate::{common, PhysAddr, VirtAddr};
|
||||||
|
|
||||||
|
hal_fn_def! {
|
||||||
|
pub mod cpu {
|
||||||
|
/// Current CPU ID.
|
||||||
|
fn cpu_id() -> u8 { 0 }
|
||||||
|
|
||||||
|
/// Current CPU frequency.
|
||||||
|
fn cpu_frequency() -> u16 { 3000 }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub mod memory: common::memory {
|
||||||
|
/// Read physical memory from `paddr` to `buf`.
|
||||||
|
fn pmem_read(paddr: PhysAddr, buf: &mut [u8]);
|
||||||
|
|
||||||
|
/// Write physical memory to `paddr` from `buf`.
|
||||||
|
fn pmem_write(paddr: PhysAddr, buf: &[u8]);
|
||||||
|
|
||||||
|
/// Zero physical memory at `[paddr, paddr + len)`.
|
||||||
|
fn pmem_zero(paddr: PhysAddr, len: usize);
|
||||||
|
|
||||||
|
/// Copy content of `src` frame to `target` frame.
|
||||||
|
fn frame_copy(src: PhysAddr, target: PhysAddr);
|
||||||
|
|
||||||
|
/// Flush the physical frame.
|
||||||
|
fn frame_flush(target: PhysAddr);
|
||||||
|
|
||||||
|
/// Allocate one physical frame.
|
||||||
|
fn frame_alloc() -> Option<PhysAddr>;
|
||||||
|
|
||||||
|
/// Allocate contiguous physical frames of totally `size` bytes.
|
||||||
|
fn frame_alloc_contiguous(size: usize, align_log2: usize) -> Option<PhysAddr>;
|
||||||
|
|
||||||
|
/// Deallocate a physical frame.
|
||||||
|
fn frame_dealloc(paddr: PhysAddr);
|
||||||
|
|
||||||
|
/// Get the physical frame contains all zeros.
|
||||||
|
fn zero_frame_addr() -> PhysAddr;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub mod interrupt {
|
||||||
|
/// Enable IRQ.
|
||||||
|
fn enable_irq(vector: u32);
|
||||||
|
|
||||||
|
/// Disable IRQ.
|
||||||
|
fn disable_irq(vector: u32);
|
||||||
|
|
||||||
|
/// Is a valid IRQ number.
|
||||||
|
fn is_valid_irq(vector: u32) -> bool;
|
||||||
|
|
||||||
|
/// Configure the specified interrupt vector. If it is invoked, it muust be
|
||||||
|
/// invoked prior to interrupt registration.
|
||||||
|
fn configure_irq(vector: u32, trig_mode: bool, polarity: bool) -> bool;
|
||||||
|
|
||||||
|
/// Add an interrupt handle to an IRQ
|
||||||
|
fn register_irq_handler(vector: u32, handler: Box<dyn Fn() + Send + Sync>) -> Option<u32>;
|
||||||
|
|
||||||
|
/// Remove the interrupt handle to an IRQ
|
||||||
|
fn unregister_irq_handler(vector: u32) -> bool;
|
||||||
|
|
||||||
|
/// Handle IRQ.
|
||||||
|
fn handle_irq(vector: u32);
|
||||||
|
|
||||||
|
/// Method used for platform allocation of blocks of MSI and MSI-X compatible
|
||||||
|
/// IRQ targets.
|
||||||
|
fn msi_allocate_block(irq_num: u32) -> Option<(usize, usize)>;
|
||||||
|
|
||||||
|
/// Method used to free a block of MSI IRQs previously allocated by msi_alloc_block().
|
||||||
|
/// This does not unregister IRQ handlers.
|
||||||
|
fn msi_free_block(irq_start: u32, irq_num: u32);
|
||||||
|
|
||||||
|
/// Register a handler function for a given msi_id within an msi_block_t. Passing a
|
||||||
|
/// NULL handler will effectively unregister a handler for a given msi_id within the
|
||||||
|
/// block.
|
||||||
|
fn msi_register_handler(irq_start: u32, irq_num: u32, msi_id: u32, handler: Box<dyn Fn() + Send + Sync>);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub mod context: common::context {
|
||||||
|
/// Enter user mode.
|
||||||
|
fn context_run(context: &mut UserContext);
|
||||||
|
|
||||||
|
/// Get fault address of the last page fault.
|
||||||
|
fn fetch_fault_vaddr() -> VirtAddr;
|
||||||
|
|
||||||
|
/// Get the trap number when trap.
|
||||||
|
fn fetch_trap_num(context: &UserContext) -> usize;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub mod thread {
|
||||||
|
/// Spawn a new thread.
|
||||||
|
fn spawn(future: Pin<Box<dyn Future<Output = ()> + Send + 'static>>, vmtoken: usize);
|
||||||
|
|
||||||
|
/// Set tid and pid of current task.
|
||||||
|
fn set_tid(tid: u64, pid: u64);
|
||||||
|
|
||||||
|
/// Get tid and pid of current task.]
|
||||||
|
fn get_tid() -> (u64, u64);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub mod timer {
|
||||||
|
/// Get current time.
|
||||||
|
fn timer_now() -> Duration;
|
||||||
|
|
||||||
|
/// Set a new timer. After `deadline`, the `callback` will be called.
|
||||||
|
fn timer_set(deadline: Duration, callback: Box<dyn FnOnce(Duration) + Send + Sync>);
|
||||||
|
|
||||||
|
/// Check timers, call when timer interrupt happened.
|
||||||
|
fn timer_tick();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub mod serial {
|
||||||
|
/// Register a callback of serial readable event.
|
||||||
|
fn serial_set_callback(callback: Box<dyn Fn() -> bool + Send + Sync>);
|
||||||
|
|
||||||
|
/// Put a char to serial buffer.
|
||||||
|
fn serial_put(x: u8);
|
||||||
|
|
||||||
|
/// Read a string from serial buffer.
|
||||||
|
fn serial_read(buf: &mut [u8]) -> usize;
|
||||||
|
|
||||||
|
/// Print format string and its arguments to console.
|
||||||
|
fn print_fmt(fmt: Arguments);
|
||||||
|
|
||||||
|
/// Print a string to console.
|
||||||
|
fn print_str(s: &str) {
|
||||||
|
print_fmt(format_args!("{}", s));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub mod rand {
|
||||||
|
/// Fill random bytes to the buffer
|
||||||
|
#[allow(unused_variables)]
|
||||||
|
fn fill_random(buf: &mut [u8]) {
|
||||||
|
cfg_if::cfg_if! {
|
||||||
|
if #[cfg(target_arch = "x86_64")] {
|
||||||
|
// TODO: optimize
|
||||||
|
for x in buf.iter_mut() {
|
||||||
|
let mut r = 0;
|
||||||
|
unsafe {
|
||||||
|
core::arch::x86_64::_rdrand16_step(&mut r);
|
||||||
|
}
|
||||||
|
*x = r as _;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub mod vdso: common::vdso {
|
||||||
|
/// Get platform specific information.
|
||||||
|
fn vdso_constants() -> VdsoConstants;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub mod dev {
|
||||||
|
hal_fn_def! {
|
||||||
|
pub mod fb: crate::common::fb {
|
||||||
|
/// Initialize framebuffer.
|
||||||
|
fn init();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub mod input {
|
||||||
|
/// Initialize input devices.
|
||||||
|
fn init();
|
||||||
|
|
||||||
|
/// Setup the callback when a keyboard event occurs.
|
||||||
|
fn kbd_set_callback(callback: Box<dyn Fn(u16, i32) + Send + Sync>);
|
||||||
|
|
||||||
|
/// Setup the callback when a mouse event occurs.
|
||||||
|
fn mouse_set_callback(callback: Box<dyn Fn([u8; 3]) + Send + Sync>);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,18 +6,23 @@
|
||||||
|
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
|
|
||||||
mod common;
|
#[macro_use]
|
||||||
|
extern crate log;
|
||||||
|
|
||||||
pub use common::{defs::*, future, user};
|
#[macro_use]
|
||||||
|
mod macros;
|
||||||
|
|
||||||
|
mod common;
|
||||||
|
mod defs;
|
||||||
|
|
||||||
|
pub use common::{addr, defs::*, future, user};
|
||||||
|
|
||||||
cfg_if::cfg_if! {
|
cfg_if::cfg_if! {
|
||||||
if #[cfg(feature = "libos")] {
|
if #[cfg(feature = "libos")] {
|
||||||
#[macro_use]
|
|
||||||
extern crate log;
|
|
||||||
mod libos;
|
mod libos;
|
||||||
pub use self::libos::*;
|
pub use self::libos::*;
|
||||||
} else {
|
} else {
|
||||||
mod unimp;
|
mod libos;
|
||||||
pub use self::unimp::*;
|
pub use self::libos::*;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +1,9 @@
|
||||||
pub use crate::common::context::*;
|
|
||||||
|
|
||||||
pub use trapframe::syscall_fn_entry as syscall_entry;
|
pub use trapframe::syscall_fn_entry as syscall_entry;
|
||||||
|
|
||||||
pub fn context_run(context: &mut UserContext) {
|
hal_fn_impl! {
|
||||||
context.run_fncall();
|
impl mod crate::defs::context {
|
||||||
}
|
fn context_run(context: &mut UserContext) {
|
||||||
|
context.run_fncall();
|
||||||
/// Get fault address of the last page fault.
|
}
|
||||||
pub fn fetch_fault_vaddr() -> crate::VirtAddr {
|
}
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get the trap number when trap.
|
|
||||||
pub fn fetch_trap_num(_context: &UserContext) -> usize {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
pub fn u8() -> u8 {
|
|
||||||
0
|
|
||||||
}
|
|
|
@ -74,59 +74,63 @@ struct FbBitfield {
|
||||||
msb_right: u32,
|
msb_right: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn init() {
|
hal_fn_impl! {
|
||||||
const FBIOGET_VSCREENINFO: u64 = 0x4600;
|
impl mod crate::defs::dev::fb {
|
||||||
const FBIOGET_FSCREENINFO: u64 = 0x4602;
|
fn init() {
|
||||||
|
const FBIOGET_VSCREENINFO: u64 = 0x4600;
|
||||||
|
const FBIOGET_FSCREENINFO: u64 = 0x4602;
|
||||||
|
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
let fbfd = unsafe { libc::open("/dev/fb0".as_ptr(), libc::O_RDWR) };
|
let fbfd = unsafe { libc::open("/dev/fb0".as_ptr(), libc::O_RDWR) };
|
||||||
#[cfg(not(target_arch = "aarch64"))]
|
#[cfg(not(target_arch = "aarch64"))]
|
||||||
let fbfd = unsafe { libc::open("/dev/fb0".as_ptr() as *const i8, libc::O_RDWR) };
|
let fbfd = unsafe { libc::open("/dev/fb0".as_ptr() as *const i8, libc::O_RDWR) };
|
||||||
if fbfd < 0 {
|
if fbfd < 0 {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut vinfo = FbVarScreeninfo::default();
|
||||||
|
if unsafe { libc::ioctl(fbfd, FBIOGET_VSCREENINFO, &mut vinfo) } < 0 {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut finfo = FbFixScreeninfo::default();
|
||||||
|
if unsafe { libc::ioctl(fbfd, FBIOGET_FSCREENINFO, &mut finfo) } < 0 {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let size = finfo.size() as usize;
|
||||||
|
let addr = unsafe {
|
||||||
|
libc::mmap(
|
||||||
|
std::ptr::null_mut::<libc::c_void>(),
|
||||||
|
size,
|
||||||
|
libc::PROT_READ | libc::PROT_WRITE,
|
||||||
|
libc::MAP_SHARED,
|
||||||
|
fbfd,
|
||||||
|
0,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
if (addr as isize) < 0 {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let (width, height) = vinfo.resolution();
|
||||||
|
let addr = addr as usize;
|
||||||
|
|
||||||
|
let fb_info = FramebufferInfo {
|
||||||
|
xres: width,
|
||||||
|
yres: height,
|
||||||
|
xres_virtual: width,
|
||||||
|
yres_virtual: height,
|
||||||
|
xoffset: 0,
|
||||||
|
yoffset: 0,
|
||||||
|
depth: ColorDepth::ColorDepth32,
|
||||||
|
format: ColorFormat::RGBA8888,
|
||||||
|
// paddr: virt_to_phys(addr),
|
||||||
|
paddr: addr,
|
||||||
|
vaddr: addr,
|
||||||
|
screen_size: size,
|
||||||
|
};
|
||||||
|
*FRAME_BUFFER.write() = Some(fb_info);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut vinfo = FbVarScreeninfo::default();
|
|
||||||
if unsafe { libc::ioctl(fbfd, FBIOGET_VSCREENINFO, &mut vinfo) } < 0 {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut finfo = FbFixScreeninfo::default();
|
|
||||||
if unsafe { libc::ioctl(fbfd, FBIOGET_FSCREENINFO, &mut finfo) } < 0 {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let size = finfo.size() as usize;
|
|
||||||
let addr = unsafe {
|
|
||||||
libc::mmap(
|
|
||||||
std::ptr::null_mut::<libc::c_void>(),
|
|
||||||
size,
|
|
||||||
libc::PROT_READ | libc::PROT_WRITE,
|
|
||||||
libc::MAP_SHARED,
|
|
||||||
fbfd,
|
|
||||||
0,
|
|
||||||
)
|
|
||||||
};
|
|
||||||
if (addr as isize) < 0 {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let (width, height) = vinfo.resolution();
|
|
||||||
let addr = addr as usize;
|
|
||||||
|
|
||||||
let fb_info = FramebufferInfo {
|
|
||||||
xres: width,
|
|
||||||
yres: height,
|
|
||||||
xres_virtual: width,
|
|
||||||
yres_virtual: height,
|
|
||||||
xoffset: 0,
|
|
||||||
yoffset: 0,
|
|
||||||
depth: ColorDepth::ColorDepth32,
|
|
||||||
format: ColorFormat::RGBA8888,
|
|
||||||
// paddr: virt_to_phys(addr),
|
|
||||||
paddr: addr,
|
|
||||||
vaddr: addr,
|
|
||||||
screen_size: size,
|
|
||||||
};
|
|
||||||
*FRAME_BUFFER.write() = Some(fb_info);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,15 +82,19 @@ fn init_mice() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mice_set_callback(callback: Box<dyn Fn([u8; 3]) + Send + Sync>) {
|
hal_fn_impl! {
|
||||||
MOUSE_CALLBACK.lock().unwrap().push(callback);
|
impl mod crate::defs::dev::input {
|
||||||
}
|
fn kbd_set_callback(callback: Box<dyn Fn(u16, i32) + Send + Sync>) {
|
||||||
|
KBD_CALLBACK.lock().unwrap().push(callback);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn kbd_set_callback(callback: Box<dyn Fn(u16, i32) + Send + Sync>) {
|
fn mouse_set_callback(callback: Box<dyn Fn([u8; 3]) + Send + Sync>) {
|
||||||
KBD_CALLBACK.lock().unwrap().push(callback);
|
MOUSE_CALLBACK.lock().unwrap().push(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn init() {
|
fn init() {
|
||||||
init_kbd();
|
init_kbd();
|
||||||
init_mice();
|
init_mice();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,69 +1,71 @@
|
||||||
use super::mem_common::{ensure_mmap_pmem, phys_to_virt, AVAILABLE_FRAMES, PMEM_SIZE};
|
use super::mem_common::{ensure_mmap_pmem, phys_to_virt, AVAILABLE_FRAMES, PMEM_SIZE};
|
||||||
use crate::{PhysAddr, PAGE_SIZE};
|
use crate::{PhysAddr, PAGE_SIZE};
|
||||||
|
|
||||||
pub use crate::common::memory::*;
|
hal_fn_impl! {
|
||||||
|
impl mod crate::defs::memory {
|
||||||
|
/// Read physical memory from `paddr` to `buf`.
|
||||||
|
fn pmem_read(paddr: PhysAddr, buf: &mut [u8]) {
|
||||||
|
trace!("pmem read: paddr={:#x}, len={:#x}", paddr, buf.len());
|
||||||
|
assert!(paddr + buf.len() <= PMEM_SIZE);
|
||||||
|
ensure_mmap_pmem();
|
||||||
|
unsafe {
|
||||||
|
(phys_to_virt(paddr) as *const u8).copy_to_nonoverlapping(buf.as_mut_ptr(), buf.len());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Read physical memory from `paddr` to `buf`.
|
/// Write physical memory to `paddr` from `buf`.
|
||||||
pub fn pmem_read(paddr: PhysAddr, buf: &mut [u8]) {
|
fn pmem_write(paddr: PhysAddr, buf: &[u8]) {
|
||||||
trace!("pmem read: paddr={:#x}, len={:#x}", paddr, buf.len());
|
trace!("pmem write: paddr={:#x}, len={:#x}", paddr, buf.len());
|
||||||
assert!(paddr + buf.len() <= PMEM_SIZE);
|
assert!(paddr + buf.len() <= PMEM_SIZE);
|
||||||
ensure_mmap_pmem();
|
ensure_mmap_pmem();
|
||||||
unsafe {
|
unsafe {
|
||||||
(phys_to_virt(paddr) as *const u8).copy_to_nonoverlapping(buf.as_mut_ptr(), buf.len());
|
buf.as_ptr()
|
||||||
|
.copy_to_nonoverlapping(phys_to_virt(paddr) as _, buf.len());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Zero physical memory at `[paddr, paddr + len)`
|
||||||
|
fn pmem_zero(paddr: PhysAddr, len: usize) {
|
||||||
|
trace!("pmem_zero: addr={:#x}, len={:#x}", paddr, len);
|
||||||
|
assert!(paddr + len <= PMEM_SIZE);
|
||||||
|
ensure_mmap_pmem();
|
||||||
|
unsafe {
|
||||||
|
core::ptr::write_bytes(phys_to_virt(paddr) as *mut u8, 0, len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Copy content of `src` frame to `target` frame
|
||||||
|
fn frame_copy(src: PhysAddr, target: PhysAddr) {
|
||||||
|
trace!("frame_copy: {:#x} <- {:#x}", target, src);
|
||||||
|
assert!(src + PAGE_SIZE <= PMEM_SIZE && target + PAGE_SIZE <= PMEM_SIZE);
|
||||||
|
ensure_mmap_pmem();
|
||||||
|
unsafe {
|
||||||
|
let buf = phys_to_virt(src) as *const u8;
|
||||||
|
buf.copy_to_nonoverlapping(phys_to_virt(target) as _, PAGE_SIZE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn frame_flush(_target: PhysAddr) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
fn frame_alloc() -> Option<PhysAddr> {
|
||||||
|
let ret = AVAILABLE_FRAMES.lock().unwrap().pop_front();
|
||||||
|
trace!("frame alloc: {:?}", ret);
|
||||||
|
ret
|
||||||
|
}
|
||||||
|
|
||||||
|
fn frame_alloc_contiguous(_size: usize, _align_log2: usize) -> Option<PhysAddr> {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn frame_dealloc(paddr: PhysAddr) {
|
||||||
|
trace!("frame dealloc: {:?}", paddr);
|
||||||
|
AVAILABLE_FRAMES.lock().unwrap().push_back(paddr);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn zero_frame_addr() -> PhysAddr {
|
||||||
|
0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Write physical memory to `paddr` from `buf`.
|
|
||||||
pub fn pmem_write(paddr: PhysAddr, buf: &[u8]) {
|
|
||||||
trace!("pmem write: paddr={:#x}, len={:#x}", paddr, buf.len());
|
|
||||||
assert!(paddr + buf.len() <= PMEM_SIZE);
|
|
||||||
ensure_mmap_pmem();
|
|
||||||
unsafe {
|
|
||||||
buf.as_ptr()
|
|
||||||
.copy_to_nonoverlapping(phys_to_virt(paddr) as _, buf.len());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Zero physical memory at `[paddr, paddr + len)`
|
|
||||||
pub fn pmem_zero(paddr: PhysAddr, len: usize) {
|
|
||||||
trace!("pmem_zero: addr={:#x}, len={:#x}", paddr, len);
|
|
||||||
assert!(paddr + len <= PMEM_SIZE);
|
|
||||||
ensure_mmap_pmem();
|
|
||||||
unsafe {
|
|
||||||
core::ptr::write_bytes(phys_to_virt(paddr) as *mut u8, 0, len);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Copy content of `src` frame to `target` frame
|
|
||||||
pub fn frame_copy(src: PhysAddr, target: PhysAddr) {
|
|
||||||
trace!("frame_copy: {:#x} <- {:#x}", target, src);
|
|
||||||
assert!(src + PAGE_SIZE <= PMEM_SIZE && target + PAGE_SIZE <= PMEM_SIZE);
|
|
||||||
ensure_mmap_pmem();
|
|
||||||
unsafe {
|
|
||||||
let buf = phys_to_virt(src) as *const u8;
|
|
||||||
buf.copy_to_nonoverlapping(phys_to_virt(target) as _, PAGE_SIZE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn frame_flush(_target: PhysAddr) {
|
|
||||||
// do nothing
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn frame_alloc() -> Option<PhysAddr> {
|
|
||||||
let ret = AVAILABLE_FRAMES.lock().unwrap().pop_front();
|
|
||||||
trace!("frame alloc: {:?}", ret);
|
|
||||||
ret
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn frame_alloc_contiguous(_size: usize, _align_log2: usize) -> Option<PhysAddr> {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn frame_dealloc(paddr: PhysAddr) {
|
|
||||||
trace!("frame dealloc: {:?}", paddr);
|
|
||||||
AVAILABLE_FRAMES.lock().unwrap().push_back(paddr);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn zero_frame_addr() -> PhysAddr {
|
|
||||||
0
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
mod mem_common;
|
mod mem_common;
|
||||||
|
|
||||||
pub mod context;
|
pub mod context;
|
||||||
pub mod cpu;
|
|
||||||
pub mod memory;
|
pub mod memory;
|
||||||
pub mod paging;
|
pub mod paging;
|
||||||
pub mod serial;
|
pub mod serial;
|
||||||
|
@ -9,17 +8,16 @@ pub mod thread;
|
||||||
pub mod timer;
|
pub mod timer;
|
||||||
pub mod vdso;
|
pub mod vdso;
|
||||||
|
|
||||||
#[path = "../unimp/interrupt.rs"]
|
pub use super::defs::{cpu, interrupt, rand};
|
||||||
pub mod interrupt;
|
|
||||||
#[path = "../unimp/rand.rs"]
|
hal_fn_impl_default!(rand, interrupt, cpu);
|
||||||
pub mod rand;
|
|
||||||
|
|
||||||
cfg_if::cfg_if! {
|
cfg_if::cfg_if! {
|
||||||
if #[cfg(target_os = "linux")] {
|
if #[cfg(target_os = "linux")] {
|
||||||
pub mod dev;
|
pub mod dev;
|
||||||
} else {
|
} else {
|
||||||
#[path = "../unimp/dev/mod.rs"]
|
pub use super::defs::dev;
|
||||||
pub mod dev;
|
hal_fn_impl_default!(dev::fb, dev::input);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,8 +41,3 @@ pub fn init() {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME
|
|
||||||
#[path = "../unimp/misc.rs"]
|
|
||||||
mod misc;
|
|
||||||
pub use misc::*;
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ use std::io::Error;
|
||||||
use std::os::unix::io::AsRawFd;
|
use std::os::unix::io::AsRawFd;
|
||||||
|
|
||||||
use super::mem_common::{mmap, FRAME_FILE};
|
use super::mem_common::{mmap, FRAME_FILE};
|
||||||
use crate::{HalResult, MMUFlags, PhysAddr, VirtAddr, PAGE_SIZE};
|
use crate::{addr::is_aligned, HalResult, MMUFlags, PhysAddr, VirtAddr, PAGE_SIZE};
|
||||||
|
|
||||||
pub use crate::common::paging::*;
|
pub use crate::common::paging::*;
|
||||||
|
|
||||||
|
@ -22,8 +22,8 @@ impl PageTable {
|
||||||
impl PageTableTrait for PageTable {
|
impl PageTableTrait for PageTable {
|
||||||
/// Map the page of `vaddr` to the frame of `paddr` with `flags`.
|
/// Map the page of `vaddr` to the frame of `paddr` with `flags`.
|
||||||
fn map(&mut self, vaddr: VirtAddr, paddr: PhysAddr, flags: MMUFlags) -> HalResult<()> {
|
fn map(&mut self, vaddr: VirtAddr, paddr: PhysAddr, flags: MMUFlags) -> HalResult<()> {
|
||||||
debug_assert!(page_aligned(vaddr));
|
debug_assert!(is_aligned(vaddr));
|
||||||
debug_assert!(page_aligned(paddr));
|
debug_assert!(is_aligned(paddr));
|
||||||
let prot = flags.to_mmap_prot();
|
let prot = flags.to_mmap_prot();
|
||||||
mmap(FRAME_FILE.as_raw_fd(), paddr, PAGE_SIZE, vaddr, prot);
|
mmap(FRAME_FILE.as_raw_fd(), paddr, PAGE_SIZE, vaddr, prot);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -36,7 +36,7 @@ impl PageTableTrait for PageTable {
|
||||||
|
|
||||||
/// Change the `flags` of the page of `vaddr`.
|
/// Change the `flags` of the page of `vaddr`.
|
||||||
fn protect(&mut self, vaddr: VirtAddr, flags: MMUFlags) -> HalResult<()> {
|
fn protect(&mut self, vaddr: VirtAddr, flags: MMUFlags) -> HalResult<()> {
|
||||||
debug_assert!(page_aligned(vaddr));
|
debug_assert!(is_aligned(vaddr));
|
||||||
let prot = flags.to_mmap_prot();
|
let prot = flags.to_mmap_prot();
|
||||||
let ret = unsafe { libc::mprotect(vaddr as _, PAGE_SIZE, prot) };
|
let ret = unsafe { libc::mprotect(vaddr as _, PAGE_SIZE, prot) };
|
||||||
assert_eq!(ret, 0, "failed to mprotect: {:?}", Error::last_os_error());
|
assert_eq!(ret, 0, "failed to mprotect: {:?}", Error::last_os_error());
|
||||||
|
@ -45,7 +45,7 @@ impl PageTableTrait for PageTable {
|
||||||
|
|
||||||
/// Query the physical address which the page of `vaddr` maps to.
|
/// Query the physical address which the page of `vaddr` maps to.
|
||||||
fn query(&mut self, vaddr: VirtAddr) -> HalResult<PhysAddr> {
|
fn query(&mut self, vaddr: VirtAddr) -> HalResult<PhysAddr> {
|
||||||
debug_assert!(page_aligned(vaddr));
|
debug_assert!(is_aligned(vaddr));
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,17 +58,13 @@ impl PageTableTrait for PageTable {
|
||||||
if pages == 0 {
|
if pages == 0 {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
debug_assert!(page_aligned(vaddr));
|
debug_assert!(is_aligned(vaddr));
|
||||||
let ret = unsafe { libc::munmap(vaddr as _, PAGE_SIZE * pages) };
|
let ret = unsafe { libc::munmap(vaddr as _, PAGE_SIZE * pages) };
|
||||||
assert_eq!(ret, 0, "failed to munmap: {:?}", Error::last_os_error());
|
assert_eq!(ret, 0, "failed to munmap: {:?}", Error::last_os_error());
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn page_aligned(x: VirtAddr) -> bool {
|
|
||||||
x % PAGE_SIZE == 0
|
|
||||||
}
|
|
||||||
|
|
||||||
trait FlagsExt {
|
trait FlagsExt {
|
||||||
fn to_mmap_prot(&self) -> libc::c_int;
|
fn to_mmap_prot(&self) -> libc::c_int;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,26 +8,28 @@ lazy_static! {
|
||||||
Mutex::new(Vec::new());
|
Mutex::new(Vec::new());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Put a char by serial interrupt handler.
|
hal_fn_impl! {
|
||||||
pub fn serial_put(x: u8) {
|
impl mod crate::defs::serial {
|
||||||
STDIN.lock().unwrap().push_back(x);
|
fn serial_put(x: u8) {
|
||||||
STDIN_CALLBACK.lock().unwrap().retain(|f| !f());
|
STDIN.lock().unwrap().push_back(x);
|
||||||
}
|
STDIN_CALLBACK.lock().unwrap().retain(|f| !f());
|
||||||
|
}
|
||||||
|
|
||||||
pub fn serial_set_callback(callback: Box<dyn Fn() -> bool + Send + Sync>) {
|
fn serial_set_callback(callback: Box<dyn Fn() -> bool + Send + Sync>) {
|
||||||
STDIN_CALLBACK.lock().unwrap().push(callback);
|
STDIN_CALLBACK.lock().unwrap().push(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn serial_read(buf: &mut [u8]) -> usize {
|
fn serial_read(buf: &mut [u8]) -> usize {
|
||||||
let mut stdin = STDIN.lock().unwrap();
|
let mut stdin = STDIN.lock().unwrap();
|
||||||
let len = stdin.len().min(buf.len());
|
let len = stdin.len().min(buf.len());
|
||||||
for c in &mut buf[..len] {
|
for c in &mut buf[..len] {
|
||||||
*c = stdin.pop_front().unwrap();
|
*c = stdin.pop_front().unwrap();
|
||||||
|
}
|
||||||
|
len
|
||||||
|
}
|
||||||
|
|
||||||
|
fn print_fmt(fmt: core::fmt::Arguments) {
|
||||||
|
eprint!("{}", fmt);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
len
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Output a char to console.
|
|
||||||
pub fn serial_write(s: &str) {
|
|
||||||
eprint!("{}", s);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,15 +6,19 @@ task_local! {
|
||||||
static PID: Cell<u64> = Cell::new(0);
|
static PID: Cell<u64> = Cell::new(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn spawn(future: Pin<Box<dyn Future<Output = ()> + Send + 'static>>, _vmtoken: usize) {
|
hal_fn_impl! {
|
||||||
async_std::task::spawn(future);
|
impl mod crate::defs::thread {
|
||||||
}
|
fn spawn(future: Pin<Box<dyn Future<Output = ()> + Send + 'static>>, _vmtoken: usize) {
|
||||||
|
async_std::task::spawn(future);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn set_tid(tid: u64, pid: u64) {
|
fn set_tid(tid: u64, pid: u64) {
|
||||||
TID.with(|x| x.set(tid));
|
TID.with(|x| x.set(tid));
|
||||||
PID.with(|x| x.set(pid));
|
PID.with(|x| x.set(pid));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_tid() -> (u64, u64) {
|
fn get_tid() -> (u64, u64) {
|
||||||
(TID.with(|x| x.get()), PID.with(|x| x.get()))
|
(TID.with(|x| x.get()), PID.with(|x| x.get()))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,21 +1,25 @@
|
||||||
use std::time::{Duration, SystemTime};
|
use std::time::{Duration, SystemTime};
|
||||||
|
|
||||||
/// Get current time.
|
hal_fn_impl! {
|
||||||
pub fn timer_now() -> Duration {
|
impl mod crate::defs::timer {
|
||||||
SystemTime::now()
|
/// Get current time.
|
||||||
.duration_since(SystemTime::UNIX_EPOCH)
|
fn timer_now() -> Duration {
|
||||||
.unwrap()
|
SystemTime::now()
|
||||||
}
|
.duration_since(SystemTime::UNIX_EPOCH)
|
||||||
|
.unwrap()
|
||||||
/// Set a new timer.
|
|
||||||
///
|
|
||||||
/// After `deadline`, the `callback` will be called.
|
|
||||||
pub fn timer_set(deadline: Duration, callback: Box<dyn FnOnce(Duration) + Send + Sync>) {
|
|
||||||
std::thread::spawn(move || {
|
|
||||||
let now = timer_now();
|
|
||||||
if deadline > now {
|
|
||||||
std::thread::sleep(deadline - now);
|
|
||||||
}
|
}
|
||||||
callback(timer_now());
|
|
||||||
});
|
/// Set a new timer.
|
||||||
|
///
|
||||||
|
/// After `deadline`, the `callback` will be called.
|
||||||
|
fn timer_set(deadline: Duration, callback: Box<dyn FnOnce(Duration) + Send + Sync>) {
|
||||||
|
std::thread::spawn(move || {
|
||||||
|
let now = timer_now();
|
||||||
|
if deadline > now {
|
||||||
|
std::thread::sleep(deadline - now);
|
||||||
|
}
|
||||||
|
callback(timer_now());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,30 +1,9 @@
|
||||||
use git_version::git_version;
|
hal_fn_impl! {
|
||||||
|
impl mod crate::defs::vdso {
|
||||||
use super::mem_common::PMEM_SIZE;
|
fn vdso_constants() -> VdsoConstants {
|
||||||
|
let mut constants = vdso_constants_template();
|
||||||
pub use crate::common::vdso::*;
|
constants.physmem = super::mem_common::PMEM_SIZE as u64;
|
||||||
|
constants
|
||||||
pub fn vdso_constants() -> VdsoConstants {
|
}
|
||||||
let tsc_frequency = 3000u16;
|
}
|
||||||
let mut constants = VdsoConstants {
|
|
||||||
max_num_cpus: 1,
|
|
||||||
features: Features {
|
|
||||||
cpu: 0,
|
|
||||||
hw_breakpoint_count: 0,
|
|
||||||
hw_watchpoint_count: 0,
|
|
||||||
},
|
|
||||||
dcache_line_size: 0,
|
|
||||||
icache_line_size: 0,
|
|
||||||
ticks_per_second: tsc_frequency as u64 * 1_000_000,
|
|
||||||
ticks_to_mono_numerator: 1000,
|
|
||||||
ticks_to_mono_denominator: tsc_frequency as u32,
|
|
||||||
physmem: PMEM_SIZE as u64,
|
|
||||||
version_string_len: 0,
|
|
||||||
version_string: Default::default(),
|
|
||||||
};
|
|
||||||
constants.set_version_string(git_version!(
|
|
||||||
prefix = "git-",
|
|
||||||
args = ["--always", "--abbrev=40", "--dirty=-dirty"]
|
|
||||||
));
|
|
||||||
constants
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,167 @@
|
||||||
|
macro_rules! hal_fn_def {
|
||||||
|
(
|
||||||
|
$(
|
||||||
|
$vis:vis mod $mod_name:ident $( : $base:path )? {
|
||||||
|
$($fn:tt)*
|
||||||
|
}
|
||||||
|
)+
|
||||||
|
) => {
|
||||||
|
$(
|
||||||
|
$vis mod $mod_name {
|
||||||
|
#![allow(unused_imports)]
|
||||||
|
$( pub use $base::*; )?
|
||||||
|
use super::*;
|
||||||
|
pub(crate) trait __HalTrait {
|
||||||
|
__hal_fn_default_imp! {
|
||||||
|
$($fn)*
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub(crate) struct __HalImpl;
|
||||||
|
__hal_fn_export! {
|
||||||
|
$($fn)*
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)+
|
||||||
|
};
|
||||||
|
() => {};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! hal_fn_impl {
|
||||||
|
(
|
||||||
|
$(
|
||||||
|
impl mod $mod_name:ident$(::$mod_name_more:ident)* {
|
||||||
|
$($fn:item)*
|
||||||
|
}
|
||||||
|
)+
|
||||||
|
) => {
|
||||||
|
$(
|
||||||
|
__hal_fn_impl_no_export! {
|
||||||
|
impl mod $mod_name$(::$mod_name_more)* {
|
||||||
|
$($fn)*
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub use $mod_name$(::$mod_name_more)*::*;
|
||||||
|
)+
|
||||||
|
};
|
||||||
|
() => {};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! hal_fn_impl_default {
|
||||||
|
(
|
||||||
|
$( $mod_name:ident$(::$mod_name_more:ident)* ),*
|
||||||
|
) => {
|
||||||
|
__hal_fn_impl_no_export! {
|
||||||
|
$( impl mod $mod_name$(::$mod_name_more)* {} )*
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! __hal_fn_default_imp {
|
||||||
|
(
|
||||||
|
$(#[$inner:ident $($args:tt)*])*
|
||||||
|
fn $fn:ident ( $($arg:ident : $type:ty),* ) $( -> $ret:ty )?;
|
||||||
|
$($tail:tt)*
|
||||||
|
) => {
|
||||||
|
$(#[$inner $($args)*])*
|
||||||
|
#[allow(unused_variables)]
|
||||||
|
fn $fn ( $($arg : $type),* ) $( -> $ret )? {
|
||||||
|
unimplemented!();
|
||||||
|
}
|
||||||
|
__hal_fn_default_imp! {
|
||||||
|
$($tail)*
|
||||||
|
}
|
||||||
|
};
|
||||||
|
(
|
||||||
|
$(#[$inner:ident $($args:tt)*])*
|
||||||
|
fn $fn:ident ( $($arg:ident : $type:ty),* ) $( -> $ret:ty )? $body:block
|
||||||
|
$($tail:tt)*
|
||||||
|
) => {
|
||||||
|
$(#[$inner $($args)*])*
|
||||||
|
fn $fn ( $($arg : $type),* ) $( -> $ret )? $body
|
||||||
|
__hal_fn_default_imp! {
|
||||||
|
$($tail)*
|
||||||
|
}
|
||||||
|
};
|
||||||
|
() => {};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! __hal_fn_export {
|
||||||
|
(
|
||||||
|
$(#[$inner:ident $($args:tt)*])*
|
||||||
|
fn $fn:ident ( $($arg:ident : $type:ty),* ) $( -> $ret:ty )?;
|
||||||
|
$($tail:tt)*
|
||||||
|
) => {
|
||||||
|
$(#[$inner $($args)*])*
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub fn $fn ( $($arg : $type),* ) $( -> $ret )? {
|
||||||
|
__HalImpl::$fn( $($arg),* )
|
||||||
|
}
|
||||||
|
__hal_fn_export! {
|
||||||
|
$($tail)*
|
||||||
|
}
|
||||||
|
};
|
||||||
|
(
|
||||||
|
$(#[$inner:ident $($args:tt)*])*
|
||||||
|
fn $fn:ident ( $($arg:ident : $type:ty),* ) $( -> $ret:ty )? $body:block
|
||||||
|
$($tail:tt)*
|
||||||
|
) => {
|
||||||
|
$(#[$inner $($args)*])*
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub fn $fn ( $($arg : $type),* ) $( -> $ret )? {
|
||||||
|
__HalImpl::$fn( $($arg),* )
|
||||||
|
}
|
||||||
|
__hal_fn_export! {
|
||||||
|
$($tail)*
|
||||||
|
}
|
||||||
|
};
|
||||||
|
() => {};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! __hal_fn_impl_no_export {
|
||||||
|
(
|
||||||
|
$(
|
||||||
|
impl mod $mod_name:ident$(::$mod_name_more:ident)* {
|
||||||
|
$($fn:item)*
|
||||||
|
}
|
||||||
|
)+
|
||||||
|
) => {
|
||||||
|
$(
|
||||||
|
impl $mod_name$(::$mod_name_more)*::__HalTrait for $mod_name$(::$mod_name_more)*::__HalImpl {
|
||||||
|
$($fn)*
|
||||||
|
}
|
||||||
|
)+
|
||||||
|
};
|
||||||
|
() => {};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
mod base {
|
||||||
|
pub const BASE: usize = 0x2333;
|
||||||
|
}
|
||||||
|
hal_fn_def! {
|
||||||
|
mod mod0: self::base {
|
||||||
|
fn test() -> f32 { 1.0 }
|
||||||
|
}
|
||||||
|
mod mod1 {
|
||||||
|
fn foo() -> usize { 0 }
|
||||||
|
fn bar(a: usize) -> usize { a }
|
||||||
|
fn unimp();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
hal_fn_impl! {
|
||||||
|
impl mod self::mod1 {
|
||||||
|
fn foo() -> usize { 233 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
hal_fn_impl_default!(mod0);
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_hal_fn_marco() {
|
||||||
|
assert_eq!(mod0::BASE, 0x2333);
|
||||||
|
assert_eq!(mod0::test(), 1.0);
|
||||||
|
assert_eq!(mod1::foo(), 233);
|
||||||
|
assert_eq!(mod1::bar(0), 0);
|
||||||
|
// base::unimp(); // unimplemented!
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,15 +0,0 @@
|
||||||
pub use crate::common::context::*;
|
|
||||||
|
|
||||||
pub fn context_run(_context: &mut UserContext) {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get fault address of the last page fault.
|
|
||||||
pub fn fetch_fault_vaddr() -> crate::VirtAddr {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get the trap number when trap.
|
|
||||||
pub fn fetch_trap_num(_context: &UserContext) -> usize {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
|
@ -1,3 +0,0 @@
|
||||||
pub fn cpu_id() -> u8 {
|
|
||||||
0
|
|
||||||
}
|
|
|
@ -1,5 +0,0 @@
|
||||||
pub use crate::common::fb::*;
|
|
||||||
|
|
||||||
pub fn init() {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
|
@ -1,13 +0,0 @@
|
||||||
use alloc::boxed::Box;
|
|
||||||
|
|
||||||
pub fn kbd_set_callback(_callback: Box<dyn Fn(u16, i32) + Send + Sync>) {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn mice_set_callback(_callback: Box<dyn Fn([u8; 3]) + Send + Sync>) {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn init() {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
|
@ -1,2 +0,0 @@
|
||||||
pub mod fb;
|
|
||||||
pub mod input;
|
|
|
@ -1,61 +0,0 @@
|
||||||
use alloc::boxed::Box;
|
|
||||||
|
|
||||||
/// Enable IRQ.
|
|
||||||
pub fn enable_irq(_vector: u32) {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Disable IRQ.
|
|
||||||
pub fn disable_irq(_vector: u32) {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Is a valid IRQ number.
|
|
||||||
pub fn is_valid_irq(_vector: u32) -> bool {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Configure the specified interrupt vector. If it is invoked, it muust be
|
|
||||||
/// invoked prior to interrupt registration.
|
|
||||||
pub fn configure_irq(_vector: u32, _trig_mode: bool, _polarity: bool) -> bool {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Add an interrupt handle to an IRQ
|
|
||||||
pub fn register_irq_handler(_vector: u32, _handle: Box<dyn Fn() + Send + Sync>) -> Option<u32> {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Remove the interrupt handle to an IRQ
|
|
||||||
pub fn unregister_irq_handler(_vector: u32) -> bool {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Handle IRQ.
|
|
||||||
pub fn handle_irq(_vector: u32) {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Method used for platform allocation of blocks of MSI and MSI-X compatible
|
|
||||||
/// IRQ targets.
|
|
||||||
pub fn msi_allocate_block(_irq_num: u32) -> Option<(usize, usize)> {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Method used to free a block of MSI IRQs previously allocated by msi_alloc_block().
|
|
||||||
/// This does not unregister IRQ handlers.
|
|
||||||
pub fn msi_free_block(_irq_start: u32, _irq_num: u32) {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Register a handler function for a given msi_id within an msi_block_t. Passing a
|
|
||||||
/// NULL handler will effectively unregister a handler for a given msi_id within the
|
|
||||||
/// block.
|
|
||||||
pub fn msi_register_handler(
|
|
||||||
_irq_start: u32,
|
|
||||||
_irq_num: u32,
|
|
||||||
_msi_id: u32,
|
|
||||||
_handle: Box<dyn Fn() + Send + Sync>,
|
|
||||||
) {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
|
@ -1,44 +0,0 @@
|
||||||
use crate::PhysAddr;
|
|
||||||
|
|
||||||
pub use crate::common::memory::*;
|
|
||||||
|
|
||||||
/// Read physical memory from `paddr` to `buf`.
|
|
||||||
pub fn pmem_read(_paddr: PhysAddr, _buf: &mut [u8]) {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Write physical memory to `paddr` from `buf`.
|
|
||||||
pub fn pmem_write(_paddr: PhysAddr, _buf: &[u8]) {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Zero physical memory at `[paddr, paddr + len)`.
|
|
||||||
pub fn pmem_zero(_paddr: PhysAddr, _len: usize) {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Copy content of `src` frame to `target` frame.
|
|
||||||
pub fn frame_copy(_src: PhysAddr, _target: PhysAddr) {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Flush the physical frame.
|
|
||||||
pub fn frame_flush(_target: PhysAddr) {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn frame_alloc() -> Option<PhysAddr> {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn frame_alloc_contiguous(_size: usize, _align_log2: usize) -> Option<PhysAddr> {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn frame_dealloc(_paddr: PhysAddr) {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn zero_frame_addr() -> PhysAddr {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
use crate::{context::UserContext, VirtAddr};
|
|
||||||
use acpi::Acpi;
|
|
||||||
|
|
||||||
/// Get fault address of the last page fault.
|
|
||||||
pub fn fetch_fault_vaddr() -> VirtAddr {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn fetch_trap_num(_context: &UserContext) -> usize {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get physical address of `acpi_rsdp` and `smbios` on x86_64.
|
|
||||||
pub fn pc_firmware_tables() -> (u64, u64) {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get ACPI Table
|
|
||||||
pub fn get_acpi_table() -> Option<Acpi> {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// IO Ports access on x86 platform
|
|
||||||
pub fn outpd(_port: u16, _value: u32) {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn inpd(_port: u16) -> u32 {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get local APIC ID
|
|
||||||
pub fn apic_local_id() -> u8 {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
pub mod context;
|
|
||||||
pub mod cpu;
|
|
||||||
pub mod dev;
|
|
||||||
pub mod interrupt;
|
|
||||||
pub mod memory;
|
|
||||||
pub mod misc;
|
|
||||||
pub mod paging;
|
|
||||||
pub mod rand;
|
|
||||||
pub mod serial;
|
|
||||||
pub mod thread;
|
|
||||||
pub mod timer;
|
|
||||||
pub mod vdso;
|
|
||||||
|
|
||||||
pub use self::misc::*; // FIXME
|
|
||||||
|
|
||||||
/// Initialize the HAL.
|
|
||||||
///
|
|
||||||
/// This function must be called at the beginning.
|
|
||||||
pub fn init() {
|
|
||||||
unimplemented!();
|
|
||||||
}
|
|
|
@ -1,50 +0,0 @@
|
||||||
use crate::{HalResult, MMUFlags, PhysAddr, VirtAddr};
|
|
||||||
|
|
||||||
pub use crate::common::paging::*;
|
|
||||||
|
|
||||||
pub struct PageTable;
|
|
||||||
|
|
||||||
impl PageTable {
|
|
||||||
/// Create a new `PageTable`.
|
|
||||||
pub fn new() -> Self {
|
|
||||||
PageTable
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get the current root page table physical address. (e.g. CR3, SATP, ...)
|
|
||||||
pub fn current() -> Self {
|
|
||||||
unimplemented!();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PageTableTrait for PageTable {
|
|
||||||
/// Map the page of `vaddr` to the frame of `paddr` with `flags`.
|
|
||||||
fn map(&mut self, _vaddr: VirtAddr, _paddr: PhysAddr, _flags: MMUFlags) -> HalResult<()> {
|
|
||||||
unimplemented!();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Unmap the page of `vaddr`.
|
|
||||||
fn unmap(&mut self, _vaddr: VirtAddr) -> HalResult<()> {
|
|
||||||
unimplemented!();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Change the `flags` of the page of `vaddr`.
|
|
||||||
fn protect(&mut self, _vaddr: VirtAddr, _flags: MMUFlags) -> HalResult<()> {
|
|
||||||
unimplemented!();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Query the physical address which the page of `vaddr` maps to.
|
|
||||||
fn query(&mut self, _vaddr: VirtAddr) -> HalResult<PhysAddr> {
|
|
||||||
unimplemented!();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get the physical address of root page table.
|
|
||||||
fn table_phys(&self) -> PhysAddr {
|
|
||||||
unimplemented!();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(target_arch = "riscv64")]
|
|
||||||
/// Activate this page table
|
|
||||||
fn activate(&self) {
|
|
||||||
unimplemented!();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,18 +0,0 @@
|
||||||
/// Fill random bytes to the buffer
|
|
||||||
#[allow(unused_variables)]
|
|
||||||
pub fn fill_random(buf: &mut [u8]) {
|
|
||||||
cfg_if::cfg_if! {
|
|
||||||
if #[cfg(target_arch = "x86_64")] {
|
|
||||||
// TODO: optimize
|
|
||||||
for x in buf.iter_mut() {
|
|
||||||
let mut r = 0;
|
|
||||||
unsafe {
|
|
||||||
core::arch::x86_64::_rdrand16_step(&mut r);
|
|
||||||
}
|
|
||||||
*x = r as _;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
use alloc::boxed::Box;
|
|
||||||
|
|
||||||
/// Put a char by serial interrupt handler.
|
|
||||||
pub fn serial_put(_x: u8) {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Register a callback of serial readable event.
|
|
||||||
pub fn serial_set_callback(_callback: Box<dyn Fn() -> bool + Send + Sync>) {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Read a string from console.
|
|
||||||
pub fn serial_read(_buf: &mut [u8]) -> usize {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Output a string to console.
|
|
||||||
pub fn serial_write(_s: &str) {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
|
@ -1,18 +0,0 @@
|
||||||
use alloc::boxed::Box;
|
|
||||||
use core::future::Future;
|
|
||||||
use core::pin::Pin;
|
|
||||||
|
|
||||||
/// Spawn a new thread.
|
|
||||||
pub fn spawn(_future: Pin<Box<dyn Future<Output = ()> + Send + 'static>>, _vmtoken: usize) {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Set tid and pid of current task.
|
|
||||||
pub fn set_tid(_tid: u64, _pid: u64) {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get tid and pid of current task.]
|
|
||||||
pub fn get_tid() -> (u64, u64) {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
use alloc::boxed::Box;
|
|
||||||
use core::time::Duration;
|
|
||||||
|
|
||||||
/// Get current time.
|
|
||||||
pub fn timer_now() -> Duration {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Set a new timer. After `deadline`, the `callback` will be called.
|
|
||||||
pub fn timer_set(_deadline: Duration, _callback: Box<dyn FnOnce(Duration) + Send + Sync>) {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn timer_set_next() {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Check timers, call when timer interrupt happened.
|
|
||||||
pub fn timer_tick() {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
|
@ -1,5 +0,0 @@
|
||||||
pub use crate::common::vdso::*;
|
|
||||||
|
|
||||||
pub fn vdso_constants() -> VdsoConstants {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
|
@ -158,7 +158,7 @@ async fn new_thread(thread: CurrentThread) {
|
||||||
8 => handle_syscall(&thread, &mut cx).await,
|
8 => handle_syscall(&thread, &mut cx).await,
|
||||||
// PageFault
|
// PageFault
|
||||||
12 | 13 | 15 => {
|
12 | 13 | 15 => {
|
||||||
let vaddr = kernel_hal::fetch_fault_vaddr();
|
let vaddr = kernel_hal::context::fetch_fault_vaddr();
|
||||||
|
|
||||||
//注意这里flags没有包含WRITE权限,后面handle会移除写权限
|
//注意这里flags没有包含WRITE权限,后面handle会移除写权限
|
||||||
let flags = if trap_num == 15 {
|
let flags = if trap_num == 15 {
|
||||||
|
|
|
@ -16,7 +16,7 @@ impl InputMiceInode {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
let data = Arc::new(Mutex::new(VecDeque::with_capacity(MAX_QUEUE)));
|
let data = Arc::new(Mutex::new(VecDeque::with_capacity(MAX_QUEUE)));
|
||||||
let data_clone = data.clone();
|
let data_clone = data.clone();
|
||||||
input::mice_set_callback(Box::new(move |data| {
|
input::mouse_set_callback(Box::new(move |data| {
|
||||||
let mut queue = data_clone.lock();
|
let mut queue = data_clone.lock();
|
||||||
while queue.len() >= MAX_QUEUE {
|
while queue.len() >= MAX_QUEUE {
|
||||||
queue.pop_front();
|
queue.pop_front();
|
||||||
|
|
|
@ -132,7 +132,7 @@ impl INode for Stdout {
|
||||||
fn write_at(&self, _offset: usize, buf: &[u8]) -> Result<usize> {
|
fn write_at(&self, _offset: usize, buf: &[u8]) -> Result<usize> {
|
||||||
// we do not care the utf-8 things, we just want to print it!
|
// we do not care the utf-8 things, we just want to print it!
|
||||||
let s = unsafe { core::str::from_utf8_unchecked(buf) };
|
let s = unsafe { core::str::from_utf8_unchecked(buf) };
|
||||||
kernel_hal::serial::serial_write(s);
|
kernel_hal::serial::print_str(s);
|
||||||
Ok(buf.len())
|
Ok(buf.len())
|
||||||
}
|
}
|
||||||
fn poll(&self) -> Result<PollStatus> {
|
fn poll(&self) -> Result<PollStatus> {
|
||||||
|
|
|
@ -186,7 +186,7 @@ fn main(ramfs_data: &'static mut [u8], cmdline: &str) -> ! {
|
||||||
let len = kernel_hal_bare::serial_read(&mut buffer);
|
let len = kernel_hal_bare::serial_read(&mut buffer);
|
||||||
for c in &buffer[..len] {
|
for c in &buffer[..len] {
|
||||||
STDIN.push((*c).into());
|
STDIN.push((*c).into());
|
||||||
// kernel_hal_bare::serial_write(alloc::format!("{}", *c as char).as_str());
|
// kernel_hal_bare::print_str(alloc::format!("{}", *c as char).as_str());
|
||||||
}
|
}
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
|
@ -241,7 +241,7 @@ async fn new_thread(thread: CurrentThread) {
|
||||||
if error_code & 0x10 != 0 {
|
if error_code & 0x10 != 0 {
|
||||||
flags.insert(MMUFlags::EXECUTE)
|
flags.insert(MMUFlags::EXECUTE)
|
||||||
}
|
}
|
||||||
let fault_vaddr = kernel_hal::fetch_fault_vaddr();
|
let fault_vaddr = kernel_hal::context::fetch_fault_vaddr();
|
||||||
info!(
|
info!(
|
||||||
"page fault from user mode {:#x} {:#x?} {:?}",
|
"page fault from user mode {:#x} {:#x?} {:?}",
|
||||||
fault_vaddr, error_code, flags
|
fault_vaddr, error_code, flags
|
||||||
|
|
|
@ -6,7 +6,7 @@ impl Syscall<'_> {
|
||||||
pub fn sys_debug_write(&self, buf: UserInPtr<u8>, len: usize) -> ZxResult {
|
pub fn sys_debug_write(&self, buf: UserInPtr<u8>, len: usize) -> ZxResult {
|
||||||
info!("debug.write: buf=({:?}; {:#x})", buf, len);
|
info!("debug.write: buf=({:?}; {:#x})", buf, len);
|
||||||
let data = buf.read_array(len)?;
|
let data = buf.read_array(len)?;
|
||||||
kernel_hal::serial::serial_write(core::str::from_utf8(&data).unwrap());
|
kernel_hal::serial::print_str(core::str::from_utf8(&data).unwrap());
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,9 +54,9 @@ impl Syscall<'_> {
|
||||||
let dlog = proc.get_object_with_rights::<DebugLog>(handle_value, Rights::WRITE)?;
|
let dlog = proc.get_object_with_rights::<DebugLog>(handle_value, Rights::WRITE)?;
|
||||||
dlog.write(Severity::Info, options, self.thread.id(), proc.id(), &data);
|
dlog.write(Severity::Info, options, self.thread.id(), proc.id(), &data);
|
||||||
// print to kernel console
|
// print to kernel console
|
||||||
kernel_hal::serial::serial_write(&data);
|
kernel_hal::serial::print_str(&data);
|
||||||
if data.as_bytes().last() != Some(&b'\n') {
|
if data.as_bytes().last() != Some(&b'\n') {
|
||||||
kernel_hal::serial::serial_write("\n");
|
kernel_hal::serial::print_str("\n");
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue