asterinas/framework/jinux-frame/src/lib.rs

165 lines
3.8 KiB
Rust
Raw Normal View History

//! The framework part of Jinux.
2022-08-08 01:01:42 +00:00
#![no_std]
#![allow(dead_code)]
#![allow(unused_variables)]
#![feature(negative_impls)]
2022-08-16 02:41:25 +00:00
#![feature(fn_traits)]
2022-08-23 09:50:07 +00:00
#![feature(const_maybe_uninit_zeroed)]
#![feature(alloc_error_handler)]
#![feature(core_intrinsics)]
#![feature(new_uninit)]
2022-08-26 15:59:20 +00:00
#![feature(link_llvm_intrinsics)]
2023-03-06 06:19:23 +00:00
#![feature(strict_provenance)]
#![feature(const_trait_impl)]
#![feature(const_ops)]
2023-07-05 13:35:07 +00:00
#![feature(generators)]
#![feature(iter_from_generator)]
2023-07-18 10:54:35 +00:00
#![feature(const_mut_refs)]
2022-08-26 15:59:20 +00:00
2022-08-08 01:01:42 +00:00
extern crate alloc;
pub mod arch;
2023-07-05 13:35:07 +00:00
pub mod bus;
2022-08-16 02:41:25 +00:00
pub mod config;
2022-08-08 01:01:42 +00:00
pub mod cpu;
mod error;
2023-02-22 14:57:19 +00:00
pub mod logger;
2023-05-05 10:07:26 +00:00
pub mod mmio;
2022-08-08 01:01:42 +00:00
pub mod prelude;
pub mod sync;
2022-08-08 01:01:42 +00:00
pub mod task;
pub mod timer;
2022-11-02 11:35:39 +00:00
pub mod trap;
2022-08-08 01:01:42 +00:00
pub mod user;
mod util;
pub mod vm;
pub use self::cpu::CpuLocal;
2022-08-23 09:50:07 +00:00
pub use self::error::Error;
pub use self::prelude::Result;
2022-09-05 06:41:15 +00:00
use alloc::vec::Vec;
2023-03-06 06:19:23 +00:00
use core::{mem, panic::PanicInfo};
2023-03-29 07:42:49 +00:00
#[cfg(target_arch = "x86_64")]
2023-03-25 09:24:34 +00:00
pub use limine::{LimineFramebufferRequest, LimineModuleRequest};
use trap::{IrqCallbackHandle, IrqLine};
use trapframe::TrapFrame;
2022-09-27 05:52:21 +00:00
2022-09-05 22:27:44 +00:00
static mut IRQ_CALLBACK_LIST: Vec<IrqCallbackHandle> = Vec::new();
2023-02-22 14:57:19 +00:00
2023-03-06 06:19:23 +00:00
pub fn init() {
arch::before_all_init();
2023-02-22 14:57:19 +00:00
logger::init();
2023-03-16 11:36:48 +00:00
vm::init();
2022-11-09 12:33:41 +00:00
trap::init();
arch::after_all_init();
2023-05-05 10:07:26 +00:00
mmio::init();
2023-07-23 10:31:43 +00:00
bus::init();
2023-03-06 06:19:23 +00:00
register_irq_common_callback();
invoke_c_init_funcs();
}
fn register_irq_common_callback() {
2022-09-05 22:27:44 +00:00
unsafe {
for i in 0..256 {
2022-09-05 06:41:15 +00:00
IRQ_CALLBACK_LIST.push(IrqLine::acquire(i as u8).on_active(general_handler))
}
}
}
fn invoke_c_init_funcs() {
extern "C" {
fn sinit_array();
fn einit_array();
}
let call_len = (einit_array as u64 - sinit_array as u64) / 8;
for i in 0..call_len {
unsafe {
let address = (sinit_array as u64 + 8 * i) as *const u64;
let function = address as *const fn();
(*function)();
}
}
}
2022-11-09 12:33:41 +00:00
fn general_handler(trap_frame: &TrapFrame) {
// info!("general handler");
// println!("{:#x?}", trap_frame);
// println!("rip = 0x{:x}", trap_frame.rip);
// println!("rsp = 0x{:x}", trap_frame.rsp);
// println!("cr2 = 0x{:x}", trap_frame.cr2);
// // println!("rbx = 0x{:x}", trap_frame.)
// panic!("couldn't handler trap right now");
2022-08-16 02:41:25 +00:00
}
2022-08-23 09:50:07 +00:00
#[inline(always)]
2022-09-01 06:25:26 +00:00
pub(crate) const fn zero<T>() -> T {
2022-08-23 09:50:07 +00:00
unsafe { mem::MaybeUninit::zeroed().assume_init() }
}
2022-09-01 06:25:26 +00:00
pub trait Testable {
fn run(&self) -> ();
}
impl<T> Testable for T
where
T: Fn(),
{
fn run(&self) {
print!("{}...\n", core::any::type_name::<T>());
2022-09-01 06:25:26 +00:00
self();
println!("[ok]");
2022-09-01 06:25:26 +00:00
}
}
pub fn test_runner(tests: &[&dyn Testable]) {
println!("Running {} tests", tests.len());
2022-09-01 06:25:26 +00:00
for test in tests {
test.run();
}
exit_qemu(QemuExitCode::Success);
}
pub fn test_panic_handler(info: &PanicInfo) -> ! {
println!("[failed]");
println!("Error: {}", info);
2022-09-01 06:25:26 +00:00
exit_qemu(QemuExitCode::Failed);
}
pub fn panic_handler() {
// let mut fp: usize;
// let stop = unsafe{
// Task::current().kstack.get_top()
// };
// info!("stop:{:x}",stop);
// unsafe{
// asm!("mov rbp, {}", out(reg) fp);
// info!("fp:{:x}",fp);
// println!("---START BACKTRACE---");
// for i in 0..10 {
// if fp == stop {
// break;
// }
// println!("#{}:ra={:#x}", i, *((fp - 8) as *const usize));
// info!("fp target:{:x}",*((fp ) as *const usize));
// fp = *((fp - 16) as *const usize);
// }
// println!("---END BACKTRACE---");
// }
}
2022-09-01 06:25:26 +00:00
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u32)]
pub enum QemuExitCode {
Success = 0x10,
Failed = 0x11,
}
pub fn exit_qemu(exit_code: QemuExitCode) -> ! {
use x86_64::instructions::port::Port;
unsafe {
let mut port = Port::new(0xf4);
port.write(exit_code as u32);
}
unreachable!()
}