Compare commits

..

12 commits

Author SHA1 Message Date
koniifer 555bc49663 minor jank auto resolution detection 2024-09-13 22:36:08 +01:00
koniifer 63c3544012 amogus example 2024-09-12 20:10:22 +01:00
koniifer e577572299 amazing random driver update 2024-09-12 19:44:27 +01:00
koniifer c2183d5138 auto framebuffer ptr 2024-09-12 18:25:30 +01:00
koniifer 022c1c196a works on arm and x86 without fiddling with stuff
memory bug fixes
update hblang
update render examples
obliterate render_driver (not useful)
2024-09-12 18:14:26 +01:00
koniifer fef5487e62 able told me to push 🙏 2024-09-11 23:09:47 +01:00
koniifer 3a6778149b update hblang 2024-09-10 00:17:59 +01:00
koniifer 3b95371c41 a touch more fiddling 2024-09-10 00:10:10 +01:00
koniifer fd155ea26a a touch of fiddling 2024-09-09 01:42:11 +01:00
koniifer 9b34e19005 fix stupid bug 2024-09-08 19:32:37 +01:00
koniifer 3ca7e13f3e pci interface skeleton
update hblang
improve libraries/render
hide some annoying warnings
minor changes to page allocator and buffers
implement page dealloc
fiddle with sysdata
2024-09-08 19:25:13 +01:00
koniifer 1031ca6314 reimplement fb_driver as software render interface. sufficiently jank double buffering implementation waiting on an intelligent design. 2024-09-07 23:08:58 +01:00
72 changed files with 410 additions and 999 deletions

26
Cargo.lock generated
View file

@ -61,9 +61,9 @@ dependencies = [
[[package]] [[package]]
name = "anyhow" name = "anyhow"
version = "1.0.89" 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 = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" checksum = "4e1496f8fb1fbf272686b8d37f523dab3e4a7443300055e74cdaa449f3114356"
[[package]] [[package]]
name = "autocfg" name = "autocfg"
@ -148,9 +148,9 @@ checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50"
[[package]] [[package]]
name = "cc" name = "cc"
version = "1.1.19" version = "1.1.18"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2d74707dde2ba56f86ae90effb3b43ddd369504387e718014de010cec7959800" checksum = "b62ac837cdb5cb22e10a256099b4fc502b1dfe560cb282963a974d7abd80e476"
dependencies = [ dependencies = [
"shlex", "shlex",
] ]
@ -390,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#254d5ed96234c8291770d84b2ac11ef7dd403b28" source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#2bc7a5c13f6ab2b3ee28f772f31eb3414fa2b25b"
[[package]] [[package]]
name = "hbbytecode" name = "hbbytecode"
version = "0.1.0" version = "0.1.0"
source = "git+https://git.ablecorp.us/ableos/holey-bytes.git#254d5ed96234c8291770d84b2ac11ef7dd403b28" source = "git+https://git.ablecorp.us/ableos/holey-bytes#2bc7a5c13f6ab2b3ee28f772f31eb3414fa2b25b"
[[package]] [[package]]
name = "hblang" name = "hblang"
version = "0.1.0" version = "0.1.0"
source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#254d5ed96234c8291770d84b2ac11ef7dd403b28" source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#2bc7a5c13f6ab2b3ee28f772f31eb3414fa2b25b"
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)",
] ]
@ -408,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#254d5ed96234c8291770d84b2ac11ef7dd403b28" source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#2bc7a5c13f6ab2b3ee28f772f31eb3414fa2b25b"
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)",
] ]
@ -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.git#254d5ed96234c8291770d84b2ac11ef7dd403b28" source = "git+https://git.ablecorp.us/ableos/holey-bytes#2bc7a5c13f6ab2b3ee28f772f31eb3414fa2b25b"
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)",
] ]
[[package]] [[package]]
@ -526,9 +526,9 @@ dependencies = [
[[package]] [[package]]
name = "iana-time-zone" name = "iana-time-zone"
version = "0.1.61" version = "0.1.60"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141"
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.git)", "hbvm 0.1.0 (git+https://git.ablecorp.us/ableos/holey-bytes)",
"limine", "limine",
"log", "log",
"sbi", "sbi",

View file

@ -1,84 +1,20 @@
pub mod protocol; use logos::Logos;
use std::io::Read; #[derive(Logos, Debug, PartialEq)]
use {
logos::{Lexer, Logos},
protocol::Protocol,
};
#[derive(Logos, Debug, PartialEq, Clone)]
#[logos(skip r"[ \t\n\f]+")] // Ignore this regex pattern between tokens #[logos(skip r"[ \t\n\f]+")] // Ignore this regex pattern between tokens
enum Token { enum Token {
// Tokens can be literal strings, of any length. // Tokens can be literal strings, of any length.
#[token("protocol")] #[token("protocol")]
Protocol, Protocol,
#[token("{")] #[token(".")]
LBrace, Period,
#[token("}")] // Or regular expressions.
RBrace, #[regex("[a-zA-Z]+")]
Text,
#[token("(")]
LParen,
#[token(")")]
RParen,
#[token(":")]
Colon,
#[token(";")]
SemiColon,
#[token(",")]
Comma,
#[token("=")]
Equal,
#[token("->")]
RArrow,
#[regex("[a-zA-Z_]+", |lex|{lex.slice().to_string()})]
Text(String),
#[regex("[1234567890]+", |lex|{lex.slice().parse::<u64>().unwrap()})]
Number(u64),
#[regex(r"@[a-zA-Z_]+", |lex|{lex.slice().to_string()})]
Decorator(String),
#[regex(r#"@[a-zA-Z_]+\([a-zA-Z,0-9=]+\)"#, |lex|{lex.slice().to_string()})]
DecoratorOption(String),
} }
pub fn build_idl(name: String) { pub fn main() {
let contents = open_protocol(name); let mut lex = Token::lexer("Create ridiculously fast Lexers.");
let lex = Token::lexer(&contents);
let mut tokens = vec![];
for x in lex {
match x {
Ok(token) => {
println!("{:?}", token);
tokens.push(token);
}
Err(err) => println!("{:?}", err),
}
}
build(tokens);
}
fn build(a: Vec<Token>) {
for toke in a {
println!("{:?}", toke);
}
}
fn open_protocol(name: String) -> String {
let path = format!("sysdata/idl/{}/src/protocol.aidl", name);
let mut file = std::fs::File::open(path).unwrap();
let mut contents = String::new();
file.read_to_string(&mut contents).unwrap();
contents
} }

View file

@ -1,17 +0,0 @@
pub enum ProtocolTypes {
Byte,
}
pub struct Protocol {}
impl Protocol {
pub fn is_empty(&self) -> bool {
true
}
pub fn validate_data(&self, data: Vec<u8>) -> bool {
if !data.is_empty() && self.is_empty() {
return false;
}
true
}
}

View file

@ -1,6 +1,4 @@
use std::io::Write; use std::io::Write;
use idl::build_idl;
pub mod idl; pub mod idl;
pub enum Options { pub enum Options {
@ -9,7 +7,7 @@ pub enum Options {
New, New,
Run, Run,
} }
#[derive(PartialEq, Debug)] #[derive(PartialEq)]
pub enum DevelopmentType { pub enum DevelopmentType {
Program, Program,
Library, Library,
@ -26,7 +24,7 @@ fn main() {
match subcommand { match subcommand {
"build" => { "build" => {
let name = &args.pop().unwrap(); let name = &args[1];
build(name.to_string()) build(name.to_string())
} }
"new" => { "new" => {
@ -105,21 +103,8 @@ fn run() {
fn build(name: String) { fn build(name: String) {
println!("building {}", name); println!("building {}", name);
let mut a = name.split("/");
let dev_type = a.next().unwrap();
let name = a.next().unwrap().to_string();
match dev_type {
"programs" => build_program(name),
"idl" => build_idl(name),
_ => {
panic!()
}
}
} }
pub fn build_program(name: String) {}
pub fn build_library(name: String) {}
fn help() { fn help() {
println!( println!(
"========== "==========

View file

@ -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.git" 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 } slab = { version = "0.4", default-features = false }

View file

@ -1,5 +1,5 @@
use {crate::logger::TERMINAL_LOGGER, core::fmt::Write, spin::Mutex}; use {crate::logger::TERMINAL_LOGGER, core::fmt::Write, spin::Mutex};
pub static 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,
}); });

View file

@ -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 = 1; const STACK_ALIGNMENT: usize = 4096;
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(layout); let stack = alloc::alloc::alloc_zeroed(layout);
VirtAddr::from_ptr(stack) + STACK_SIZE as u64 VirtAddr::from_ptr(stack) + STACK_SIZE as u64
}; };

View file

@ -1,52 +1,56 @@
// 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},
}; };
/// Safety: Using LAPIC or IDT before init() is UB pub unsafe fn init() {
/// Using trace!("Initialising IDT");
static mut LAPIC: LocalApic = unsafe { MaybeUninit::zeroed().assume_init() }; IDT.load();
static mut IDT: InterruptDescriptorTable = unsafe { MaybeUninit::zeroed().assume_init() }; Lazy::force(&LAPIC);
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 unsafe fn init() { pub(crate) static LAPIC: Lazy<Mutex<LocalApic>> = Lazy::new(|| {
trace!("Initializing IDT and LAPIC"); let mut lapic = LocalApicBuilder::new()
// 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(
x2apic::lapic::xapic_base() unsafe { 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");
LAPIC.enable(); unsafe { lapic.enable() };
Mutex::new(lapic)
});
x86_64::instructions::interrupts::enable(); static IDT: Lazy<InterruptDescriptorTable> = Lazy::new(|| {
} 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:#?}")
@ -60,9 +64,7 @@ extern "x86-interrupt" fn page_fault(
} }
extern "x86-interrupt" fn timer(_isf: InterruptStackFrame) { extern "x86-interrupt" fn timer(_isf: InterruptStackFrame) {
unsafe { unsafe { LAPIC.lock().end_of_interrupt() };
LAPIC.end_of_interrupt();
}
} }
extern "x86-interrupt" fn apic_err(_: InterruptStackFrame) { extern "x86-interrupt" fn apic_err(_: InterruptStackFrame) {
@ -70,7 +72,5 @@ extern "x86-interrupt" fn apic_err(_: InterruptStackFrame) {
} }
extern "x86-interrupt" fn spurious(_: InterruptStackFrame) { extern "x86-interrupt" fn spurious(_: InterruptStackFrame) {
unsafe { unsafe { LAPIC.lock().end_of_interrupt() };
LAPIC.end_of_interrupt();
}
} }

View file

@ -6,7 +6,6 @@ use {
core::fmt, core::fmt,
hashbrown::HashMap, hashbrown::HashMap,
}; };
/// A device object. /// A device object.
/// TODO define device /// TODO define device
pub type Device = xml::XMLElement; pub type Device = xml::XMLElement;
@ -24,29 +23,27 @@ impl DeviceTree {
let mut dt = Self { let mut dt = Self {
devices: HashMap::new(), devices: HashMap::new(),
}; };
device_tree!( device_tree!(dt, [
dt, "Mice",
[ "Keyboards",
"Mice", "Controllers",
"Keyboards", "Generic HIDs",
"Controllers", "Disk Drives",
"Generic HIDs", "CD Drives",
"Disk Drives", "Batteries",
"CD Drives", "Monitors",
"Batteries", "GPUs",
"Monitors", "CPUs",
"GPUs", "USB",
"CPUs", "Serial Ports",
"USB", "Cameras",
"Serial Ports", "Biometric Devices",
"Cameras", ]);
"Biometric Devices",
]
);
dt dt
} }
} }
use crate::{device_tree, tab, utils::TAB}; use crate::{utils::TAB, device_tree};
use crate::tab;
impl fmt::Display for DeviceTree { impl fmt::Display for DeviceTree {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
writeln!(f)?; writeln!(f)?;

View file

@ -1,19 +1,16 @@
//! Environment call handling routines //! Environment call handling routines
use crate::holeybytes::kernel_services::{ use crate::holeybytes::kernel_services::{block_read, service_definition_service::sds_msg_handler};
block_read, dt_msg_handler::dt_msg_handler, logging_service::log_msg_handler,
service_definition_service::sds_msg_handler,
};
use { use {
super::Vm, super::Vm,
crate::{arch, ipc::buffer::IpcBuffer, kmain::IPC_BUFFERS}, crate::{arch, ipc::buffer::IpcBuffer, kmain::IPC_BUFFERS},
log::{debug, error, info, trace}, log::{debug, error, info, trace, warn},
}; };
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,50 +94,104 @@ 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 => unsafe { 0 => 'wow: {
let size = msg_vec[1]; let size = match msg_vec[0] {
let addr = u16::from_le_bytes(msg_vec[2..4].try_into().unwrap()); 0 => 1,
let value = match size { 1 => 2,
0 => x86_in::<u8>(addr) as u64, 2 => 4,
1 => x86_in::<u16>(addr) as u64, _ => {
2 => x86_in::<u32>(addr) as u64, error!("Tried to write more than 32 bits");
_ => panic!("Trying to read size other than: 8, 16, 32 from port."), break 'wow;
}
}; };
// info!("Read the value {} from address {}", value, addr); let addr = u16::from_le_bytes(msg_vec[1..3].try_into().unwrap());
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 => unsafe { 1 => 'wow: {
let size = msg_vec[1]; let size = match msg_vec[1] {
let addr = u16::from_le_bytes(msg_vec[2..4].try_into().unwrap()); 0 => 1,
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);
match size { unsafe {
0 => x86_out(addr, msg_vec[4]), match size {
1 => x86_out( 1 => x86_out(addr, msg_vec[3]),
addr, 2 => x86_out(
u16::from_le_bytes(msg_vec[4..6].try_into().unwrap_unchecked()), addr,
), u16::from_le_bytes(
2 => x86_out( msg_vec[3..5].try_into().unwrap_unchecked(),
addr, ),
u32::from_le_bytes(msg_vec[4..8].try_into().unwrap_unchecked()), ),
), 4 => x86_out(
_ => panic!("How?"), addr,
u32::from_le_bytes(
msg_vec[3..7].try_into().unwrap_unchecked(),
),
),
_ => panic!("How?"),
}
} }
}, }
_ => {} _ => {}
} }
} }
#[cfg(not(target_arch = "x86_64"))]
3 => unimplemented!("TODO: implement whatever buffer 3 does for no x86_64"),
// source of rng // source of rng
4 => { 4 => {
// limit to last 32 bits // limit to last 32 bits
vm.registers[1] = vm.registers[1] =
hbvm::value::Value(crate::arch::hardware_random_u64() & 0xFFFFFFFF); hbvm::value::Value(crate::arch::hardware_random_u64() & 0xFFFFFFFF);
} }
5 => match dt_msg_handler(vm, mem_addr, length) { // get arch
Ok(()) => {} 5 => {
Err(_) => log::error!("Improper dt query"), 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)
}
}
// AbleCode™ (get fb ptr)
6 => {
use {
crate::kmain::FB_REQ,
limine::{Framebuffer, NonNullPtr},
};
let fb1: &NonNullPtr<Framebuffer> =
&FB_REQ.get_response().get().unwrap().framebuffers()[0];
let msg = block_read(mem_addr, length)[0];
if msg == b'p' {
// ptr
let fb_front = fb1.address.as_ptr().unwrap() as *const u8;
log::info!("Graphics front ptr {:?}", fb_front);
vm.registers[1] = hbvm::value::Value(fb_front as u64);
} else if msg == b'w' {
// width
log::info!("FB Width: {}", fb1.width);
vm.registers[1] = hbvm::value::Value(fb1.width);
} else if msg == b'h' {
// height
log::info!("FB Height: {}", fb1.height);
vm.registers[1] = hbvm::value::Value(fb1.height);
}
}
buffer_id => { buffer_id => {
let mut buffs = IPC_BUFFERS.lock(); let mut buffs = IPC_BUFFERS.lock();
match buffs.get_mut(&buffer_id) { match buffs.get_mut(&buffer_id) {
@ -221,6 +272,34 @@ 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 msg_vec = block_read(mem_addr, length);
let log_level = msg_vec.last().unwrap();
match core::str::from_utf8(&msg_vec[1..]) {
Ok(strr) => {
// use LogLevel::*;
let _ll = match log_level {
0 | 48 => error!("{}", strr),
1 | 49 => warn!("{}", strr),
2 | 50 => info!("{}", strr),
3 | 51 => debug!("{}", strr),
4 | 52 => trace!("{}", strr),
_ => {
return Err(LogError::InvalidLogFormat);
}
};
}
Err(e) => {
error!("{:?}", e);
}
}
Ok(())
}
#[derive(Debug)] #[derive(Debug)]
pub enum LogError { pub enum LogError {
NoMessages, NoMessages,

View file

@ -1,87 +0,0 @@
use {
crate::holeybytes::{kernel_services::block_read, Vm},
alloc::{
string::{String, ToString},
vec::Vec,
},
};
pub enum DtError {
QueryFailure,
}
pub fn dt_msg_handler(vm: &mut Vm, mem_addr: u64, length: usize) -> Result<(), DtError> {
let msg_vec = block_read(mem_addr, length);
let mut bytes: Vec<u8> = Vec::new();
for byte in msg_vec {
if *byte == 0 {
break;
}
bytes.push(*byte)
}
let query_string = String::from_utf8(bytes).unwrap();
log::trace!("Query {}", query_string);
let ret = query_parse(query_string);
log::trace!("Query response {}", ret);
vm.registers[1] = hbvm::value::Value(ret);
Ok(())
}
fn query_parse(query_string: String) -> u64 {
let qt_parse_step_one = query_string.split("/");
let mut qt_parse_step_two: Vec<String> = Vec::new();
for a in qt_parse_step_one {
qt_parse_step_two.push(a.to_string());
}
let first_fragment: &str = &qt_parse_step_two[0];
let ret = match first_fragment {
"framebuffer" => framebuffer_parse(qt_parse_step_two),
"cpu" => cpu_parse(qt_parse_step_two),
_ => 0,
};
return ret;
}
fn cpu_parse(qt_parse_step_two: Vec<String>) -> u64 {
let second_fragment: &str = &qt_parse_step_two[1];
match second_fragment {
// "architecture" => {
// return 0;
// }
_ => {
return 0;
}
};
}
fn framebuffer_parse(qt_parse_step_two: Vec<String>) -> u64 {
use crate::kmain::FB_REQ;
let fbs = &FB_REQ.get_response().get().unwrap().framebuffers();
let second_fragment: &str = &qt_parse_step_two[1];
match second_fragment {
"fb0" => {
let fb_front = &fbs[0];
let third_fragment: &str = &qt_parse_step_two[2];
let ret = match third_fragment {
"ptr" => {
let ptr = fb_front.address.as_ptr().unwrap();
ptr as usize as u64
}
"width" => fb_front.width,
"height" => fb_front.height,
_ => 0,
};
return ret;
}
_ => {
return 0;
}
};
}

View file

@ -1,49 +0,0 @@
use crate::holeybytes::{kernel_services::block_read, Vm};
#[derive(Debug)]
pub enum LogError {
InvalidLogFormat,
}
use log::Record;
pub fn log_msg_handler(_vm: &mut Vm, mem_addr: u64, length: usize) -> Result<(), LogError> {
let msg_vec = block_read(mem_addr, length);
let log_level = msg_vec.last().unwrap();
let file_name = "None";
let line_number = 0;
match core::str::from_utf8(&msg_vec[..msg_vec.len()]) {
Ok(strr) => {
use log::Level::*;
let log_level = match log_level {
0 | 48 => Error,
1 | 49 => Warn,
2 | 50 => Info,
3 | 51 => Debug,
4 | 52 => Trace,
_ => {
return Err(LogError::InvalidLogFormat);
}
};
log::logger().log(
&Record::builder()
.args(format_args!("{}", strr))
.level(log_level)
.target("Userspace")
.file(Some(file_name))
.line(Some(line_number))
.module_path(Some(&file_name))
.build(),
);
}
Err(e) => {
log::error!("{:?}", e);
}
}
Ok(())
}

View file

@ -1,6 +1,6 @@
use { use {
crate::holeybytes::{kernel_services::block_read, Vm}, crate::holeybytes::{kernel_services::block_read, Vm},
alloc::alloc::{alloc, dealloc}, alloc::alloc::{alloc_zeroed, 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(Layout::from_size_align_unchecked(4096, 4096)) }; let ptr = unsafe { alloc_zeroed(Layout::new::<[u8; 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(Layout::from_size_align_unchecked( alloc_zeroed(Layout::from_size_align_unchecked(
page_count as usize * 4096, page_count as usize * 4096,
4096, 1,
)) ))
}; };
@ -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, 4096), Layout::from_size_align_unchecked(page_count as usize * 4096, 1),
) )
} }
} }

View file

@ -1,11 +1,9 @@
use core::slice; use core::slice;
pub mod dt_msg_handler;
pub mod logging_service;
pub mod mem_serve; 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 mut [u8] { pub fn block_read<'a>(mem_addr: u64, length: usize) -> &'a [u8] {
unsafe { slice::from_raw_parts_mut(mem_addr as *mut _, length) } unsafe { slice::from_raw_parts(mem_addr as *const u8, length) }
} }

View file

@ -1,7 +1,7 @@
use { use {
crate::{ crate::{
arch::hardware_random_u64, arch::hardware_random_u64,
holeybytes::{kernel_services::block_read, Vm}, holeybytes::{ecah::LogError, kernel_services::block_read, Vm},
ipc::{buffer::IpcBuffer, protocol::Protocol}, ipc::{buffer::IpcBuffer, protocol::Protocol},
kmain::IPC_BUFFERS, kmain::IPC_BUFFERS,
}, },
@ -15,12 +15,12 @@ pub static SERVICES: Lazy<Mutex<Services>> = Lazy::new(|| {
dt.0.insert(0, Protocol::void()); dt.0.insert(0, Protocol::void());
Mutex::new(dt) Mutex::new(dt)
}); });
#[derive(Debug)]
pub enum ServiceError { pub fn sds_msg_handler(vm: &mut Vm, mem_addr: u64, length: usize) -> Result<(), LogError> {
InvalidFormat,
}
pub fn sds_msg_handler(vm: &mut Vm, mem_addr: u64, length: usize) -> Result<(), ServiceError> {
let 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(); let sds_event_type: ServiceEventType = msg_vec[0].into();
// info!("Length {}", msg_vec.len()); // info!("Length {}", msg_vec.len());

View file

@ -3,7 +3,7 @@ mod kernel_services;
mod mem; mod mem;
use { use {
alloc::alloc::{alloc, dealloc}, alloc::alloc::{alloc_zeroed, dealloc},
core::{ core::{
alloc::Layout, alloc::Layout,
future::Future, future::Future,
@ -61,22 +61,28 @@ 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) => {
log::error!("HBVM Error\r\nRegister dump: {:?}", self.vm.registers,); error!("HBVM Error\r\nRegister dump: {:?}", self.vm.registers);
return Poll::Ready(Err(err)); 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) => {
log::error!( error!(
"HBVM Debug breakpoint\r\nRegister dump: {:?}", "HBVM Debug breakpoint\r\nRegister dump: {:?}",
self.vm.registers, self.vm.registers
); );
cx.waker().wake_by_ref();
Poll::Pending
} }
} }
cx.waker().wake_by_ref();
Poll::Pending
} }
} }
@ -102,5 +108,5 @@ const fn stack_layout() -> Layout {
#[inline(always)] #[inline(always)]
fn allocate_stack() -> *mut u8 { fn allocate_stack() -> *mut u8 {
unsafe { alloc(stack_layout()) } unsafe { alloc_zeroed(stack_layout()) }
} }

View file

@ -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, trace}, log::{debug, info},
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
debug!("Device Tree: {}", dt); info!("Device Tree: {}", dt);
trace!("Boot complete. Moving to init_system"); info!("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,32 +60,39 @@ 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]);
} }
debug!("Graphics initialised"); log::info!("Graphics initialised");
debug!( log::info!(
"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.iter() { for module in boot_modules.into_iter().take(bm_take) {
let cmd = module.cmd.trim_matches('"'); let mut cmd = module.cmd;
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);
let mut thr = ExecThread::new(&module.bytes, Address::new(0));
if cmd_len > 0 {
thr.set_arguments(cmd.as_ptr() as u64, cmd_len);
}
executor.spawn(async move { 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 { if let Err(e) = thr.await {
log::error!("{e:?}"); log::error!("{e:?}");
} }
}) })
} }
debug!("Random number: {}", hardware_random_u64()); info!("Random number: {}", hardware_random_u64());
executor.run(); executor.run();
}; };

View file

@ -2,9 +2,8 @@
//! 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,

View file

@ -0,0 +1,2 @@
protocol abc {
}

View file

@ -1,24 +0,0 @@
@auto_increment
enum LogLevel {
Error = 0,
Warn,
Info,
Debug,
Trace,
}
@auto_increment
enum LogResult {
Err = 0,
Ok,
}
struct Log {
log_level: LogLevel,
}
@visibility(public)
protocol Log {
fn log(Log) -> LogResult;
fn flush() -> LogResult;
}

View file

@ -1 +0,0 @@
# dt_api

View file

@ -1,8 +0,0 @@
stn := @use("rel:../../stn/src/lib.hb");
.{string, memory, buffer} := stn
dt_get := fn(query: ^u8): int {
message_length := string.length(query)
return @eca(int, 3, 5, query, message_length)
}

View file

@ -0,0 +1,14 @@
Element := struct {
width: int,
height: int,
x: u16,
y: u16,
id: int,
}
create_element := fn(): Element {
return Element.(0, 0, 0, 0, 0)
}

View file

@ -0,0 +1,3 @@
FrameID := struct {
}

View file

@ -1,24 +1,12 @@
stn := @use("rel:../../stn/src/lib.hb");
.{string, memory, buffer} := stn
WindowID := struct { WindowID := struct {
host_id: int, host_id: int,
window_id: int, window_id: int,
} }
create_window := fn(channel: int): void { create_window := fn(): WindowID {
// get the horizon buffer return WindowID.(1, 2)
// request a new window and provide the callback buffer }
// wait to recieve a message
windowing_system_buffer := buffer.search("XHorizon\0")
if windowing_system_buffer == 0 {
} else {
msg := "\{01}\0"
msg_length := 2
@eca(void, 3, windowing_system_buffer, msg, msg_length)
}
update_ui := fn(window_id: WindowID): void {
return return
} }

View file

@ -0,0 +1,3 @@
ui_lisp_text_example := "(text id_1)\0";

View file

@ -1,21 +0,0 @@
structures := @use("rel:structures.hb")
version := @use("rel:version.hb")
// Refer to here https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkApplicationInfo.html
ApplicationInfo := struct {
sType: int,
pNext: ^int,
application_name: ^u8,
application_version: int,
engine_name: int,
engine_version: int,
api_version: int,
}
new_application_info := fn(app_name: ^u8, app_version: int, engine_name: ^u8, engine_version: int, api_version: int): ApplicationInfo {
app_info_type := structures.ApplicationInfoType
app_info := ApplicationInfo.(app_info_type, 0, app_name, app_version, engine_name, engine_version, api_version)
return app_info
}

View file

@ -1,14 +0,0 @@
OutOfHostMemory := -1
OutOfDeviceMemory := -2
InitializationFailed := -3
DeviceLost := -4
MemoryMapFailed := -5
LayerNotPresent := -6
ExtensionNotPresent := -7
FeatureNotPresent := -8
IncompatibleDriver := -9
TooManyObjects := -10
FormatNotSupported := -11
FragmentedPool := -12
Unknown := -13

View file

@ -1,10 +0,0 @@
Extent3D := struct {
width: int,
height: int,
depth: int,
}
Extent2D := struct {
width: int,
height: int,
}

View file

@ -1,35 +0,0 @@
application := @use("rel:application.hb");
.{ApplicationInfo} := application
structures := @use("rel:structures.hb")
errors := @use("rel:errors.hb")
// https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkInstanceCreateInfo.html
InstanceCreateInfo := struct {
sType: int,
pNext: int,
flags: int,
application_info: ^ApplicationInfo,
enabled_layer_count: int,
ppEnabledLayerNames: int,
enabled_extension_count: int,
ppEnabledExtensionNames: int,
}
new_create_info := fn(application_info: ^ApplicationInfo): InstanceCreateInfo {
create_info_type := structures.InstanceCreateInfoType
enabled_layer_count := 0
create_info := InstanceCreateInfo.(create_info_type, 0, 0, application_info, enabled_layer_count, 0, 0, 0)
return create_info
}
// TODO
Instance := struct {inner: int}
void_instance := fn(): Instance {
return Instance.(0)
}
create_instance := fn(create_info: ^InstanceCreateInfo, allocator_callback: int, new_obj: ^Instance): int {
return errors.IncompatibleDriver
}

View file

@ -1,17 +1,7 @@
application := @use("rel:application.hb") VK_VERSION_MAJOR := 1;
VK_VERSION_MINOR := 0;
results := @use("rel:results.hb") init_vulkan := fn(): void {
errors := @use("rel:errors.hb")
offsets := @use("rel:offset.hb") return
extends := @use("rel:extends.hb")
rect := @use("rel:rect.hb")
structures := @use("rel:structures.hb")
instance := @use("rel:instance.hb")
version := @use("rel:version.hb")
init_vulkan := fn(): int {
return errors.IncompatibleDriver
} }

View file

@ -1,10 +0,0 @@
Offset3D := struct {
x: int,
y: int,
z: int,
}
Offset2D := struct {
x: int,
y: int,
}

View file

@ -1,7 +0,0 @@
offsets := @use("rel:offset.hb")
extends := @use("rel:extends.hb")
Rect2D := struct {
offset: offsets.Offset2D,
extent: extends.Extent2D,
}

View file

@ -1,7 +0,0 @@
// NonErrors
Success := 0
NotReady := 1
Timeout := 2
EventSet := 3
EventReset := 4
Incomplete := 5

View file

@ -1,61 +0,0 @@
ApplicationInfoType := 0
InstanceCreateInfoType := 1
DeviceQueueCreateInfo := 2
DeviceCreateInfo := 3
SubmitInfo := 4
MemoryAllocateInfo := 5
MappedMemoryRange := 6
BindSparseInfo := 7
FenceCreateInfo := 8
SemaphoreCreateInfo := 9
EventCreateInfo := 10
QueryPoolCreateInfo := 11
BufferCreateInfo := 12
BufferViewCreateInfo := 13
ImageCreateInfo := 14
ImageViewCreateInfo := 15
ShaderModuleCreateInfo := 16
PipelineCacheCreateInfo := 17
PipelineShaderStageCreateInfo := 18
PipelineVertexInputStateCreateInfo := 19
PipelineInputAssemblyStateCreateInfo := 20
PipelineTessellationStateCreateInfo := 21
PipelineViewportStateCreateInfo := 22
PipelineRasterizationStateCreateInfo := 23
PipelineMultisampleStateCreateInfo := 24
PipelineDepthStencilStateCreateInfo := 25
PipelineColorBlendStateCreateInfo := 26
PipelineDynamicStateCreateInfo := 27
GraphicsPipelineCreateInfo := 28
ComputePipelineCreateInfo := 29
PipelineLayoutCreateInfo := 30
SamplerCreateInfo := 31
DescriptorSetLayoutCreateInfo := 32
DescriptorPoolCreateInfo := 33
DescriptorSetAllocateInfo := 34
WriteDescriptorSet := 35
CopyDescriptorSet := 36
FramebufferCreateInfo := 37
RenderPassCreateInfo := 38
CommandPoolCreateInfo := 39
CommandBufferAllocateInfo := 40
CommandBufferInheritanceInfo := 41
CommandBufferBeginInfo := 42
RenderPassBeginInfo := 43
BufferMemoryBarrier := 44
ImageMemoryBarrier := 45
MemoryBarrier := 46
LoaderInstanceCreateInfo := 47
LoaderDeviceCreateInfo := 48

View file

@ -1,9 +0,0 @@
ApiVersion1_0 := make_api_version(0, 1, 0, 0)
make_version := fn(major: int, minor: int, patch: int): int {
return major << 22 | minor << 12 | patch
}
make_api_version := fn(variant: int, major: int, minor: int, patch: int): int {
return variant << 29 | major << 22 | minor << 12 | patch
}

View file

@ -1 +0,0 @@
# pci

View file

@ -1,28 +0,0 @@
PCIAddress := struct {
bus: u8,
device: u8,
function: u8,
}
find_device := fn(vendor_id: int, device_id: int, pci_address: PCIAddress): int {
return 1
}
scan_bus := fn(): void {
}
config_read32 := fn(bus: u32, device: u32, func: u32, offset: u32): u32 {
// construct address param
address := bus << 16 | device << 11 | func << 8
address |= offset
address &= 0xFC
address |= 0x80000000
// write address
//Port::new(0xCF8).write(address);
// read data
//Port::new(0xCFC).read()
return
}

View file

@ -1,5 +1,4 @@
.{math, memory} := @use("../../stn/src/lib.hb"); .{math, memory} := @use("../../stn/src/lib.hb");
.{dt_get} := @use("../../dt_api/src/lib.hb");
.{IVec2} := @use("rel:lib.hb") .{IVec2} := @use("rel:lib.hb")
Color := struct {b: u8, g: u8, r: u8, a: u8} Color := struct {b: u8, g: u8, r: u8, a: u8}
@ -20,13 +19,16 @@ light_blue := Color.(255, 0, 0, 255)
light_magenta := Color.(255, 0, 255, 255) light_magenta := Color.(255, 0, 255, 255)
light_cyan := Color.(255, 255, 0, 255) light_cyan := Color.(255, 255, 0, 255)
// might not work for some resolutions, but needs to be comptime because... // fb_width := 1024
// fb_height := 768
// fb_pixels := fb_width * fb_height
// fb_bytes := fb_pixels << 2
copy_pixels := 0xC000 >> 2 copy_pixels := 0xC000 >> 2
// partitions := fb_pixels / copy_pixels
// total_pages := 1 + fb_bytes >> 12
ctx := @as(Context, idk) ctx := @as(Context, idk)
// some of these are redudant holdovers from fb_driver
// will keep them for future work if necessary
Context := struct { Context := struct {
fb: ^Color, fb: ^Color,
bb: ^Color, bb: ^Color,
@ -40,8 +42,8 @@ Context := struct {
} }
init := fn(): void { init := fn(): void {
width := dt_get("framebuffer/fb0/width\0") width := @eca(int, 3, 6, "w\0", 2)
height := dt_get("framebuffer/fb0/height\0") height := @eca(int, 3, 6, "h\0", 2)
// width := 1024 // width := 1024
// height := 768 // height := 768
pixels := width * height pixels := width * height
@ -50,7 +52,7 @@ init := fn(): void {
pages := 1 + bytes >> 12 pages := 1 + bytes >> 12
back_buffer := create_back_buffer(pages) back_buffer := create_back_buffer(pages)
ctx = Context.{ ctx = Context.{
fb: dt_get("framebuffer/fb0/ptr\0"), fb: @eca(^Color, 3, 6, "p\0", 2),
bb: back_buffer, bb: back_buffer,
buf: back_buffer, buf: back_buffer,
width, width,
@ -184,8 +186,8 @@ put_line_low := fn(p0: IVec2, p1: IVec2, color: Color): void {
dy := p1.y - p0.y dy := p1.y - p0.y
yi := 1 yi := 1
if dy < 0 { if dy < 0 {
yi = -1 yi = 0 - 1
dy = -dy dy = 0 - dy
} }
D := 2 * dy - dx D := 2 * dy - dx
y := p0.y y := p0.y
@ -208,8 +210,8 @@ put_line_high := fn(p0: IVec2, p1: IVec2, color: Color): void {
dy := p1.y - p0.y dy := p1.y - p0.y
xi := 1 xi := 1
if dy < 0 { if dy < 0 {
xi = -1 xi = 0 - 1
dx = -dx dx = 0 - dx
} }
D := 2 * dx - dy D := 2 * dx - dy
x := p0.x x := p0.x

View file

@ -1,5 +1,5 @@
.{pci, memory, string, log} := @use("../../stn/src/lib.hb");
.{IVec2} := @use("rel:lib.hb") .{IVec2} := @use("rel:lib.hb")
// .{pci, memory, string, log} := @use("../../stn/src/lib.hb");
Color := struct {b: u8, g: u8, r: u8, a: u8} Color := struct {b: u8, g: u8, r: u8, a: u8}
white := Color.(255, 255, 255, 255) white := Color.(255, 255, 255, 255)
@ -76,5 +76,16 @@ sync := fn(): void {
} }
init := fn(): void { init := fn(): void {
b := memory.request_page(1)
bus := 0
device := 0
loop if bus == 256 break else {
loop if device == 32 break else {
a := pci.config_read(0, 0, 0, 0)
log.info(string.display_int(a, b))
device += 1
}
bus += 1
}
return return
} }

View file

@ -4,8 +4,10 @@ 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, length: int): void { send_message := fn(msg: ^u8, buffer_id: int): void {
return @eca(void, 3, buffer_id, msg, length) msg_length := @inline(string.length, msg)
@eca(i32, 3, buffer_id, msg, msg_length)
return
} }
create := fn(msg: ^u8): int { create := fn(msg: ^u8): int {

View file

@ -17,23 +17,38 @@ 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 {
return @eca(void, 3, 3, &OutbMsg.(1, 0, addr, value), @sizeof(OutbMsg)) msg := "\0\0\0\0\0";
*@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 {
return @eca(u8, 3, 3, &InbMsg.(0, 0, addr), @sizeof(InbMsg)) msg := "\0\0\0\0";
*@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 {
return @eca(void, 3, 3, &OutlMsg.(1, 2, addr, value), @sizeof(OutlMsg)) msg := "\0\0\0\0\0\0\0\0";
*@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 {
return @eca(u32, 3, 3, &InlMsg.(0, 2, addr), @sizeof(InlMsg)) msg := "\0\0\0\0";
*@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)
} }

View file

@ -4,29 +4,19 @@ length := fn(ptr: ^u8): int {
return len return len
} }
// WTFFF is wrong with display_int
display_int := fn(num: int, p: ^u8): ^u8 { display_int := fn(num: int, p: ^u8): ^u8 {
ptr := p i := 0
negative := num < 0
if negative {
num = -num
}
if num == 0 { if num == 0 {
*ptr = 48 *p = 48
ptr += 1 return p
} else {
loop if num == 0 break else {
*ptr = num % 10 + 48
ptr += 1
num /= 10
}
} }
if negative { loop if num == 0 break else {
*ptr = 45 *(p + i) = num % 10 + 48
ptr += 1 num /= 10
}; i += 1
*ptr = 0 }
@inline(reverse, p) @inline(reverse, p);
*(p + i) = 0
return p return p
} }

View file

@ -1 +0,0 @@
# dt_buffer_test

View file

@ -1,11 +0,0 @@
[package]
name = "dt_buffer_test"
authors = ["able"]
[dependants.libraries]
[dependants.binaries]
hblang.version = "1.0.0"
[build]
command = "hblang src/main.hb"

View file

@ -1,14 +0,0 @@
dt_api := @use("../../../libraries/dt_api/src/lib.hb");
.{dt_get} := dt_api
main := fn(): int {
dt_api.dt_get("framebuffer/fb0/width\0")
dt_api.dt_get("cpu/cpu0/architecture\0")
// Checking if the first detected serial port is memory mapped or port mapped
// 0 -> memory mapped
// 1 -> port mapped
dt_get("serial_ports/sp0/mapping\0")
return 0
}

View file

@ -1,3 +0,0 @@
# Horizon
The Horizon Windowing system server. This is the component that spawns/layouts and renders windows.
For the api look in libraries/horizon_api.

View file

@ -1,11 +0,0 @@
[package]
name = "horizon"
authors = ["able"]
[dependants.libraries]
[dependants.binaries]
hblang.version = "1.0.0"
[build]
command = "hblang src/main.hb"

View file

@ -1,6 +0,0 @@
alias HostID = u64;
struct WindowID {
host_id: HostID,
window_id: u64
}

View file

@ -1,12 +0,0 @@
stn := @use("../../../libraries/stn/src/lib.hb");
.{string, memory, buffer} := stn
horizon_api := @use("../../../libraries/horizon_api/src/lib.hb")
main := fn(): int {
a := buffer.create("XHorizon\0")
loop {
}
return 0
}

View file

@ -1 +0,0 @@
# horizon_testing_program

View file

@ -1,11 +0,0 @@
[package]
name = "horizon_testing_program"
authors = ["able"]
[dependants.libraries]
[dependants.binaries]
hblang.version = "1.0.0"
[build]
command = "hblang src/main.hb"

View file

@ -1,35 +0,0 @@
stn := @use("../../../libraries/stn/src/lib.hb");
.{string, memory, buffer, log} := stn
horizon_api := @use("../../../libraries/horizon_api/src/lib.hb");
.{create_window} := horizon_api
ignim := @use("../../../libraries/ignim/src/lib.hb");
.{errors} := ignim
main := fn(): int {
windowing_system_buffer := buffer.create("XHorizon\0")
// TODO: get WindowID
create_window(windowing_system_buffer)
program_name := "Horizon Testing Program\0"
program_version := ignim.version.make_version(0, 1, 0)
engine_name := "None\0"
engine_version := ignim.version.make_version(0, 0, 0)
api_version := ignim.version.make_api_version(0, 1, 0, 0)
app_info := ignim.application.new_application_info(program_name, program_version, engine_name, engine_version, api_version)
create_info := ignim.instance.new_create_info(&app_info)
instance := ignim.instance.void_instance()
// TODO: recursively follow this https://vulkan-tutorial.com/Drawing_a_triangle/Setup/Instance
ret := ignim.instance.create_instance(&create_info, 0, &instance)
if ret == errors.IncompatibleDriver {
log.error("Driver Incompatible with Vulkan\0")
}
return 0
}

View file

@ -0,0 +1,2 @@
# KVStore
This is a small single process in memory key value store.

View file

@ -0,0 +1,37 @@
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;
}

View file

@ -1,3 +0,0 @@
# 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

View file

@ -1,11 +0,0 @@
[package]
name = "ps2_driver"
authors = ["Talha Qamar"]
[dependants.libraries]
[dependants.binaries]
hblang.version = "1.0.0"
[build]
command = "hblang src/main.hb"

View file

@ -1,33 +0,0 @@
.{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
}

View file

@ -13,7 +13,7 @@ example := fn(): void {
render.clear(color) render.clear(color)
render.sync() render.sync()
if (color.b & 255) == 255 | (color.b & 255) == 0 { if (color.b & 255) == 255 | (color.b & 255) == 0 {
n = -n n = 0 - n
} }
color.b += n color.b += n
} }

View file

@ -15,10 +15,10 @@ example := fn(): void {
render.clear(render.black) render.clear(render.black)
if pos.x == 0 | pos.x == width - 100 { if pos.x == 0 | pos.x == width - 100 {
vel.x = -vel.x vel.x = 0 - vel.x
} }
if pos.y == 0 | pos.y == height - 100 { if pos.y == 0 | pos.y == height - 100 {
vel.y = -vel.y vel.y = 0 - vel.y
} }
pos += vel pos += vel

View file

@ -1 +0,0 @@
# svga_driver

View file

@ -1,11 +0,0 @@
[package]
name = "svga_driver"
authors = ["able"]
[dependants.libraries]
[dependants.binaries]
hblang.version = "1.0.0"
[build]
command = "hblang src/main.hb"

View file

@ -1,41 +0,0 @@
pci := @use("../../../libraries/pci/src/lib.hb");
.{PCIAddress} := pci
SVGADevice := struct {
pciAddr: PCIAddress,
ioBase: u32,
fifoMem: ^u32,
fbMem: ^u8,
fifoSize: int,
fbSize: int,
vramSize: int,
deviceVersionId: int,
capabilities: int,
width: int,
height: int,
bpp: int,
pitch: int,
}
svga_device := fn(): SVGADevice {
pci_addr := PCIAddress.(0, 0, 0)
return SVGADevice.(pci_addr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
}
/*
struct {
uint32 reservedSize;
Bool usingBounceBuffer;
uint8 bounceBuffer[1024 * 1024];
uint32 nextFence;
} fifo;
volatile struct {
uint32 pending;
uint32 switchContext;
IntrContext oldContext;
IntrContext newContext;
uint32 count;
} irq;
*/

View file

@ -1,33 +0,0 @@
device := @use("rel:device.hb")
pci := @use("../../../libraries/pci/src/lib.hb")
stn := @use("../../../libraries/stn/src/lib.hb");
.{string, memory, buffer, log} := stn
reg := @use("rel:reg.hb")
PCI_VENDOR_ID_VMWARE := 0x15AD
PCI_DEVICE_ID_VMWARE_SVGA2 := 0x405
init := fn(): void {
svga_struct := device.svga_device()
if pci.find_device(PCI_VENDOR_ID_VMWARE, PCI_DEVICE_ID_VMWARE_SVGA2, svga_struct.pciAddr) {
log.error("No VMware SVGA device found.\0")
}
return
}
write_reg := fn(index: u32, value: u32): void {
}
SVGA_disable := fn(): void {
write_reg(reg.SVGA_REG_ENABLE, 0)
return
}
main := fn(): int {
init()
return 0
}

View file

@ -1,4 +0,0 @@
SVGA_REG_ENABLE_DISABLE := 0
SVGA_REG_ENABLE_ENABLE := 1
SVGA_REG_ENABLE_HIDE := 2
SVGA_REG_ENABLE_ENABLE_HIDE := SVGA_REG_ENABLE_ENABLE | SVGA_REG_ENABLE_HIDE

View file

@ -17,32 +17,17 @@ resolution = "1024x768x24"
[boot.limine.ableos.modules] [boot.limine.ableos.modules]
# [boot.limine.ableos.modules.tests] [boot.limine.ableos.modules.tests]
# path = "boot:///tests.hbf" path = "boot:///tests.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"
# [boot.limine.ableos.modules.horizon]
# path = "boot:///horizon.hbf"
# [boot.limine.ableos.modules.horizon_testing_program]
# path = "boot:///horizon_testing_program.hbf"
# [boot.limine.ableos.modules.dt_buffer_test]
# path = "boot:///dt_buffer_test.hbf"
# [boot.limine.ableos.modules.svga_driver]
# path = "boot:///svga_driver.hbf"
[boot.limine.ableos.modules.ps2_driver]
path = "boot:///ps2_driver.hbf"

View file

@ -0,0 +1,4 @@
/// a b c
void main(){}
// Generated documentation below

View file

@ -0,0 +1,2 @@
(label "Documentation")
(label "")

View file

@ -1,27 +0,0 @@
/*
the following snippet lays out the following.
10 11
*/
(vertical
(label "10")
(label "11"))
/*
Each button must have an ID. This ID must be unique per button or the buttons with the same
ID will be treated as the same button.
*/
(button id:8)
/*
This unique ID rull applies to any interactable element.
*/
(label interactive:true id:9)
/*
The ID is used to send a message to the buffer of the process that handles UI.
The following code will handle displaying text locally and also sending the delta change to the buffer.
*/
(line-edit id:10)

View file

@ -0,0 +1,7 @@
(vertical
(horizontal
(label "Function main")
(button "goto declaration" (on_click "src/main.c:2")))
(label "takes void")
(label "returns void")
(label "a b c"))

View file

@ -0,0 +1,5 @@
- container
- horizontal
- vertical
- framebuffer
-