able told me to push 🙏

This commit is contained in:
koniifer 2024-09-11 23:09:47 +01:00
parent 3a6778149b
commit fef5487e62
20 changed files with 270 additions and 296 deletions

40
Cargo.lock generated
View file

@ -2,6 +2,15 @@
# It is not intended for manual editing.
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]]
name = "addr2line"
version = "0.24.1"
@ -52,9 +61,9 @@ dependencies = [
[[package]]
name = "anyhow"
version = "1.0.87"
version = "1.0.88"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "10f00e1f6e58a40e807377c75c6a7f97bf9044fab57816f2414e6f5f4499d7b8"
checksum = "4e1496f8fb1fbf272686b8d37f523dab3e4a7443300055e74cdaa449f3114356"
[[package]]
name = "autocfg"
@ -381,17 +390,17 @@ dependencies = [
[[package]]
name = "hbbytecode"
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]]
name = "hbbytecode"
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]]
name = "hblang"
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 = [
"hbvm 0.1.0 (git+https://git.ablecorp.us/AbleOS/holey-bytes.git)",
]
@ -399,7 +408,7 @@ dependencies = [
[[package]]
name = "hbvm"
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 = [
"hbbytecode 0.1.0 (git+https://git.ablecorp.us/AbleOS/holey-bytes.git)",
]
@ -407,7 +416,7 @@ dependencies = [
[[package]]
name = "hbvm"
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 = [
"hbbytecode 0.1.0 (git+https://git.ablecorp.us/ableos/holey-bytes)",
]
@ -583,8 +592,8 @@ dependencies = [
name = "kernel"
version = "0.2.0"
dependencies = [
"aarch64-cpu",
"crossbeam-queue",
"crossbeam-utils",
"derive_more",
"embedded-graphics",
"hashbrown",
@ -592,6 +601,7 @@ dependencies = [
"limine",
"log",
"sbi",
"slab",
"spin",
"uart_16550",
"versioning",
@ -989,9 +999,9 @@ dependencies = [
[[package]]
name = "rustls"
version = "0.23.12"
version = "0.23.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c58f8c84392efc0a126acce10fa59ff7b3d2ac06ab451a33f2741989b806b044"
checksum = "f2dabaac7466917e566adb06783a81ca48944c6898a1b08b9374106dd671f4c8"
dependencies = [
"once_cell",
"ring",
@ -1218,6 +1228,12 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]]
name = "tock-registers"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "696941a0aee7e276a165a978b37918fd5d22c55c3d6bda197813070ca9c0f21c"
[[package]]
name = "tokio"
version = "1.40.0"
@ -1349,9 +1365,9 @@ checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75"
[[package]]
name = "unicode-ident"
version = "1.0.12"
version = "1.0.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe"
[[package]]
name = "unicode-normalization"

View file

@ -9,6 +9,7 @@ embedded-graphics = "0.8"
hbvm.git = "https://git.ablecorp.us/ableos/holey-bytes"
log = "0.4"
spin = "0.9"
slab = { version = "0.4", default-features = false }
uart_16550 = { version = "0.3", features = ["nightly"] }
xml.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
features = ["alloc", "nightly"]
[dependencies.crossbeam-utils]
version = "0.8"
default-features = false
# [dependencies.clparse]
# git = "https://git.ablecorp.us/ableos/ableos_userland"
# default-features = false
@ -56,3 +53,6 @@ virtio-drivers = "0.7"
[target.'cfg(target_arch = "riscv64")'.dependencies]
sbi = "0.2.0"
[target.'cfg(target_arch = "aarch64")'.dependencies]
aarch64-cpu = "9"

View file

@ -1,5 +1,5 @@
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,
});
@ -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 {
SERIAL_CONSOLE.lock().write_fmt(args)?;
TERMINAL_LOGGER.lock().write_fmt(args)?;

View file

@ -1,6 +1,7 @@
pub use logging::log;
use {
crate::{allocator, bootmodules::BootModule, kmain::kmain},
alloc::vec::Vec,
core::arch::asm,
limine::FramebufferRequest,
};
@ -41,7 +42,7 @@ unsafe extern "C" fn _kernel_start() -> ! {
static KFILE_REQ: KernelFileRequest = KernelFileRequest::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() {
let bm = bm.unwrap();
@ -52,18 +53,13 @@ unsafe extern "C" fn _kernel_start() -> ! {
let raw_bytes = core::slice::from_raw_parts(
file.base.as_ptr().expect("invalid initrd"),
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() {
panic!("invalid file path: {:?}", file_path);
}
let file_cmd = alloc::string::String::from_utf8(
file.cmdline.to_str().unwrap().to_bytes().to_vec(),
);
let file_cmd = file.cmdline.to_str().unwrap().to_str();
if file_cmd.is_err() {
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);
}
crate::kmain::kmain(
kmain(
KFILE_REQ
.get_response()
.get()
@ -99,8 +95,6 @@ unsafe extern "C" fn _kernel_start() -> ! {
.unwrap_or_default(),
bootmodules,
);
spin_loop();
}
pub fn spin_loop() -> ! {
@ -110,7 +104,15 @@ pub fn spin_loop() -> ! {
}
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() {}

View file

@ -1,7 +1,7 @@
mod memory;
use {
alloc::boxed::Box,
alloc::{boxed::Box, vec::Vec},
core::{
arch::{asm, global_asm},
fmt::Write,
@ -45,7 +45,7 @@ extern "C" {
static USABLE_MEMORY_SIZE: usize;
}
static SERIAL_CONSOLE: Once<Mutex<MmioSerialPort>> = Once::new();
pub static SERIAL_CONSOLE: Once<Mutex<MmioSerialPort>> = Once::new();
#[no_mangle]
unsafe extern "C" fn _kernel_start() -> ! {
@ -95,7 +95,7 @@ unsafe extern "C" fn _kernel_start() -> ! {
in(reg) satp_value,
);
crate::kmain::kmain("baka=9", None);
crate::kmain::kmain("baka=9", Vec::new());
}
/// 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 {
SERIAL_CONSOLE.get().unwrap().lock().write_fmt(args)
}

View file

@ -11,6 +11,9 @@ use {
pub const DOUBLE_FAULT_IX: u16 = 0;
const STACK_SIZE: usize = 5 * 1024;
const STACK_ALIGNMENT: usize = 4096;
pub unsafe fn init() {
use x86_64::instructions::{
segmentation::{Segment, CS, SS},
@ -32,15 +35,15 @@ struct Selectors {
static TSS: Lazy<TaskStateSegment> = Lazy::new(|| {
let mut tss = TaskStateSegment::new();
tss.interrupt_stack_table[usize::from(DOUBLE_FAULT_IX)] = {
const SIZE: usize = 5 * 1024;
let stack = unsafe {
alloc::alloc::alloc_zeroed(
alloc::alloc::Layout::from_size_align(SIZE, 1).expect("stack pointer"),
)
};
VirtAddr::from_ptr(stack) + SIZE as u64
let stack_ptr = unsafe {
let layout = alloc::alloc::Layout::from_size_align(STACK_SIZE, STACK_ALIGNMENT)
.expect("Failed to create stack layout");
let stack = alloc::alloc::alloc_zeroed(layout);
VirtAddr::from_ptr(stack) + STACK_SIZE as u64
};
tss.interrupt_stack_table[usize::from(DOUBLE_FAULT_IX)] = stack_ptr;
tss
});

View file

@ -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};
pub mod memory;
@ -142,18 +142,13 @@ unsafe extern "C" fn start() -> ! {
let raw_bytes = core::slice::from_raw_parts(
file.base.as_ptr().expect("invalid initrd"),
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() {
panic!("invalid file path: {:?}", file_path);
}
let file_cmd = alloc::string::String::from_utf8(
file.cmdline.to_str().unwrap().to_bytes().to_vec(),
);
let file_cmd = file.cmdline.to_str().unwrap().to_str();
if file_cmd.is_err() {
panic!("invalid module cmd: {:?}", file_cmd);
}
@ -191,15 +186,10 @@ unsafe extern "C" fn start() -> ! {
)
}
use crossbeam_utils::Backoff;
/// Spin loop
pub fn spin_loop() -> ! {
let backoff = Backoff::new();
loop {
core::hint::spin_loop();
// x86_64::instructions::hlt();
backoff.spin()
x86_64::instructions::hlt()
}
}
@ -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() {}
#[allow(unused)]

View file

@ -1,20 +1,20 @@
use {
// crate::alloc::string::ToString,
alloc::{string::String, vec::Vec},
alloc::vec::Vec,
// clparse::Arguments,
// core::fmt::{Debug, Display},
// log::trace,
// xml::XMLElement,
};
pub type BootModules = Vec<BootModule>;
pub type BootModules<'a> = Vec<BootModule<'a>>;
pub struct BootModule {
pub path: String,
pub bytes: Vec<u8>,
pub cmd: String,
pub struct BootModule<'a> {
pub path: &'a str,
pub bytes: &'a [u8],
pub cmd: &'a str,
}
impl BootModule {
pub fn new(path: String, bytes: Vec<u8>, cmd: String) -> Self {
impl<'a> BootModule<'a> {
pub fn new(path: &'a str, bytes: &'a [u8], cmd: &'a str) -> Self {
Self { path, bytes, cmd }
}
}

View file

@ -5,7 +5,6 @@ use crate::holeybytes::kernel_services::{block_read, service_definition_service:
use {
super::Vm,
crate::{arch, ipc::buffer::IpcBuffer, kmain::IPC_BUFFERS},
alloc::string::String,
log::{debug, error, info, trace, warn},
};
@ -79,26 +78,19 @@ pub fn handler(vm: &mut Vm) {
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 => {
unsafe fn x86_in(address: u16) -> u8 {
x86_64::instructions::port::Port::new(address).read()
}
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) {
unsafe fn x86_out<T: x86_64::instructions::port::PortWrite>(
address: u16,
value: T,
) {
x86_64::instructions::port::Port::new(address).write(value);
}
unsafe fn x86_out_16(address: u16, value: u16) {
x86_64::instructions::port::Port::new(address).write(value);
unsafe fn x86_in<T: x86_64::instructions::port::PortRead>(address: u16) -> T {
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_type = msg_vec[0];
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 value = unsafe {
match size {
1 => x86_in(addr) as u64,
2 => x86_in_16(addr) as u64,
4 => x86_in_32(addr) as u64,
1 => x86_in::<u8>(addr) as u64,
2 => x86_in::<u16>(addr) as u64,
4 => x86_in::<u32>(addr) as u64,
_ => panic!("how?"),
}
};
@ -141,13 +133,13 @@ pub fn handler(vm: &mut Vm) {
unsafe {
match size {
1 => x86_out(addr, msg_vec[3]),
2 => x86_out_16(
2 => x86_out(
addr,
u16::from_le_bytes(
msg_vec[3..5].try_into().unwrap_unchecked(),
),
),
4 => x86_out_32(
4 => x86_out(
addr,
u32::from_le_bytes(
msg_vec[3..7].try_into().unwrap_unchecked(),
@ -162,7 +154,18 @@ pub fn handler(vm: &mut Vm) {
}
// source of rng
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 => {
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> {
// let message_length = 8 + 8 + 8;
// 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();
match String::from_utf8(msg_vec) {
let log_level = msg_vec.last().unwrap();
match core::str::from_utf8(&msg_vec[1..]) {
Ok(strr) => {
// use LogLevel::*;
let _ll = match log_level {

View file

@ -1,15 +1,9 @@
use alloc::vec::Vec;
use core::slice;
pub mod mem_serve;
pub mod service_definition_service;
pub fn block_read(mem_addr: u64, length: usize) -> Vec<u8> {
let mut msg_vec = Vec::with_capacity(length);
let xyz = mem_addr as *const u8;
for x in 0..(length as isize) {
let value = unsafe { xyz.offset(x).read() };
msg_vec.push(value);
}
msg_vec
#[inline(always)]
pub fn block_read<'a>(mem_addr: u64, length: usize) -> &'a [u8] {
unsafe { slice::from_raw_parts(mem_addr as *const u8, length) }
}

View file

@ -5,12 +5,11 @@ use {
ipc::{buffer::IpcBuffer, protocol::Protocol},
kmain::IPC_BUFFERS,
},
alloc::string::String,
hashbrown::HashMap,
log::{info, trace},
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(|| {
let mut dt = Services(HashMap::new());
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> {
let mut msg_vec = block_read(mem_addr, length);
let msg_vec = block_read(mem_addr, length);
if msg_vec.is_empty() {
return Err(LogError::NoMessages);
}
let sds_event_type: ServiceEventType = msg_vec[0].into();
msg_vec.remove(0);
// info!("Length {}", msg_vec.len());
use ServiceEventType::*;
match sds_event_type {
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);
vm.registers[1] = hbvm::value::Value(ret as u64);
}
DeleteService => todo!(),
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);
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 mut services = SERVICES.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);
services.0.insert(buff_id, protocol_.clone());
buff.protocol = protocol_.clone();
buff.protocol = protocol_;
buffers.insert(buff_id, buff);
trace!("BufferID({}) => {}", buff_id, protocol);
@ -95,13 +95,13 @@ fn sds_create_service(protocol: String) -> u64 {
buff_id
}
fn sds_search_service(protocol: String) -> u64 {
fn sds_search_service(protocol: &str) -> u64 {
let services = SERVICES.lock();
let compare = Protocol::from(protocol.clone());
let compare = Protocol::from(protocol);
for (bid, protocol_canidate) in &services.0 {
trace!("BID-{bid} protocol_canidate {:?}", protocol_canidate);
if protocol_canidate == &compare {
trace!("BufferID({}) => {}", bid, protocol.clone());
trace!("BufferID({}) => {}", bid, protocol);
return *bid;
}
}

View file

@ -3,12 +3,11 @@ mod kernel_services;
mod mem;
use {
alloc::alloc::{alloc_zeroed, dealloc},
core::{
alloc::Layout,
future::Future,
marker::PhantomData,
pin::Pin,
ptr::NonNull,
task::{Context, Poll},
},
hbvm::{
@ -22,21 +21,20 @@ const STACK_SIZE: usize = 1024 * 1024;
const TIMER_QUOTIENT: usize = 1000;
type Vm = hbvm::Vm<mem::Memory, TIMER_QUOTIENT>;
pub struct ExecThread<'p> {
pub struct ExecThread {
vm: Vm,
stack_bottom: NonNull<u8>,
_phantom: PhantomData<&'p [u8]>,
stack_bottom: *mut 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) {
self.vm.registers[1] = hbvm::value::Value(ptr);
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(
mem::Memory {},
Address::new(program.as_ptr() as u64 + entrypoint.get()),
@ -44,27 +42,21 @@ impl<'p> ExecThread<'p> {
let stack_bottom = allocate_stack();
vm.write_reg(
254,
(stack_bottom.as_ptr() as usize + STACK_SIZE - 1) as u64,
);
vm.write_reg(254, (stack_bottom as usize + STACK_SIZE - 1) as u64);
ExecThread {
vm,
stack_bottom,
_phantom: PhantomData,
}
ExecThread { vm, stack_bottom }
}
}
impl<'p> Drop for ExecThread<'p> {
impl<'p> Drop for ExecThread {
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>;
#[inline(always)]
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
match self.vm.run() {
@ -105,7 +97,6 @@ impl HandlePageFault for PageFaultHandler {
dataptr: *mut u8,
) -> bool {
error!("REASON: {reason} vaddr: {vaddr} size: {size:?} Dataptr {dataptr:p}");
false
}
}
@ -116,8 +107,6 @@ const fn stack_layout() -> Layout {
}
#[inline(always)]
fn allocate_stack() -> NonNull<u8> {
let layout = stack_layout();
NonNull::new(unsafe { alloc::alloc::alloc_zeroed(layout) })
.unwrap_or_else(|| alloc::alloc::handle_alloc_error(layout))
fn allocate_stack() -> *mut u8 {
unsafe { alloc_zeroed(stack_layout()) }
}

View file

@ -9,12 +9,12 @@ pub enum BufferTypes {
Bound(ArrayQueue<Message>),
}
/// Interproccess buffer
pub struct IpcBuffer {
pub protocol: Protocol,
pub struct IpcBuffer<'a> {
pub protocol: Protocol<'a>,
pub buffer: BufferTypes,
}
impl IpcBuffer {
impl<'a> IpcBuffer<'a> {
pub fn new(bounded: bool, length: u64) -> Self {
log::debug!(
"New IPCBuffer\r

View file

@ -10,11 +10,11 @@ pub struct Funct {
gives: Vec<String>,
}
#[derive(Debug, PartialEq, Clone)]
pub struct Protocol {
types: HashMap<String, Type>,
fns: HashMap<String, Funct>,
pub struct Protocol<'a> {
types: HashMap<&'a str, Type>,
fns: HashMap<&'a str, Funct>,
}
impl Protocol {
impl<'a> Protocol<'a> {
pub fn void() -> Self {
Self {
types: HashMap::new(),
@ -27,8 +27,8 @@ impl Protocol {
}
}
impl From<String> for Protocol {
fn from(value: alloc::string::String) -> Self {
impl<'a> From<&'a str> for Protocol<'a> {
fn from(value: &'a str) -> Self {
let mut hm_t = HashMap::new();
hm_t.insert(value, Type {});
Self {

View file

@ -72,25 +72,24 @@ pub fn kmain(_cmdline: &str, boot_modules: BootModules) -> ! {
for module in boot_modules.into_iter().take(bm_take) {
let mut cmd = module.cmd;
if cmd.len() > 2 {
// Remove the quotes
cmd.remove(0);
cmd.pop();
// // Remove the quotes
// cmd.remove(0);
// 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);
executor
.spawn(async move {
let mut thr = ExecThread::new(&module.bytes, Address::new(0));
if cmd_len > 0 {
thr.set_arguments(cmd.as_bytes().as_ptr() as u64, cmd_len);
}
if let Err(e) = thr.await {
log::error!("{e:?}");
}
})
.unwrap();
executor.spawn(async move {
let mut thr = ExecThread::new(&module.bytes, Address::new(0));
if cmd_len > 0 {
thr.set_arguments(cmd.as_bytes().as_ptr() as u64, cmd_len);
}
if let Err(e) = thr.await {
log::error!("{e:?}");
}
})
}
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 type IpcBuffers = HashMap<u64, IpcBuffer>;
pub type IpcBuffers<'a> = HashMap<u64, IpcBuffer<'a>>;
pub static IPC_BUFFERS: Lazy<Mutex<IpcBuffers>> = Lazy::new(|| {
let mut bufs = HashMap::new();
let log_buffer = IpcBuffer::new(false, 0);

View file

@ -1,17 +1,14 @@
use {
alloc::{boxed::Box, sync::Arc, task::Wake},
alloc::{boxed::Box, sync::Arc},
core::{
future::Future,
pin::Pin,
sync::atomic::{AtomicUsize, Ordering},
task::{Context, Poll, Waker},
task::{Context, Poll, RawWaker, RawWakerVTable, Waker},
},
crossbeam_queue::SegQueue,
crossbeam_utils::CachePadded,
slab::Slab,
};
use alloc::vec::Vec;
pub fn yield_now() -> impl Future<Output = ()> {
struct YieldNow(bool);
impl Future for YieldNow {
@ -32,37 +29,34 @@ pub fn yield_now() -> impl Future<Output = ()> {
YieldNow(false)
}
#[derive(Default)]
pub struct Executor {
tasks: Vec<CachePadded<TaskSlot>>,
pub struct Executor<F: Future<Output = ()> + Send> {
tasks: Slab<Task<F>>,
task_queue: Arc<TaskQueue>,
max_tasks: usize,
}
impl Executor {
pub fn new(max_tasks: usize) -> Self {
impl<F: Future<Output = ()> + Send> Executor<F> {
pub fn new(size: usize) -> Self {
Self {
tasks: (0..max_tasks)
.map(|_| CachePadded::new(TaskSlot::default()))
.collect(),
task_queue: Arc::new(TaskQueue::new(max_tasks)),
max_tasks,
tasks: Slab::with_capacity(size),
task_queue: Arc::new(TaskQueue::new()),
}
}
pub fn spawn(&mut self, future: impl Future<Output = ()> + Send + 'static) -> Result<(), ()> {
let task_id = self.task_queue.allocate_task_id().ok_or(())?;
self.tasks[task_id.0].lock.replace(Task::new(future));
self.task_queue.push(task_id);
Ok(())
#[inline]
pub fn spawn(&mut self, future: F) {
self.task_queue
.queue
.push(self.tasks.insert(Task::new(future)));
}
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 {
self.task_queue.batch_pop(&mut task_batch);
if task_batch.is_empty() {
self.task_queue.batch_pop(&mut task_batch, &mut batch_len);
if batch_len == 0 {
if self.task_queue.is_empty() {
break;
} else {
@ -70,23 +64,18 @@ impl Executor {
}
}
for id in task_batch.drain(..) {
let task_slot = &mut self.tasks[id.0];
for &id in &task_batch[..batch_len] {
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();
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 waker = unsafe { Waker::from_raw(TaskWaker::into_raw_waker(waker)) };
let mut cx = Context::from_waker(&waker);
if let Poll::Ready(()) = task.poll(&mut cx) {
task_slot.waker = None;
self.task_queue.free_task_id(id);
} else {
task_slot.lock.replace(task_opt.take().unwrap());
self.tasks.remove(id);
self.task_queue.free_tasks.push(id);
}
}
}
@ -94,21 +83,17 @@ impl Executor {
}
}
#[derive(Default)]
struct TaskSlot {
lock: Option<Task>,
waker: Option<Arc<TaskWaker>>,
struct Task<F: Future<Output = ()> + Send> {
future: Pin<Box<F>>,
waker: Option<TaskWaker>,
}
struct Task {
future: Pin<Box<dyn Future<Output = ()> + Send>>,
}
impl Task {
impl<F: Future<Output = ()> + Send> Task<F> {
#[inline(always)]
pub fn new(future: impl Future<Output = ()> + Send + 'static) -> Self {
pub fn new(future: F) -> Self {
Self {
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 {
id: TaskId,
id: usize,
task_queue: Arc<TaskQueue>,
}
impl TaskWaker {
#[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 }
}
}
impl Wake for TaskWaker {
#[inline(always)]
fn wake(self: Arc<Self>) {
self.task_queue.push(self.id);
fn wake(&self) {
self.task_queue.queue.push(self.id);
}
#[inline(always)]
fn wake_by_ref(self: &Arc<Self>) {
self.task_queue.push(self.id);
fn into_raw_waker(waker: &TaskWaker) -> RawWaker {
let ptr = waker as *const TaskWaker;
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 {
queue: SegQueue<TaskId>,
next_task: AtomicUsize,
max_tasks: usize,
free_tasks: SegQueue<TaskId>,
queue: SegQueue<usize>,
next_task: usize,
free_tasks: SegQueue<usize>,
}
impl TaskQueue {
fn new(max_tasks: usize) -> Self {
fn new() -> Self {
Self {
queue: SegQueue::new(),
next_task: AtomicUsize::new(0),
max_tasks,
queue: SegQueue::new(),
next_task: 0,
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)]
fn free_task_id(&self, id: TaskId) {
self.free_tasks.push(id);
}
#[inline(always)]
fn push(&self, id: TaskId) {
self.queue.push(id);
}
#[inline(always)]
fn batch_pop(&self, output: &mut Vec<TaskId>) {
fn batch_pop(&self, output: &mut [usize], len: &mut usize) {
*len = 0;
while let Some(id) = self.queue.pop() {
output.push(id);
if output.len() >= output.capacity() {
output[*len] = id;
*len += 1;
if *len == output.len() {
break;
}
}

View file

@ -370,7 +370,7 @@ fn run(release: bool, target: Target) -> Result<(), Error> {
#[rustfmt::skip]
com.args([
"-M", "virt",
"-cpu", "cortex-a72",
"-cpu", "max",
"-device", "ramfb",
"-device", "qemu-xhci",
"-device", "usb-kbd",

View file

@ -29,8 +29,7 @@ total_pages := 1 + fb_bytes >> 12
front_buffer := @as(^Color, @bitcast(0xFFFF8000C0000000))
// 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 := @as(^Color, @bitcast(0xFFFF8000C0000000 + fb_bytes))
back_buffer := front_buffer + fb_pixels
create_back_buffer := fn(): ^Color {
if total_pages <= 0xFF {
@ -50,25 +49,26 @@ create_back_buffer := fn(): ^Color {
}
clear := fn(color: Color): void {
n := 0
loop if n == 512 break else {
*(back_buffer + n) = color
n += 1
cursor := back_buffer
boundary := cursor + 512
loop if cursor == boundary break else {
*cursor = color
cursor += 1
}
n = 1
loop if n == 8 break else {
*(@as(^[Color; 512], @bitcast(back_buffer)) + n) = *@as(^[Color; 512], @bitcast(back_buffer))
n += 1
boundary += 512 * 7
loop if cursor == boundary break else {
*@as(^[Color; 512], @bitcast(cursor)) = *@as(^[Color; 512], @bitcast(back_buffer))
cursor += 512
}
n = 1
loop if n == copy_pixels >> 12 break else {
*(@as(^[Color; 4096], @bitcast(back_buffer)) + n) = *@as(^[Color; 4096], @bitcast(back_buffer))
n += 1
boundary += copy_pixels - 4096
loop if cursor == boundary break else {
*@as(^[Color; 4096], @bitcast(cursor)) = *@as(^[Color; 4096], @bitcast(back_buffer))
cursor += 4096
}
n = 1
loop if n == partitions break else {
*(@as(^[Color; copy_pixels], @bitcast(back_buffer)) + n) = *@as(^[Color; copy_pixels], @bitcast(back_buffer))
n += 1
boundary += (partitions - 1) * copy_pixels
loop if cursor == boundary break else {
*@as(^[Color; copy_pixels], @bitcast(cursor)) = *@as(^[Color; copy_pixels], @bitcast(back_buffer))
cursor += @sizeof([u8; copy_pixels])
}
return
}
@ -214,6 +214,13 @@ set_dimensions := fn(new: IVec2): 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()
return
}

View file

@ -1,4 +1,4 @@
.{example} := @use("./examples/amogus.hb")
.{example} := @use("./examples/random.hb")
main := fn(): void {
@inline(example)

View file

@ -23,14 +23,14 @@ resolution = "1024x768x24"
[boot.limine.ableos.modules.1render_driver]
path = "boot:///render_driver.hbf"
[boot.limine.ableos.modules.0serial_driver]
path = "boot:///serial_driver.hbf"
# [boot.limine.ableos.modules.0serial_driver]
# path = "boot:///serial_driver.hbf"
[boot.limine.ableos.modules.diskio_driver]
path = "boot:///diskio_driver.hbf"
# [boot.limine.ableos.modules.diskio_driver]
# path = "boot:///diskio_driver.hbf"
[boot.limine.ableos.modules.render_example]
path = "boot:///render_example.hbf"
[boot.limine.ableos.modules.serial_driver_test]
path = "boot:///serial_driver_test.hbf"
# [boot.limine.ableos.modules.serial_driver_test]
# path = "boot:///serial_driver_test.hbf"