forked from AbleOS/ableos
a touch more fiddling
This commit is contained in:
parent
fd155ea26a
commit
3b95371c41
53
Cargo.lock
generated
53
Cargo.lock
generated
|
@ -166,15 +166,6 @@ dependencies = [
|
||||||
"windows-targets",
|
"windows-targets",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "convert_case"
|
|
||||||
version = "0.6.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca"
|
|
||||||
dependencies = [
|
|
||||||
"unicode-segmentation",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "core-foundation-sys"
|
name = "core-foundation-sys"
|
||||||
version = "0.8.7"
|
version = "0.8.7"
|
||||||
|
@ -211,7 +202,6 @@ version = "1.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22"
|
checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"convert_case",
|
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn",
|
"syn",
|
||||||
|
@ -391,17 +381,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#e8a5027cab7ce008dbb0964fe0522c8fef585979"
|
source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#67b8ffe2f223629850c293858abbb0cc5337a850"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hbbytecode"
|
name = "hbbytecode"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://git.ablecorp.us/ableos/holey-bytes#e8a5027cab7ce008dbb0964fe0522c8fef585979"
|
source = "git+https://git.ablecorp.us/ableos/holey-bytes#67b8ffe2f223629850c293858abbb0cc5337a850"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hblang"
|
name = "hblang"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#e8a5027cab7ce008dbb0964fe0522c8fef585979"
|
source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#67b8ffe2f223629850c293858abbb0cc5337a850"
|
||||||
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)",
|
||||||
]
|
]
|
||||||
|
@ -409,7 +399,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#e8a5027cab7ce008dbb0964fe0522c8fef585979"
|
source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#67b8ffe2f223629850c293858abbb0cc5337a850"
|
||||||
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)",
|
||||||
]
|
]
|
||||||
|
@ -417,7 +407,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#e8a5027cab7ce008dbb0964fe0522c8fef585979"
|
source = "git+https://git.ablecorp.us/ableos/holey-bytes#67b8ffe2f223629850c293858abbb0cc5337a850"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"hbbytecode 0.1.0 (git+https://git.ablecorp.us/ableos/holey-bytes)",
|
"hbbytecode 0.1.0 (git+https://git.ablecorp.us/ableos/holey-bytes)",
|
||||||
]
|
]
|
||||||
|
@ -507,9 +497,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hyper-util"
|
name = "hyper-util"
|
||||||
version = "0.1.7"
|
version = "0.1.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cde7055719c54e36e95e8719f95883f22072a48ede39db7fc17a4e1d5281e9b9"
|
checksum = "da62f120a8a37763efb0cf8fdf264b884c7b8b9ac8660b900c8661030c00e6ba"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"futures-channel",
|
"futures-channel",
|
||||||
|
@ -594,16 +584,14 @@ name = "kernel"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"crossbeam-queue",
|
"crossbeam-queue",
|
||||||
|
"crossbeam-utils",
|
||||||
"derive_more",
|
"derive_more",
|
||||||
"embedded-graphics",
|
"embedded-graphics",
|
||||||
"hashbrown",
|
"hashbrown",
|
||||||
"hbvm 0.1.0 (git+https://git.ablecorp.us/ableos/holey-bytes)",
|
"hbvm 0.1.0 (git+https://git.ablecorp.us/ableos/holey-bytes)",
|
||||||
"kiam",
|
|
||||||
"limine",
|
"limine",
|
||||||
"log",
|
"log",
|
||||||
"rdrand",
|
|
||||||
"sbi",
|
"sbi",
|
||||||
"slab",
|
|
||||||
"spin",
|
"spin",
|
||||||
"uart_16550",
|
"uart_16550",
|
||||||
"versioning",
|
"versioning",
|
||||||
|
@ -613,12 +601,6 @@ dependencies = [
|
||||||
"xml",
|
"xml",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "kiam"
|
|
||||||
version = "0.1.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "cb0fc32485e41ae5e9dedd1442f36dec998431adc9f321224c2c5d645f38fdcb"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lazy_static"
|
name = "lazy_static"
|
||||||
version = "1.5.0"
|
version = "1.5.0"
|
||||||
|
@ -907,15 +889,6 @@ dependencies = [
|
||||||
"bitflags 1.3.2",
|
"bitflags 1.3.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rdrand"
|
|
||||||
version = "0.8.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d92195228612ac8eed47adbc2ed0f04e513a4ccb98175b6f2bd04d963b533655"
|
|
||||||
dependencies = [
|
|
||||||
"rand_core",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex-syntax"
|
name = "regex-syntax"
|
||||||
version = "0.8.4"
|
version = "0.8.4"
|
||||||
|
@ -1046,9 +1019,9 @@ checksum = "fc0a2ce646f8655401bb81e7927b812614bd5d91dbc968696be50603510fcaf0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustls-webpki"
|
name = "rustls-webpki"
|
||||||
version = "0.102.7"
|
version = "0.102.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "84678086bd54edf2b415183ed7a94d0efb049f1b646a33e22a36f3794be6ae56"
|
checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ring",
|
"ring",
|
||||||
"rustls-pki-types",
|
"rustls-pki-types",
|
||||||
|
@ -1389,12 +1362,6 @@ dependencies = [
|
||||||
"tinyvec",
|
"tinyvec",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "unicode-segmentation"
|
|
||||||
version = "1.11.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-xid"
|
name = "unicode-xid"
|
||||||
version = "0.2.5"
|
version = "0.2.5"
|
||||||
|
|
|
@ -9,13 +9,11 @@ embedded-graphics = "0.8"
|
||||||
hbvm.git = "https://git.ablecorp.us/ableos/holey-bytes"
|
hbvm.git = "https://git.ablecorp.us/ableos/holey-bytes"
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
spin = "0.9"
|
spin = "0.9"
|
||||||
uart_16550 = "0.3"
|
uart_16550 = { version = "0.3", features = ["nightly"] }
|
||||||
slab = { version = "0.4", default-features = false }
|
|
||||||
xml.git = "https://git.ablecorp.us/ableos/ableos_userland"
|
xml.git = "https://git.ablecorp.us/ableos/ableos_userland"
|
||||||
versioning.git = "https://git.ablecorp.us/ableos/ableos_userland"
|
versioning.git = "https://git.ablecorp.us/ableos/ableos_userland"
|
||||||
# able_graphics_library.git = "https://git.ablecorp.us/ableos/ableos_userland"
|
# able_graphics_library.git = "https://git.ablecorp.us/ableos/ableos_userland"
|
||||||
hashbrown = "0.14"
|
hashbrown = { version = "0.14", features = ["nightly"] }
|
||||||
kiam = "0.1"
|
|
||||||
|
|
||||||
[dependencies.limine]
|
[dependencies.limine]
|
||||||
version = "0.1"
|
version = "0.1"
|
||||||
|
@ -24,7 +22,11 @@ version = "0.1"
|
||||||
[dependencies.crossbeam-queue]
|
[dependencies.crossbeam-queue]
|
||||||
version = "0.3"
|
version = "0.3"
|
||||||
default-features = false
|
default-features = false
|
||||||
features = ["alloc"]
|
features = ["alloc", "nightly"]
|
||||||
|
|
||||||
|
[dependencies.crossbeam-utils]
|
||||||
|
version = "0.8"
|
||||||
|
default-features = false
|
||||||
|
|
||||||
# [dependencies.clparse]
|
# [dependencies.clparse]
|
||||||
# git = "https://git.ablecorp.us/ableos/ableos_userland"
|
# git = "https://git.ablecorp.us/ableos/ableos_userland"
|
||||||
|
@ -51,9 +53,6 @@ features = [
|
||||||
x86_64 = "0.15"
|
x86_64 = "0.15"
|
||||||
x2apic = "0.4"
|
x2apic = "0.4"
|
||||||
virtio-drivers = "0.7"
|
virtio-drivers = "0.7"
|
||||||
# rdrand = "*"
|
|
||||||
rdrand = { version = "0.8", default-features = false }
|
|
||||||
|
|
||||||
|
|
||||||
[target.'cfg(target_arch = "riscv64")'.dependencies]
|
[target.'cfg(target_arch = "riscv64")'.dependencies]
|
||||||
sbi = "0.2.0"
|
sbi = "0.2.0"
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
use core::num;
|
use core::num;
|
||||||
|
|
||||||
use alloc::boxed::Box;
|
use {
|
||||||
use spin::{Mutex, Once};
|
crate::memory::{MemoryManager, PhysicalAddress, VirtualAddress},
|
||||||
use crate::memory::{MemoryManager, PhysicalAddress, VirtualAddress};
|
alloc::boxed::Box,
|
||||||
|
spin::{Mutex, Once},
|
||||||
|
};
|
||||||
|
|
||||||
use super::PAGE_SIZE;
|
use super::PAGE_SIZE;
|
||||||
|
|
||||||
|
@ -28,7 +30,7 @@ impl PageSize {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct PageTable {
|
pub struct PageTable {
|
||||||
entries: [PageEntry; 512]
|
entries: [PageEntry; 512],
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PageTable {
|
impl PageTable {
|
||||||
|
@ -72,8 +74,14 @@ impl PageTable {
|
||||||
/// flags MUST include one or more of the following:
|
/// flags MUST include one or more of the following:
|
||||||
/// Read, Write, Execute
|
/// Read, Write, Execute
|
||||||
/// The valid bit automatically gets added
|
/// The valid bit automatically gets added
|
||||||
pub fn map(&mut self, vaddr: VirtualAddress, paddr: PhysicalAddress, flags: PageEntryFlags, page_size: PageSize) {
|
pub fn map(
|
||||||
assert!(flags as usize & 0xe != 0);
|
&mut self,
|
||||||
|
vaddr: VirtualAddress,
|
||||||
|
paddr: PhysicalAddress,
|
||||||
|
flags: PageEntryFlags,
|
||||||
|
page_size: PageSize,
|
||||||
|
) {
|
||||||
|
assert!(flags as usize & 0xE != 0);
|
||||||
|
|
||||||
let vpn = vaddr.vpns();
|
let vpn = vaddr.vpns();
|
||||||
let ppn = paddr.ppns();
|
let ppn = paddr.ppns();
|
||||||
|
@ -91,7 +99,7 @@ impl PageTable {
|
||||||
}
|
}
|
||||||
|
|
||||||
let entry = v.addr().as_mut_ptr::<PageEntry>();
|
let entry = v.addr().as_mut_ptr::<PageEntry>();
|
||||||
v = unsafe { entry.add(vpn[i]).as_mut().unwrap() };
|
v = unsafe { entry.add(vpn[i]).as_mut().unwrap() };
|
||||||
}
|
}
|
||||||
|
|
||||||
// When we get here, we should be at VPN[0] and v should be pointing to our entry.
|
// When we get here, we should be at VPN[0] and v should be pointing to our entry.
|
||||||
|
@ -105,14 +113,24 @@ impl PageTable {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Identity maps a page of memory
|
/// Identity maps a page of memory
|
||||||
pub fn identity_map(&mut self, addr: PhysicalAddress, flags: PageEntryFlags, page_size: PageSize) {
|
pub fn identity_map(
|
||||||
|
&mut self,
|
||||||
|
addr: PhysicalAddress,
|
||||||
|
flags: PageEntryFlags,
|
||||||
|
page_size: PageSize,
|
||||||
|
) {
|
||||||
// log::debug!("identity mapped {addr}");
|
// log::debug!("identity mapped {addr}");
|
||||||
self.map(addr.as_addr().into(), addr, flags, page_size);
|
self.map(addr.as_addr().into(), addr, flags, page_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Identity maps a range of contiguous memory
|
/// Identity maps a range of contiguous memory
|
||||||
/// This assumes that start <= end
|
/// This assumes that start <= end
|
||||||
pub fn identity_map_range(&mut self, start: PhysicalAddress, end: PhysicalAddress, flags: PageEntryFlags) {
|
pub fn identity_map_range(
|
||||||
|
&mut self,
|
||||||
|
start: PhysicalAddress,
|
||||||
|
end: PhysicalAddress,
|
||||||
|
flags: PageEntryFlags,
|
||||||
|
) {
|
||||||
log::debug!("start: {start}, end: {end}");
|
log::debug!("start: {start}, end: {end}");
|
||||||
let mut mem_addr = start.as_addr() & !(PAGE_SIZE - 1);
|
let mut mem_addr = start.as_addr() & !(PAGE_SIZE - 1);
|
||||||
let num_pages = (align_val(end.as_addr(), 12) - mem_addr - 1) / PAGE_SIZE + 1;
|
let num_pages = (align_val(end.as_addr(), 12) - mem_addr - 1) / PAGE_SIZE + 1;
|
||||||
|
@ -142,7 +160,7 @@ impl PageTable {
|
||||||
}
|
}
|
||||||
|
|
||||||
let entry = v.addr().as_mut_ptr::<PageEntry>();
|
let entry = v.addr().as_mut_ptr::<PageEntry>();
|
||||||
v = unsafe { entry.add(vpn[i]).as_mut().unwrap() };
|
v = unsafe { entry.add(vpn[i]).as_mut().unwrap() };
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we're here this is an unmapped page
|
// If we're here this is an unmapped page
|
||||||
|
@ -228,7 +246,7 @@ impl PageEntry {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn addr(&self) -> PhysicalAddress {
|
fn addr(&self) -> PhysicalAddress {
|
||||||
((self.entry() as usize & !0x3ff) << 2).into()
|
((self.entry() as usize & !0x3FF) << 2).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn destroy(&mut self) {
|
fn destroy(&mut self) {
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
use {crate::bootmodules::BootModule, core::arch::asm, log::warn, rdrand::RdSeed};
|
use core::arch::x86_64::{_rdrand32_step, _rdrand64_step, _rdseed32_step, _rdseed64_step};
|
||||||
|
|
||||||
|
use {crate::bootmodules::BootModule, core::arch::asm, log::warn};
|
||||||
pub mod memory;
|
pub mod memory;
|
||||||
|
|
||||||
mod cpuid;
|
mod cpuid;
|
||||||
|
@ -189,62 +191,43 @@ unsafe extern "C" fn start() -> ! {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
use crossbeam_utils::Backoff;
|
||||||
|
|
||||||
/// Spin loop
|
/// Spin loop
|
||||||
pub fn spin_loop() -> ! {
|
pub fn spin_loop() -> ! {
|
||||||
|
let backoff = Backoff::new();
|
||||||
loop {
|
loop {
|
||||||
x86_64::instructions::hlt();
|
core::hint::spin_loop();
|
||||||
|
// x86_64::instructions::hlt();
|
||||||
|
backoff.spin()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn hardware_random_u64() -> u64 {
|
pub fn hardware_random_u64() -> u64 {
|
||||||
use {log::trace, rdrand::RdRand};
|
let mut out: u64 = 0;
|
||||||
let gen = RdRand::new();
|
match unsafe { _rdrand64_step(&mut out) } {
|
||||||
match gen {
|
1 => out,
|
||||||
Ok(gen) => {
|
_ => {
|
||||||
let ret = gen.try_next_u64().unwrap();
|
|
||||||
trace!("Random {}", ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
Err(_) => {
|
|
||||||
warn!("RDRand not supported.");
|
warn!("RDRand not supported.");
|
||||||
// Try rdseed
|
// Try rdseed
|
||||||
let gen = RdSeed::new();
|
match unsafe { _rdseed64_step(&mut out) } {
|
||||||
match gen {
|
1 => out,
|
||||||
Ok(gen) => {
|
_ => panic!("Neither RDRand or RDSeed are supported"),
|
||||||
let ret = gen.try_next_u64().unwrap();
|
|
||||||
trace!("Random {}", ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
Err(_) => {
|
|
||||||
panic!("Neither RDRand or RDSeed are supported")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn hardware_random_u32() -> u32 {
|
pub fn hardware_random_u32() -> u32 {
|
||||||
use {log::trace, rdrand::RdRand};
|
let mut out: u32 = 0;
|
||||||
let gen = RdRand::new();
|
match unsafe { _rdrand32_step(&mut out) } {
|
||||||
match gen {
|
1 => out,
|
||||||
Ok(gen) => {
|
_ => {
|
||||||
let ret = gen.try_next_u32().unwrap();
|
|
||||||
trace!("Random {}", ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
Err(_) => {
|
|
||||||
warn!("RDRand not supported.");
|
warn!("RDRand not supported.");
|
||||||
// Try rdseed
|
// Try rdseed
|
||||||
let gen = RdSeed::new();
|
match unsafe { _rdseed32_step(&mut out) } {
|
||||||
match gen {
|
1 => out,
|
||||||
Ok(gen) => {
|
_ => panic!("Neither RDRand or RDSeed are supported"),
|
||||||
let ret = gen.try_next_u32().unwrap();
|
|
||||||
trace!("Random {}", ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
Err(_) => {
|
|
||||||
panic!("Neither RDRand or RDSeed are supported")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,7 +65,7 @@ impl<'p> Drop for ExecThread<'p> {
|
||||||
|
|
||||||
impl<'p> Future for ExecThread<'p> {
|
impl<'p> Future for ExecThread<'p> {
|
||||||
type Output = Result<(), VmRunError>;
|
type Output = Result<(), VmRunError>;
|
||||||
|
#[inline(always)]
|
||||||
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) => {
|
||||||
|
@ -110,10 +110,12 @@ impl HandlePageFault for PageFaultHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
const fn stack_layout() -> Layout {
|
const fn stack_layout() -> Layout {
|
||||||
unsafe { Layout::from_size_align_unchecked(STACK_SIZE, 4096) }
|
unsafe { Layout::from_size_align_unchecked(STACK_SIZE, 4096) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
fn allocate_stack() -> NonNull<u8> {
|
fn allocate_stack() -> NonNull<u8> {
|
||||||
let layout = stack_layout();
|
let layout = stack_layout();
|
||||||
NonNull::new(unsafe { alloc::alloc::alloc_zeroed(layout) })
|
NonNull::new(unsafe { alloc::alloc::alloc_zeroed(layout) })
|
||||||
|
|
|
@ -66,7 +66,7 @@ pub fn kmain(_cmdline: &str, boot_modules: BootModules) -> ! {
|
||||||
fb1.address.as_ptr().unwrap() as *const u8
|
fb1.address.as_ptr().unwrap() as *const u8
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut executor = crate::task::Executor::default();
|
let mut executor = crate::task::Executor::new(256);
|
||||||
let bm_take = boot_modules.len();
|
let bm_take = boot_modules.len();
|
||||||
unsafe {
|
unsafe {
|
||||||
for module in boot_modules.into_iter().take(bm_take) {
|
for module in boot_modules.into_iter().take(bm_take) {
|
||||||
|
@ -80,16 +80,17 @@ pub fn kmain(_cmdline: &str, boot_modules: BootModules) -> ! {
|
||||||
|
|
||||||
log::info!("Spawning {} with arguments \"{}\"", module.path, cmd);
|
log::info!("Spawning {} with arguments \"{}\"", module.path, cmd);
|
||||||
|
|
||||||
executor.spawn(async move {
|
executor
|
||||||
let mut thr = ExecThread::new(&module.bytes, Address::new(0));
|
.spawn(async move {
|
||||||
if cmd_len > 0 {
|
let mut thr = ExecThread::new(&module.bytes, Address::new(0));
|
||||||
thr.set_arguments(cmd.as_bytes().as_ptr() as u64, cmd_len);
|
if cmd_len > 0 {
|
||||||
}
|
thr.set_arguments(cmd.as_bytes().as_ptr() as u64, cmd_len);
|
||||||
|
}
|
||||||
if let Err(e) = thr.await {
|
if let Err(e) = thr.await {
|
||||||
log::error!("{e:?}");
|
log::error!("{e:?}");
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
info!("Random number: {}", hardware_random_u64());
|
info!("Random number: {}", hardware_random_u64());
|
||||||
|
|
|
@ -1,23 +1,23 @@
|
||||||
#![allow(unused)]
|
|
||||||
|
|
||||||
use {
|
use {
|
||||||
alloc::{boxed::Box, sync::Arc, task::Wake},
|
alloc::{boxed::Box, sync::Arc, task::Wake},
|
||||||
core::{
|
core::{
|
||||||
future::Future,
|
future::Future,
|
||||||
pin::Pin,
|
pin::Pin,
|
||||||
|
sync::atomic::{AtomicUsize, Ordering},
|
||||||
task::{Context, Poll, Waker},
|
task::{Context, Poll, Waker},
|
||||||
},
|
},
|
||||||
crossbeam_queue::SegQueue,
|
crossbeam_queue::SegQueue,
|
||||||
hashbrown::HashMap,
|
crossbeam_utils::CachePadded,
|
||||||
slab::Slab,
|
|
||||||
spin::Mutex,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use alloc::vec::Vec;
|
||||||
|
|
||||||
pub fn yield_now() -> impl Future<Output = ()> {
|
pub fn yield_now() -> impl Future<Output = ()> {
|
||||||
struct YieldNow(bool);
|
struct YieldNow(bool);
|
||||||
impl Future for YieldNow {
|
impl Future for YieldNow {
|
||||||
type Output = ();
|
type Output = ();
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
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> {
|
||||||
if self.0 {
|
if self.0 {
|
||||||
Poll::Ready(())
|
Poll::Ready(())
|
||||||
|
@ -34,86 +34,168 @@ pub fn yield_now() -> impl Future<Output = ()> {
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct Executor {
|
pub struct Executor {
|
||||||
tasks: Slab<Task>,
|
tasks: Vec<CachePadded<TaskSlot>>,
|
||||||
queue: Arc<SegQueue<TaskId>>,
|
task_queue: Arc<TaskQueue>,
|
||||||
wakers: HashMap<TaskId, Waker>, // Keeping HashMap as it is more performant for lookups.
|
max_tasks: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Executor {
|
impl Executor {
|
||||||
pub fn new() -> Self {
|
pub fn new(max_tasks: usize) -> Self {
|
||||||
Self {
|
Self {
|
||||||
tasks: Slab::new(),
|
tasks: (0..max_tasks)
|
||||||
queue: Arc::new(SegQueue::new()),
|
.map(|_| CachePadded::new(TaskSlot::default()))
|
||||||
wakers: HashMap::new(),
|
.collect(),
|
||||||
|
task_queue: Arc::new(TaskQueue::new(max_tasks)),
|
||||||
|
max_tasks,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn spawn(&mut self, future: impl Future<Output = ()> + Send + 'static) {
|
pub fn spawn(&mut self, future: impl Future<Output = ()> + Send + 'static) -> Result<(), ()> {
|
||||||
let task_id = TaskId(self.tasks.insert(Task::new(future)));
|
let task_id = self.task_queue.allocate_task_id().ok_or(())?;
|
||||||
self.queue.push(task_id);
|
self.tasks[task_id.0].lock.replace(Task::new(future));
|
||||||
|
self.task_queue.push(task_id);
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run(&mut self) {
|
pub fn run(&mut self) {
|
||||||
|
let mut task_batch = Vec::with_capacity(16);
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
while let Some(id) = self.queue.pop() {
|
self.task_queue.batch_pop(&mut task_batch);
|
||||||
if let Some(task) = self.tasks.get_mut(id.0) {
|
if task_batch.is_empty() {
|
||||||
let waker = self.wakers.entry(id).or_insert_with(|| {
|
if self.task_queue.is_empty() {
|
||||||
Waker::from(Arc::new(TaskWaker {
|
break;
|
||||||
id,
|
|
||||||
queue: Arc::clone(&self.queue),
|
|
||||||
}))
|
|
||||||
});
|
|
||||||
|
|
||||||
let mut cx = Context::from_waker(waker);
|
|
||||||
|
|
||||||
if let Poll::Ready(()) = task.poll(&mut cx) {
|
|
||||||
self.tasks.remove(id.0);
|
|
||||||
self.wakers.remove(&id);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
panic!("Attempted to get task from empty slot: {}", id.0);
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.tasks.is_empty() {
|
for id in task_batch.drain(..) {
|
||||||
break;
|
let task_slot = &mut self.tasks[id.0];
|
||||||
|
|
||||||
|
let mut task_opt = task_slot.lock.take();
|
||||||
|
if let Some(task) = &mut task_opt {
|
||||||
|
let waker = task_slot.waker.get_or_insert_with(|| {
|
||||||
|
Arc::new(TaskWaker::new(id, Arc::clone(&self.task_queue)))
|
||||||
|
});
|
||||||
|
|
||||||
|
let waker = Waker::from(Arc::clone(waker));
|
||||||
|
let mut cx = Context::from_waker(&waker);
|
||||||
|
|
||||||
|
if let Poll::Ready(()) = task.poll(&mut cx) {
|
||||||
|
task_slot.waker = None;
|
||||||
|
self.task_queue.free_task_id(id);
|
||||||
|
} else {
|
||||||
|
task_slot.lock.replace(task_opt.take().unwrap());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
struct TaskSlot {
|
||||||
|
lock: Option<Task>,
|
||||||
|
waker: Option<Arc<TaskWaker>>,
|
||||||
|
}
|
||||||
|
|
||||||
struct Task {
|
struct Task {
|
||||||
future: Pin<Box<dyn Future<Output = ()> + Send>>,
|
future: Pin<Box<dyn Future<Output = ()> + Send>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Task {
|
impl Task {
|
||||||
|
#[inline(always)]
|
||||||
pub fn new(future: impl Future<Output = ()> + Send + 'static) -> Self {
|
pub fn new(future: impl Future<Output = ()> + Send + 'static) -> Self {
|
||||||
log::trace!("New task scheduled");
|
|
||||||
Self {
|
Self {
|
||||||
future: Box::pin(future),
|
future: Box::pin(future),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
fn poll(&mut self, cx: &mut Context) -> Poll<()> {
|
fn poll(&mut self, cx: &mut Context) -> Poll<()> {
|
||||||
self.future.as_mut().poll(cx)
|
self.future.as_mut().poll(cx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Hash, Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
struct TaskId(usize);
|
struct TaskId(usize);
|
||||||
|
|
||||||
struct TaskWaker {
|
struct TaskWaker {
|
||||||
id: TaskId,
|
id: TaskId,
|
||||||
queue: Arc<SegQueue<TaskId>>,
|
task_queue: Arc<TaskQueue>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TaskWaker {
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn new(id: TaskId, task_queue: Arc<TaskQueue>) -> Self {
|
||||||
|
Self { id, task_queue }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Wake for TaskWaker {
|
impl Wake for TaskWaker {
|
||||||
|
#[inline(always)]
|
||||||
fn wake(self: Arc<Self>) {
|
fn wake(self: Arc<Self>) {
|
||||||
log::trace!("Woke Task-{:?}", self.id);
|
self.task_queue.push(self.id);
|
||||||
self.queue.push(self.id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
fn wake_by_ref(self: &Arc<Self>) {
|
fn wake_by_ref(self: &Arc<Self>) {
|
||||||
self.queue.push(self.id);
|
self.task_queue.push(self.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
struct TaskQueue {
|
||||||
|
queue: SegQueue<TaskId>,
|
||||||
|
next_task: AtomicUsize,
|
||||||
|
max_tasks: usize,
|
||||||
|
free_tasks: SegQueue<TaskId>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TaskQueue {
|
||||||
|
fn new(max_tasks: usize) -> Self {
|
||||||
|
Self {
|
||||||
|
queue: SegQueue::new(),
|
||||||
|
next_task: AtomicUsize::new(0),
|
||||||
|
max_tasks,
|
||||||
|
free_tasks: SegQueue::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn allocate_task_id(&self) -> Option<TaskId> {
|
||||||
|
self.free_tasks.pop().or_else(|| {
|
||||||
|
let id = self.next_task.fetch_add(1, Ordering::Relaxed);
|
||||||
|
if id < self.max_tasks {
|
||||||
|
Some(TaskId(id))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn free_task_id(&self, id: TaskId) {
|
||||||
|
self.free_tasks.push(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn push(&self, id: TaskId) {
|
||||||
|
self.queue.push(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn batch_pop(&self, output: &mut Vec<TaskId>) {
|
||||||
|
while let Some(id) = self.queue.pop() {
|
||||||
|
output.push(id);
|
||||||
|
if output.len() >= output.capacity() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn is_empty(&self) -> bool {
|
||||||
|
self.queue.is_empty()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,18 @@ edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
str-reader = "0.1"
|
str-reader = "0.1"
|
||||||
derive_more = { version = "1", features = ["full"] }
|
derive_more = { version = "1", default-features = false, features = [
|
||||||
|
"add",
|
||||||
|
"add_assign",
|
||||||
|
"constructor",
|
||||||
|
"display",
|
||||||
|
"from",
|
||||||
|
"into",
|
||||||
|
"mul",
|
||||||
|
"mul_assign",
|
||||||
|
"not",
|
||||||
|
"sum",
|
||||||
|
] }
|
||||||
error-stack = "0.5"
|
error-stack = "0.5"
|
||||||
fatfs = "0.3"
|
fatfs = "0.3"
|
||||||
toml = "0.8"
|
toml = "0.8"
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#![allow(unused)]
|
// #![allow(unused)]
|
||||||
|
|
||||||
mod dev;
|
mod dev;
|
||||||
|
|
||||||
|
@ -195,7 +195,7 @@ TERM_BACKDROP={}
|
||||||
let modules = value.get_mut("modules").unwrap().as_table_mut().unwrap();
|
let modules = value.get_mut("modules").unwrap().as_table_mut().unwrap();
|
||||||
// let mut real_modules = modules.clone();
|
// let mut real_modules = modules.clone();
|
||||||
|
|
||||||
modules.into_iter().for_each(|(key, value)| {
|
modules.into_iter().for_each(|(_, value)| {
|
||||||
if value.is_table() {
|
if value.is_table() {
|
||||||
let path = get_path_without_boot_prefix(
|
let path = get_path_without_boot_prefix(
|
||||||
value.get("path").expect("You must have `path` as a value"),
|
value.get("path").expect("You must have `path` as a value"),
|
||||||
|
@ -244,7 +244,7 @@ TERM_BACKDROP={}
|
||||||
let bootdir = fs.root_dir().create_dir("efi")?.create_dir("boot")?;
|
let bootdir = fs.root_dir().create_dir("efi")?.create_dir("boot")?;
|
||||||
|
|
||||||
let mut f = fs.root_dir().create_file("limine.cfg")?;
|
let mut f = fs.root_dir().create_file("limine.cfg")?;
|
||||||
let a = f.write(limine_str.as_bytes())?;
|
let _ = f.write(limine_str.as_bytes())?;
|
||||||
drop(f);
|
drop(f);
|
||||||
|
|
||||||
io::copy(
|
io::copy(
|
||||||
|
@ -446,6 +446,7 @@ enum Target {
|
||||||
Aarch64,
|
Aarch64,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(unused)]
|
||||||
#[derive(Debug, Display)]
|
#[derive(Debug, Display)]
|
||||||
enum Error {
|
enum Error {
|
||||||
#[display("Failed to build the kernel")]
|
#[display("Failed to build the kernel")]
|
||||||
|
@ -466,6 +467,7 @@ enum Error {
|
||||||
|
|
||||||
impl Context for Error {}
|
impl Context for Error {}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
fn fmt_qemu_err(e: Option<i32>) -> impl Display {
|
fn fmt_qemu_err(e: Option<i32>) -> impl Display {
|
||||||
struct W(Option<i32>);
|
struct W(Option<i32>);
|
||||||
impl Display for W {
|
impl Display for W {
|
||||||
|
|
|
@ -23,7 +23,7 @@ fb_width := 1024
|
||||||
fb_height := 768
|
fb_height := 768
|
||||||
fb_pixels := fb_width * fb_height
|
fb_pixels := fb_width * fb_height
|
||||||
fb_bytes := fb_pixels << 2
|
fb_bytes := fb_pixels << 2
|
||||||
copy_pixels := math.min(0x1800, fb_bytes) >> 2
|
copy_pixels := math.min(0xC000, fb_bytes) >> 2
|
||||||
partitions := fb_pixels / copy_pixels
|
partitions := fb_pixels / copy_pixels
|
||||||
total_pages := 1 + fb_bytes >> 12
|
total_pages := 1 + fb_bytes >> 12
|
||||||
|
|
||||||
|
@ -51,12 +51,22 @@ create_back_buffer := fn(): ^Color {
|
||||||
|
|
||||||
clear := fn(color: Color): void {
|
clear := fn(color: Color): void {
|
||||||
n := 0
|
n := 0
|
||||||
loop if n >= copy_pixels break else {
|
loop if n == 512 break else {
|
||||||
*(back_buffer + n) = color
|
*(back_buffer + n) = color
|
||||||
n += 1
|
n += 1
|
||||||
}
|
}
|
||||||
n = 1
|
n = 1
|
||||||
loop if n >= partitions break else {
|
loop if n == 8 break else {
|
||||||
|
*(@as(^[Color; 512], @bitcast(back_buffer)) + n) = *@as(^[Color; 512], @bitcast(back_buffer))
|
||||||
|
n += 1
|
||||||
|
}
|
||||||
|
n = 1
|
||||||
|
loop if n == copy_pixels >> 12 break else {
|
||||||
|
*(@as(^[Color; 4096], @bitcast(back_buffer)) + n) = *@as(^[Color; 4096], @bitcast(back_buffer))
|
||||||
|
n += 1
|
||||||
|
}
|
||||||
|
n = 1
|
||||||
|
loop if n == partitions break else {
|
||||||
*(@as(^[Color; copy_pixels], @bitcast(back_buffer)) + n) = *@as(^[Color; copy_pixels], @bitcast(back_buffer))
|
*(@as(^[Color; copy_pixels], @bitcast(back_buffer)) + n) = *@as(^[Color; copy_pixels], @bitcast(back_buffer))
|
||||||
n += 1
|
n += 1
|
||||||
}
|
}
|
||||||
|
@ -65,7 +75,7 @@ clear := fn(color: Color): void {
|
||||||
|
|
||||||
sync := fn(): void {
|
sync := fn(): void {
|
||||||
n := 0
|
n := 0
|
||||||
loop if n >= partitions break else {
|
loop if n == partitions break else {
|
||||||
*(@as(^[Color; copy_pixels], @bitcast(front_buffer)) + n) = *(@as(^[Color; copy_pixels], @bitcast(back_buffer)) + n)
|
*(@as(^[Color; copy_pixels], @bitcast(front_buffer)) + n) = *(@as(^[Color; copy_pixels], @bitcast(back_buffer)) + n)
|
||||||
n += 1
|
n += 1
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
.{example} := @use("./examples/lines.hb")
|
.{example} := @use("./examples/amogus.hb")
|
||||||
|
|
||||||
main := fn(): void {
|
main := fn(): void {
|
||||||
@inline(example)
|
@inline(example)
|
||||||
|
|
Loading…
Reference in a new issue