forked from AbleOS/ableos
tack inplace hbvm
This commit is contained in:
parent
282688d48b
commit
2744e8e67b
23
Cargo.lock
generated
23
Cargo.lock
generated
|
@ -5,9 +5,10 @@ version = 3
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "able_graphics_library"
|
name = "able_graphics_library"
|
||||||
version = "0.1.2"
|
version = "0.1.2"
|
||||||
source = "git+https://git.ablecorp.us/ableos/ableos_userland#70a65fc10d2caafe370be90eb0e31aa7d9347218"
|
source = "git+https://git.ablecorp.us/ableos/ableos_userland#f433484f2f56a4e8f77b1f39680b88c3d1e27830"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"embedded-graphics",
|
"embedded-graphics",
|
||||||
|
"log",
|
||||||
"versioning",
|
"versioning",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -140,9 +141,9 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clparse"
|
name = "clparse"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://git.ablecorp.us/ableos/ableos_userland#70a65fc10d2caafe370be90eb0e31aa7d9347218"
|
source = "git+https://git.ablecorp.us/ableos/ableos_userland#f433484f2f56a4e8f77b1f39680b88c3d1e27830"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"hashbrown 0.13.2",
|
"hashbrown 0.12.3",
|
||||||
"log",
|
"log",
|
||||||
"toml",
|
"toml",
|
||||||
]
|
]
|
||||||
|
@ -364,6 +365,15 @@ dependencies = [
|
||||||
"ahash 0.8.3",
|
"ahash 0.8.3",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hbvm"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "git+https://git.ablecorp.us/ableos/holey-bytes#76302b4ca8aeda6597ee51cb1cf5f59a5d385c4f"
|
||||||
|
dependencies = [
|
||||||
|
"hashbrown 0.13.2",
|
||||||
|
"log",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hermit-abi"
|
name = "hermit-abi"
|
||||||
version = "0.1.19"
|
version = "0.1.19"
|
||||||
|
@ -457,7 +467,8 @@ dependencies = [
|
||||||
"derive_more",
|
"derive_more",
|
||||||
"embedded-graphics",
|
"embedded-graphics",
|
||||||
"error-stack 0.3.1",
|
"error-stack 0.3.1",
|
||||||
"hashbrown 0.13.2",
|
"hashbrown 0.12.3",
|
||||||
|
"hbvm",
|
||||||
"limine",
|
"limine",
|
||||||
"log",
|
"log",
|
||||||
"rdrand",
|
"rdrand",
|
||||||
|
@ -822,7 +833,7 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "versioning"
|
name = "versioning"
|
||||||
version = "0.1.3"
|
version = "0.1.3"
|
||||||
source = "git+https://git.ablecorp.us/ableos/ableos_userland#70a65fc10d2caafe370be90eb0e31aa7d9347218"
|
source = "git+https://git.ablecorp.us/ableos/ableos_userland#f433484f2f56a4e8f77b1f39680b88c3d1e27830"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
@ -1110,7 +1121,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "xml"
|
name = "xml"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://git.ablecorp.us/ableos/ableos_userland#70a65fc10d2caafe370be90eb0e31aa7d9347218"
|
source = "git+https://git.ablecorp.us/ableos/ableos_userland#f433484f2f56a4e8f77b1f39680b88c3d1e27830"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
|
@ -3,5 +3,4 @@ TODO:
|
||||||
|
|
||||||
# Compiling
|
# Compiling
|
||||||
1. `git submodule --update init`
|
1. `git submodule --update init`
|
||||||
1. Add [this binary](https://git.ablecorp.us/AbleOS/ableos/src/commit/e6c8d184d42961cf3cfa2e4aa319fc86c8880585/test.wasm) to the root.
|
|
||||||
1. `cargo repbuild`
|
1. `cargo repbuild`
|
||||||
|
|
|
@ -6,7 +6,7 @@ resolver = "2"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
|
||||||
|
hbvm = { git = "https://git.ablecorp.us/ableos/holey-bytes" }
|
||||||
embedded-graphics = "0.7.1"
|
embedded-graphics = "0.7.1"
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,8 @@ SECTIONS
|
||||||
/* Align initial kernel heap to page boundary */
|
/* Align initial kernel heap to page boundary */
|
||||||
. = ALIGN(4K);
|
. = ALIGN(4K);
|
||||||
PROVIDE(_initial_kernel_heap_start = .);
|
PROVIDE(_initial_kernel_heap_start = .);
|
||||||
PROVIDE(_initial_kernel_heap_size = 1024 * 1024);
|
/* PROVIDE(_initial_kernel_heap_size = 1024 * 1024); */
|
||||||
|
PROVIDE(_initial_kernel_heap_size = 1024 * 4096);
|
||||||
. += _initial_kernel_heap_size;
|
. += _initial_kernel_heap_size;
|
||||||
} :data
|
} :data
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,8 @@ struct Allocator(Mutex<Option<Heap>>);
|
||||||
|
|
||||||
unsafe impl GlobalAlloc for Allocator {
|
unsafe impl GlobalAlloc for Allocator {
|
||||||
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
|
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
|
||||||
|
// log::info!("Global allocation");
|
||||||
|
|
||||||
let mut lock = self.0.lock();
|
let mut lock = self.0.lock();
|
||||||
let allocator = lock.as_mut().expect("heap allocator should be initialized");
|
let allocator = lock.as_mut().expect("heap allocator should be initialized");
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@ use {
|
||||||
pub static DISPLAY: Lazy<Mutex<Display>> = Lazy::new(|| {
|
pub static DISPLAY: Lazy<Mutex<Display>> = Lazy::new(|| {
|
||||||
static FB_REQ: FramebufferRequest = FramebufferRequest::new(0);
|
static FB_REQ: FramebufferRequest = FramebufferRequest::new(0);
|
||||||
let fb1: &NonNullPtr<Framebuffer> = &FB_REQ.get_response().get().unwrap().framebuffers()[0];
|
let fb1: &NonNullPtr<Framebuffer> = &FB_REQ.get_response().get().unwrap().framebuffers()[0];
|
||||||
|
|
||||||
{
|
{
|
||||||
use crate::alloc::string::ToString;
|
use crate::alloc::string::ToString;
|
||||||
let mut dt = DEVICE_TREE.lock();
|
let mut dt = DEVICE_TREE.lock();
|
||||||
|
@ -22,8 +23,13 @@ pub static DISPLAY: Lazy<Mutex<Display>> = Lazy::new(|| {
|
||||||
disp.set_attribute("bits per pixel", fb1.bpp);
|
disp.set_attribute("bits per pixel", fb1.bpp);
|
||||||
dt.devices.insert("Displays".to_string(), alloc::vec![disp]);
|
dt.devices.insert("Displays".to_string(), alloc::vec![disp]);
|
||||||
}
|
}
|
||||||
|
let size: usize = (fb1.width * fb1.height).try_into().unwrap();
|
||||||
|
let back_buffer: alloc::vec::Vec<u32> = alloc::vec![0; 800*600];
|
||||||
|
|
||||||
let m = Mutex::new(Display {
|
let m = Mutex::new(Display {
|
||||||
fb: fb1.address.as_ptr().unwrap().cast(),
|
fb: fb1.address.as_ptr().unwrap().cast(),
|
||||||
|
// bb: fb1.address.as_ptr().unwrap().cast(),
|
||||||
|
bb: back_buffer.as_slice().as_ptr() as *mut u32,
|
||||||
size: Size::new(fb1.width as u32, fb1.height as u32),
|
size: Size::new(fb1.width as u32, fb1.height as u32),
|
||||||
color: Rgb888::WHITE,
|
color: Rgb888::WHITE,
|
||||||
});
|
});
|
||||||
|
|
|
@ -7,7 +7,7 @@ use {
|
||||||
uart_16550::SerialPort,
|
uart_16550::SerialPort,
|
||||||
};
|
};
|
||||||
|
|
||||||
static SERIAL_CONSOLE: Mutex<SerialPort> = Mutex::new(unsafe { SerialPort::new(0x3F8) });
|
pub static SERIAL_CONSOLE: Mutex<SerialPort> = Mutex::new(unsafe { SerialPort::new(0x3F8) });
|
||||||
static TERMINAL_LOGGER: Lazy<Mutex<TermLogger>> = Lazy::new(|| Mutex::new(TermLogger::new()));
|
static TERMINAL_LOGGER: Lazy<Mutex<TermLogger>> = Lazy::new(|| Mutex::new(TermLogger::new()));
|
||||||
|
|
||||||
pub fn init() {
|
pub fn init() {
|
||||||
|
@ -17,8 +17,10 @@ pub fn init() {
|
||||||
|
|
||||||
pub fn log(args: core::fmt::Arguments<'_>) -> core::fmt::Result {
|
pub fn log(args: core::fmt::Arguments<'_>) -> core::fmt::Result {
|
||||||
x86_64::instructions::interrupts::without_interrupts(|| {
|
x86_64::instructions::interrupts::without_interrupts(|| {
|
||||||
TERMINAL_LOGGER.lock().write_fmt(args)?;
|
// TERMINAL_LOGGER.lock().write_fmt(args)?;
|
||||||
SERIAL_CONSOLE.lock().write_fmt(args)
|
let mut sc = SERIAL_CONSOLE.lock();
|
||||||
|
sc.write_fmt(args)?;
|
||||||
|
Ok(())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,9 +8,9 @@ pub mod memory;
|
||||||
|
|
||||||
mod cpuid;
|
mod cpuid;
|
||||||
mod gdt;
|
mod gdt;
|
||||||
mod graphics;
|
pub mod graphics;
|
||||||
pub(crate) mod interrupts;
|
pub(crate) mod interrupts;
|
||||||
mod logging;
|
pub mod logging;
|
||||||
pub mod pci;
|
pub mod pci;
|
||||||
pub mod virtio;
|
pub mod virtio;
|
||||||
|
|
||||||
|
@ -114,12 +114,57 @@ unsafe extern "C" fn _kernel_start() -> ! {
|
||||||
graphics::init();
|
graphics::init();
|
||||||
let mut dis = DISPLAY.lock();
|
let mut dis = DISPLAY.lock();
|
||||||
use {able_graphics_library::raw_pixel, embedded_graphics::prelude::RgbColor};
|
use {able_graphics_library::raw_pixel, embedded_graphics::prelude::RgbColor};
|
||||||
dis.set_color(Rgb888::GREEN);
|
// dis.set_color(Rgb888::GREEN);
|
||||||
dis.line(1, 1, 700, 1000, 1);
|
// dis.line(400, 400, 700, 100, 50);
|
||||||
// dis.line(10, 10, 100, 10, 10);
|
|
||||||
// dis.line(100, 10, 1, 1, 10);
|
// dis.set_color(Rgb888::new(100, 23, 100));
|
||||||
|
|
||||||
|
// dis.line(100, 100, 400, 400, 3);
|
||||||
|
|
||||||
|
// dis.line(100, 100, 700, 100, 1);
|
||||||
|
dis.set_color(Rgb888::YELLOW);
|
||||||
|
let thick = 3;
|
||||||
|
let p1 = (400, 30);
|
||||||
|
let p2 = (200, 150);
|
||||||
|
let p3 = (600, 150);
|
||||||
|
let p4 = (200, 350);
|
||||||
|
let p5 = (600, 350);
|
||||||
|
let p6 = (400, 470);
|
||||||
|
|
||||||
|
{
|
||||||
|
//HEXAGON
|
||||||
|
|
||||||
|
dis.line(p1.0, p1.1, p2.0, p2.1, thick);
|
||||||
|
dis.line(p1.0, p1.1, p3.0, p3.1, thick);
|
||||||
|
dis.line(p2.0, p2.1, p4.0, p4.1, thick);
|
||||||
|
dis.line(p3.0, p3.1, p5.0, p5.1, thick);
|
||||||
|
dis.line(p6.0, p6.1, p4.0, p4.1, thick);
|
||||||
|
dis.line(p6.0, p6.1, p5.0, p5.1, thick);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
dis.line(600, 150, 200, 350, thick);
|
||||||
|
dis.line(600, 350, 400, 250, thick);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
dis.set_color(Rgb888::WHITE);
|
||||||
|
let hp1 = (350, 150);
|
||||||
|
let hp2 = (350, 350);
|
||||||
|
let hp3 = (450, 250);
|
||||||
|
let hp4 = (350, 250);
|
||||||
|
let hp5 = (450, 150);
|
||||||
|
let hp6 = (450, 350);
|
||||||
|
|
||||||
|
dis.line(hp1.0, hp1.1, hp2.0, hp2.1, thick);
|
||||||
|
dis.line(hp3.0, hp3.1, hp4.0, hp4.1, thick);
|
||||||
|
dis.line(hp5.0, hp5.1, hp6.0, hp6.1, thick);
|
||||||
|
}
|
||||||
|
|
||||||
|
dis.swap_buffers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let rand = xml::XMLElement::new("Random");
|
||||||
|
|
||||||
crate::kmain::kmain(
|
crate::kmain::kmain(
|
||||||
KFILE_REQ
|
KFILE_REQ
|
||||||
.get_response()
|
.get_response()
|
||||||
|
@ -144,7 +189,7 @@ unsafe extern "C" fn _kernel_start() -> ! {
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
use embedded_graphics::prelude::WebColors;
|
||||||
/// Spin loop
|
/// Spin loop
|
||||||
pub fn sloop() -> ! {
|
pub fn sloop() -> ! {
|
||||||
loop {
|
loop {
|
||||||
|
|
|
@ -23,10 +23,22 @@ pub fn init() {
|
||||||
let id = device_info.device_id.id;
|
let id = device_info.device_id.id;
|
||||||
use Vendor::*;
|
use Vendor::*;
|
||||||
let (dev_type, dev_name) = match (vendor, id) {
|
let (dev_type, dev_name) = match (vendor, id) {
|
||||||
|
(Qemu, 4369) => ("GPUs", "QEMU VGA"),
|
||||||
(VirtIO, 4176) => ("GPUs", "VirtIO PCI GPU"),
|
(VirtIO, 4176) => ("GPUs", "VirtIO PCI GPU"),
|
||||||
(CirrusLogic, 184) => ("GPUs", "Cirrus SVGA"), //GD 5446?
|
(CirrusLogic, 184) => ("GPUs", "Cirrus SVGA"), //GD 5446?
|
||||||
(_, _) => ("Unidentified PCI", "UNKNOWN DEVICE"),
|
(_, _) => ("Unidentified PCI", "UNKNOWN DEVICE"),
|
||||||
};
|
};
|
||||||
|
// let (dev_type, dev_name) = match device_info.full_class {
|
||||||
|
// PciFullClass::Unclassified_NonVgaCompatible => todo!(),
|
||||||
|
// PciFullClass::Unclassified_VgaCompatible => todo!(),
|
||||||
|
|
||||||
|
// PciFullClass::Display_VGA => ("GPUs", "VGA Device"),
|
||||||
|
// PciFullClass::Display_XGA => ("GPUs", "XGA Device"),
|
||||||
|
// PciFullClass::Display_3D => ("GPUs", "3D Device"),
|
||||||
|
// PciFullClass::Display_Other => ("GPUs", "Other"),
|
||||||
|
|
||||||
|
// _ => ("Unidentified PCI", "UNKNOWN DEVICE"),
|
||||||
|
// };
|
||||||
|
|
||||||
let mut dev = xml::XMLElement::new(dev_name);
|
let mut dev = xml::XMLElement::new(dev_name);
|
||||||
let mut pci_info = xml::XMLElement::new("PCI Info");
|
let mut pci_info = xml::XMLElement::new("PCI Info");
|
||||||
|
|
|
@ -3,6 +3,7 @@ use alloc::{string::String, vec::Vec};
|
||||||
use {crate::alloc::string::ToString, core::fmt, hashbrown::HashMap};
|
use {crate::alloc::string::ToString, core::fmt, hashbrown::HashMap};
|
||||||
pub type Device = xml::XMLElement;
|
pub type Device = xml::XMLElement;
|
||||||
|
|
||||||
|
// TODO: alphabatize this list
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct DeviceTree {
|
pub struct DeviceTree {
|
||||||
pub devices: HashMap<String, Vec<Device>>,
|
pub devices: HashMap<String, Vec<Device>>,
|
||||||
|
|
57
kernel/src/host_functions.rs
Normal file
57
kernel/src/host_functions.rs
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
use {alloc::collections::VecDeque, hbvm::engine::Engine};
|
||||||
|
|
||||||
|
use {
|
||||||
|
crossbeam_queue::{ArrayQueue, SegQueue},
|
||||||
|
log::trace,
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::{ipc::message::Message, kmain::DEVICE_TREE};
|
||||||
|
pub enum HostError {
|
||||||
|
MemoryError,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn ipc_send(engine: &mut Engine) -> Result<(), HostError> {
|
||||||
|
let handle = engine.registers.f0;
|
||||||
|
let message_start = engine.registers.f1;
|
||||||
|
let message_length = engine.registers.f2;
|
||||||
|
|
||||||
|
let mut ipc_msg: alloc::vec::Vec<u8> = alloc::vec![];
|
||||||
|
|
||||||
|
for x in message_start..message_start + message_length {
|
||||||
|
let byte = engine.read_mem_addr_8(x);
|
||||||
|
match byte {
|
||||||
|
Ok(byte) => ipc_msg.push(byte),
|
||||||
|
Err(_) => return Err(HostError::MemoryError),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log::trace!("Message bytes {:?}", ipc_msg);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn ipc_recv(engine: &mut Engine) {}
|
||||||
|
|
||||||
|
/// Check f0 for the buffer type
|
||||||
|
/// 0 means an unbound buffer
|
||||||
|
/// 1 means a bound buffer
|
||||||
|
/// Check f1 if the buffer is bound
|
||||||
|
///
|
||||||
|
/// f2 Return a handle to the sender
|
||||||
|
/// f3 returns a handle the the reciever
|
||||||
|
pub fn ipc_mkbuf(engine: &mut Engine) {
|
||||||
|
match engine.registers.f0 as usize {
|
||||||
|
0 => {
|
||||||
|
trace!("Making a new ipc unbound buffer");
|
||||||
|
let buf: SegQueue<Message> = SegQueue::new();
|
||||||
|
}
|
||||||
|
1 => {
|
||||||
|
let buf_len = engine.registers.f1 as usize;
|
||||||
|
trace!("Making a new ipc buffer with capacity {}", buf_len);
|
||||||
|
let buf: ArrayQueue<Message> = ArrayQueue::new(buf_len);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn rpc_discover(engine: &mut Engine) {}
|
||||||
|
pub fn rpc_register(engine: &mut Engine) {}
|
||||||
|
pub fn rpc_call(engine: &mut Engine) {}
|
15
kernel/src/ipc/buffer.rs
Normal file
15
kernel/src/ipc/buffer.rs
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
use crossbeam_queue::{ArrayQueue, SegQueue};
|
||||||
|
|
||||||
|
use super::message::Message;
|
||||||
|
|
||||||
|
enum BufferTypes {
|
||||||
|
Unbound(SegQueue<Message>),
|
||||||
|
Bound(ArrayQueue<Message>),
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct IpcBuffer {
|
||||||
|
protocol: Protocol,
|
||||||
|
buffer: BufferTypes,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Protocol {}
|
3
kernel/src/ipc/message.rs
Normal file
3
kernel/src/ipc/message.rs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
use alloc::vec::Vec;
|
||||||
|
|
||||||
|
pub type Message = Vec<u8>;
|
24
kernel/src/ipc/mod.rs
Normal file
24
kernel/src/ipc/mod.rs
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
pub mod buffer;
|
||||||
|
pub mod message;
|
||||||
|
|
||||||
|
use alloc::string::ToString;
|
||||||
|
|
||||||
|
pub struct IpcV1 {
|
||||||
|
abc: alloc::string::String,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct IpcV2 {
|
||||||
|
abc: alloc::string::String,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn IPCV1_to_IPCV2(ipc_v1: IpcV1) -> IpcV2 {
|
||||||
|
return IpcV2 {
|
||||||
|
abc: "abc".to_string(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn IPCV2_to_IPCV1(ipc_v2: IpcV2) -> IpcV1 {
|
||||||
|
return IpcV1 {
|
||||||
|
abc: "abc".to_string(),
|
||||||
|
};
|
||||||
|
}
|
|
@ -7,7 +7,13 @@ use {
|
||||||
spin::{Lazy, Mutex},
|
spin::{Lazy, Mutex},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::device_tree::DeviceTree;
|
use {embedded_graphics::pixelcolor::Rgb888, hbvm::engine::Engine};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
arch::{graphics::DISPLAY, logging::SERIAL_CONSOLE},
|
||||||
|
device_tree::DeviceTree,
|
||||||
|
// host_functions::read_device_tree,
|
||||||
|
};
|
||||||
|
|
||||||
use crate::alloc::string::ToString;
|
use crate::alloc::string::ToString;
|
||||||
|
|
||||||
|
@ -39,10 +45,40 @@ pub fn kmain(cmdline: &str, bootstrap: Option<&'static [u8]>) -> ! {
|
||||||
let mut dt = DEVICE_TREE.lock();
|
let mut dt = DEVICE_TREE.lock();
|
||||||
|
|
||||||
info!("Device Tree {}", &dt);
|
info!("Device Tree {}", &dt);
|
||||||
|
|
||||||
|
let bytes = alloc::vec![0];
|
||||||
|
let mut prog = Engine::new(bytes);
|
||||||
|
// prog.enviroment_call_table[0] = read_device_tree;
|
||||||
|
prog.run();
|
||||||
|
prog.dump();
|
||||||
|
|
||||||
|
// TODO: change this to a driver
|
||||||
|
{
|
||||||
|
let mut buf = [8; 128 * 4];
|
||||||
|
|
||||||
|
let mut sc = SERIAL_CONSOLE.lock();
|
||||||
|
loop {
|
||||||
|
let byte = sc.receive();
|
||||||
|
if byte == b'\r' {
|
||||||
|
sc.send(b'\n');
|
||||||
|
}
|
||||||
|
sc.send(byte);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
crate::arch::sloop()
|
crate::arch::sloop()
|
||||||
}
|
}
|
||||||
|
use embedded_graphics::prelude::RgbColor;
|
||||||
|
|
||||||
|
use hbvm::bytecode::ops::Operations::*;
|
||||||
pub static DEVICE_TREE: Lazy<Mutex<DeviceTree>> = Lazy::new(|| {
|
pub static DEVICE_TREE: Lazy<Mutex<DeviceTree>> = Lazy::new(|| {
|
||||||
let mut dt = DeviceTree::new();
|
let mut dt = DeviceTree::new();
|
||||||
Mutex::new(dt)
|
Mutex::new(dt)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
#[test_case]
|
||||||
|
fn trivial_assertion() {
|
||||||
|
trace!("trivial assertion... ");
|
||||||
|
assert_eq!(1, 1);
|
||||||
|
info!("[ok]");
|
||||||
|
}
|
||||||
|
|
|
@ -10,6 +10,9 @@
|
||||||
ptr_sub_ptr
|
ptr_sub_ptr
|
||||||
)]
|
)]
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
#![feature(custom_test_frameworks)]
|
||||||
|
#![test_runner(crate::test_runner)]
|
||||||
|
|
||||||
// #![deny(missing_docs)]
|
// #![deny(missing_docs)]
|
||||||
|
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
|
@ -18,10 +21,11 @@ mod allocator;
|
||||||
mod arch;
|
mod arch;
|
||||||
pub mod device_tree;
|
pub mod device_tree;
|
||||||
pub mod handle;
|
pub mod handle;
|
||||||
|
pub mod host_functions;
|
||||||
|
pub mod ipc;
|
||||||
mod kmain;
|
mod kmain;
|
||||||
mod logger;
|
mod logger;
|
||||||
mod memory;
|
mod memory;
|
||||||
mod task;
|
|
||||||
pub mod utils;
|
pub mod utils;
|
||||||
|
|
||||||
use versioning::Version;
|
use versioning::Version;
|
||||||
|
@ -50,3 +54,11 @@ fn panic(info: &core::panic::PanicInfo) -> ! {
|
||||||
|
|
||||||
loop {}
|
loop {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
fn test_runner(tests: &[&dyn Fn()]) {
|
||||||
|
println!("Running {} tests", tests.len());
|
||||||
|
for test in tests {
|
||||||
|
test();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
|
|
||||||
extern crate kernel;
|
extern crate kernel;
|
||||||
|
|
|
@ -1,149 +0,0 @@
|
||||||
//! Async task and executor
|
|
||||||
|
|
||||||
use alloc::{boxed::Box, collections::BTreeMap, sync::Arc, task::Wake};
|
|
||||||
use core::{
|
|
||||||
future::Future,
|
|
||||||
pin::Pin,
|
|
||||||
task::{Context, Poll, Waker},
|
|
||||||
};
|
|
||||||
use crossbeam_queue::SegQueue;
|
|
||||||
use slab::Slab;
|
|
||||||
use spin::RwLock;
|
|
||||||
|
|
||||||
type TaskQueue = Arc<SegQueue<TaskId>>;
|
|
||||||
type SpawnQueue = Arc<SegQueue<Task>>;
|
|
||||||
|
|
||||||
static SPAWN_QUEUE: RwLock<Option<SpawnQueue>> = RwLock::new(None);
|
|
||||||
|
|
||||||
/// Spawn a new task
|
|
||||||
pub fn spawn(future: impl Future<Output = ()> + Send + 'static) {
|
|
||||||
match &*SPAWN_QUEUE.read() {
|
|
||||||
Some(s) => s.push(Task::new(future)),
|
|
||||||
None => panic!("no task executor is running"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Forcibly yield a task
|
|
||||||
pub fn yield_now() -> impl Future<Output = ()> {
|
|
||||||
struct YieldNow(bool);
|
|
||||||
impl Future for YieldNow {
|
|
||||||
type Output = ();
|
|
||||||
|
|
||||||
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
|
||||||
if self.0 {
|
|
||||||
Poll::Ready(())
|
|
||||||
} else {
|
|
||||||
self.0 = true;
|
|
||||||
cx.waker().wake_by_ref();
|
|
||||||
Poll::Pending
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
YieldNow(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Tasks executor
|
|
||||||
#[derive(Default)]
|
|
||||||
pub struct Executor {
|
|
||||||
/// All spawned tasks' stash
|
|
||||||
tasks: Slab<Task>,
|
|
||||||
|
|
||||||
/// Awake tasks' queue
|
|
||||||
queue: TaskQueue,
|
|
||||||
|
|
||||||
/// Incoming tasks to enqueue
|
|
||||||
incoming: SpawnQueue,
|
|
||||||
|
|
||||||
/// Wakers
|
|
||||||
wakers: BTreeMap<TaskId, Waker>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Executor {
|
|
||||||
/// Spawn a task
|
|
||||||
pub fn spawn(&mut self, future: impl Future<Output = ()> + Send + 'static) {
|
|
||||||
self.queue
|
|
||||||
.push(TaskId(self.tasks.insert(Task::new(future))));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Spin poll loop until it runs out of tasks
|
|
||||||
pub fn run(&mut self) {
|
|
||||||
// Assign `self.incoming` to global spawn queue to spawn tasks
|
|
||||||
// from within
|
|
||||||
{
|
|
||||||
let mut spawner = SPAWN_QUEUE.write();
|
|
||||||
if spawner.is_some() {
|
|
||||||
panic!("task executor is already running");
|
|
||||||
}
|
|
||||||
|
|
||||||
*spawner = Some(Arc::clone(&self.incoming));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Try to get incoming task, if none available, poll
|
|
||||||
// enqueued one
|
|
||||||
while let Some(id) = self
|
|
||||||
.incoming
|
|
||||||
.pop()
|
|
||||||
.map(|t| TaskId(self.tasks.insert(t)))
|
|
||||||
.or_else(|| self.queue.pop())
|
|
||||||
{
|
|
||||||
let Some(task) = self.tasks.get_mut(id.0) else {
|
|
||||||
panic!("attempted to get non-extant task with id {}", id.0)
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut cx = Context::from_waker(self.wakers.entry(id).or_insert_with(|| {
|
|
||||||
Waker::from(Arc::new(TaskWaker {
|
|
||||||
id,
|
|
||||||
queue: Arc::clone(&self.queue),
|
|
||||||
}))
|
|
||||||
}));
|
|
||||||
|
|
||||||
match task.poll(&mut cx) {
|
|
||||||
Poll::Ready(()) => {
|
|
||||||
// Task done, unregister
|
|
||||||
self.tasks.remove(id.0);
|
|
||||||
self.wakers.remove(&id);
|
|
||||||
}
|
|
||||||
Poll::Pending => (),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*SPAWN_QUEUE.write() = None;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
|
||||||
struct TaskId(usize);
|
|
||||||
|
|
||||||
/// Async task
|
|
||||||
struct Task {
|
|
||||||
future: Pin<Box<dyn Future<Output = ()> + Send>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Task {
|
|
||||||
/// Create a new task from a future
|
|
||||||
fn new(future: impl Future<Output = ()> + Send + 'static) -> Self {
|
|
||||||
Self {
|
|
||||||
future: Box::pin(future),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn poll(&mut self, cx: &mut Context) -> Poll<()> {
|
|
||||||
self.future.as_mut().poll(cx)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct TaskWaker {
|
|
||||||
id: TaskId,
|
|
||||||
queue: TaskQueue,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Wake for TaskWaker {
|
|
||||||
fn wake(self: Arc<Self>) {
|
|
||||||
self.wake_by_ref();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn wake_by_ref(self: &Arc<Self>) {
|
|
||||||
self.queue.push(self.id);
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in a new issue