forked from AbleOS/ableos
able told me to push 🙏
This commit is contained in:
parent
3a6778149b
commit
fef5487e62
40
Cargo.lock
generated
40
Cargo.lock
generated
|
@ -2,6 +2,15 @@
|
||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
version = 3
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "aarch64-cpu"
|
||||||
|
version = "9.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ac42a04a61c19fc8196dd728022a784baecc5d63d7e256c01ad1b3fbfab26287"
|
||||||
|
dependencies = [
|
||||||
|
"tock-registers",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "addr2line"
|
name = "addr2line"
|
||||||
version = "0.24.1"
|
version = "0.24.1"
|
||||||
|
@ -52,9 +61,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "anyhow"
|
name = "anyhow"
|
||||||
version = "1.0.87"
|
version = "1.0.88"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "10f00e1f6e58a40e807377c75c6a7f97bf9044fab57816f2414e6f5f4499d7b8"
|
checksum = "4e1496f8fb1fbf272686b8d37f523dab3e4a7443300055e74cdaa449f3114356"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "autocfg"
|
name = "autocfg"
|
||||||
|
@ -381,17 +390,17 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hbbytecode"
|
name = "hbbytecode"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#b51f964caee71ad350d0c1f66e4694202a5d7f12"
|
source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#dc418bd5e0b962ec9413af72e5d624e17febcbf2"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hbbytecode"
|
name = "hbbytecode"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://git.ablecorp.us/ableos/holey-bytes#b51f964caee71ad350d0c1f66e4694202a5d7f12"
|
source = "git+https://git.ablecorp.us/ableos/holey-bytes#dc418bd5e0b962ec9413af72e5d624e17febcbf2"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hblang"
|
name = "hblang"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#b51f964caee71ad350d0c1f66e4694202a5d7f12"
|
source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#dc418bd5e0b962ec9413af72e5d624e17febcbf2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"hbvm 0.1.0 (git+https://git.ablecorp.us/AbleOS/holey-bytes.git)",
|
"hbvm 0.1.0 (git+https://git.ablecorp.us/AbleOS/holey-bytes.git)",
|
||||||
]
|
]
|
||||||
|
@ -399,7 +408,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hbvm"
|
name = "hbvm"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#b51f964caee71ad350d0c1f66e4694202a5d7f12"
|
source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#dc418bd5e0b962ec9413af72e5d624e17febcbf2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"hbbytecode 0.1.0 (git+https://git.ablecorp.us/AbleOS/holey-bytes.git)",
|
"hbbytecode 0.1.0 (git+https://git.ablecorp.us/AbleOS/holey-bytes.git)",
|
||||||
]
|
]
|
||||||
|
@ -407,7 +416,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hbvm"
|
name = "hbvm"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://git.ablecorp.us/ableos/holey-bytes#b51f964caee71ad350d0c1f66e4694202a5d7f12"
|
source = "git+https://git.ablecorp.us/ableos/holey-bytes#dc418bd5e0b962ec9413af72e5d624e17febcbf2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"hbbytecode 0.1.0 (git+https://git.ablecorp.us/ableos/holey-bytes)",
|
"hbbytecode 0.1.0 (git+https://git.ablecorp.us/ableos/holey-bytes)",
|
||||||
]
|
]
|
||||||
|
@ -583,8 +592,8 @@ dependencies = [
|
||||||
name = "kernel"
|
name = "kernel"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"aarch64-cpu",
|
||||||
"crossbeam-queue",
|
"crossbeam-queue",
|
||||||
"crossbeam-utils",
|
|
||||||
"derive_more",
|
"derive_more",
|
||||||
"embedded-graphics",
|
"embedded-graphics",
|
||||||
"hashbrown",
|
"hashbrown",
|
||||||
|
@ -592,6 +601,7 @@ dependencies = [
|
||||||
"limine",
|
"limine",
|
||||||
"log",
|
"log",
|
||||||
"sbi",
|
"sbi",
|
||||||
|
"slab",
|
||||||
"spin",
|
"spin",
|
||||||
"uart_16550",
|
"uart_16550",
|
||||||
"versioning",
|
"versioning",
|
||||||
|
@ -989,9 +999,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustls"
|
name = "rustls"
|
||||||
version = "0.23.12"
|
version = "0.23.13"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c58f8c84392efc0a126acce10fa59ff7b3d2ac06ab451a33f2741989b806b044"
|
checksum = "f2dabaac7466917e566adb06783a81ca48944c6898a1b08b9374106dd671f4c8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"ring",
|
"ring",
|
||||||
|
@ -1218,6 +1228,12 @@ version = "0.1.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tock-registers"
|
||||||
|
version = "0.8.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "696941a0aee7e276a165a978b37918fd5d22c55c3d6bda197813070ca9c0f21c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio"
|
name = "tokio"
|
||||||
version = "1.40.0"
|
version = "1.40.0"
|
||||||
|
@ -1349,9 +1365,9 @@ checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-ident"
|
name = "unicode-ident"
|
||||||
version = "1.0.12"
|
version = "1.0.13"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-normalization"
|
name = "unicode-normalization"
|
||||||
|
|
|
@ -9,6 +9,7 @@ embedded-graphics = "0.8"
|
||||||
hbvm.git = "https://git.ablecorp.us/ableos/holey-bytes"
|
hbvm.git = "https://git.ablecorp.us/ableos/holey-bytes"
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
spin = "0.9"
|
spin = "0.9"
|
||||||
|
slab = { version = "0.4", default-features = false }
|
||||||
uart_16550 = { version = "0.3", features = ["nightly"] }
|
uart_16550 = { version = "0.3", features = ["nightly"] }
|
||||||
xml.git = "https://git.ablecorp.us/ableos/ableos_userland"
|
xml.git = "https://git.ablecorp.us/ableos/ableos_userland"
|
||||||
versioning.git = "https://git.ablecorp.us/ableos/ableos_userland"
|
versioning.git = "https://git.ablecorp.us/ableos/ableos_userland"
|
||||||
|
@ -24,10 +25,6 @@ version = "0.3"
|
||||||
default-features = false
|
default-features = false
|
||||||
features = ["alloc", "nightly"]
|
features = ["alloc", "nightly"]
|
||||||
|
|
||||||
[dependencies.crossbeam-utils]
|
|
||||||
version = "0.8"
|
|
||||||
default-features = false
|
|
||||||
|
|
||||||
# [dependencies.clparse]
|
# [dependencies.clparse]
|
||||||
# git = "https://git.ablecorp.us/ableos/ableos_userland"
|
# git = "https://git.ablecorp.us/ableos/ableos_userland"
|
||||||
# default-features = false
|
# default-features = false
|
||||||
|
@ -56,3 +53,6 @@ virtio-drivers = "0.7"
|
||||||
|
|
||||||
[target.'cfg(target_arch = "riscv64")'.dependencies]
|
[target.'cfg(target_arch = "riscv64")'.dependencies]
|
||||||
sbi = "0.2.0"
|
sbi = "0.2.0"
|
||||||
|
|
||||||
|
[target.'cfg(target_arch = "aarch64")'.dependencies]
|
||||||
|
aarch64-cpu = "9"
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use {crate::logger::TERMINAL_LOGGER, core::fmt::Write, spin::Mutex};
|
use {crate::logger::TERMINAL_LOGGER, core::fmt::Write, spin::Mutex};
|
||||||
const SERIAL_CONSOLE: Mutex<SerialConsole> = Mutex::new(SerialConsole {
|
static SERIAL_CONSOLE: Mutex<SerialConsole> = Mutex::new(SerialConsole {
|
||||||
uart: 0x09000000 as *mut u8,
|
uart: 0x09000000 as *mut u8,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -17,6 +17,9 @@ impl core::fmt::Write for SerialConsole {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsafe impl Sync for SerialConsole {}
|
||||||
|
unsafe impl Send for SerialConsole {}
|
||||||
|
|
||||||
pub fn log(args: core::fmt::Arguments<'_>) -> core::fmt::Result {
|
pub fn log(args: core::fmt::Arguments<'_>) -> core::fmt::Result {
|
||||||
SERIAL_CONSOLE.lock().write_fmt(args)?;
|
SERIAL_CONSOLE.lock().write_fmt(args)?;
|
||||||
TERMINAL_LOGGER.lock().write_fmt(args)?;
|
TERMINAL_LOGGER.lock().write_fmt(args)?;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
pub use logging::log;
|
pub use logging::log;
|
||||||
use {
|
use {
|
||||||
crate::{allocator, bootmodules::BootModule, kmain::kmain},
|
crate::{allocator, bootmodules::BootModule, kmain::kmain},
|
||||||
|
alloc::vec::Vec,
|
||||||
core::arch::asm,
|
core::arch::asm,
|
||||||
limine::FramebufferRequest,
|
limine::FramebufferRequest,
|
||||||
};
|
};
|
||||||
|
@ -41,7 +42,7 @@ unsafe extern "C" fn _kernel_start() -> ! {
|
||||||
static KFILE_REQ: KernelFileRequest = KernelFileRequest::new(0);
|
static KFILE_REQ: KernelFileRequest = KernelFileRequest::new(0);
|
||||||
static MOD_REQ: ModuleRequest = ModuleRequest::new(0);
|
static MOD_REQ: ModuleRequest = ModuleRequest::new(0);
|
||||||
|
|
||||||
let mut bootmodules = alloc::vec::Vec::new();
|
let mut bootmodules = Vec::new();
|
||||||
|
|
||||||
if bm.is_some() {
|
if bm.is_some() {
|
||||||
let bm = bm.unwrap();
|
let bm = bm.unwrap();
|
||||||
|
@ -52,18 +53,13 @@ unsafe extern "C" fn _kernel_start() -> ! {
|
||||||
let raw_bytes = core::slice::from_raw_parts(
|
let raw_bytes = core::slice::from_raw_parts(
|
||||||
file.base.as_ptr().expect("invalid initrd"),
|
file.base.as_ptr().expect("invalid initrd"),
|
||||||
file.length as usize,
|
file.length as usize,
|
||||||
)
|
|
||||||
.to_vec();
|
|
||||||
|
|
||||||
let file_path = alloc::string::String::from_utf8(
|
|
||||||
file.path.to_str().unwrap().to_bytes().to_vec(),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let file_path = file.path.to_str().unwrap().to_str();
|
||||||
if file_path.is_err() {
|
if file_path.is_err() {
|
||||||
panic!("invalid file path: {:?}", file_path);
|
panic!("invalid file path: {:?}", file_path);
|
||||||
}
|
}
|
||||||
let file_cmd = alloc::string::String::from_utf8(
|
let file_cmd = file.cmdline.to_str().unwrap().to_str();
|
||||||
file.cmdline.to_str().unwrap().to_bytes().to_vec(),
|
|
||||||
);
|
|
||||||
if file_cmd.is_err() {
|
if file_cmd.is_err() {
|
||||||
panic!("invalid module cmd: {:?}", file_cmd);
|
panic!("invalid module cmd: {:?}", file_cmd);
|
||||||
}
|
}
|
||||||
|
@ -85,7 +81,7 @@ unsafe extern "C" fn _kernel_start() -> ! {
|
||||||
assert_eq!(bm.module_count, bootmodules.len() as u64);
|
assert_eq!(bm.module_count, bootmodules.len() as u64);
|
||||||
}
|
}
|
||||||
|
|
||||||
crate::kmain::kmain(
|
kmain(
|
||||||
KFILE_REQ
|
KFILE_REQ
|
||||||
.get_response()
|
.get_response()
|
||||||
.get()
|
.get()
|
||||||
|
@ -99,8 +95,6 @@ unsafe extern "C" fn _kernel_start() -> ! {
|
||||||
.unwrap_or_default(),
|
.unwrap_or_default(),
|
||||||
bootmodules,
|
bootmodules,
|
||||||
);
|
);
|
||||||
|
|
||||||
spin_loop();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn spin_loop() -> ! {
|
pub fn spin_loop() -> ! {
|
||||||
|
@ -110,7 +104,15 @@ pub fn spin_loop() -> ! {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn hardware_random_u64() -> u64 {
|
pub fn hardware_random_u64() -> u64 {
|
||||||
0
|
if let Some(rng) = aarch64_cpu::asm::random::ArmRng::new() {
|
||||||
|
if let Some(rnd) = rng.rndr() {
|
||||||
|
rnd
|
||||||
|
} else {
|
||||||
|
panic!("RNG failure :(")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
panic!("RNDR failure :(((")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn register_dump() {}
|
pub fn register_dump() {}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
mod memory;
|
mod memory;
|
||||||
|
|
||||||
use {
|
use {
|
||||||
alloc::boxed::Box,
|
alloc::{boxed::Box, vec::Vec},
|
||||||
core::{
|
core::{
|
||||||
arch::{asm, global_asm},
|
arch::{asm, global_asm},
|
||||||
fmt::Write,
|
fmt::Write,
|
||||||
|
@ -45,7 +45,7 @@ extern "C" {
|
||||||
static USABLE_MEMORY_SIZE: usize;
|
static USABLE_MEMORY_SIZE: usize;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SERIAL_CONSOLE: Once<Mutex<MmioSerialPort>> = Once::new();
|
pub static SERIAL_CONSOLE: Once<Mutex<MmioSerialPort>> = Once::new();
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
unsafe extern "C" fn _kernel_start() -> ! {
|
unsafe extern "C" fn _kernel_start() -> ! {
|
||||||
|
@ -95,7 +95,7 @@ unsafe extern "C" fn _kernel_start() -> ! {
|
||||||
in(reg) satp_value,
|
in(reg) satp_value,
|
||||||
);
|
);
|
||||||
|
|
||||||
crate::kmain::kmain("baka=9", None);
|
crate::kmain::kmain("baka=9", Vec::new());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Spin loop
|
/// Spin loop
|
||||||
|
@ -105,6 +105,12 @@ pub fn spin_loop() -> ! {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn hardware_random_u64() -> u64 {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn register_dump() {}
|
||||||
|
|
||||||
pub fn log(args: core::fmt::Arguments<'_>) -> core::fmt::Result {
|
pub fn log(args: core::fmt::Arguments<'_>) -> core::fmt::Result {
|
||||||
SERIAL_CONSOLE.get().unwrap().lock().write_fmt(args)
|
SERIAL_CONSOLE.get().unwrap().lock().write_fmt(args)
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,9 @@ use {
|
||||||
|
|
||||||
pub const DOUBLE_FAULT_IX: u16 = 0;
|
pub const DOUBLE_FAULT_IX: u16 = 0;
|
||||||
|
|
||||||
|
const STACK_SIZE: usize = 5 * 1024;
|
||||||
|
const STACK_ALIGNMENT: usize = 4096;
|
||||||
|
|
||||||
pub unsafe fn init() {
|
pub unsafe fn init() {
|
||||||
use x86_64::instructions::{
|
use x86_64::instructions::{
|
||||||
segmentation::{Segment, CS, SS},
|
segmentation::{Segment, CS, SS},
|
||||||
|
@ -32,15 +35,15 @@ struct Selectors {
|
||||||
|
|
||||||
static TSS: Lazy<TaskStateSegment> = Lazy::new(|| {
|
static TSS: Lazy<TaskStateSegment> = Lazy::new(|| {
|
||||||
let mut tss = TaskStateSegment::new();
|
let mut tss = TaskStateSegment::new();
|
||||||
tss.interrupt_stack_table[usize::from(DOUBLE_FAULT_IX)] = {
|
|
||||||
const SIZE: usize = 5 * 1024;
|
let stack_ptr = unsafe {
|
||||||
let stack = unsafe {
|
let layout = alloc::alloc::Layout::from_size_align(STACK_SIZE, STACK_ALIGNMENT)
|
||||||
alloc::alloc::alloc_zeroed(
|
.expect("Failed to create stack layout");
|
||||||
alloc::alloc::Layout::from_size_align(SIZE, 1).expect("stack pointer"),
|
let stack = alloc::alloc::alloc_zeroed(layout);
|
||||||
)
|
VirtAddr::from_ptr(stack) + STACK_SIZE as u64
|
||||||
};
|
|
||||||
VirtAddr::from_ptr(stack) + SIZE as u64
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
tss.interrupt_stack_table[usize::from(DOUBLE_FAULT_IX)] = stack_ptr;
|
||||||
tss
|
tss
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use core::arch::x86_64::{_rdrand32_step, _rdrand64_step, _rdseed32_step, _rdseed64_step};
|
use core::arch::x86_64::{_rdrand64_step, _rdseed64_step};
|
||||||
|
|
||||||
use {crate::bootmodules::BootModule, core::arch::asm, log::warn};
|
use {crate::bootmodules::BootModule, core::arch::asm, log::warn};
|
||||||
pub mod memory;
|
pub mod memory;
|
||||||
|
@ -142,18 +142,13 @@ unsafe extern "C" fn start() -> ! {
|
||||||
let raw_bytes = core::slice::from_raw_parts(
|
let raw_bytes = core::slice::from_raw_parts(
|
||||||
file.base.as_ptr().expect("invalid initrd"),
|
file.base.as_ptr().expect("invalid initrd"),
|
||||||
file.length as usize,
|
file.length as usize,
|
||||||
)
|
|
||||||
.to_vec();
|
|
||||||
|
|
||||||
let file_path = alloc::string::String::from_utf8(
|
|
||||||
file.path.to_str().unwrap().to_bytes().to_vec(),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let file_path = file.path.to_str().unwrap().to_str();
|
||||||
if file_path.is_err() {
|
if file_path.is_err() {
|
||||||
panic!("invalid file path: {:?}", file_path);
|
panic!("invalid file path: {:?}", file_path);
|
||||||
}
|
}
|
||||||
let file_cmd = alloc::string::String::from_utf8(
|
let file_cmd = file.cmdline.to_str().unwrap().to_str();
|
||||||
file.cmdline.to_str().unwrap().to_bytes().to_vec(),
|
|
||||||
);
|
|
||||||
if file_cmd.is_err() {
|
if file_cmd.is_err() {
|
||||||
panic!("invalid module cmd: {:?}", file_cmd);
|
panic!("invalid module cmd: {:?}", file_cmd);
|
||||||
}
|
}
|
||||||
|
@ -191,15 +186,10 @@ unsafe extern "C" fn start() -> ! {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
use crossbeam_utils::Backoff;
|
|
||||||
|
|
||||||
/// Spin loop
|
/// Spin loop
|
||||||
pub fn spin_loop() -> ! {
|
pub fn spin_loop() -> ! {
|
||||||
let backoff = Backoff::new();
|
|
||||||
loop {
|
loop {
|
||||||
core::hint::spin_loop();
|
x86_64::instructions::hlt()
|
||||||
// x86_64::instructions::hlt();
|
|
||||||
backoff.spin()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -218,21 +208,6 @@ pub fn hardware_random_u64() -> u64 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn hardware_random_u32() -> u32 {
|
|
||||||
let mut out: u32 = 0;
|
|
||||||
match unsafe { _rdrand32_step(&mut out) } {
|
|
||||||
1 => out,
|
|
||||||
_ => {
|
|
||||||
warn!("RDRand not supported.");
|
|
||||||
// Try rdseed
|
|
||||||
match unsafe { _rdseed32_step(&mut out) } {
|
|
||||||
1 => out,
|
|
||||||
_ => panic!("Neither RDRand or RDSeed are supported"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_edid() {}
|
pub fn get_edid() {}
|
||||||
|
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
|
|
|
@ -1,20 +1,20 @@
|
||||||
use {
|
use {
|
||||||
// crate::alloc::string::ToString,
|
// crate::alloc::string::ToString,
|
||||||
alloc::{string::String, vec::Vec},
|
alloc::vec::Vec,
|
||||||
// clparse::Arguments,
|
// clparse::Arguments,
|
||||||
// core::fmt::{Debug, Display},
|
// core::fmt::{Debug, Display},
|
||||||
// log::trace,
|
// log::trace,
|
||||||
// xml::XMLElement,
|
// xml::XMLElement,
|
||||||
};
|
};
|
||||||
pub type BootModules = Vec<BootModule>;
|
pub type BootModules<'a> = Vec<BootModule<'a>>;
|
||||||
|
|
||||||
pub struct BootModule {
|
pub struct BootModule<'a> {
|
||||||
pub path: String,
|
pub path: &'a str,
|
||||||
pub bytes: Vec<u8>,
|
pub bytes: &'a [u8],
|
||||||
pub cmd: String,
|
pub cmd: &'a str,
|
||||||
}
|
}
|
||||||
impl BootModule {
|
impl<'a> BootModule<'a> {
|
||||||
pub fn new(path: String, bytes: Vec<u8>, cmd: String) -> Self {
|
pub fn new(path: &'a str, bytes: &'a [u8], cmd: &'a str) -> Self {
|
||||||
Self { path, bytes, cmd }
|
Self { path, bytes, cmd }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,6 @@ use crate::holeybytes::kernel_services::{block_read, service_definition_service:
|
||||||
use {
|
use {
|
||||||
super::Vm,
|
super::Vm,
|
||||||
crate::{arch, ipc::buffer::IpcBuffer, kmain::IPC_BUFFERS},
|
crate::{arch, ipc::buffer::IpcBuffer, kmain::IPC_BUFFERS},
|
||||||
alloc::string::String,
|
|
||||||
log::{debug, error, info, trace, warn},
|
log::{debug, error, info, trace, warn},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -79,26 +78,19 @@ pub fn handler(vm: &mut Vm) {
|
||||||
Err(_) => {}
|
Err(_) => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#[cfg(not(target_arch = "x86_64"))]
|
||||||
|
3 => info!("TODO: implement whatever buffer 3 does for no x86_64"),
|
||||||
|
#[cfg(target_arch = "x86_64")]
|
||||||
3 => {
|
3 => {
|
||||||
unsafe fn x86_in(address: u16) -> u8 {
|
unsafe fn x86_out<T: x86_64::instructions::port::PortWrite>(
|
||||||
x86_64::instructions::port::Port::new(address).read()
|
address: u16,
|
||||||
}
|
value: T,
|
||||||
unsafe fn x86_in_16(address: u16) -> u16 {
|
) {
|
||||||
x86_64::instructions::port::Port::new(address).read()
|
|
||||||
}
|
|
||||||
unsafe fn x86_in_32(address: u16) -> u32 {
|
|
||||||
x86_64::instructions::port::Port::new(address).read()
|
|
||||||
}
|
|
||||||
unsafe fn x86_out(address: u16, value: u8) {
|
|
||||||
x86_64::instructions::port::Port::new(address).write(value);
|
x86_64::instructions::port::Port::new(address).write(value);
|
||||||
}
|
}
|
||||||
unsafe fn x86_out_16(address: u16, value: u16) {
|
unsafe fn x86_in<T: x86_64::instructions::port::PortRead>(address: u16) -> T {
|
||||||
x86_64::instructions::port::Port::new(address).write(value);
|
x86_64::instructions::port::Port::new(address).read()
|
||||||
}
|
}
|
||||||
unsafe fn x86_out_32(address: u16, value: u32) {
|
|
||||||
x86_64::instructions::port::Port::new(address).write(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
let msg_vec = block_read(mem_addr, length);
|
let msg_vec = block_read(mem_addr, length);
|
||||||
let msg_type = msg_vec[0];
|
let msg_type = msg_vec[0];
|
||||||
match msg_type {
|
match msg_type {
|
||||||
|
@ -115,9 +107,9 @@ pub fn handler(vm: &mut Vm) {
|
||||||
let addr = u16::from_le_bytes(msg_vec[1..3].try_into().unwrap());
|
let addr = u16::from_le_bytes(msg_vec[1..3].try_into().unwrap());
|
||||||
let value = unsafe {
|
let value = unsafe {
|
||||||
match size {
|
match size {
|
||||||
1 => x86_in(addr) as u64,
|
1 => x86_in::<u8>(addr) as u64,
|
||||||
2 => x86_in_16(addr) as u64,
|
2 => x86_in::<u16>(addr) as u64,
|
||||||
4 => x86_in_32(addr) as u64,
|
4 => x86_in::<u32>(addr) as u64,
|
||||||
_ => panic!("how?"),
|
_ => panic!("how?"),
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -141,13 +133,13 @@ pub fn handler(vm: &mut Vm) {
|
||||||
unsafe {
|
unsafe {
|
||||||
match size {
|
match size {
|
||||||
1 => x86_out(addr, msg_vec[3]),
|
1 => x86_out(addr, msg_vec[3]),
|
||||||
2 => x86_out_16(
|
2 => x86_out(
|
||||||
addr,
|
addr,
|
||||||
u16::from_le_bytes(
|
u16::from_le_bytes(
|
||||||
msg_vec[3..5].try_into().unwrap_unchecked(),
|
msg_vec[3..5].try_into().unwrap_unchecked(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
4 => x86_out_32(
|
4 => x86_out(
|
||||||
addr,
|
addr,
|
||||||
u32::from_le_bytes(
|
u32::from_le_bytes(
|
||||||
msg_vec[3..7].try_into().unwrap_unchecked(),
|
msg_vec[3..7].try_into().unwrap_unchecked(),
|
||||||
|
@ -162,7 +154,18 @@ pub fn handler(vm: &mut Vm) {
|
||||||
}
|
}
|
||||||
// source of rng
|
// source of rng
|
||||||
4 => {
|
4 => {
|
||||||
vm.registers[1] = hbvm::value::Value(crate::arch::hardware_random_u32() as u64);
|
// limit to last 32 bits
|
||||||
|
vm.registers[1] =
|
||||||
|
hbvm::value::Value(crate::arch::hardware_random_u64() & 0xFFFFFFFF);
|
||||||
|
}
|
||||||
|
5 => {
|
||||||
|
if cfg!(target_arch = "x86_64") {
|
||||||
|
vm.registers[1] = hbvm::value::Value(0);
|
||||||
|
} else if cfg!(target_arch = "aarch64") {
|
||||||
|
vm.registers[1] = hbvm::value::Value(1);
|
||||||
|
} else {
|
||||||
|
vm.registers[1] = hbvm::value::Value(u64::MAX)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
buffer_id => {
|
buffer_id => {
|
||||||
let mut buffs = IPC_BUFFERS.lock();
|
let mut buffs = IPC_BUFFERS.lock();
|
||||||
|
@ -247,10 +250,10 @@ pub fn handler(vm: &mut Vm) {
|
||||||
fn log_msg_handler(_vm: &mut Vm, mem_addr: u64, length: usize) -> Result<(), LogError> {
|
fn log_msg_handler(_vm: &mut Vm, mem_addr: u64, length: usize) -> Result<(), LogError> {
|
||||||
// let message_length = 8 + 8 + 8;
|
// let message_length = 8 + 8 + 8;
|
||||||
// log::info!("Mem Addr 0x{:x?} length {}", mem_addr, length);
|
// log::info!("Mem Addr 0x{:x?} length {}", mem_addr, length);
|
||||||
let mut msg_vec = block_read(mem_addr, length);
|
let msg_vec = block_read(mem_addr, length);
|
||||||
|
|
||||||
let log_level = msg_vec.pop().unwrap();
|
let log_level = msg_vec.last().unwrap();
|
||||||
match String::from_utf8(msg_vec) {
|
match core::str::from_utf8(&msg_vec[1..]) {
|
||||||
Ok(strr) => {
|
Ok(strr) => {
|
||||||
// use LogLevel::*;
|
// use LogLevel::*;
|
||||||
let _ll = match log_level {
|
let _ll = match log_level {
|
||||||
|
|
|
@ -1,15 +1,9 @@
|
||||||
use alloc::vec::Vec;
|
use core::slice;
|
||||||
|
|
||||||
pub mod mem_serve;
|
pub mod mem_serve;
|
||||||
pub mod service_definition_service;
|
pub mod service_definition_service;
|
||||||
|
|
||||||
pub fn block_read(mem_addr: u64, length: usize) -> Vec<u8> {
|
#[inline(always)]
|
||||||
let mut msg_vec = Vec::with_capacity(length);
|
pub fn block_read<'a>(mem_addr: u64, length: usize) -> &'a [u8] {
|
||||||
let xyz = mem_addr as *const u8;
|
unsafe { slice::from_raw_parts(mem_addr as *const u8, length) }
|
||||||
|
|
||||||
for x in 0..(length as isize) {
|
|
||||||
let value = unsafe { xyz.offset(x).read() };
|
|
||||||
msg_vec.push(value);
|
|
||||||
}
|
|
||||||
msg_vec
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,12 +5,11 @@ use {
|
||||||
ipc::{buffer::IpcBuffer, protocol::Protocol},
|
ipc::{buffer::IpcBuffer, protocol::Protocol},
|
||||||
kmain::IPC_BUFFERS,
|
kmain::IPC_BUFFERS,
|
||||||
},
|
},
|
||||||
alloc::string::String,
|
|
||||||
hashbrown::HashMap,
|
hashbrown::HashMap,
|
||||||
log::{info, trace},
|
log::{info, trace},
|
||||||
spin::{lazy::Lazy, Mutex},
|
spin::{lazy::Lazy, Mutex},
|
||||||
};
|
};
|
||||||
pub struct Services(HashMap<u64, Protocol>);
|
pub struct Services<'a>(HashMap<u64, Protocol<'a>>);
|
||||||
pub static SERVICES: Lazy<Mutex<Services>> = Lazy::new(|| {
|
pub static SERVICES: Lazy<Mutex<Services>> = Lazy::new(|| {
|
||||||
let mut dt = Services(HashMap::new());
|
let mut dt = Services(HashMap::new());
|
||||||
dt.0.insert(0, Protocol::void());
|
dt.0.insert(0, Protocol::void());
|
||||||
|
@ -18,25 +17,26 @@ pub static SERVICES: Lazy<Mutex<Services>> = Lazy::new(|| {
|
||||||
});
|
});
|
||||||
|
|
||||||
pub fn sds_msg_handler(vm: &mut Vm, mem_addr: u64, length: usize) -> Result<(), LogError> {
|
pub fn sds_msg_handler(vm: &mut Vm, mem_addr: u64, length: usize) -> Result<(), LogError> {
|
||||||
let mut msg_vec = block_read(mem_addr, length);
|
let msg_vec = block_read(mem_addr, length);
|
||||||
if msg_vec.is_empty() {
|
if msg_vec.is_empty() {
|
||||||
return Err(LogError::NoMessages);
|
return Err(LogError::NoMessages);
|
||||||
}
|
}
|
||||||
let sds_event_type: ServiceEventType = msg_vec[0].into();
|
let sds_event_type: ServiceEventType = msg_vec[0].into();
|
||||||
msg_vec.remove(0);
|
|
||||||
|
|
||||||
// info!("Length {}", msg_vec.len());
|
// info!("Length {}", msg_vec.len());
|
||||||
|
|
||||||
use ServiceEventType::*;
|
use ServiceEventType::*;
|
||||||
match sds_event_type {
|
match sds_event_type {
|
||||||
CreateService => {
|
CreateService => {
|
||||||
let string = String::from_utf8(msg_vec).expect("Our bytes should be valid utf8");
|
let string =
|
||||||
|
core::str::from_utf8(&msg_vec[1..]).expect("Our bytes should be valid utf8");
|
||||||
let ret = sds_create_service(string);
|
let ret = sds_create_service(string);
|
||||||
vm.registers[1] = hbvm::value::Value(ret as u64);
|
vm.registers[1] = hbvm::value::Value(ret as u64);
|
||||||
}
|
}
|
||||||
DeleteService => todo!(),
|
DeleteService => todo!(),
|
||||||
SearchServices => {
|
SearchServices => {
|
||||||
let string = String::from_utf8(msg_vec).expect("Our bytes should be valid utf8");
|
let string =
|
||||||
|
core::str::from_utf8(&msg_vec[1..]).expect("Our bytes should be valid utf8");
|
||||||
let ret = sds_search_service(string);
|
let ret = sds_search_service(string);
|
||||||
vm.registers[1] = hbvm::value::Value(ret as u64);
|
vm.registers[1] = hbvm::value::Value(ret as u64);
|
||||||
}
|
}
|
||||||
|
@ -78,16 +78,16 @@ impl From<u8> for ServiceEventType {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sds_create_service(protocol: String) -> u64 {
|
fn sds_create_service(protocol: &'static str) -> u64 {
|
||||||
let buff_id = hardware_random_u64();
|
let buff_id = hardware_random_u64();
|
||||||
let mut services = SERVICES.lock();
|
let mut services = SERVICES.lock();
|
||||||
let mut buffers = IPC_BUFFERS.lock();
|
let mut buffers = IPC_BUFFERS.lock();
|
||||||
|
|
||||||
let protocol_ = Protocol::from(protocol.clone());
|
let protocol_ = Protocol::from(protocol);
|
||||||
let mut buff = IpcBuffer::new(false, 0);
|
let mut buff = IpcBuffer::new(false, 0);
|
||||||
|
|
||||||
services.0.insert(buff_id, protocol_.clone());
|
services.0.insert(buff_id, protocol_.clone());
|
||||||
buff.protocol = protocol_.clone();
|
buff.protocol = protocol_;
|
||||||
buffers.insert(buff_id, buff);
|
buffers.insert(buff_id, buff);
|
||||||
|
|
||||||
trace!("BufferID({}) => {}", buff_id, protocol);
|
trace!("BufferID({}) => {}", buff_id, protocol);
|
||||||
|
@ -95,13 +95,13 @@ fn sds_create_service(protocol: String) -> u64 {
|
||||||
buff_id
|
buff_id
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sds_search_service(protocol: String) -> u64 {
|
fn sds_search_service(protocol: &str) -> u64 {
|
||||||
let services = SERVICES.lock();
|
let services = SERVICES.lock();
|
||||||
let compare = Protocol::from(protocol.clone());
|
let compare = Protocol::from(protocol);
|
||||||
for (bid, protocol_canidate) in &services.0 {
|
for (bid, protocol_canidate) in &services.0 {
|
||||||
trace!("BID-{bid} protocol_canidate {:?}", protocol_canidate);
|
trace!("BID-{bid} protocol_canidate {:?}", protocol_canidate);
|
||||||
if protocol_canidate == &compare {
|
if protocol_canidate == &compare {
|
||||||
trace!("BufferID({}) => {}", bid, protocol.clone());
|
trace!("BufferID({}) => {}", bid, protocol);
|
||||||
return *bid;
|
return *bid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,12 +3,11 @@ mod kernel_services;
|
||||||
mod mem;
|
mod mem;
|
||||||
|
|
||||||
use {
|
use {
|
||||||
|
alloc::alloc::{alloc_zeroed, dealloc},
|
||||||
core::{
|
core::{
|
||||||
alloc::Layout,
|
alloc::Layout,
|
||||||
future::Future,
|
future::Future,
|
||||||
marker::PhantomData,
|
|
||||||
pin::Pin,
|
pin::Pin,
|
||||||
ptr::NonNull,
|
|
||||||
task::{Context, Poll},
|
task::{Context, Poll},
|
||||||
},
|
},
|
||||||
hbvm::{
|
hbvm::{
|
||||||
|
@ -22,21 +21,20 @@ const STACK_SIZE: usize = 1024 * 1024;
|
||||||
const TIMER_QUOTIENT: usize = 1000;
|
const TIMER_QUOTIENT: usize = 1000;
|
||||||
type Vm = hbvm::Vm<mem::Memory, TIMER_QUOTIENT>;
|
type Vm = hbvm::Vm<mem::Memory, TIMER_QUOTIENT>;
|
||||||
|
|
||||||
pub struct ExecThread<'p> {
|
pub struct ExecThread {
|
||||||
vm: Vm,
|
vm: Vm,
|
||||||
stack_bottom: NonNull<u8>,
|
stack_bottom: *mut u8,
|
||||||
_phantom: PhantomData<&'p [u8]>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl<'p> Send for ExecThread<'p> {}
|
unsafe impl Send for ExecThread {}
|
||||||
|
|
||||||
impl<'p> ExecThread<'p> {
|
impl ExecThread {
|
||||||
pub fn set_arguments(&mut self, ptr: u64, length: u64) {
|
pub fn set_arguments(&mut self, ptr: u64, length: u64) {
|
||||||
self.vm.registers[1] = hbvm::value::Value(ptr);
|
self.vm.registers[1] = hbvm::value::Value(ptr);
|
||||||
self.vm.registers[2] = hbvm::value::Value(length);
|
self.vm.registers[2] = hbvm::value::Value(length);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn new(program: &'p [u8], entrypoint: Address) -> Self {
|
pub unsafe fn new(program: &[u8], entrypoint: Address) -> Self {
|
||||||
let mut vm = Vm::new(
|
let mut vm = Vm::new(
|
||||||
mem::Memory {},
|
mem::Memory {},
|
||||||
Address::new(program.as_ptr() as u64 + entrypoint.get()),
|
Address::new(program.as_ptr() as u64 + entrypoint.get()),
|
||||||
|
@ -44,27 +42,21 @@ impl<'p> ExecThread<'p> {
|
||||||
|
|
||||||
let stack_bottom = allocate_stack();
|
let stack_bottom = allocate_stack();
|
||||||
|
|
||||||
vm.write_reg(
|
vm.write_reg(254, (stack_bottom as usize + STACK_SIZE - 1) as u64);
|
||||||
254,
|
|
||||||
(stack_bottom.as_ptr() as usize + STACK_SIZE - 1) as u64,
|
|
||||||
);
|
|
||||||
|
|
||||||
ExecThread {
|
ExecThread { vm, stack_bottom }
|
||||||
vm,
|
|
||||||
stack_bottom,
|
|
||||||
_phantom: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'p> Drop for ExecThread<'p> {
|
impl<'p> Drop for ExecThread {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
unsafe { alloc::alloc::dealloc(self.stack_bottom.as_ptr(), stack_layout()) };
|
unsafe { dealloc(self.stack_bottom, stack_layout()) };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'p> Future for ExecThread<'p> {
|
impl<'p> Future for ExecThread {
|
||||||
type Output = Result<(), VmRunError>;
|
type Output = Result<(), VmRunError>;
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||||
match self.vm.run() {
|
match self.vm.run() {
|
||||||
|
@ -105,7 +97,6 @@ impl HandlePageFault for PageFaultHandler {
|
||||||
dataptr: *mut u8,
|
dataptr: *mut u8,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
error!("REASON: {reason} vaddr: {vaddr} size: {size:?} Dataptr {dataptr:p}");
|
error!("REASON: {reason} vaddr: {vaddr} size: {size:?} Dataptr {dataptr:p}");
|
||||||
|
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -116,8 +107,6 @@ const fn stack_layout() -> Layout {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn allocate_stack() -> NonNull<u8> {
|
fn allocate_stack() -> *mut u8 {
|
||||||
let layout = stack_layout();
|
unsafe { alloc_zeroed(stack_layout()) }
|
||||||
NonNull::new(unsafe { alloc::alloc::alloc_zeroed(layout) })
|
|
||||||
.unwrap_or_else(|| alloc::alloc::handle_alloc_error(layout))
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,12 +9,12 @@ pub enum BufferTypes {
|
||||||
Bound(ArrayQueue<Message>),
|
Bound(ArrayQueue<Message>),
|
||||||
}
|
}
|
||||||
/// Interproccess buffer
|
/// Interproccess buffer
|
||||||
pub struct IpcBuffer {
|
pub struct IpcBuffer<'a> {
|
||||||
pub protocol: Protocol,
|
pub protocol: Protocol<'a>,
|
||||||
pub buffer: BufferTypes,
|
pub buffer: BufferTypes,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IpcBuffer {
|
impl<'a> IpcBuffer<'a> {
|
||||||
pub fn new(bounded: bool, length: u64) -> Self {
|
pub fn new(bounded: bool, length: u64) -> Self {
|
||||||
log::debug!(
|
log::debug!(
|
||||||
"New IPCBuffer\r
|
"New IPCBuffer\r
|
||||||
|
|
|
@ -10,11 +10,11 @@ pub struct Funct {
|
||||||
gives: Vec<String>,
|
gives: Vec<String>,
|
||||||
}
|
}
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub struct Protocol {
|
pub struct Protocol<'a> {
|
||||||
types: HashMap<String, Type>,
|
types: HashMap<&'a str, Type>,
|
||||||
fns: HashMap<String, Funct>,
|
fns: HashMap<&'a str, Funct>,
|
||||||
}
|
}
|
||||||
impl Protocol {
|
impl<'a> Protocol<'a> {
|
||||||
pub fn void() -> Self {
|
pub fn void() -> Self {
|
||||||
Self {
|
Self {
|
||||||
types: HashMap::new(),
|
types: HashMap::new(),
|
||||||
|
@ -27,8 +27,8 @@ impl Protocol {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<String> for Protocol {
|
impl<'a> From<&'a str> for Protocol<'a> {
|
||||||
fn from(value: alloc::string::String) -> Self {
|
fn from(value: &'a str) -> Self {
|
||||||
let mut hm_t = HashMap::new();
|
let mut hm_t = HashMap::new();
|
||||||
hm_t.insert(value, Type {});
|
hm_t.insert(value, Type {});
|
||||||
Self {
|
Self {
|
||||||
|
|
|
@ -72,25 +72,24 @@ pub fn kmain(_cmdline: &str, boot_modules: BootModules) -> ! {
|
||||||
for module in boot_modules.into_iter().take(bm_take) {
|
for module in boot_modules.into_iter().take(bm_take) {
|
||||||
let mut cmd = module.cmd;
|
let mut cmd = module.cmd;
|
||||||
if cmd.len() > 2 {
|
if cmd.len() > 2 {
|
||||||
// Remove the quotes
|
// // Remove the quotes
|
||||||
cmd.remove(0);
|
// cmd.remove(0);
|
||||||
cmd.pop();
|
// cmd.pop();
|
||||||
|
cmd = &cmd[1..cmd.len()]
|
||||||
}
|
}
|
||||||
let cmd_len = cmd.as_bytes().len() as u64;
|
let cmd_len = cmd.len() as u64;
|
||||||
|
|
||||||
log::info!("Spawning {} with arguments \"{}\"", module.path, cmd);
|
log::info!("Spawning {} with arguments \"{}\"", module.path, cmd);
|
||||||
|
|
||||||
executor
|
executor.spawn(async move {
|
||||||
.spawn(async move {
|
let mut thr = ExecThread::new(&module.bytes, Address::new(0));
|
||||||
let mut thr = ExecThread::new(&module.bytes, Address::new(0));
|
if cmd_len > 0 {
|
||||||
if cmd_len > 0 {
|
thr.set_arguments(cmd.as_bytes().as_ptr() as u64, cmd_len);
|
||||||
thr.set_arguments(cmd.as_bytes().as_ptr() as u64, cmd_len);
|
}
|
||||||
}
|
if let Err(e) = thr.await {
|
||||||
if let Err(e) = thr.await {
|
log::error!("{e:?}");
|
||||||
log::error!("{e:?}");
|
}
|
||||||
}
|
})
|
||||||
})
|
|
||||||
.unwrap();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
info!("Random number: {}", hardware_random_u64());
|
info!("Random number: {}", hardware_random_u64());
|
||||||
|
@ -107,7 +106,7 @@ pub static DEVICE_TREE: Lazy<Mutex<DeviceTree>> = Lazy::new(|| {
|
||||||
});
|
});
|
||||||
pub static FB_REQ: FramebufferRequest = FramebufferRequest::new(0);
|
pub static FB_REQ: FramebufferRequest = FramebufferRequest::new(0);
|
||||||
|
|
||||||
pub type IpcBuffers = HashMap<u64, IpcBuffer>;
|
pub type IpcBuffers<'a> = HashMap<u64, IpcBuffer<'a>>;
|
||||||
pub static IPC_BUFFERS: Lazy<Mutex<IpcBuffers>> = Lazy::new(|| {
|
pub static IPC_BUFFERS: Lazy<Mutex<IpcBuffers>> = Lazy::new(|| {
|
||||||
let mut bufs = HashMap::new();
|
let mut bufs = HashMap::new();
|
||||||
let log_buffer = IpcBuffer::new(false, 0);
|
let log_buffer = IpcBuffer::new(false, 0);
|
||||||
|
|
|
@ -1,17 +1,14 @@
|
||||||
use {
|
use {
|
||||||
alloc::{boxed::Box, sync::Arc, task::Wake},
|
alloc::{boxed::Box, sync::Arc},
|
||||||
core::{
|
core::{
|
||||||
future::Future,
|
future::Future,
|
||||||
pin::Pin,
|
pin::Pin,
|
||||||
sync::atomic::{AtomicUsize, Ordering},
|
task::{Context, Poll, RawWaker, RawWakerVTable, Waker},
|
||||||
task::{Context, Poll, Waker},
|
|
||||||
},
|
},
|
||||||
crossbeam_queue::SegQueue,
|
crossbeam_queue::SegQueue,
|
||||||
crossbeam_utils::CachePadded,
|
slab::Slab,
|
||||||
};
|
};
|
||||||
|
|
||||||
use alloc::vec::Vec;
|
|
||||||
|
|
||||||
pub fn yield_now() -> impl Future<Output = ()> {
|
pub fn yield_now() -> impl Future<Output = ()> {
|
||||||
struct YieldNow(bool);
|
struct YieldNow(bool);
|
||||||
impl Future for YieldNow {
|
impl Future for YieldNow {
|
||||||
|
@ -32,37 +29,34 @@ pub fn yield_now() -> impl Future<Output = ()> {
|
||||||
YieldNow(false)
|
YieldNow(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
pub struct Executor<F: Future<Output = ()> + Send> {
|
||||||
pub struct Executor {
|
tasks: Slab<Task<F>>,
|
||||||
tasks: Vec<CachePadded<TaskSlot>>,
|
|
||||||
task_queue: Arc<TaskQueue>,
|
task_queue: Arc<TaskQueue>,
|
||||||
max_tasks: usize,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Executor {
|
impl<F: Future<Output = ()> + Send> Executor<F> {
|
||||||
pub fn new(max_tasks: usize) -> Self {
|
pub fn new(size: usize) -> Self {
|
||||||
Self {
|
Self {
|
||||||
tasks: (0..max_tasks)
|
tasks: Slab::with_capacity(size),
|
||||||
.map(|_| CachePadded::new(TaskSlot::default()))
|
task_queue: Arc::new(TaskQueue::new()),
|
||||||
.collect(),
|
|
||||||
task_queue: Arc::new(TaskQueue::new(max_tasks)),
|
|
||||||
max_tasks,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn spawn(&mut self, future: impl Future<Output = ()> + Send + 'static) -> Result<(), ()> {
|
#[inline]
|
||||||
let task_id = self.task_queue.allocate_task_id().ok_or(())?;
|
pub fn spawn(&mut self, future: F) {
|
||||||
self.tasks[task_id.0].lock.replace(Task::new(future));
|
self.task_queue
|
||||||
self.task_queue.push(task_id);
|
.queue
|
||||||
Ok(())
|
.push(self.tasks.insert(Task::new(future)));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run(&mut self) {
|
pub fn run(&mut self) {
|
||||||
let mut task_batch = Vec::with_capacity(16);
|
let mut task_batch = [0; 32];
|
||||||
|
let mut batch_len = 0;
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
self.task_queue.batch_pop(&mut task_batch);
|
self.task_queue.batch_pop(&mut task_batch, &mut batch_len);
|
||||||
if task_batch.is_empty() {
|
|
||||||
|
if batch_len == 0 {
|
||||||
if self.task_queue.is_empty() {
|
if self.task_queue.is_empty() {
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
|
@ -70,23 +64,18 @@ impl Executor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for id in task_batch.drain(..) {
|
for &id in &task_batch[..batch_len] {
|
||||||
let task_slot = &mut self.tasks[id.0];
|
if let Some(task) = self.tasks.get_mut(id) {
|
||||||
|
let waker = task
|
||||||
|
.waker
|
||||||
|
.get_or_insert_with(|| TaskWaker::new(id, Arc::clone(&self.task_queue)));
|
||||||
|
|
||||||
let mut task_opt = task_slot.lock.take();
|
let waker = unsafe { Waker::from_raw(TaskWaker::into_raw_waker(waker)) };
|
||||||
if let Some(task) = &mut task_opt {
|
|
||||||
let waker = task_slot.waker.get_or_insert_with(|| {
|
|
||||||
Arc::new(TaskWaker::new(id, Arc::clone(&self.task_queue)))
|
|
||||||
});
|
|
||||||
|
|
||||||
let waker = Waker::from(Arc::clone(waker));
|
|
||||||
let mut cx = Context::from_waker(&waker);
|
let mut cx = Context::from_waker(&waker);
|
||||||
|
|
||||||
if let Poll::Ready(()) = task.poll(&mut cx) {
|
if let Poll::Ready(()) = task.poll(&mut cx) {
|
||||||
task_slot.waker = None;
|
self.tasks.remove(id);
|
||||||
self.task_queue.free_task_id(id);
|
self.task_queue.free_tasks.push(id);
|
||||||
} else {
|
|
||||||
task_slot.lock.replace(task_opt.take().unwrap());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -94,21 +83,17 @@ impl Executor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
struct Task<F: Future<Output = ()> + Send> {
|
||||||
struct TaskSlot {
|
future: Pin<Box<F>>,
|
||||||
lock: Option<Task>,
|
waker: Option<TaskWaker>,
|
||||||
waker: Option<Arc<TaskWaker>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Task {
|
impl<F: Future<Output = ()> + Send> Task<F> {
|
||||||
future: Pin<Box<dyn Future<Output = ()> + Send>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Task {
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn new(future: impl Future<Output = ()> + Send + 'static) -> Self {
|
pub fn new(future: F) -> Self {
|
||||||
Self {
|
Self {
|
||||||
future: Box::pin(future),
|
future: Box::pin(future),
|
||||||
|
waker: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,77 +103,69 @@ impl Task {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
|
||||||
struct TaskId(usize);
|
|
||||||
|
|
||||||
struct TaskWaker {
|
struct TaskWaker {
|
||||||
id: TaskId,
|
id: usize,
|
||||||
task_queue: Arc<TaskQueue>,
|
task_queue: Arc<TaskQueue>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TaskWaker {
|
impl TaskWaker {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn new(id: TaskId, task_queue: Arc<TaskQueue>) -> Self {
|
fn new(id: usize, task_queue: Arc<TaskQueue>) -> Self {
|
||||||
Self { id, task_queue }
|
Self { id, task_queue }
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl Wake for TaskWaker {
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn wake(self: Arc<Self>) {
|
fn wake(&self) {
|
||||||
self.task_queue.push(self.id);
|
self.task_queue.queue.push(self.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
fn into_raw_waker(waker: &TaskWaker) -> RawWaker {
|
||||||
fn wake_by_ref(self: &Arc<Self>) {
|
let ptr = waker as *const TaskWaker;
|
||||||
self.task_queue.push(self.id);
|
RawWaker::new(ptr.cast(), &VTABLE)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
const VTABLE: RawWakerVTable = RawWakerVTable::new(clone_raw, wake_raw, wake_by_ref_raw, drop_raw);
|
||||||
|
|
||||||
|
unsafe fn clone_raw(ptr: *const ()) -> RawWaker {
|
||||||
|
let waker = &*(ptr as *const TaskWaker);
|
||||||
|
TaskWaker::into_raw_waker(waker)
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe fn wake_raw(ptr: *const ()) {
|
||||||
|
let waker = &*(ptr as *const TaskWaker);
|
||||||
|
waker.wake();
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe fn wake_by_ref_raw(ptr: *const ()) {
|
||||||
|
let waker = &*(ptr as *const TaskWaker);
|
||||||
|
waker.wake();
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe fn drop_raw(_: *const ()) {}
|
||||||
|
|
||||||
struct TaskQueue {
|
struct TaskQueue {
|
||||||
queue: SegQueue<TaskId>,
|
queue: SegQueue<usize>,
|
||||||
next_task: AtomicUsize,
|
next_task: usize,
|
||||||
max_tasks: usize,
|
free_tasks: SegQueue<usize>,
|
||||||
free_tasks: SegQueue<TaskId>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TaskQueue {
|
impl TaskQueue {
|
||||||
fn new(max_tasks: usize) -> Self {
|
fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
queue: SegQueue::new(),
|
queue: SegQueue::new(),
|
||||||
next_task: AtomicUsize::new(0),
|
next_task: 0,
|
||||||
max_tasks,
|
|
||||||
free_tasks: SegQueue::new(),
|
free_tasks: SegQueue::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn allocate_task_id(&self) -> Option<TaskId> {
|
|
||||||
self.free_tasks.pop().or_else(|| {
|
|
||||||
let id = self.next_task.fetch_add(1, Ordering::Relaxed);
|
|
||||||
if id < self.max_tasks {
|
|
||||||
Some(TaskId(id))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn free_task_id(&self, id: TaskId) {
|
fn batch_pop(&self, output: &mut [usize], len: &mut usize) {
|
||||||
self.free_tasks.push(id);
|
*len = 0;
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn push(&self, id: TaskId) {
|
|
||||||
self.queue.push(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn batch_pop(&self, output: &mut Vec<TaskId>) {
|
|
||||||
while let Some(id) = self.queue.pop() {
|
while let Some(id) = self.queue.pop() {
|
||||||
output.push(id);
|
output[*len] = id;
|
||||||
if output.len() >= output.capacity() {
|
*len += 1;
|
||||||
|
if *len == output.len() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -370,7 +370,7 @@ fn run(release: bool, target: Target) -> Result<(), Error> {
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
com.args([
|
com.args([
|
||||||
"-M", "virt",
|
"-M", "virt",
|
||||||
"-cpu", "cortex-a72",
|
"-cpu", "max",
|
||||||
"-device", "ramfb",
|
"-device", "ramfb",
|
||||||
"-device", "qemu-xhci",
|
"-device", "qemu-xhci",
|
||||||
"-device", "usb-kbd",
|
"-device", "usb-kbd",
|
||||||
|
|
|
@ -29,8 +29,7 @@ total_pages := 1 + fb_bytes >> 12
|
||||||
|
|
||||||
front_buffer := @as(^Color, @bitcast(0xFFFF8000C0000000))
|
front_buffer := @as(^Color, @bitcast(0xFFFF8000C0000000))
|
||||||
// jank back buffer time, im sure nothing will go wrong
|
// jank back buffer time, im sure nothing will go wrong
|
||||||
// will be removed as soon as i can figure out a fast way of doing runtime global scope
|
back_buffer := front_buffer + fb_pixels
|
||||||
back_buffer := @as(^Color, @bitcast(0xFFFF8000C0000000 + fb_bytes))
|
|
||||||
|
|
||||||
create_back_buffer := fn(): ^Color {
|
create_back_buffer := fn(): ^Color {
|
||||||
if total_pages <= 0xFF {
|
if total_pages <= 0xFF {
|
||||||
|
@ -50,25 +49,26 @@ create_back_buffer := fn(): ^Color {
|
||||||
}
|
}
|
||||||
|
|
||||||
clear := fn(color: Color): void {
|
clear := fn(color: Color): void {
|
||||||
n := 0
|
cursor := back_buffer
|
||||||
loop if n == 512 break else {
|
boundary := cursor + 512
|
||||||
*(back_buffer + n) = color
|
loop if cursor == boundary break else {
|
||||||
n += 1
|
*cursor = color
|
||||||
|
cursor += 1
|
||||||
}
|
}
|
||||||
n = 1
|
boundary += 512 * 7
|
||||||
loop if n == 8 break else {
|
loop if cursor == boundary break else {
|
||||||
*(@as(^[Color; 512], @bitcast(back_buffer)) + n) = *@as(^[Color; 512], @bitcast(back_buffer))
|
*@as(^[Color; 512], @bitcast(cursor)) = *@as(^[Color; 512], @bitcast(back_buffer))
|
||||||
n += 1
|
cursor += 512
|
||||||
}
|
}
|
||||||
n = 1
|
boundary += copy_pixels - 4096
|
||||||
loop if n == copy_pixels >> 12 break else {
|
loop if cursor == boundary break else {
|
||||||
*(@as(^[Color; 4096], @bitcast(back_buffer)) + n) = *@as(^[Color; 4096], @bitcast(back_buffer))
|
*@as(^[Color; 4096], @bitcast(cursor)) = *@as(^[Color; 4096], @bitcast(back_buffer))
|
||||||
n += 1
|
cursor += 4096
|
||||||
}
|
}
|
||||||
n = 1
|
boundary += (partitions - 1) * copy_pixels
|
||||||
loop if n == partitions break else {
|
loop if cursor == boundary break else {
|
||||||
*(@as(^[Color; copy_pixels], @bitcast(back_buffer)) + n) = *@as(^[Color; copy_pixels], @bitcast(back_buffer))
|
*@as(^[Color; copy_pixels], @bitcast(cursor)) = *@as(^[Color; copy_pixels], @bitcast(back_buffer))
|
||||||
n += 1
|
cursor += @sizeof([u8; copy_pixels])
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -214,6 +214,13 @@ set_dimensions := fn(new: IVec2): void {
|
||||||
}
|
}
|
||||||
|
|
||||||
init := fn(): void {
|
init := fn(): void {
|
||||||
|
arch := @eca(int, 3, 5)
|
||||||
|
// 0: x86_64, 1: aarch64, 2: riscv, (2^64)-1: other
|
||||||
|
if arch == 0 {
|
||||||
|
front_buffer = @as(^Color, @bitcast(0xFFFF8000C0000000))
|
||||||
|
} else if arch == 1 {
|
||||||
|
front_buffer = @as(^Color, @bitcast(0xFFFF8000BC430000))
|
||||||
|
}
|
||||||
back_buffer = create_back_buffer()
|
back_buffer = create_back_buffer()
|
||||||
return
|
return
|
||||||
}
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
.{example} := @use("./examples/amogus.hb")
|
.{example} := @use("./examples/random.hb")
|
||||||
|
|
||||||
main := fn(): void {
|
main := fn(): void {
|
||||||
@inline(example)
|
@inline(example)
|
||||||
|
|
|
@ -23,14 +23,14 @@ resolution = "1024x768x24"
|
||||||
[boot.limine.ableos.modules.1render_driver]
|
[boot.limine.ableos.modules.1render_driver]
|
||||||
path = "boot:///render_driver.hbf"
|
path = "boot:///render_driver.hbf"
|
||||||
|
|
||||||
[boot.limine.ableos.modules.0serial_driver]
|
# [boot.limine.ableos.modules.0serial_driver]
|
||||||
path = "boot:///serial_driver.hbf"
|
# path = "boot:///serial_driver.hbf"
|
||||||
|
|
||||||
[boot.limine.ableos.modules.diskio_driver]
|
# [boot.limine.ableos.modules.diskio_driver]
|
||||||
path = "boot:///diskio_driver.hbf"
|
# path = "boot:///diskio_driver.hbf"
|
||||||
|
|
||||||
[boot.limine.ableos.modules.render_example]
|
[boot.limine.ableos.modules.render_example]
|
||||||
path = "boot:///render_example.hbf"
|
path = "boot:///render_example.hbf"
|
||||||
|
|
||||||
[boot.limine.ableos.modules.serial_driver_test]
|
# [boot.limine.ableos.modules.serial_driver_test]
|
||||||
path = "boot:///serial_driver_test.hbf"
|
# path = "boot:///serial_driver_test.hbf"
|
||||||
|
|
Loading…
Reference in a new issue