forked from AbleOS/ableos
Compare commits
12 commits
master
...
render-api
Author | SHA1 | Date | |
---|---|---|---|
koniifer | 555bc49663 | ||
koniifer | 63c3544012 | ||
koniifer | e577572299 | ||
koniifer | c2183d5138 | ||
koniifer | 022c1c196a | ||
koniifer | fef5487e62 | ||
koniifer | 3a6778149b | ||
koniifer | 3b95371c41 | ||
koniifer | fd155ea26a | ||
koniifer | 9b34e19005 | ||
koniifer | 3ca7e13f3e | ||
koniifer | 1031ca6314 |
26
Cargo.lock
generated
26
Cargo.lock
generated
|
@ -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",
|
||||||
|
|
|
@ -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
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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!(
|
||||||
"==========
|
"==========
|
||||||
|
|
|
@ -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 }
|
||||||
|
|
|
@ -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,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,9 +23,7 @@ impl DeviceTree {
|
||||||
let mut dt = Self {
|
let mut dt = Self {
|
||||||
devices: HashMap::new(),
|
devices: HashMap::new(),
|
||||||
};
|
};
|
||||||
device_tree!(
|
device_tree!(dt, [
|
||||||
dt,
|
|
||||||
[
|
|
||||||
"Mice",
|
"Mice",
|
||||||
"Keyboards",
|
"Keyboards",
|
||||||
"Controllers",
|
"Controllers",
|
||||||
|
@ -41,12 +38,12 @@ impl DeviceTree {
|
||||||
"Serial Ports",
|
"Serial Ports",
|
||||||
"Cameras",
|
"Cameras",
|
||||||
"Biometric Devices",
|
"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)?;
|
|
@ -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());
|
||||||
vm.registers[1] = hbvm::value::Value(value);
|
let value = unsafe {
|
||||||
},
|
|
||||||
1 => unsafe {
|
|
||||||
let size = msg_vec[1];
|
|
||||||
let addr = u16::from_le_bytes(msg_vec[2..4].try_into().unwrap());
|
|
||||||
trace!("Setting address {}", addr);
|
|
||||||
match size {
|
match size {
|
||||||
0 => x86_out(addr, msg_vec[4]),
|
1 => x86_in::<u8>(addr) as u64,
|
||||||
1 => x86_out(
|
2 => x86_in::<u16>(addr) as u64,
|
||||||
addr,
|
4 => x86_in::<u32>(addr) as u64,
|
||||||
u16::from_le_bytes(msg_vec[4..6].try_into().unwrap_unchecked()),
|
_ => panic!("how?"),
|
||||||
),
|
}
|
||||||
|
};
|
||||||
|
trace!("Read the value {} from address {}", value, addr);
|
||||||
|
vm.registers[1] = hbvm::value::Value(value);
|
||||||
|
}
|
||||||
|
1 => 'wow: {
|
||||||
|
let size = match msg_vec[1] {
|
||||||
|
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);
|
||||||
|
unsafe {
|
||||||
|
match size {
|
||||||
|
1 => x86_out(addr, msg_vec[3]),
|
||||||
2 => x86_out(
|
2 => x86_out(
|
||||||
addr,
|
addr,
|
||||||
u32::from_le_bytes(msg_vec[4..8].try_into().unwrap_unchecked()),
|
u16::from_le_bytes(
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
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,
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -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(())
|
|
||||||
}
|
|
|
@ -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),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) }
|
||||||
}
|
}
|
||||||
|
|
|
@ -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());
|
||||||
|
|
|
@ -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,23 +61,29 @@ 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) => return Poll::Ready(Ok(())),
|
Ok(VmRunOk::End) => Poll::Ready(Ok(())),
|
||||||
Ok(VmRunOk::Ecall) => ecah::handler(&mut self.vm),
|
Ok(VmRunOk::Ecall) => {
|
||||||
Ok(VmRunOk::Timer) => (),
|
ecah::handler(&mut self.vm);
|
||||||
Ok(VmRunOk::Breakpoint) => {
|
|
||||||
log::error!(
|
|
||||||
"HBVM Debug breakpoint\r\nRegister dump: {:?}",
|
|
||||||
self.vm.registers,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cx.waker().wake_by_ref();
|
cx.waker().wake_by_ref();
|
||||||
Poll::Pending
|
Poll::Pending
|
||||||
}
|
}
|
||||||
|
Ok(VmRunOk::Timer) => {
|
||||||
|
cx.waker().wake_by_ref();
|
||||||
|
Poll::Pending
|
||||||
|
}
|
||||||
|
Ok(VmRunOk::Breakpoint) => {
|
||||||
|
error!(
|
||||||
|
"HBVM Debug breakpoint\r\nRegister dump: {:?}",
|
||||||
|
self.vm.registers
|
||||||
|
);
|
||||||
|
cx.waker().wake_by_ref();
|
||||||
|
Poll::Pending
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct PageFaultHandler;
|
struct PageFaultHandler;
|
||||||
|
@ -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()) }
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
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_ptr() as u64, cmd_len);
|
thr.set_arguments(cmd.as_bytes().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:?}");
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
debug!("Random number: {}", hardware_random_u64());
|
info!("Random number: {}", hardware_random_u64());
|
||||||
|
|
||||||
executor.run();
|
executor.run();
|
||||||
};
|
};
|
||||||
|
|
|
@ -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,
|
||||||
|
|
2
sysdata/idl/abc/src/protocol.aidl
Normal file
2
sysdata/idl/abc/src/protocol.aidl
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
protocol abc {
|
||||||
|
}
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -1 +0,0 @@
|
||||||
# dt_api
|
|
|
@ -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)
|
|
||||||
}
|
|
14
sysdata/libraries/horizon_api/src/element.hb
Normal file
14
sysdata/libraries/horizon_api/src/element.hb
Normal 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)
|
||||||
|
}
|
||||||
|
|
3
sysdata/libraries/horizon_api/src/frame.hb
Normal file
3
sysdata/libraries/horizon_api/src/frame.hb
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
FrameID := struct {
|
||||||
|
|
||||||
|
}
|
|
@ -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
|
||||||
}
|
}
|
3
sysdata/libraries/horizon_api/src/text.hb
Normal file
3
sysdata/libraries/horizon_api/src/text.hb
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
ui_lisp_text_example := "(text id_1)\0";
|
||||||
|
|
||||||
|
|
|
@ -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
|
|
||||||
}
|
|
|
@ -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
|
|
|
@ -1,10 +0,0 @@
|
||||||
Extent3D := struct {
|
|
||||||
width: int,
|
|
||||||
height: int,
|
|
||||||
depth: int,
|
|
||||||
}
|
|
||||||
|
|
||||||
Extent2D := struct {
|
|
||||||
width: int,
|
|
||||||
height: int,
|
|
||||||
}
|
|
|
@ -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
|
|
||||||
}
|
|
|
@ -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
|
|
||||||
}
|
}
|
|
@ -1,10 +0,0 @@
|
||||||
Offset3D := struct {
|
|
||||||
x: int,
|
|
||||||
y: int,
|
|
||||||
z: int,
|
|
||||||
}
|
|
||||||
|
|
||||||
Offset2D := struct {
|
|
||||||
x: int,
|
|
||||||
y: int,
|
|
||||||
}
|
|
|
@ -1,7 +0,0 @@
|
||||||
offsets := @use("rel:offset.hb")
|
|
||||||
extends := @use("rel:extends.hb")
|
|
||||||
|
|
||||||
Rect2D := struct {
|
|
||||||
offset: offsets.Offset2D,
|
|
||||||
extent: extends.Extent2D,
|
|
||||||
}
|
|
|
@ -1,7 +0,0 @@
|
||||||
// NonErrors
|
|
||||||
Success := 0
|
|
||||||
NotReady := 1
|
|
||||||
Timeout := 2
|
|
||||||
EventSet := 3
|
|
||||||
EventReset := 4
|
|
||||||
Incomplete := 5
|
|
|
@ -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
|
|
|
@ -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
|
|
||||||
}
|
|
|
@ -1 +0,0 @@
|
||||||
# pci
|
|
|
@ -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
|
|
||||||
}
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
|
@ -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 {
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
|
@ -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 {
|
loop if num == 0 break else {
|
||||||
*ptr = num % 10 + 48
|
*(p + i) = num % 10 + 48
|
||||||
ptr += 1
|
|
||||||
num /= 10
|
num /= 10
|
||||||
|
i += 1
|
||||||
}
|
}
|
||||||
}
|
@inline(reverse, p);
|
||||||
if negative {
|
*(p + i) = 0
|
||||||
*ptr = 45
|
|
||||||
ptr += 1
|
|
||||||
};
|
|
||||||
*ptr = 0
|
|
||||||
@inline(reverse, p)
|
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
# dt_buffer_test
|
|
|
@ -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"
|
|
|
@ -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
|
|
||||||
}
|
|
|
@ -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.
|
|
|
@ -1,11 +0,0 @@
|
||||||
[package]
|
|
||||||
name = "horizon"
|
|
||||||
authors = ["able"]
|
|
||||||
|
|
||||||
[dependants.libraries]
|
|
||||||
|
|
||||||
[dependants.binaries]
|
|
||||||
hblang.version = "1.0.0"
|
|
||||||
|
|
||||||
[build]
|
|
||||||
command = "hblang src/main.hb"
|
|
|
@ -1,6 +0,0 @@
|
||||||
alias HostID = u64;
|
|
||||||
|
|
||||||
struct WindowID {
|
|
||||||
host_id: HostID,
|
|
||||||
window_id: u64
|
|
||||||
}
|
|
|
@ -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
|
|
||||||
}
|
|
|
@ -1 +0,0 @@
|
||||||
# horizon_testing_program
|
|
|
@ -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"
|
|
|
@ -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
|
|
||||||
}
|
|
2
sysdata/programs/kvstore/README.md
Normal file
2
sysdata/programs/kvstore/README.md
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
# KVStore
|
||||||
|
This is a small single process in memory key value store.
|
37
sysdata/programs/kvstore/src/main.hb
Normal file
37
sysdata/programs/kvstore/src/main.hb
Normal 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;
|
||||||
|
}
|
|
@ -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
|
|
|
@ -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"
|
|
|
@ -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
|
|
||||||
}
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
# svga_driver
|
|
|
@ -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"
|
|
|
@ -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;
|
|
||||||
*/
|
|
|
@ -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
|
|
||||||
}
|
|
|
@ -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
|
|
|
@ -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"
|
|
||||||
|
|
4
sysdata/ui_lisp/doc_example.ul
Normal file
4
sysdata/ui_lisp/doc_example.ul
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
/// a b c
|
||||||
|
void main(){}
|
||||||
|
|
||||||
|
// Generated documentation below
|
2
sysdata/ui_lisp/documentation.ul
Normal file
2
sysdata/ui_lisp/documentation.ul
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
(label "Documentation")
|
||||||
|
(label "")
|
|
@ -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)
|
|
7
sysdata/ui_lisp/ui_lisp.ul
Normal file
7
sysdata/ui_lisp/ui_lisp.ul
Normal 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"))
|
5
sysdata/ui_lisp/windowing_system_ui_lang.md
Normal file
5
sysdata/ui_lisp/windowing_system_ui_lang.md
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
- container
|
||||||
|
- horizontal
|
||||||
|
- vertical
|
||||||
|
- framebuffer
|
||||||
|
-
|
Loading…
Reference in a new issue