Compare commits
8 commits
d9caa17f3c
...
d2488689fe
Author | SHA1 | Date | |
---|---|---|---|
Able | d2488689fe | ||
Able | fe70d81bd0 | ||
Able | cc076d9540 | ||
Able | 3173b63c93 | ||
koniifer | 48027196b1 | ||
koniifer | 78553a3190 | ||
koniifer | df74b09134 | ||
koniifer | 2321efd2e7 |
28
Cargo.lock
generated
28
Cargo.lock
generated
|
@ -61,9 +61,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "anyhow"
|
name = "anyhow"
|
||||||
version = "1.0.88"
|
version = "1.0.89"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4e1496f8fb1fbf272686b8d37f523dab3e4a7443300055e74cdaa449f3114356"
|
checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "autocfg"
|
name = "autocfg"
|
||||||
|
@ -148,9 +148,9 @@ checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.1.18"
|
version = "1.1.20"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b62ac837cdb5cb22e10a256099b4fc502b1dfe560cb282963a974d7abd80e476"
|
checksum = "45bcde016d64c21da4be18b655631e5ab6d3107607e71a73a9f53eb48aae23fb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"shlex",
|
"shlex",
|
||||||
]
|
]
|
||||||
|
@ -395,7 +395,7 @@ source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#4a9b9de87fd56a6bbd5
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hbbytecode"
|
name = "hbbytecode"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://git.ablecorp.us/ableos/holey-bytes#c133c2dbe71b3f1e1142bacef200775ae0c1d22d"
|
source = "git+https://git.ablecorp.us/ableos/holey-bytes.git#4a9b9de87fd56a6bbd5d0ca2c622104d4807612b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hblang"
|
name = "hblang"
|
||||||
|
@ -416,9 +416,9 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hbvm"
|
name = "hbvm"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://git.ablecorp.us/ableos/holey-bytes#c133c2dbe71b3f1e1142bacef200775ae0c1d22d"
|
source = "git+https://git.ablecorp.us/ableos/holey-bytes.git#4a9b9de87fd56a6bbd5d0ca2c622104d4807612b"
|
||||||
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.git)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -526,9 +526,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "iana-time-zone"
|
name = "iana-time-zone"
|
||||||
version = "0.1.60"
|
version = "0.1.61"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141"
|
checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"android_system_properties",
|
"android_system_properties",
|
||||||
"core-foundation-sys",
|
"core-foundation-sys",
|
||||||
|
@ -597,7 +597,7 @@ dependencies = [
|
||||||
"derive_more",
|
"derive_more",
|
||||||
"embedded-graphics",
|
"embedded-graphics",
|
||||||
"hashbrown",
|
"hashbrown",
|
||||||
"hbvm 0.1.0 (git+https://git.ablecorp.us/ableos/holey-bytes)",
|
"hbvm 0.1.0 (git+https://git.ablecorp.us/ableos/holey-bytes.git)",
|
||||||
"limine",
|
"limine",
|
||||||
"log",
|
"log",
|
||||||
"sbi",
|
"sbi",
|
||||||
|
@ -737,9 +737,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "once_cell"
|
name = "once_cell"
|
||||||
version = "1.20.0"
|
version = "1.19.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "33ea5043e58958ee56f3e15a90aee535795cd7dfd319846288d93c5b57d85cbe"
|
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "paste"
|
name = "paste"
|
||||||
|
@ -1283,9 +1283,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "toml_edit"
|
name = "toml_edit"
|
||||||
version = "0.22.20"
|
version = "0.22.21"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d"
|
checksum = "3b072cee73c449a636ffd6f32bd8de3a9f7119139aff882f44943ce2986dc5cf"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"indexmap",
|
"indexmap",
|
||||||
"serde",
|
"serde",
|
||||||
|
|
|
@ -6,7 +6,7 @@ version = "0.2.0"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
embedded-graphics = "0.8"
|
embedded-graphics = "0.8"
|
||||||
hbvm.git = "https://git.ablecorp.us/ableos/holey-bytes"
|
hbvm.git = "https://git.ablecorp.us/ableos/holey-bytes.git"
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
spin = "0.9"
|
spin = "0.9"
|
||||||
slab = { version = "0.4", default-features = false }
|
slab = { version = "0.4", default-features = false }
|
||||||
|
|
|
@ -12,7 +12,7 @@ use {
|
||||||
pub const DOUBLE_FAULT_IX: u16 = 0;
|
pub const DOUBLE_FAULT_IX: u16 = 0;
|
||||||
|
|
||||||
const STACK_SIZE: usize = 5 * 1024;
|
const STACK_SIZE: usize = 5 * 1024;
|
||||||
const STACK_ALIGNMENT: usize = 4096;
|
const STACK_ALIGNMENT: usize = 1;
|
||||||
|
|
||||||
pub unsafe fn init() {
|
pub unsafe fn init() {
|
||||||
use x86_64::instructions::{
|
use x86_64::instructions::{
|
||||||
|
@ -39,7 +39,7 @@ static TSS: Lazy<TaskStateSegment> = Lazy::new(|| {
|
||||||
let stack_ptr = unsafe {
|
let stack_ptr = unsafe {
|
||||||
let layout = alloc::alloc::Layout::from_size_align(STACK_SIZE, STACK_ALIGNMENT)
|
let layout = alloc::alloc::Layout::from_size_align(STACK_SIZE, STACK_ALIGNMENT)
|
||||||
.expect("Failed to create stack layout");
|
.expect("Failed to create stack layout");
|
||||||
let stack = alloc::alloc::alloc_zeroed(layout);
|
let stack = alloc::alloc::alloc(layout);
|
||||||
VirtAddr::from_ptr(stack) + STACK_SIZE as u64
|
VirtAddr::from_ptr(stack) + STACK_SIZE as u64
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,56 +1,52 @@
|
||||||
// TODO: Turn apic keyboard interrupt into a standard ipc message
|
|
||||||
use {
|
use {
|
||||||
|
core::mem::MaybeUninit,
|
||||||
log::trace,
|
log::trace,
|
||||||
spin::{Lazy, Mutex},
|
|
||||||
x2apic::lapic::{LocalApic, LocalApicBuilder},
|
x2apic::lapic::{LocalApic, LocalApicBuilder},
|
||||||
x86_64::structures::idt::{InterruptDescriptorTable, InterruptStackFrame, PageFaultErrorCode},
|
x86_64::structures::idt::{InterruptDescriptorTable, InterruptStackFrame, PageFaultErrorCode},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub unsafe fn init() {
|
/// Safety: Using LAPIC or IDT before init() is UB
|
||||||
trace!("Initialising IDT");
|
/// Using
|
||||||
IDT.load();
|
static mut LAPIC: LocalApic = unsafe { MaybeUninit::zeroed().assume_init() };
|
||||||
Lazy::force(&LAPIC);
|
static mut IDT: InterruptDescriptorTable = unsafe { MaybeUninit::zeroed().assume_init() };
|
||||||
x86_64::instructions::interrupts::enable();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[repr(u8)]
|
#[repr(u8)]
|
||||||
enum Interrupt {
|
enum Interrupt {
|
||||||
Timer = 32,
|
Timer = 32,
|
||||||
|
|
||||||
ApicErr = u8::MAX - 1,
|
ApicErr = u8::MAX - 1,
|
||||||
Spurious = u8::MAX,
|
Spurious = u8::MAX,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) static LAPIC: Lazy<Mutex<LocalApic>> = Lazy::new(|| {
|
pub unsafe fn init() {
|
||||||
let mut lapic = LocalApicBuilder::new()
|
trace!("Initializing IDT and LAPIC");
|
||||||
|
|
||||||
|
// Initialize and load the IDT
|
||||||
|
IDT = InterruptDescriptorTable::new();
|
||||||
|
IDT.double_fault
|
||||||
|
.set_handler_fn(double_fault)
|
||||||
|
.set_stack_index(super::gdt::DOUBLE_FAULT_IX);
|
||||||
|
IDT.page_fault.set_handler_fn(page_fault);
|
||||||
|
|
||||||
|
IDT[Interrupt::ApicErr as u8].set_handler_fn(apic_err);
|
||||||
|
IDT[Interrupt::Spurious as u8].set_handler_fn(spurious);
|
||||||
|
IDT[Interrupt::Timer as u8].set_handler_fn(timer);
|
||||||
|
|
||||||
|
IDT.load();
|
||||||
|
|
||||||
|
LAPIC = LocalApicBuilder::new()
|
||||||
.timer_vector(Interrupt::Timer as usize)
|
.timer_vector(Interrupt::Timer as usize)
|
||||||
.error_vector(Interrupt::ApicErr as usize)
|
.error_vector(Interrupt::ApicErr as usize)
|
||||||
.spurious_vector(Interrupt::Spurious as usize)
|
.spurious_vector(Interrupt::Spurious as usize)
|
||||||
.set_xapic_base(
|
.set_xapic_base(
|
||||||
unsafe { x2apic::lapic::xapic_base() }
|
x2apic::lapic::xapic_base()
|
||||||
+ super::memory::HHDM_OFFSET.load(core::sync::atomic::Ordering::Relaxed),
|
+ super::memory::HHDM_OFFSET.load(core::sync::atomic::Ordering::Relaxed),
|
||||||
)
|
)
|
||||||
.build()
|
.build()
|
||||||
.expect("failed to setup Local APIC");
|
.expect("Failed to setup Local APIC");
|
||||||
unsafe { lapic.enable() };
|
LAPIC.enable();
|
||||||
Mutex::new(lapic)
|
|
||||||
});
|
|
||||||
|
|
||||||
static IDT: Lazy<InterruptDescriptorTable> = Lazy::new(|| {
|
x86_64::instructions::interrupts::enable();
|
||||||
let mut idt = InterruptDescriptorTable::new();
|
}
|
||||||
unsafe {
|
|
||||||
idt.double_fault
|
|
||||||
.set_handler_fn(double_fault)
|
|
||||||
.set_stack_index(super::gdt::DOUBLE_FAULT_IX);
|
|
||||||
}
|
|
||||||
idt.page_fault.set_handler_fn(page_fault);
|
|
||||||
|
|
||||||
idt[Interrupt::ApicErr as u8].set_handler_fn(apic_err);
|
|
||||||
idt[Interrupt::Spurious as u8].set_handler_fn(spurious);
|
|
||||||
idt[Interrupt::Timer as u8].set_handler_fn(timer);
|
|
||||||
|
|
||||||
idt
|
|
||||||
});
|
|
||||||
|
|
||||||
extern "x86-interrupt" fn double_fault(stack_frame: InterruptStackFrame, error_code: u64) -> ! {
|
extern "x86-interrupt" fn double_fault(stack_frame: InterruptStackFrame, error_code: u64) -> ! {
|
||||||
panic!("Double fault: error code {error_code} \n{stack_frame:#?}")
|
panic!("Double fault: error code {error_code} \n{stack_frame:#?}")
|
||||||
|
@ -64,7 +60,9 @@ extern "x86-interrupt" fn page_fault(
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "x86-interrupt" fn timer(_isf: InterruptStackFrame) {
|
extern "x86-interrupt" fn timer(_isf: InterruptStackFrame) {
|
||||||
unsafe { LAPIC.lock().end_of_interrupt() };
|
unsafe {
|
||||||
|
LAPIC.end_of_interrupt();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "x86-interrupt" fn apic_err(_: InterruptStackFrame) {
|
extern "x86-interrupt" fn apic_err(_: InterruptStackFrame) {
|
||||||
|
@ -72,5 +70,7 @@ extern "x86-interrupt" fn apic_err(_: InterruptStackFrame) {
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "x86-interrupt" fn spurious(_: InterruptStackFrame) {
|
extern "x86-interrupt" fn spurious(_: InterruptStackFrame) {
|
||||||
unsafe { LAPIC.lock().end_of_interrupt() };
|
unsafe {
|
||||||
|
LAPIC.end_of_interrupt();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ use {
|
||||||
|
|
||||||
pub fn handler(vm: &mut Vm) {
|
pub fn handler(vm: &mut Vm) {
|
||||||
let ecall_number = vm.registers[2].cast::<u64>();
|
let ecall_number = vm.registers[2].cast::<u64>();
|
||||||
|
// log::info!("eca called :pensive:");
|
||||||
// debug!("Ecall number {:?}", ecall_number);
|
// debug!("Ecall number {:?}", ecall_number);
|
||||||
//info!("Register dump: {:?}", vm.registers);
|
//info!("Register dump: {:?}", vm.registers);
|
||||||
|
|
||||||
|
@ -97,61 +97,35 @@ pub fn handler(vm: &mut Vm) {
|
||||||
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 {
|
||||||
0 => 'wow: {
|
0 => unsafe {
|
||||||
let size = match msg_vec[0] {
|
let size = msg_vec[1];
|
||||||
0 => 1,
|
let addr = u16::from_le_bytes(msg_vec[2..4].try_into().unwrap());
|
||||||
1 => 2,
|
let value = match size {
|
||||||
2 => 4,
|
0 => x86_in::<u8>(addr) as u64,
|
||||||
_ => {
|
1 => x86_in::<u16>(addr) as u64,
|
||||||
error!("Tried to write more than 32 bits");
|
2 => x86_in::<u32>(addr) as u64,
|
||||||
break 'wow;
|
_ => panic!("Trying to read size other than: 8, 16, 32 from port."),
|
||||||
}
|
|
||||||
};
|
};
|
||||||
let addr = u16::from_le_bytes(msg_vec[1..3].try_into().unwrap());
|
// info!("Read the value {} from address {}", value, addr);
|
||||||
let value = unsafe {
|
|
||||||
match size {
|
|
||||||
1 => x86_in::<u8>(addr) as u64,
|
|
||||||
2 => x86_in::<u16>(addr) as u64,
|
|
||||||
4 => x86_in::<u32>(addr) as u64,
|
|
||||||
_ => panic!("how?"),
|
|
||||||
}
|
|
||||||
};
|
|
||||||
trace!("Read the value {} from address {}", value, addr);
|
|
||||||
vm.registers[1] = hbvm::value::Value(value);
|
vm.registers[1] = hbvm::value::Value(value);
|
||||||
}
|
},
|
||||||
1 => 'wow: {
|
1 => unsafe {
|
||||||
let size = match msg_vec[1] {
|
let size = msg_vec[1];
|
||||||
0 => 1,
|
let addr = u16::from_le_bytes(msg_vec[2..4].try_into().unwrap());
|
||||||
1 => 2,
|
|
||||||
2 => 4,
|
|
||||||
_ => {
|
|
||||||
error!("Tried to write more than 32 bits");
|
|
||||||
break 'wow;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let addr = unsafe {
|
|
||||||
u16::from_le_bytes(msg_vec[1..3].try_into().unwrap_unchecked())
|
|
||||||
};
|
|
||||||
trace!("Setting address {}", addr);
|
trace!("Setting address {}", addr);
|
||||||
unsafe {
|
|
||||||
match size {
|
match size {
|
||||||
1 => x86_out(addr, msg_vec[3]),
|
0 => x86_out(addr, msg_vec[4]),
|
||||||
|
1 => x86_out(
|
||||||
|
addr,
|
||||||
|
u16::from_le_bytes(msg_vec[4..6].try_into().unwrap_unchecked()),
|
||||||
|
),
|
||||||
2 => x86_out(
|
2 => x86_out(
|
||||||
addr,
|
addr,
|
||||||
u16::from_le_bytes(
|
u32::from_le_bytes(msg_vec[4..8].try_into().unwrap_unchecked()),
|
||||||
msg_vec[3..5].try_into().unwrap_unchecked(),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
4 => x86_out(
|
|
||||||
addr,
|
|
||||||
u32::from_le_bytes(
|
|
||||||
msg_vec[3..7].try_into().unwrap_unchecked(),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
_ => panic!("How?"),
|
_ => panic!("How?"),
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
}
|
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use {
|
use {
|
||||||
crate::holeybytes::{kernel_services::block_read, Vm},
|
crate::holeybytes::{kernel_services::block_read, Vm},
|
||||||
alloc::alloc::{alloc_zeroed, dealloc},
|
alloc::alloc::{alloc, dealloc},
|
||||||
core::alloc::Layout,
|
core::alloc::Layout,
|
||||||
log::{debug, info},
|
log::{debug, info},
|
||||||
};
|
};
|
||||||
|
@ -17,7 +17,7 @@ pub enum MemoryQuotaType {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn alloc_page(vm: &mut Vm, _mem_addr: u64, _length: usize) -> Result<(), MemoryServiceError> {
|
fn alloc_page(vm: &mut Vm, _mem_addr: u64, _length: usize) -> Result<(), MemoryServiceError> {
|
||||||
let ptr = unsafe { alloc_zeroed(Layout::new::<[u8; 4096]>()) };
|
let ptr = unsafe { alloc(Layout::from_size_align_unchecked(4096, 4096)) };
|
||||||
info!("Block address: {:?}", ptr);
|
info!("Block address: {:?}", ptr);
|
||||||
vm.registers[1] = hbvm::value::Value(ptr as u64);
|
vm.registers[1] = hbvm::value::Value(ptr as u64);
|
||||||
vm.registers[2] = hbvm::value::Value(4096);
|
vm.registers[2] = hbvm::value::Value(4096);
|
||||||
|
@ -40,9 +40,9 @@ pub fn memory_msg_handler(
|
||||||
log::debug!("Allocating {} pages @ {:x}", page_count, mptr);
|
log::debug!("Allocating {} pages @ {:x}", page_count, mptr);
|
||||||
|
|
||||||
let ptr = unsafe {
|
let ptr = unsafe {
|
||||||
alloc_zeroed(Layout::from_size_align_unchecked(
|
alloc(Layout::from_size_align_unchecked(
|
||||||
page_count as usize * 4096,
|
page_count as usize * 4096,
|
||||||
1,
|
4096,
|
||||||
))
|
))
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ pub fn memory_msg_handler(
|
||||||
unsafe {
|
unsafe {
|
||||||
dealloc(
|
dealloc(
|
||||||
mptr as *mut u8,
|
mptr as *mut u8,
|
||||||
Layout::from_size_align_unchecked(page_count as usize * 4096, 1),
|
Layout::from_size_align_unchecked(page_count as usize * 4096, 4096),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,6 @@ pub mod mem_serve;
|
||||||
pub mod service_definition_service;
|
pub mod service_definition_service;
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn block_read<'a>(mem_addr: u64, length: usize) -> &'a [u8] {
|
pub fn block_read<'a>(mem_addr: u64, length: usize) -> &'a mut [u8] {
|
||||||
unsafe { slice::from_raw_parts(mem_addr as *const u8, length) }
|
unsafe { slice::from_raw_parts_mut(mem_addr as *mut _, length) }
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ mod kernel_services;
|
||||||
mod mem;
|
mod mem;
|
||||||
|
|
||||||
use {
|
use {
|
||||||
alloc::alloc::{alloc_zeroed, dealloc},
|
alloc::alloc::{alloc, dealloc},
|
||||||
core::{
|
core::{
|
||||||
alloc::Layout,
|
alloc::Layout,
|
||||||
future::Future,
|
future::Future,
|
||||||
|
@ -61,29 +61,23 @@ impl<'p> Future for ExecThread {
|
||||||
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() {
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
error!("HBVM Error\r\nRegister dump: {:?}", self.vm.registers);
|
log::error!("HBVM Error\r\nRegister dump: {:?}", self.vm.registers,);
|
||||||
Poll::Ready(Err(err))
|
return Poll::Ready(Err(err));
|
||||||
}
|
|
||||||
Ok(VmRunOk::End) => Poll::Ready(Ok(())),
|
|
||||||
Ok(VmRunOk::Ecall) => {
|
|
||||||
ecah::handler(&mut self.vm);
|
|
||||||
cx.waker().wake_by_ref();
|
|
||||||
Poll::Pending
|
|
||||||
}
|
|
||||||
Ok(VmRunOk::Timer) => {
|
|
||||||
cx.waker().wake_by_ref();
|
|
||||||
Poll::Pending
|
|
||||||
}
|
}
|
||||||
|
Ok(VmRunOk::End) => return Poll::Ready(Ok(())),
|
||||||
|
Ok(VmRunOk::Ecall) => ecah::handler(&mut self.vm),
|
||||||
|
Ok(VmRunOk::Timer) => (),
|
||||||
Ok(VmRunOk::Breakpoint) => {
|
Ok(VmRunOk::Breakpoint) => {
|
||||||
error!(
|
log::error!(
|
||||||
"HBVM Debug breakpoint\r\nRegister dump: {:?}",
|
"HBVM Debug breakpoint\r\nRegister dump: {:?}",
|
||||||
self.vm.registers
|
self.vm.registers,
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
cx.waker().wake_by_ref();
|
cx.waker().wake_by_ref();
|
||||||
Poll::Pending
|
Poll::Pending
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct PageFaultHandler;
|
struct PageFaultHandler;
|
||||||
|
@ -108,5 +102,5 @@ const fn stack_layout() -> Layout {
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn allocate_stack() -> *mut u8 {
|
fn allocate_stack() -> *mut u8 {
|
||||||
unsafe { alloc_zeroed(stack_layout()) }
|
unsafe { alloc(stack_layout()) }
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ use {
|
||||||
hashbrown::HashMap,
|
hashbrown::HashMap,
|
||||||
hbvm::mem::Address,
|
hbvm::mem::Address,
|
||||||
limine::{Framebuffer, FramebufferRequest, NonNullPtr},
|
limine::{Framebuffer, FramebufferRequest, NonNullPtr},
|
||||||
log::{debug, info},
|
log::{debug, trace},
|
||||||
spin::{Lazy, Mutex},
|
spin::{Lazy, Mutex},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -36,9 +36,9 @@ pub fn kmain(_cmdline: &str, boot_modules: BootModules) -> ! {
|
||||||
let dt = DEVICE_TREE.lock();
|
let dt = DEVICE_TREE.lock();
|
||||||
|
|
||||||
// TODO(Able): This line causes a deadlock
|
// TODO(Able): This line causes a deadlock
|
||||||
info!("Device Tree: {}", dt);
|
debug!("Device Tree: {}", dt);
|
||||||
|
|
||||||
info!("Boot complete. Moving to init_system");
|
trace!("Boot complete. Moving to init_system");
|
||||||
|
|
||||||
// TODO: schedule the disk driver from the initramfs
|
// TODO: schedule the disk driver from the initramfs
|
||||||
// TODO: schedule the filesystem driver from the initramfs
|
// TODO: schedule the filesystem driver from the initramfs
|
||||||
|
@ -60,39 +60,32 @@ pub fn kmain(_cmdline: &str, boot_modules: BootModules) -> ! {
|
||||||
disp.set_attribute("pitch", fb1.pitch);
|
disp.set_attribute("pitch", fb1.pitch);
|
||||||
dt.devices.insert("Displays".to_string(), alloc::vec![disp]);
|
dt.devices.insert("Displays".to_string(), alloc::vec![disp]);
|
||||||
}
|
}
|
||||||
log::info!("Graphics initialised");
|
debug!("Graphics initialised");
|
||||||
log::info!(
|
debug!(
|
||||||
"Graphics front ptr {:?}",
|
"Graphics front ptr {:?}",
|
||||||
fb1.address.as_ptr().unwrap() as *const u8
|
fb1.address.as_ptr().unwrap() as *const u8
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut executor = crate::task::Executor::new(256);
|
let mut executor = crate::task::Executor::new(256);
|
||||||
let bm_take = boot_modules.len();
|
|
||||||
unsafe {
|
unsafe {
|
||||||
for module in boot_modules.into_iter().take(bm_take) {
|
for module in boot_modules.iter() {
|
||||||
let mut cmd = module.cmd;
|
let cmd = module.cmd.trim_matches('"');
|
||||||
if cmd.len() > 2 {
|
|
||||||
// // Remove the quotes
|
|
||||||
// cmd.remove(0);
|
|
||||||
// cmd.pop();
|
|
||||||
cmd = &cmd[1..cmd.len()]
|
|
||||||
}
|
|
||||||
let cmd_len = cmd.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.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_ptr() as u64, cmd_len);
|
||||||
}
|
}
|
||||||
|
executor.spawn(async move {
|
||||||
if let Err(e) = thr.await {
|
if let Err(e) = thr.await {
|
||||||
log::error!("{e:?}");
|
log::error!("{e:?}");
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
info!("Random number: {}", hardware_random_u64());
|
debug!("Random number: {}", hardware_random_u64());
|
||||||
|
|
||||||
executor.run();
|
executor.run();
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,8 +2,9 @@
|
||||||
//! Named akern.
|
//! Named akern.
|
||||||
//! Akern is woefully undersupported at the moment but we are looking to add support improve hardware discovery and make our lives as kernel and operating system developers easier and better
|
//! Akern is woefully undersupported at the moment but we are looking to add support improve hardware discovery and make our lives as kernel and operating system developers easier and better
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![feature(new_uninit)]
|
|
||||||
#![feature(
|
#![feature(
|
||||||
|
exclusive_wrapper,
|
||||||
|
new_uninit,
|
||||||
abi_x86_interrupt,
|
abi_x86_interrupt,
|
||||||
alloc_error_handler,
|
alloc_error_handler,
|
||||||
ptr_sub_ptr,
|
ptr_sub_ptr,
|
||||||
|
|
|
@ -4,10 +4,8 @@ receive_message := fn(buffer_id: int, memory_map_location: ^u8, length: int): ^u
|
||||||
return @eca(^u8, 4, buffer_id, memory_map_location, length)
|
return @eca(^u8, 4, buffer_id, memory_map_location, length)
|
||||||
}
|
}
|
||||||
|
|
||||||
send_message := fn(msg: ^u8, buffer_id: int): void {
|
send_message := fn(msg: ^u8, buffer_id: int, length: int): void {
|
||||||
msg_length := @inline(string.length, msg)
|
return @eca(void, 3, buffer_id, msg, length)
|
||||||
@eca(i32, 3, buffer_id, msg, msg_length)
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
create := fn(msg: ^u8): int {
|
create := fn(msg: ^u8): int {
|
||||||
|
|
|
@ -1,14 +1,9 @@
|
||||||
acs := @use("rel:acs.hb")
|
acs := @use("rel:acs.hb")
|
||||||
|
|
||||||
|
|
||||||
// Paths without a node-disk component are to be treated as local files.
|
// Paths without a node-disk component are to be treated as local files.
|
||||||
// file_path := "DID:/test\0";
|
// file_path := "DID:/test\0";
|
||||||
Path := struct {
|
Path := struct {// DiskID holds the host id
|
||||||
// DiskID holds the host id
|
disk_id: acs.DiskID, length: u8, data: ^u8}
|
||||||
disk_id: acs.DiskID
|
|
||||||
length: u8,
|
|
||||||
data: ^u8
|
|
||||||
}
|
|
||||||
|
|
||||||
FileID := struct {
|
FileID := struct {
|
||||||
host_id: int,
|
host_id: int,
|
||||||
|
|
|
@ -17,38 +17,23 @@ release_page := fn(ptr: ^u8, page_count: u8): void {
|
||||||
return @eca(void, 3, 2, msg, 12)
|
return @eca(void, 3, 2, msg, 12)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OutbMsg := struct {a: u8, b: u8, addr: u16, value: u8}
|
||||||
|
InbMsg := struct {a: u8, b: u8, addr: u16}
|
||||||
|
OutlMsg := struct {a: u8, b: u8, addr: u16, value: u32}
|
||||||
|
InlMsg := struct {a: u8, b: u8, addr: u16}
|
||||||
|
|
||||||
outb := fn(addr: u16, value: u8): void {
|
outb := fn(addr: u16, value: u8): void {
|
||||||
msg := "\0\0\0\0\0";
|
return @eca(void, 3, 3, &OutbMsg.(1, 0, addr, value), @sizeof(OutbMsg))
|
||||||
*@as(^u8, msg) = @as(u8, 1);
|
|
||||||
*@as(^u8, msg + 1) = @as(u8, 0);
|
|
||||||
*@as(^u16, @bitcast(msg + 2)) = addr;
|
|
||||||
*@as(^u8, msg + 4) = value
|
|
||||||
@eca(void, 3, 3, msg, 5)
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inb := fn(addr: u16): u8 {
|
inb := fn(addr: u16): u8 {
|
||||||
msg := "\0\0\0\0";
|
return @eca(u8, 3, 3, &InbMsg.(0, 0, addr), @sizeof(InbMsg))
|
||||||
*@as(^u8, msg) = @as(u8, 0);
|
|
||||||
*@as(^u8, msg + 1) = @as(u8, 0);
|
|
||||||
*@as(^u16, @bitcast(msg + 2)) = addr
|
|
||||||
return @eca(u8, 3, 3, msg, 4)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
outl := fn(addr: u16, value: u32): void {
|
outl := fn(addr: u16, value: u32): void {
|
||||||
msg := "\0\0\0\0\0\0\0\0";
|
return @eca(void, 3, 3, &OutlMsg.(1, 2, addr, value), @sizeof(OutlMsg))
|
||||||
*@as(^u8, msg) = @as(u8, 1);
|
|
||||||
*@as(^u8, msg + 1) = @as(u8, 2);
|
|
||||||
*@as(^u16, @bitcast(msg + 2)) = addr;
|
|
||||||
*@as(^u32, @bitcast(msg + 4)) = value
|
|
||||||
@eca(void, 3, 3, msg, 8)
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inl := fn(addr: u16): u32 {
|
inl := fn(addr: u16): u32 {
|
||||||
msg := "\0\0\0\0";
|
return @eca(u32, 3, 3, &InlMsg.(0, 2, addr), @sizeof(InlMsg))
|
||||||
*@as(^u8, msg) = @as(u8, 0);
|
|
||||||
*@as(^u8, msg + 1) = @as(u8, 2);
|
|
||||||
*@as(^u16, @bitcast(msg + 2)) = addr
|
|
||||||
return @eca(u32, 3, 3, msg, 4)
|
|
||||||
}
|
}
|
|
@ -3,45 +3,46 @@ length := fn(ptr: ^u8): int {
|
||||||
loop if *(ptr + len) == 0 break else len += 1
|
loop if *(ptr + len) == 0 break else len += 1
|
||||||
return len
|
return len
|
||||||
}
|
}
|
||||||
display_int := fn(num: int, p: ^u8): ^u8 {
|
|
||||||
i := 0
|
|
||||||
if num == 0 {
|
|
||||||
*p = 48;
|
|
||||||
*(p + 1) = 0
|
|
||||||
return p
|
|
||||||
}
|
|
||||||
|
|
||||||
neg := false
|
// WTFFF is wrong with display_int
|
||||||
if num < 0 {
|
display_int := fn(num: int, p: ^u8): ^u8 {
|
||||||
neg = true
|
ptr := p
|
||||||
|
negative := num < 0
|
||||||
|
if negative {
|
||||||
num = -num
|
num = -num
|
||||||
}
|
}
|
||||||
|
if num == 0 {
|
||||||
|
*ptr = 48
|
||||||
|
ptr += 1
|
||||||
|
} else {
|
||||||
loop if num == 0 break else {
|
loop if num == 0 break else {
|
||||||
*(p + i) = num % 10 + 48
|
*ptr = num % 10 + 48
|
||||||
|
ptr += 1
|
||||||
num /= 10
|
num /= 10
|
||||||
i += 1
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if neg {
|
|
||||||
*(p + i) = 45
|
|
||||||
i += 1
|
|
||||||
}
|
}
|
||||||
|
if negative {
|
||||||
reverse(p, i)
|
*ptr = 45
|
||||||
|
ptr += 1
|
||||||
|
};
|
||||||
|
*ptr = 0
|
||||||
|
@inline(reverse, p)
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
reverse := fn(p: ^u8, len: int): void {
|
reverse := fn(s: ^u8): void {
|
||||||
start := 0
|
//reverse a string, don't remove digits
|
||||||
end := len - 1
|
len := 0
|
||||||
loop if start >= end break else {
|
loop if *(s + len) == 0 break else len += 1
|
||||||
temp := *(p + start);
|
i := 0
|
||||||
*(p + start) = *(p + end);
|
j := len - 1
|
||||||
*(p + end) = temp
|
temp := 0
|
||||||
start += 1
|
loop if i >= j break else {
|
||||||
end -= 1
|
temp = *(s + i);
|
||||||
|
*(s + i) = *(s + j);
|
||||||
|
*(s + j) = temp
|
||||||
|
i += 1
|
||||||
|
j -= 1
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
|
@ -45,13 +45,11 @@ main := fn(): int {
|
||||||
|
|
||||||
msg_type := 0
|
msg_type := 0
|
||||||
|
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
// Open file
|
// Open file
|
||||||
if msg_type == 0 {
|
if msg_type == 0 {
|
||||||
// Paths without a node-disk component are to be treated as local files.
|
// Paths without a node-disk component are to be treated as local files.
|
||||||
file_path := "node-disk:/test\0";
|
file_path := "node-disk:/test\0"
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// error
|
// error
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
# KVStore
|
|
||||||
This is a small single process in memory key value store.
|
|
|
@ -1,37 +0,0 @@
|
||||||
Message := struct {
|
|
||||||
msg_type: u8,
|
|
||||||
key: String,
|
|
||||||
value: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
# Message Type
|
|
||||||
0 => Set Key type
|
|
||||||
1 => Get Key
|
|
||||||
*/
|
|
||||||
|
|
||||||
recv_msg:= fn(): Message {
|
|
||||||
return Message.{
|
|
||||||
msg_type: 0,
|
|
||||||
key: "",
|
|
||||||
value: "",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
main := fn(): int {
|
|
||||||
loop {
|
|
||||||
msg := recv_msg();
|
|
||||||
if msg.msg_type == 0 {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if msg.msg_type == 1 {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if 2 <= msg.msg_type {
|
|
||||||
error("Unexpected message type in the bagging area");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
3
sysdata/programs/ps2_driver/README.md
Normal file
3
sysdata/programs/ps2_driver/README.md
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
# PS/2 Driver
|
||||||
|
|
||||||
|
This program is a simple driver to read keypresses from a PS/2 Keyboard Also will contain an abstraction for the PS/2 controller in general so the Mouse code will probably also live here...maybe
|
11
sysdata/programs/ps2_driver/meta.toml
Normal file
11
sysdata/programs/ps2_driver/meta.toml
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
[package]
|
||||||
|
name = "ps2_driver"
|
||||||
|
authors = ["Talha Qamar"]
|
||||||
|
|
||||||
|
[dependants.libraries]
|
||||||
|
|
||||||
|
[dependants.binaries]
|
||||||
|
hblang.version = "1.0.0"
|
||||||
|
|
||||||
|
[build]
|
||||||
|
command = "hblang src/main.hb"
|
33
sysdata/programs/ps2_driver/src/main.hb
Normal file
33
sysdata/programs/ps2_driver/src/main.hb
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
.{memory, log, string, buffer} := @use("../../../libraries/stn/src/lib.hb")
|
||||||
|
|
||||||
|
send_byte := fn(byte: u8): u8 {
|
||||||
|
memory.outb(96, byte)
|
||||||
|
return memory.inb(96)
|
||||||
|
}
|
||||||
|
|
||||||
|
main := fn(): int {
|
||||||
|
send_byte(238)
|
||||||
|
log.info("PS/2 Driver Loaded\0")
|
||||||
|
if send_byte(238) == 238 {
|
||||||
|
log.info("PS/2 Keyboard Echoed\0")
|
||||||
|
}
|
||||||
|
a := 0
|
||||||
|
// a += 1
|
||||||
|
if send_byte(244) == 250 {
|
||||||
|
log.info("Enabled scanning\0")
|
||||||
|
}
|
||||||
|
buf := buffer.create("XKeyboard\0")
|
||||||
|
ptr := memory.request_page(1)
|
||||||
|
prev_input := 250
|
||||||
|
loop {
|
||||||
|
input := memory.inb(96)
|
||||||
|
if input == prev_input {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
prev_input = input
|
||||||
|
keycode_str := string.display_int(input, ptr)
|
||||||
|
log.info(keycode_str)
|
||||||
|
buffer.send_message(&input, buf, 1)
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
.{example} := @use("./examples/colors.hb")
|
.{example} := @use("./examples/amogus.hb")
|
||||||
|
|
||||||
main := fn(): void {
|
main := fn(): void {
|
||||||
@inline(example)
|
@inline(example)
|
||||||
|
|
|
@ -46,3 +46,5 @@ path = "boot:///svga_driver.hbf"
|
||||||
|
|
||||||
[boot.limine.ableos.modules.filesystem_fat32]
|
[boot.limine.ableos.modules.filesystem_fat32]
|
||||||
path = "boot:///filesystem_fat32.hbf"
|
path = "boot:///filesystem_fat32.hbf"
|
||||||
|
[boot.limine.ableos.modules.pumpkin_print]
|
||||||
|
path = "boot:///pumpkin_print.hbf"
|
||||||
|
|
Loading…
Reference in a new issue