Compare commits

..

21 commits

Author SHA1 Message Date
koniifer 41b339dfd0 omfg it's fixed 🙏 2024-09-16 21:56:52 +01:00
koniifer a8d38e04c4 let's just use strings for now 2024-09-16 20:45:19 +01:00
koniifer 1f4fce0f66 please bugs begone 2024-09-16 20:15:51 +01:00
koniifer b021fc5b86 bug squashing & testing 2024-09-15 17:01:29 +01:00
able 5f2b181f22 Merge pull request 'good luck able' (#17) from koniifer/ableos-framebuffer:master into master
Reviewed-on: https://git.ablecorp.us/AbleOS/ableos/pulls/17
2024-09-14 16:44:05 +00:00
koniifer 43ea77c18f merge mainline branch and do some housekeeping 2024-09-14 11:26:32 +01:00
Able 2b2e0c514b multiline 2024-09-14 04:28:45 -05:00
Able fcca015866 minor changes 2024-09-14 04:05:40 -05:00
Able cc9337348e PCI+SVGA skeleton 2024-09-14 03:51:57 -05:00
Able 028949559b ignim checkpoint 2024-09-14 00:31:35 -05:00
Able 91380539d9 Ignim work 2024-09-13 23:11:50 -05:00
Able ec25c0f207 update on the logger
Further changes pending on the IDL
2024-09-13 20:50:12 -05:00
Able 1b5cb54a2b ignim work 2024-09-13 20:17:47 -05:00
Able 9686349476 add support for the device tree 2024-09-13 18:11:23 -05:00
koniifer f8c7873978 squash 2024-09-13 22:41:31 +01:00
Able 40cc412ab3 Horizon API work 2024-09-13 16:40:05 -05:00
Able cd369b39d5 more changes to make konii so anger 2024-09-12 15:34:28 -05:00
mlokr 331cbf5da1
fixing arm compilation errors 2024-09-10 21:52:57 +02:00
Able 0594b99a59 cleanup 2024-09-03 03:34:29 -05:00
Able 1855307cd9 IDL tokenization 2024-09-02 21:50:43 -05:00
Able 7426bf479f idl work 2024-08-30 12:31:45 -05:00
72 changed files with 999 additions and 410 deletions

26
Cargo.lock generated
View file

@ -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.19"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b62ac837cdb5cb22e10a256099b4fc502b1dfe560cb282963a974d7abd80e476" checksum = "2d74707dde2ba56f86ae90effb3b43ddd369504387e718014de010cec7959800"
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#2bc7a5c13f6ab2b3ee28f772f31eb3414fa2b25b" source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#254d5ed96234c8291770d84b2ac11ef7dd403b28"
[[package]] [[package]]
name = "hbbytecode" name = "hbbytecode"
version = "0.1.0" version = "0.1.0"
source = "git+https://git.ablecorp.us/ableos/holey-bytes#2bc7a5c13f6ab2b3ee28f772f31eb3414fa2b25b" source = "git+https://git.ablecorp.us/ableos/holey-bytes.git#254d5ed96234c8291770d84b2ac11ef7dd403b28"
[[package]] [[package]]
name = "hblang" name = "hblang"
version = "0.1.0" version = "0.1.0"
source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#2bc7a5c13f6ab2b3ee28f772f31eb3414fa2b25b" source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#254d5ed96234c8291770d84b2ac11ef7dd403b28"
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#2bc7a5c13f6ab2b3ee28f772f31eb3414fa2b25b" source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#254d5ed96234c8291770d84b2ac11ef7dd403b28"
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#2bc7a5c13f6ab2b3ee28f772f31eb3414fa2b25b" source = "git+https://git.ablecorp.us/ableos/holey-bytes.git#254d5ed96234c8291770d84b2ac11ef7dd403b28"
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",

View file

@ -1,20 +1,84 @@
use logos::Logos; pub mod protocol;
#[derive(Logos, Debug, PartialEq)] use std::io::Read;
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("{")]
Period, LBrace,
// Or regular expressions. #[token("}")]
#[regex("[a-zA-Z]+")] RBrace,
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 main() { pub fn build_idl(name: String) {
let mut lex = Token::lexer("Create ridiculously fast Lexers."); let contents = open_protocol(name);
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
} }

17
dev/src/idl/protocol.rs Normal file
View file

@ -0,0 +1,17 @@
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,4 +1,6 @@
use std::io::Write; use std::io::Write;
use idl::build_idl;
pub mod idl; pub mod idl;
pub enum Options { pub enum Options {
@ -7,7 +9,7 @@ pub enum Options {
New, New,
Run, Run,
} }
#[derive(PartialEq)] #[derive(PartialEq, Debug)]
pub enum DevelopmentType { pub enum DevelopmentType {
Program, Program,
Library, Library,
@ -24,7 +26,7 @@ fn main() {
match subcommand { match subcommand {
"build" => { "build" => {
let name = &args[1]; let name = &args.pop().unwrap();
build(name.to_string()) build(name.to_string())
} }
"new" => { "new" => {
@ -103,7 +105,20 @@ 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" 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 }

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};
static SERIAL_CONSOLE: Mutex<SerialConsole> = Mutex::new(SerialConsole { pub 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 = 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
}; };

View file

@ -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();
}
} }

View file

@ -6,6 +6,7 @@ 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;
@ -23,7 +24,9 @@ impl DeviceTree {
let mut dt = Self { let mut dt = Self {
devices: HashMap::new(), devices: HashMap::new(),
}; };
device_tree!(dt, [ device_tree!(
dt,
[
"Mice", "Mice",
"Keyboards", "Keyboards",
"Controllers", "Controllers",
@ -38,12 +41,12 @@ impl DeviceTree {
"Serial Ports", "Serial Ports",
"Cameras", "Cameras",
"Biometric Devices", "Biometric Devices",
]); ]
);
dt dt
} }
} }
use crate::{utils::TAB, device_tree}; use crate::{device_tree, tab, utils::TAB};
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,16 +1,19 @@
//! Environment call handling routines //! Environment call handling routines
use crate::holeybytes::kernel_services::{block_read, service_definition_service::sds_msg_handler}; use crate::holeybytes::kernel_services::{
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, warn}, log::{debug, error, info, trace},
}; };
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);
@ -94,104 +97,50 @@ 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?"),
} }
} },
}
_ => {} _ => {}
} }
} }
#[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);
} }
// get arch 5 => match dt_msg_handler(vm, mem_addr, length) {
5 => { Ok(()) => {}
if cfg!(target_arch = "x86_64") { Err(_) => log::error!("Improper dt query"),
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) {
@ -272,34 +221,6 @@ 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

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

@ -0,0 +1,49 @@
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_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),
) )
} }
} }

View file

@ -1,9 +1,11 @@
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 [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) }
} }

View file

@ -1,7 +1,7 @@
use { use {
crate::{ crate::{
arch::hardware_random_u64, arch::hardware_random_u64,
holeybytes::{ecah::LogError, kernel_services::block_read, Vm}, holeybytes::{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 fn sds_msg_handler(vm: &mut Vm, mem_addr: u64, length: usize) -> Result<(), LogError> { pub enum ServiceError {
let msg_vec = block_read(mem_addr, length); InvalidFormat,
if msg_vec.is_empty() {
return Err(LogError::NoMessages);
} }
pub fn sds_msg_handler(vm: &mut Vm, mem_addr: u64, length: usize) -> Result<(), ServiceError> {
let msg_vec = block_read(mem_addr, length);
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_zeroed, dealloc}, alloc::alloc::{alloc, dealloc},
core::{ core::{
alloc::Layout, alloc::Layout,
future::Future, future::Future,
@ -61,30 +61,24 @@ 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;
impl HandlePageFault for PageFaultHandler { impl HandlePageFault for 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()) }
} }

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, 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();
}; };

View file

@ -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,

View file

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

View file

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

@ -0,0 +1 @@
# dt_api

View file

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

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

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

View file

@ -1,12 +1,24 @@
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(): WindowID { create_window := fn(channel: int): void {
return WindowID.(1, 2) // get the horizon buffer
// 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

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

View file

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

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

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

View file

@ -0,0 +1,35 @@
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,7 +1,17 @@
VK_VERSION_MAJOR := 1; application := @use("rel:application.hb")
VK_VERSION_MINOR := 0;
init_vulkan := fn(): void { results := @use("rel:results.hb")
errors := @use("rel:errors.hb")
return offsets := @use("rel:offset.hb")
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

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

View file

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

View file

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

View file

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

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

@ -0,0 +1 @@
# pci

View file

@ -0,0 +1,28 @@
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,4 +1,5 @@
.{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}
@ -19,16 +20,13 @@ 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)
// fb_width := 1024 // might not work for some resolutions, but needs to be comptime because...
// 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,
@ -42,8 +40,8 @@ Context := struct {
} }
init := fn(): void { init := fn(): void {
width := @eca(int, 3, 6, "w\0", 2) width := dt_get("framebuffer/fb0/width\0")
height := @eca(int, 3, 6, "h\0", 2) height := dt_get("framebuffer/fb0/height\0")
// width := 1024 // width := 1024
// height := 768 // height := 768
pixels := width * height pixels := width * height
@ -52,7 +50,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: @eca(^Color, 3, 6, "p\0", 2), fb: dt_get("framebuffer/fb0/ptr\0"),
bb: back_buffer, bb: back_buffer,
buf: back_buffer, buf: back_buffer,
width, width,
@ -186,8 +184,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 = 0 - 1 yi = -1
dy = 0 - dy dy = -dy
} }
D := 2 * dy - dx D := 2 * dy - dx
y := p0.y y := p0.y
@ -210,8 +208,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 = 0 - 1 xi = -1
dx = 0 - dx dx = -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,16 +76,5 @@ 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,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 {

View file

@ -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)
} }

View file

@ -4,19 +4,29 @@ 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 {
i := 0 ptr := p
negative := num < 0
if negative {
num = -num
}
if num == 0 { if num == 0 {
*p = 48 *ptr = 48
return p 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
} }
@inline(reverse, p); }
*(p + i) = 0 if negative {
*ptr = 45
ptr += 1
};
*ptr = 0
@inline(reverse, p)
return p return p
} }

View file

@ -0,0 +1 @@
# dt_buffer_test

View file

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

View file

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

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

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

View file

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

View file

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

@ -0,0 +1 @@
# horizon_testing_program

View file

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

View file

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

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

View file

@ -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;
}

View 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

View 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"

View 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
}

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 = 0 - n n = -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 = 0 - vel.x vel.x = -vel.x
} }
if pos.y == 0 | pos.y == height - 100 { if pos.y == 0 | pos.y == height - 100 {
vel.y = 0 - vel.y vel.y = -vel.y
} }
pos += vel pos += vel

View file

@ -0,0 +1 @@
# svga_driver

View file

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

View file

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

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

@ -0,0 +1,4 @@
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,17 +17,32 @@ 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

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

View file

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

View file

@ -0,0 +1,27 @@
/*
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

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

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