toolchain: migrate to 1.94.0 toolchain
This commit is contained in:
Generated
+1
-16
@@ -25,7 +25,6 @@ dependencies = [
|
|||||||
name = "abi-lib"
|
name = "abi-lib"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"compiler_builtins",
|
|
||||||
"rustc-std-workspace-core",
|
"rustc-std-workspace-core",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -33,7 +32,6 @@ dependencies = [
|
|||||||
name = "abi-serde"
|
name = "abi-serde"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"compiler_builtins",
|
|
||||||
"rustc-std-workspace-alloc",
|
"rustc-std-workspace-alloc",
|
||||||
"rustc-std-workspace-core",
|
"rustc-std-workspace-core",
|
||||||
]
|
]
|
||||||
@@ -407,15 +405,6 @@ version = "1.0.3"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990"
|
checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "compiler_builtins"
|
|
||||||
version = "0.1.146"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "a97117b1434b79833f39a5fabdf82f890bd98c1988334dea1cb67f7e627fa311"
|
|
||||||
dependencies = [
|
|
||||||
"rustc-std-workspace-core",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "console"
|
name = "console"
|
||||||
version = "0.15.10"
|
version = "0.15.10"
|
||||||
@@ -1291,9 +1280,8 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "libm"
|
name = "libm"
|
||||||
version = "0.2.8"
|
version = "0.2.8"
|
||||||
source = "git+https://git.alnyan.me/yggdrasil/libm.git#ace5825d9683d2bf4a71c8f18f2c854660c297b2"
|
source = "git+https://git.alnyan.me/yggdrasil/libm.git#78b62c33fc6a56b6c063c19bbffc5224616b7028"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"compiler_builtins",
|
|
||||||
"rustc-std-workspace-core",
|
"rustc-std-workspace-core",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -1330,7 +1318,6 @@ version = "0.1.0"
|
|||||||
name = "libyalloc"
|
name = "libyalloc"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"compiler_builtins",
|
|
||||||
"libc",
|
"libc",
|
||||||
"rustc-std-workspace-core",
|
"rustc-std-workspace-core",
|
||||||
"yggdrasil-rt",
|
"yggdrasil-rt",
|
||||||
@@ -3023,7 +3010,6 @@ dependencies = [
|
|||||||
"abi-lib",
|
"abi-lib",
|
||||||
"abi-serde",
|
"abi-serde",
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
"compiler_builtins",
|
|
||||||
"prettyplease",
|
"prettyplease",
|
||||||
"rustc-std-workspace-alloc",
|
"rustc-std-workspace-alloc",
|
||||||
"rustc-std-workspace-core",
|
"rustc-std-workspace-core",
|
||||||
@@ -3101,7 +3087,6 @@ dependencies = [
|
|||||||
"abi-lib",
|
"abi-lib",
|
||||||
"abi-serde",
|
"abi-serde",
|
||||||
"cc",
|
"cc",
|
||||||
"compiler_builtins",
|
|
||||||
"libm",
|
"libm",
|
||||||
"prettyplease",
|
"prettyplease",
|
||||||
"rustc-std-workspace-alloc",
|
"rustc-std-workspace-alloc",
|
||||||
|
|||||||
@@ -89,6 +89,7 @@ features = ["no_std_stream"]
|
|||||||
|
|
||||||
[workspace.lints.rust]
|
[workspace.lints.rust]
|
||||||
unexpected_cfgs = { level = "allow", check-cfg = ['cfg(rust_analyzer)'] }
|
unexpected_cfgs = { level = "allow", check-cfg = ['cfg(rust_analyzer)'] }
|
||||||
|
unsafe_op_in_unsafe_fn.level = "deny"
|
||||||
[workspace.lints.clippy]
|
[workspace.lints.clippy]
|
||||||
derivable_impls = { level = "allow" }
|
derivable_impls = { level = "allow" }
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
"arch": "aarch64",
|
"arch": "aarch64",
|
||||||
"os": "none",
|
"os": "none",
|
||||||
"abi": "softfloat",
|
"abi": "softfloat",
|
||||||
|
"rustc-abi": "softfloat",
|
||||||
"llvm-target": "aarch64-unknown-none",
|
"llvm-target": "aarch64-unknown-none",
|
||||||
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32",
|
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32",
|
||||||
"max-atomic-width": 128,
|
"max-atomic-width": 128,
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
{
|
{
|
||||||
"arch": "riscv64",
|
"arch": "riscv64",
|
||||||
"os": "none",
|
"os": "none",
|
||||||
"abi": "softfloat",
|
|
||||||
"cpu": "generic-rv64",
|
"cpu": "generic-rv64",
|
||||||
|
"llvm-abiname": "lp64",
|
||||||
"llvm-target": "riscv64",
|
"llvm-target": "riscv64",
|
||||||
"data-layout": "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128",
|
"data-layout": "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128",
|
||||||
"max-atomic-width": 64,
|
"max-atomic-width": 64,
|
||||||
@@ -20,7 +20,6 @@
|
|||||||
|
|
||||||
"crt-objects-fallback": "false",
|
"crt-objects-fallback": "false",
|
||||||
"emit-debug-gdb-scripts": false,
|
"emit-debug-gdb-scripts": false,
|
||||||
"llvm-abiname": "lp64",
|
|
||||||
|
|
||||||
"linker": "rust-lld",
|
"linker": "rust-lld",
|
||||||
"linker-flavor": "ld.lld"
|
"linker-flavor": "ld.lld"
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#![no_std]
|
#![no_std]
|
||||||
#![feature(decl_macro)]
|
|
||||||
#![allow(clippy::new_without_default)]
|
#![allow(clippy::new_without_default)]
|
||||||
|
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "kernel-arch-hosted"
|
name = "kernel-arch-hosted"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2024"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
kernel-arch-interface.workspace = true
|
kernel-arch-interface.workspace = true
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "kernel-arch-interface"
|
name = "kernel-arch-interface"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2024"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
yggdrasil-abi.workspace = true
|
yggdrasil-abi.workspace = true
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ impl<A: Architecture, S: Scheduler + 'static> CpuImpl<A, S> {
|
|||||||
///
|
///
|
||||||
/// See [Architecture::set_local_cpu].
|
/// See [Architecture::set_local_cpu].
|
||||||
pub unsafe fn set_local(&'static mut self) {
|
pub unsafe fn set_local(&'static mut self) {
|
||||||
A::set_local_cpu(self as *mut _ as *mut _)
|
unsafe { A::set_local_cpu(self as *mut _ as *mut _) }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn try_local<'a>() -> Option<LocalCpuImpl<'a, A, S>> {
|
pub fn try_local<'a>() -> Option<LocalCpuImpl<'a, A, S>> {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#![no_std]
|
#![no_std]
|
||||||
#![feature(step_trait, const_trait_impl, never_type, decl_macro)]
|
#![feature(never_type)]
|
||||||
#![allow(clippy::new_without_default)]
|
#![allow(clippy::new_without_default)]
|
||||||
|
|
||||||
use core::ops::Range;
|
use core::ops::Range;
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ impl<A: KernelTableManager> RawDeviceMemoryMapping<A> {
|
|||||||
size: usize,
|
size: usize,
|
||||||
attrs: DeviceMemoryAttributes,
|
attrs: DeviceMemoryAttributes,
|
||||||
) -> Result<Self, Error> {
|
) -> Result<Self, Error> {
|
||||||
A::map_device_pages(base, size, attrs)
|
unsafe { A::map_device_pages(base, size, attrs) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Consumes the device mapping, leaking its address without deallocating the translation
|
/// Consumes the device mapping, leaking its address without deallocating the translation
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "kernel-arch-x86"
|
name = "kernel-arch-x86"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2024"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
kernel-arch-interface.workspace = true
|
kernel-arch-interface.workspace = true
|
||||||
|
|||||||
@@ -170,36 +170,40 @@ impl CpuFeatureSet for CpuFeatures {
|
|||||||
|
|
||||||
#[cfg(any(target_arch = "x86_64", rust_analyzer))]
|
#[cfg(any(target_arch = "x86_64", rust_analyzer))]
|
||||||
unsafe fn raw_cpuid(eax: u32, result: &mut [u32]) {
|
unsafe fn raw_cpuid(eax: u32, result: &mut [u32]) {
|
||||||
core::arch::asm!(
|
unsafe {
|
||||||
r#"
|
core::arch::asm!(
|
||||||
|
r#"
|
||||||
push %rbx
|
push %rbx
|
||||||
cpuid
|
cpuid
|
||||||
mov %ebx, {0:e}
|
mov %ebx, {0:e}
|
||||||
pop %rbx
|
pop %rbx
|
||||||
"#,
|
"#,
|
||||||
out(reg) result[0],
|
out(reg) result[0],
|
||||||
out("edx") result[1],
|
out("edx") result[1],
|
||||||
out("ecx") result[2],
|
out("ecx") result[2],
|
||||||
in("eax") eax,
|
in("eax") eax,
|
||||||
options(att_syntax)
|
options(att_syntax)
|
||||||
);
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(target_arch = "x86", rust_analyzer))]
|
#[cfg(any(target_arch = "x86", rust_analyzer))]
|
||||||
unsafe fn raw_cpuid(eax: u32, result: &mut [u32]) {
|
unsafe fn raw_cpuid(eax: u32, result: &mut [u32]) {
|
||||||
core::arch::asm!(
|
unsafe {
|
||||||
r#"
|
core::arch::asm!(
|
||||||
|
r#"
|
||||||
push %ebx
|
push %ebx
|
||||||
cpuid
|
cpuid
|
||||||
mov %ebx, {0:e}
|
mov %ebx, {0:e}
|
||||||
pop %ebx
|
pop %ebx
|
||||||
"#,
|
"#,
|
||||||
out(reg) result[0],
|
out(reg) result[0],
|
||||||
out("edx") result[1],
|
out("edx") result[1],
|
||||||
out("ecx") result[2],
|
out("ecx") result[2],
|
||||||
in("eax") eax,
|
in("eax") eax,
|
||||||
options(att_syntax)
|
options(att_syntax)
|
||||||
);
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cpuid_features() -> (EcxFeatures, EdxFeatures, ExtEdxFeatures) {
|
fn cpuid_features() -> (EcxFeatures, EdxFeatures, ExtEdxFeatures) {
|
||||||
|
|||||||
+34
-32
@@ -225,42 +225,44 @@ mod imp {
|
|||||||
offset: gdt_addr,
|
offset: gdt_addr,
|
||||||
};
|
};
|
||||||
|
|
||||||
core::arch::asm!(
|
unsafe {
|
||||||
r#"
|
core::arch::asm!(
|
||||||
wbinvd
|
r#"
|
||||||
lgdt ({0})
|
wbinvd
|
||||||
|
lgdt ({0})
|
||||||
|
|
||||||
// Have to use iretq here
|
// Have to use iretq here
|
||||||
mov %rsp, %rcx
|
mov %rsp, %rcx
|
||||||
leaq 1f(%rip), %rax
|
leaq 1f(%rip), %rax
|
||||||
|
|
||||||
// SS:RSP
|
// SS:RSP
|
||||||
pushq $0x10
|
pushq $0x10
|
||||||
pushq %rcx
|
pushq %rcx
|
||||||
|
|
||||||
// RFLAGS
|
// RFLAGS
|
||||||
pushfq
|
pushfq
|
||||||
|
|
||||||
// CS:RIP
|
// CS:RIP
|
||||||
pushq $0x08
|
pushq $0x08
|
||||||
pushq %rax
|
pushq %rax
|
||||||
iretq
|
iretq
|
||||||
1:
|
1:
|
||||||
mov $0x10, %ax
|
mov $0x10, %ax
|
||||||
mov %ax, %ds
|
mov %ax, %ds
|
||||||
mov %ax, %es
|
mov %ax, %es
|
||||||
mov %ax, %fs
|
mov %ax, %fs
|
||||||
mov %ax, %gs
|
mov %ax, %gs
|
||||||
mov %ax, %ss
|
mov %ax, %ss
|
||||||
|
|
||||||
mov $0x28, %ax
|
mov $0x28, %ax
|
||||||
ltr %ax
|
ltr %ax
|
||||||
"#,
|
"#,
|
||||||
in(reg) &gdtr,
|
in(reg) &gdtr,
|
||||||
out("rax") _,
|
out("rax") _,
|
||||||
out("rcx") _,
|
out("rcx") _,
|
||||||
options(att_syntax)
|
options(att_syntax)
|
||||||
);
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Initializes and loads the GDT data structure for the current CPU.
|
/// Initializes and loads the GDT data structure for the current CPU.
|
||||||
@@ -270,7 +272,7 @@ mod imp {
|
|||||||
/// Intended to be called once per each CPU during their early initialization.
|
/// Intended to be called once per each CPU during their early initialization.
|
||||||
pub unsafe fn init() -> usize {
|
pub unsafe fn init() -> usize {
|
||||||
let (gdt, tss) = create_gdt();
|
let (gdt, tss) = create_gdt();
|
||||||
load_gdt(gdt);
|
unsafe { load_gdt(gdt) };
|
||||||
(tss as *const Tss).addr()
|
(tss as *const Tss).addr()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,7 +76,9 @@ impl IoPortAccess<u32> for IoPort<u32> {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn inb(port: u16) -> u8 {
|
pub unsafe fn inb(port: u16) -> u8 {
|
||||||
let value: u8;
|
let value: u8;
|
||||||
core::arch::asm!("inb %dx, %al", in("dx") port, out("al") value, options(att_syntax));
|
unsafe {
|
||||||
|
core::arch::asm!("inb %dx, %al", in("dx") port, out("al") value, options(att_syntax))
|
||||||
|
};
|
||||||
value
|
value
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,7 +90,9 @@ pub unsafe fn inb(port: u16) -> u8 {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn inw(port: u16) -> u16 {
|
pub unsafe fn inw(port: u16) -> u16 {
|
||||||
let value: u16;
|
let value: u16;
|
||||||
core::arch::asm!("inw %dx, %ax", in("dx") port, out("ax") value, options(att_syntax));
|
unsafe {
|
||||||
|
core::arch::asm!("inw %dx, %ax", in("dx") port, out("ax") value, options(att_syntax))
|
||||||
|
};
|
||||||
value
|
value
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,7 +104,9 @@ pub unsafe fn inw(port: u16) -> u16 {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn inl(port: u16) -> u32 {
|
pub unsafe fn inl(port: u16) -> u32 {
|
||||||
let value: u32;
|
let value: u32;
|
||||||
core::arch::asm!("inl %dx, %eax", in("dx") port, out("eax") value, options(att_syntax));
|
unsafe {
|
||||||
|
core::arch::asm!("inl %dx, %eax", in("dx") port, out("eax") value, options(att_syntax))
|
||||||
|
};
|
||||||
value
|
value
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -111,7 +117,9 @@ pub unsafe fn inl(port: u16) -> u32 {
|
|||||||
/// Provides direct access to port I/O, unsafe.
|
/// Provides direct access to port I/O, unsafe.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn outb(port: u16, value: u8) {
|
pub unsafe fn outb(port: u16, value: u8) {
|
||||||
core::arch::asm!("outb %al, %dx", in("dx") port, in("al") value, options(att_syntax));
|
unsafe {
|
||||||
|
core::arch::asm!("outb %al, %dx", in("dx") port, in("al") value, options(att_syntax))
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Writes a 16-bit value to the I/O port.
|
/// Writes a 16-bit value to the I/O port.
|
||||||
@@ -121,7 +129,9 @@ pub unsafe fn outb(port: u16, value: u8) {
|
|||||||
/// Provides direct access to port I/O, unsafe.
|
/// Provides direct access to port I/O, unsafe.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn outw(port: u16, value: u16) {
|
pub unsafe fn outw(port: u16, value: u16) {
|
||||||
core::arch::asm!("outw %ax, %dx", in("dx") port, in("ax") value, options(att_syntax));
|
unsafe {
|
||||||
|
core::arch::asm!("outw %ax, %dx", in("dx") port, in("ax") value, options(att_syntax))
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Writes a 32-bit value to the I/O port.
|
/// Writes a 32-bit value to the I/O port.
|
||||||
@@ -131,7 +141,9 @@ pub unsafe fn outw(port: u16, value: u16) {
|
|||||||
/// Provides direct access to port I/O, unsafe.
|
/// Provides direct access to port I/O, unsafe.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn outl(port: u16, value: u32) {
|
pub unsafe fn outl(port: u16, value: u32) {
|
||||||
core::arch::asm!("outl %eax, %dx", in("dx") port, in("eax") value, options(att_syntax));
|
unsafe {
|
||||||
|
core::arch::asm!("outl %eax, %dx", in("dx") port, in("eax") value, options(att_syntax))
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "kernel-arch-x86_64"
|
name = "kernel-arch-x86_64"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2024"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
yggdrasil-abi.workspace = true
|
yggdrasil-abi.workspace = true
|
||||||
|
|||||||
@@ -255,7 +255,7 @@ impl<K: KernelTableManager, PA: PhysicalMemoryAllocator<Address = PhysicalAddres
|
|||||||
type Context = TaskContextImpl<K, PA>;
|
type Context = TaskContextImpl<K, PA>;
|
||||||
|
|
||||||
unsafe fn fork(&self, address_space: u64) -> Result<TaskContextImpl<K, PA>, Error> {
|
unsafe fn fork(&self, address_space: u64) -> Result<TaskContextImpl<K, PA>, Error> {
|
||||||
TaskContextImpl::from_syscall_frame(self, address_space)
|
unsafe { TaskContextImpl::from_syscall_frame(self, address_space) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_return_value(&mut self, value: u64) {
|
fn set_return_value(&mut self, value: u64) {
|
||||||
@@ -405,18 +405,20 @@ impl<K: KernelTableManager, PA: PhysicalMemoryAllocator<Address = PhysicalAddres
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn store_state(&self) {
|
unsafe fn store_state(&self) {
|
||||||
FpuContext::store(self.fpu_context.get());
|
unsafe { FpuContext::store(self.fpu_context.get()) };
|
||||||
// No need to save TSS/%cr3/%fs base back into the TCB, only the kernel
|
// No need to save TSS/%cr3/%fs base back into the TCB, only the kernel
|
||||||
// can make changes to those
|
// can make changes to those
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn load_state(&self) {
|
unsafe fn load_state(&self) {
|
||||||
FpuContext::restore(self.fpu_context.get());
|
unsafe {
|
||||||
// When the task is interrupted from Ring 3, make the CPU load
|
FpuContext::restore(self.fpu_context.get());
|
||||||
// the top of its kernel stack
|
// When the task is interrupted from Ring 3, make the CPU load
|
||||||
ArchitectureImpl::set_local_tss_sp0(self.tss_rsp0);
|
// the top of its kernel stack
|
||||||
MSR_IA32_FS_BASE.set((*self.inner.get()).fs_base as u64);
|
ArchitectureImpl::set_local_tss_sp0(self.tss_rsp0);
|
||||||
CR3.set_address(self.cr3);
|
MSR_IA32_FS_BASE.set((*self.inner.get()).fs_base as u64);
|
||||||
|
CR3.set_address(self.cr3);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -506,8 +508,10 @@ impl<K: KernelTableManager, PA: PhysicalMemoryAllocator<Address = PhysicalAddres
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn enter(&self) -> ! {
|
unsafe fn enter(&self) -> ! {
|
||||||
self.load_state();
|
unsafe {
|
||||||
__x86_64_enter_task(self.inner.get())
|
self.load_state();
|
||||||
|
__x86_64_enter_task(self.inner.get())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn switch(&self, from: &Self) {
|
unsafe fn switch(&self, from: &Self) {
|
||||||
@@ -515,14 +519,18 @@ impl<K: KernelTableManager, PA: PhysicalMemoryAllocator<Address = PhysicalAddres
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
from.store_state();
|
unsafe {
|
||||||
self.load_state();
|
from.store_state();
|
||||||
__x86_64_switch_task(self.inner.get(), from.inner.get())
|
self.load_state();
|
||||||
|
__x86_64_switch_task(self.inner.get(), from.inner.get())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn switch_and_drop(&self, thread: *const ()) {
|
unsafe fn switch_and_drop(&self, thread: *const ()) {
|
||||||
self.load_state();
|
unsafe {
|
||||||
__x86_64_switch_and_drop(self.inner.get(), thread)
|
self.load_state();
|
||||||
|
__x86_64_switch_and_drop(self.inner.get(), thread)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_thread_pointer(&self, tp: usize) {
|
fn set_thread_pointer(&self, tp: usize) {
|
||||||
@@ -561,7 +569,7 @@ fn setup_common_context(builder: &mut StackBuilder, entry: usize) {
|
|||||||
builder.push(0); // %rbx
|
builder.push(0); // %rbx
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" {
|
unsafe extern "C" {
|
||||||
fn __x86_64_task_enter_kernel();
|
fn __x86_64_task_enter_kernel();
|
||||||
fn __x86_64_task_enter_user();
|
fn __x86_64_task_enter_user();
|
||||||
fn __x86_64_task_enter_from_fork();
|
fn __x86_64_task_enter_from_fork();
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ impl Architecture for ArchitectureImpl {
|
|||||||
|
|
||||||
unsafe fn set_local_cpu(cpu: *mut ()) {
|
unsafe fn set_local_cpu(cpu: *mut ()) {
|
||||||
MSR_IA32_KERNEL_GS_BASE.set(cpu as u64);
|
MSR_IA32_KERNEL_GS_BASE.set(cpu as u64);
|
||||||
core::arch::asm!("wbinvd; swapgs");
|
unsafe { core::arch::asm!("wbinvd; swapgs") };
|
||||||
}
|
}
|
||||||
|
|
||||||
fn local_cpu() -> *mut () {
|
fn local_cpu() -> *mut () {
|
||||||
@@ -127,7 +127,7 @@ impl Architecture for ArchitectureImpl {
|
|||||||
)));
|
)));
|
||||||
cpu.this = cpu.deref_mut();
|
cpu.this = cpu.deref_mut();
|
||||||
|
|
||||||
cpu.set_local();
|
unsafe { cpu.set_local() };
|
||||||
}
|
}
|
||||||
|
|
||||||
fn idle_task() -> extern "C" fn(usize) -> ! {
|
fn idle_task() -> extern "C" fn(usize) -> ! {
|
||||||
@@ -153,10 +153,12 @@ impl Architecture for ArchitectureImpl {
|
|||||||
|
|
||||||
unsafe fn set_interrupt_mask(mask: bool) -> bool {
|
unsafe fn set_interrupt_mask(mask: bool) -> bool {
|
||||||
let old = Self::interrupt_mask();
|
let old = Self::interrupt_mask();
|
||||||
if mask {
|
unsafe {
|
||||||
core::arch::asm!("cli");
|
if mask {
|
||||||
} else {
|
core::arch::asm!("cli");
|
||||||
core::arch::asm!("sti");
|
} else {
|
||||||
|
core::arch::asm!("sti");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
old
|
old
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -101,29 +101,33 @@ impl DevicePageTableLevel for L3DeviceMemory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(super) unsafe fn setup(have_1gib_pages: bool) {
|
pub(super) unsafe fn setup(have_1gib_pages: bool) {
|
||||||
let phys = PhysicalAddress::from_usize(auto_lower_address(&raw const KERNEL_PDPT));
|
unsafe {
|
||||||
KERNEL_PML4[KERNEL_L0I] = PageEntry::table(phys, PageAttributes::WRITABLE);
|
let phys = PhysicalAddress::from_usize(auto_lower_address(&raw const KERNEL_PDPT));
|
||||||
|
KERNEL_PML4[KERNEL_L0I] = PageEntry::table(phys, PageAttributes::WRITABLE);
|
||||||
|
|
||||||
if have_1gib_pages {
|
if have_1gib_pages {
|
||||||
for i in 0..IDENTITY_SIZE_L1 {
|
for i in 0..IDENTITY_SIZE_L1 {
|
||||||
let phys = PhysicalAddress::from_usize(i * L1::SIZE);
|
let phys = PhysicalAddress::from_usize(i * L1::SIZE);
|
||||||
KERNEL_PDPT[i] = PageEntry::<L1>::block(phys, PageAttributes::WRITABLE);
|
KERNEL_PDPT[i] = PageEntry::<L1>::block(phys, PageAttributes::WRITABLE);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// TODO
|
||||||
|
ArchitectureImpl::halt();
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
// TODO
|
|
||||||
ArchitectureImpl::halt();
|
|
||||||
}
|
|
||||||
|
|
||||||
// DEVICE_L1 -> Device L2 table
|
// DEVICE_L1 -> Device L2 table
|
||||||
// 0..DEVICE_MAPPING_L3_COUNT -> Device L3 tables -> Device L3 pages
|
// 0..DEVICE_MAPPING_L3_COUNT -> Device L3 tables -> Device L3 pages
|
||||||
// ..512 -> Device L2 pages
|
// ..512 -> Device L2 pages
|
||||||
for i in 0..DEVICE_MAPPING_L3_COUNT {
|
for i in 0..DEVICE_MAPPING_L3_COUNT {
|
||||||
|
let phys = PhysicalAddress::from_usize(auto_lower_address(
|
||||||
|
&raw const DEVICE_MEMORY.normal.0[i],
|
||||||
|
));
|
||||||
|
DEVICE_MEMORY.large.0[i] = PageEntry::table(phys, PageAttributes::WRITABLE);
|
||||||
|
}
|
||||||
let phys =
|
let phys =
|
||||||
PhysicalAddress::from_usize(auto_lower_address(&raw const DEVICE_MEMORY.normal.0[i]));
|
PhysicalAddress::from_usize(auto_lower_address(&raw const DEVICE_MEMORY.large.0));
|
||||||
DEVICE_MEMORY.large.0[i] = PageEntry::table(phys, PageAttributes::WRITABLE);
|
KERNEL_PDPT[DEVICE_L1] = PageEntry::table(phys, PageAttributes::WRITABLE);
|
||||||
}
|
}
|
||||||
let phys = PhysicalAddress::from_usize(auto_lower_address(&raw const DEVICE_MEMORY.large.0));
|
|
||||||
KERNEL_PDPT[DEVICE_L1] = PageEntry::table(phys, PageAttributes::WRITABLE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) unsafe fn load() {
|
pub(super) unsafe fn load() {
|
||||||
|
|||||||
@@ -41,13 +41,17 @@ impl KernelTableManager for KernelTableManagerImpl {
|
|||||||
) -> Result<RawDeviceMemoryMapping<Self>, Error> {
|
) -> Result<RawDeviceMemoryMapping<Self>, Error> {
|
||||||
let _lock = fixed::LOCK.lock();
|
let _lock = fixed::LOCK.lock();
|
||||||
#[allow(static_mut_refs)]
|
#[allow(static_mut_refs)]
|
||||||
fixed::DEVICE_MEMORY.map_device_pages(PhysicalAddress::from_u64(base), count, attrs)
|
unsafe {
|
||||||
|
fixed::DEVICE_MEMORY.map_device_pages(PhysicalAddress::from_u64(base), count, attrs)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn unmap_device_pages(mapping: &RawDeviceMemoryMapping<Self>) {
|
unsafe fn unmap_device_pages(mapping: &RawDeviceMemoryMapping<Self>) {
|
||||||
let _lock = fixed::LOCK.lock();
|
let _lock = fixed::LOCK.lock();
|
||||||
#[allow(static_mut_refs)]
|
#[allow(static_mut_refs)]
|
||||||
fixed::DEVICE_MEMORY.unmap_device_pages(mapping);
|
unsafe {
|
||||||
|
fixed::DEVICE_MEMORY.unmap_device_pages(mapping)
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,9 +88,11 @@ pub fn auto_lower_address<T>(pointer: *const T) -> usize {
|
|||||||
/// Unsafe, must only be called by BSP during its early init, must already be in "higher-half"
|
/// Unsafe, must only be called by BSP during its early init, must already be in "higher-half"
|
||||||
#[inline(never)]
|
#[inline(never)]
|
||||||
pub unsafe fn init_fixed_tables(have_1gib_pages: bool, bsp: bool) {
|
pub unsafe fn init_fixed_tables(have_1gib_pages: bool, bsp: bool) {
|
||||||
fixed::setup(have_1gib_pages);
|
unsafe {
|
||||||
if bsp {
|
fixed::setup(have_1gib_pages);
|
||||||
fixed::load();
|
if bsp {
|
||||||
|
fixed::load();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,5 +101,5 @@ pub unsafe fn init_fixed_tables(have_1gib_pages: bool, bsp: bool) {
|
|||||||
/// `address` must be page-aligned.
|
/// `address` must be page-aligned.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn flush_tlb_entry(address: usize) {
|
pub unsafe fn flush_tlb_entry(address: usize) {
|
||||||
core::arch::asm!("invlpg ({0})", in(reg) address, options(att_syntax));
|
unsafe { core::arch::asm!("invlpg ({0})", in(reg) address, options(att_syntax)) };
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -85,8 +85,10 @@ impl<TA: TableAllocator> ProcessAddressSpaceManager<TA> for ProcessAddressSpaceI
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn clear(&mut self) {
|
unsafe fn clear(&mut self) {
|
||||||
self.l0
|
unsafe {
|
||||||
.drop_range::<TA>(0..((Self::UPPER_LIMIT_PFN * L3::SIZE).page_index::<L1>()));
|
self.l0
|
||||||
|
.drop_range::<TA>(0..((Self::UPPER_LIMIT_PFN * L3::SIZE).page_index::<L1>()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -220,7 +220,7 @@ impl<L: EntryLevel> PageTable<L> {
|
|||||||
/// Unsafe: the caller must ensure the provided reference is properly aligned and contains sane
|
/// Unsafe: the caller must ensure the provided reference is properly aligned and contains sane
|
||||||
/// data.
|
/// data.
|
||||||
pub unsafe fn from_raw_slice_mut(data: &mut [PageEntry<L>; 512]) -> &mut Self {
|
pub unsafe fn from_raw_slice_mut(data: &mut [PageEntry<L>; 512]) -> &mut Self {
|
||||||
core::mem::transmute(data)
|
unsafe { core::mem::transmute(data) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Allocates a new page table, filling it with non-preset entries
|
/// Allocates a new page table, filling it with non-preset entries
|
||||||
@@ -243,8 +243,10 @@ impl<L: EntryLevel> PageTable<L> {
|
|||||||
///
|
///
|
||||||
/// The caller must ensure the table is no longer in use and is not referenced anymore.
|
/// The caller must ensure the table is no longer in use and is not referenced anymore.
|
||||||
pub unsafe fn free<TA: TableAllocator>(this: PhysicalRefMut<Self, KernelTableManagerImpl>) {
|
pub unsafe fn free<TA: TableAllocator>(this: PhysicalRefMut<Self, KernelTableManagerImpl>) {
|
||||||
let physical = this.as_physical_address();
|
unsafe {
|
||||||
TA::free_page_table(physical);
|
let physical = this.as_physical_address();
|
||||||
|
TA::free_page_table(physical);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// /// Returns the physical address of this table
|
// /// Returns the physical address of this table
|
||||||
@@ -303,25 +305,29 @@ where
|
|||||||
const FULL_RANGE: Range<usize> = 0..512;
|
const FULL_RANGE: Range<usize> = 0..512;
|
||||||
|
|
||||||
unsafe fn drop_range<TA: TableAllocator>(&mut self, range: Range<usize>) {
|
unsafe fn drop_range<TA: TableAllocator>(&mut self, range: Range<usize>) {
|
||||||
for index in range {
|
unsafe {
|
||||||
let entry = self[index];
|
for index in range {
|
||||||
|
let entry = self[index];
|
||||||
|
|
||||||
if let Some(table) = entry.as_table() {
|
if let Some(table) = entry.as_table() {
|
||||||
let mut table_ref: PhysicalRefMut<PageTable<L::NextLevel>, KernelTableManagerImpl> =
|
let mut table_ref: PhysicalRefMut<
|
||||||
PhysicalRefMut::map(table);
|
PageTable<L::NextLevel>,
|
||||||
|
KernelTableManagerImpl,
|
||||||
|
> = PhysicalRefMut::map(table);
|
||||||
|
|
||||||
table_ref.drop_all::<TA>();
|
table_ref.drop_all::<TA>();
|
||||||
|
|
||||||
TA::free_page_table(table);
|
TA::free_page_table(table);
|
||||||
} else if entry.is_present() {
|
} else if entry.is_present() {
|
||||||
// Memory must've been cleared beforehand, so no non-table entries must be present
|
// Memory must've been cleared beforehand, so no non-table entries must be present
|
||||||
panic!(
|
panic!(
|
||||||
"Expected a table containing only tables, got table[{}] = {:#x?}",
|
"Expected a table containing only tables, got table[{}] = {:#x?}",
|
||||||
index, entry.0
|
index, entry.0
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
self[index] = PageEntry::INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
self[index] = PageEntry::INVALID;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "ygg_driver_ahci"
|
name = "ygg_driver_ahci"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2024"
|
||||||
authors = ["Mark Poliakov <mark@alnyan.me>"]
|
authors = ["Mark Poliakov <mark@alnyan.me>"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
|||||||
@@ -115,7 +115,7 @@ impl AtaCommand for AtaIdentify {
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn into_response(self) -> Self::Response {
|
unsafe fn into_response(self) -> Self::Response {
|
||||||
DmaBuffer::assume_init(self.buffer)
|
unsafe { DmaBuffer::assume_init(self.buffer) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
#![allow(unsafe_op_in_unsafe_fn)]
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "ygg_driver_usb"
|
name = "ygg_driver_usb"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2024"
|
||||||
authors = ["Mark Poliakov <mark@alnyan.me>"]
|
authors = ["Mark Poliakov <mark@alnyan.me>"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
generic_const_exprs,
|
generic_const_exprs,
|
||||||
iter_array_chunks,
|
iter_array_chunks,
|
||||||
maybe_uninit_as_bytes,
|
maybe_uninit_as_bytes,
|
||||||
maybe_uninit_fill,
|
|
||||||
maybe_uninit_array_assume_init
|
maybe_uninit_array_assume_init
|
||||||
)]
|
)]
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "ext2"
|
name = "ext2"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2024"
|
||||||
authors = ["Mark Poliakov <mark@alnyan.me>"]
|
authors = ["Mark Poliakov <mark@alnyan.me>"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
#![feature(impl_trait_in_assoc_type)]
|
|
||||||
#![cfg_attr(not(test), no_std)]
|
#![cfg_attr(not(test), no_std)]
|
||||||
#![allow(clippy::new_ret_no_self)]
|
#![allow(clippy::new_ret_no_self)]
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "kernel-fs"
|
name = "kernel-fs"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2024"
|
||||||
authors = ["Mark Poliakov <mark@alnyan.me>"]
|
authors = ["Mark Poliakov <mark@alnyan.me>"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "memfs"
|
name = "memfs"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2024"
|
||||||
authors = ["Mark Poliakov <mark@alnyan.me>"]
|
authors = ["Mark Poliakov <mark@alnyan.me>"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
|||||||
@@ -159,7 +159,7 @@ impl<'a, A: BlockAllocator> BlockRaw<'a, A> {
|
|||||||
panic!("Null block dereference");
|
panic!("Null block dereference");
|
||||||
}
|
}
|
||||||
|
|
||||||
&mut *(self.inner.ptr as *mut _)
|
unsafe { &mut *(self.inner.ptr as *mut _) }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@@ -197,7 +197,7 @@ impl<A: BlockAllocator> BlockData<'_, A> {
|
|||||||
pub unsafe fn copy_on_write(address: usize) -> Self {
|
pub unsafe fn copy_on_write(address: usize) -> Self {
|
||||||
Self {
|
Self {
|
||||||
inner: BlockRaw {
|
inner: BlockRaw {
|
||||||
inner: BlockRef::copy_on_write(address),
|
inner: unsafe { BlockRef::copy_on_write(address) },
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "ygg_driver_input"
|
name = "ygg_driver_input"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2024"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
yggdrasil-abi.workspace = true
|
yggdrasil-abi.workspace = true
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
#![feature(map_try_insert)]
|
|
||||||
#![allow(clippy::type_complexity, clippy::new_without_default)]
|
#![allow(clippy::type_complexity, clippy::new_without_default)]
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "ygg_driver_net_loopback"
|
name = "ygg_driver_net_loopback"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2024"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
yggdrasil-abi.workspace = true
|
yggdrasil-abi.workspace = true
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "ygg_driver_usb_xhci"
|
name = "ygg_driver_usb_xhci"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2024"
|
||||||
authors = ["Mark Poliakov <mark@alnyan.me>"]
|
authors = ["Mark Poliakov <mark@alnyan.me>"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
#![no_std]
|
#![no_std]
|
||||||
#![allow(clippy::new_without_default)]
|
#![allow(clippy::new_without_default)]
|
||||||
#![feature(iter_array_chunks)]
|
|
||||||
|
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "ygg_driver_virtio_core"
|
name = "ygg_driver_virtio_core"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2024"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
yggdrasil-abi.workspace = true
|
yggdrasil-abi.workspace = true
|
||||||
|
|||||||
@@ -272,7 +272,7 @@ impl DescriptorTable {
|
|||||||
visitor: F,
|
visitor: F,
|
||||||
) -> u16 {
|
) -> u16 {
|
||||||
debug_assert_ne!(count, 0);
|
debug_assert_ne!(count, 0);
|
||||||
let mut current = self.first_free.unwrap_unchecked();
|
let mut current = unsafe { self.first_free.unwrap_unchecked() };
|
||||||
let head = current;
|
let head = current;
|
||||||
for i in 0..count {
|
for i in 0..count {
|
||||||
let descriptor = &mut self.descriptors[current as usize];
|
let descriptor = &mut self.descriptors[current as usize];
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "ygg_driver_virtio_gpu"
|
name = "ygg_driver_virtio_gpu"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2024"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
yggdrasil-abi.workspace = true
|
yggdrasil-abi.workspace = true
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "ygg_driver_virtio_net"
|
name = "ygg_driver_virtio_net"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2024"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
yggdrasil-abi.workspace = true
|
yggdrasil-abi.workspace = true
|
||||||
|
|||||||
@@ -263,7 +263,7 @@ impl<T: Transport + 'static> Device for VirtioNet<T> {
|
|||||||
unsafe fn init(self: Arc<Self>, _cx: DeviceInitContext) -> Result<(), Error> {
|
unsafe fn init(self: Arc<Self>, _cx: DeviceInitContext) -> Result<(), Error> {
|
||||||
let status = self.begin_init()?;
|
let status = self.begin_init()?;
|
||||||
|
|
||||||
self.setup_queues()?;
|
unsafe { self.setup_queues() }?;
|
||||||
|
|
||||||
self.finish_init(status);
|
self.finish_init(status);
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "device-api"
|
name = "device-api"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2024"
|
||||||
authors = ["Mark Poliakov <mark@alnyan.me>"]
|
authors = ["Mark Poliakov <mark@alnyan.me>"]
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "device-api-macros"
|
name = "device-api-macros"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2024"
|
||||||
authors = ["Mark Poliakov <mark@alnyan.me>"]
|
authors = ["Mark Poliakov <mark@alnyan.me>"]
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|||||||
@@ -151,11 +151,11 @@ impl I2CDevice {
|
|||||||
|
|
||||||
impl Device for I2CDevice {
|
impl Device for I2CDevice {
|
||||||
unsafe fn init(self: Arc<Self>, cx: DeviceInitContext) -> Result<(), Error> {
|
unsafe fn init(self: Arc<Self>, cx: DeviceInitContext) -> Result<(), Error> {
|
||||||
self.device.clone().init(cx)
|
unsafe { self.device.clone().init(cx) }
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn init_irq(self: Arc<Self>) -> Result<(), Error> {
|
unsafe fn init_irq(self: Arc<Self>) -> Result<(), Error> {
|
||||||
self.device.clone().init_irq()
|
unsafe { self.device.clone().init_irq() }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn display_name(&self) -> &str {
|
fn display_name(&self) -> &str {
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
#![feature(trait_alias)]
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![allow(clippy::new_without_default)]
|
#![allow(clippy::new_without_default)]
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
//! * `pl011` - basic peripheral usage with `reg` and `interrupts`
|
//! * `pl011` - basic peripheral usage with `reg` and `interrupts`
|
||||||
//! * `gic` in aarch64 - interrupt controller/mapper implementation
|
//! * `gic` in aarch64 - interrupt controller/mapper implementation
|
||||||
#![cfg_attr(any(not(test), rust_analyzer), no_std)]
|
#![cfg_attr(any(not(test), rust_analyzer), no_std)]
|
||||||
#![feature(trait_alias, decl_macro)]
|
#![feature(decl_macro)]
|
||||||
#![allow(clippy::type_complexity)]
|
#![allow(clippy::type_complexity)]
|
||||||
#![warn(missing_docs)]
|
#![warn(missing_docs)]
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "module-build"
|
name = "module-build"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2024"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "vmalloc"
|
name = "vmalloc"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2024"
|
||||||
authors = ["Mark Poliakov <mark@alnyan.me>"]
|
authors = ["Mark Poliakov <mark@alnyan.me>"]
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
|
|
||||||
#![deny(missing_docs)]
|
#![deny(missing_docs)]
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![feature(linked_list_cursors)]
|
|
||||||
|
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "libk-mm"
|
name = "libk-mm"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2024"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
yggdrasil-abi.workspace = true
|
yggdrasil-abi.workspace = true
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "libk-mm-interface"
|
name = "libk-mm-interface"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2024"
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
|||||||
@@ -93,13 +93,15 @@ impl<N: DevicePageTableLevel, L: DevicePageTableLevel> DevicePageManager<N, L> {
|
|||||||
.ok_or(Error::OutOfMemory)?;
|
.ok_or(Error::OutOfMemory)?;
|
||||||
let mapped_address = mapped_base + large_offset;
|
let mapped_address = mapped_base + large_offset;
|
||||||
|
|
||||||
Ok(RawDeviceMemoryMapping::from_raw_parts(
|
Ok(unsafe {
|
||||||
large_aligned_base.into_u64(),
|
RawDeviceMemoryMapping::from_raw_parts(
|
||||||
mapped_address,
|
large_aligned_base.into_u64(),
|
||||||
mapped_base,
|
mapped_address,
|
||||||
large_page_count,
|
mapped_base,
|
||||||
L::Level::SIZE,
|
large_page_count,
|
||||||
))
|
L::Level::SIZE,
|
||||||
|
)
|
||||||
|
})
|
||||||
} else {
|
} else {
|
||||||
// Allocate from small page pool
|
// Allocate from small page pool
|
||||||
let mapped_base = self
|
let mapped_base = self
|
||||||
@@ -108,13 +110,15 @@ impl<N: DevicePageTableLevel, L: DevicePageTableLevel> DevicePageManager<N, L> {
|
|||||||
.ok_or(Error::OutOfMemory)?;
|
.ok_or(Error::OutOfMemory)?;
|
||||||
let mapped_address = mapped_base + small_offset;
|
let mapped_address = mapped_base + small_offset;
|
||||||
|
|
||||||
Ok(RawDeviceMemoryMapping::from_raw_parts(
|
Ok(unsafe {
|
||||||
small_aligned_base.into_u64(),
|
RawDeviceMemoryMapping::from_raw_parts(
|
||||||
mapped_address,
|
small_aligned_base.into_u64(),
|
||||||
mapped_base,
|
mapped_address,
|
||||||
small_page_count,
|
mapped_base,
|
||||||
N::Level::SIZE,
|
small_page_count,
|
||||||
))
|
N::Level::SIZE,
|
||||||
|
)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -125,17 +129,19 @@ impl<N: DevicePageTableLevel, L: DevicePageTableLevel> DevicePageManager<N, L> {
|
|||||||
&mut self,
|
&mut self,
|
||||||
mapping: &RawDeviceMemoryMapping<A>,
|
mapping: &RawDeviceMemoryMapping<A>,
|
||||||
) {
|
) {
|
||||||
if mapping.page_size == N::Level::SIZE {
|
unsafe {
|
||||||
self.normal
|
if mapping.page_size == N::Level::SIZE {
|
||||||
.remove_mapping(mapping.base_address, mapping.page_count);
|
self.normal
|
||||||
} else if mapping.page_size == L::Level::SIZE {
|
.remove_mapping(mapping.base_address, mapping.page_count);
|
||||||
self.large
|
} else if mapping.page_size == L::Level::SIZE {
|
||||||
.remove_mapping(mapping.base_address, mapping.page_count);
|
self.large
|
||||||
} else {
|
.remove_mapping(mapping.base_address, mapping.page_count);
|
||||||
unreachable!(
|
} else {
|
||||||
"Invalid device memory mapping with page size {:#x}",
|
unreachable!(
|
||||||
mapping.page_size
|
"Invalid device memory mapping with page size {:#x}",
|
||||||
)
|
mapping.page_size
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#![no_std]
|
#![no_std]
|
||||||
#![feature(step_trait, const_trait_impl)]
|
#![feature(step_trait)]
|
||||||
|
|
||||||
use core::ops::{Deref, DerefMut};
|
use core::ops::{Deref, DerefMut};
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ impl<'a, T: Sized, K: KernelTableManager> PhysicalRefMut<'a, T, K> {
|
|||||||
/// contains T. The caller must also take care of access synchronization and make sure no
|
/// contains T. The caller must also take care of access synchronization and make sure no
|
||||||
/// aliasing occurs.
|
/// aliasing occurs.
|
||||||
pub unsafe fn map(physical: PhysicalAddress) -> PhysicalRefMut<'a, T, K> {
|
pub unsafe fn map(physical: PhysicalAddress) -> PhysicalRefMut<'a, T, K> {
|
||||||
let value = virtualize_raw::<_, K>(physical);
|
let value = unsafe { virtualize_raw::<_, K>(physical) };
|
||||||
PhysicalRefMut {
|
PhysicalRefMut {
|
||||||
value,
|
value,
|
||||||
_pd: PhantomData,
|
_pd: PhantomData,
|
||||||
@@ -48,7 +48,7 @@ impl<'a, T: Sized, K: KernelTableManager> PhysicalRefMut<'a, T, K> {
|
|||||||
/// contains [T; len]. The caller must also take care of access synchronization and make
|
/// contains [T; len]. The caller must also take care of access synchronization and make
|
||||||
/// sure no aliasing occurs.
|
/// sure no aliasing occurs.
|
||||||
pub unsafe fn map_slice(physical: PhysicalAddress, len: usize) -> PhysicalRefMut<'a, [T], K> {
|
pub unsafe fn map_slice(physical: PhysicalAddress, len: usize) -> PhysicalRefMut<'a, [T], K> {
|
||||||
let value = virtualize_slice_raw::<_, K>(physical, len);
|
let value = unsafe { virtualize_slice_raw::<_, K>(physical, len) };
|
||||||
PhysicalRefMut {
|
PhysicalRefMut {
|
||||||
value,
|
value,
|
||||||
_pd: PhantomData,
|
_pd: PhantomData,
|
||||||
@@ -66,7 +66,9 @@ impl<T: ?Sized, K: KernelTableManager> PhysicalRefMut<'_, T, K> {
|
|||||||
|
|
||||||
impl<T: ?Sized, K: KernelTableManager> AsPhysicalAddress for PhysicalRefMut<'_, T, K> {
|
impl<T: ?Sized, K: KernelTableManager> AsPhysicalAddress for PhysicalRefMut<'_, T, K> {
|
||||||
unsafe fn as_physical_address(&self) -> PhysicalAddress {
|
unsafe fn as_physical_address(&self) -> PhysicalAddress {
|
||||||
PhysicalAddress::raw_from_virtualized::<K>(PhysicalRefMut::<T, K>::as_address(self))
|
unsafe {
|
||||||
|
PhysicalAddress::raw_from_virtualized::<K>(PhysicalRefMut::<T, K>::as_address(self))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -106,7 +108,7 @@ impl<'a, T: Sized, K: KernelTableManager> PhysicalRef<'a, T, K> {
|
|||||||
/// The caller must ensure the correct origin of the physical address as well that it actually
|
/// The caller must ensure the correct origin of the physical address as well that it actually
|
||||||
/// contains T.
|
/// contains T.
|
||||||
pub unsafe fn map(physical: PhysicalAddress) -> PhysicalRef<'a, T, K> {
|
pub unsafe fn map(physical: PhysicalAddress) -> PhysicalRef<'a, T, K> {
|
||||||
let value = virtualize_raw::<_, K>(physical);
|
let value = unsafe { virtualize_raw::<_, K>(physical) };
|
||||||
PhysicalRef {
|
PhysicalRef {
|
||||||
value,
|
value,
|
||||||
_pd: PhantomData,
|
_pd: PhantomData,
|
||||||
@@ -121,7 +123,7 @@ impl<'a, T: Sized, K: KernelTableManager> PhysicalRef<'a, T, K> {
|
|||||||
/// The caller must ensure the correct origin of the physical address as well that it actually
|
/// The caller must ensure the correct origin of the physical address as well that it actually
|
||||||
/// contains [T; len].
|
/// contains [T; len].
|
||||||
pub unsafe fn map_slice(physical: PhysicalAddress, len: usize) -> PhysicalRef<'a, [T], K> {
|
pub unsafe fn map_slice(physical: PhysicalAddress, len: usize) -> PhysicalRef<'a, [T], K> {
|
||||||
let value = virtualize_slice_raw::<_, K>(physical, len);
|
let value = unsafe { virtualize_slice_raw::<_, K>(physical, len) };
|
||||||
PhysicalRef {
|
PhysicalRef {
|
||||||
value,
|
value,
|
||||||
_pd: PhantomData,
|
_pd: PhantomData,
|
||||||
@@ -139,7 +141,7 @@ impl<T: ?Sized, K: KernelTableManager> PhysicalRef<'_, T, K> {
|
|||||||
|
|
||||||
impl<T: ?Sized, K: KernelTableManager> AsPhysicalAddress for PhysicalRef<'_, T, K> {
|
impl<T: ?Sized, K: KernelTableManager> AsPhysicalAddress for PhysicalRef<'_, T, K> {
|
||||||
unsafe fn as_physical_address(&self) -> PhysicalAddress {
|
unsafe fn as_physical_address(&self) -> PhysicalAddress {
|
||||||
PhysicalAddress::raw_from_virtualized::<K>(PhysicalRef::<T, K>::as_address(self))
|
unsafe { PhysicalAddress::raw_from_virtualized::<K>(PhysicalRef::<T, K>::as_address(self)) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -162,7 +164,7 @@ unsafe fn virtualize_raw<'a, T: Sized, K: KernelTableManager>(
|
|||||||
) -> &'a mut T {
|
) -> &'a mut T {
|
||||||
// TODO check align
|
// TODO check align
|
||||||
let address = physical.raw_virtualize::<K>();
|
let address = physical.raw_virtualize::<K>();
|
||||||
&mut *(address as *mut T)
|
unsafe { &mut *(address as *mut T) }
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn virtualize_slice_raw<'a, T: Sized, K: KernelTableManager>(
|
unsafe fn virtualize_slice_raw<'a, T: Sized, K: KernelTableManager>(
|
||||||
@@ -171,5 +173,5 @@ unsafe fn virtualize_slice_raw<'a, T: Sized, K: KernelTableManager>(
|
|||||||
) -> &'a mut [T] {
|
) -> &'a mut [T] {
|
||||||
// TODO check align
|
// TODO check align
|
||||||
let address = physical.raw_virtualize::<K>();
|
let address = physical.raw_virtualize::<K>();
|
||||||
core::slice::from_raw_parts_mut(address as *mut T, len)
|
unsafe { core::slice::from_raw_parts_mut(address as *mut T, len) }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ pub trait EntryLevelDrop {
|
|||||||
/// Caller must ensure the unmapped range is not in use by some other thread and will not be
|
/// Caller must ensure the unmapped range is not in use by some other thread and will not be
|
||||||
/// referred to from this point.
|
/// referred to from this point.
|
||||||
unsafe fn drop_all<TA: TableAllocator>(&mut self) {
|
unsafe fn drop_all<TA: TableAllocator>(&mut self) {
|
||||||
self.drop_range::<TA>(Self::FULL_RANGE)
|
unsafe { self.drop_range::<TA>(Self::FULL_RANGE) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ impl DeviceMemoryMapping {
|
|||||||
size: usize,
|
size: usize,
|
||||||
attrs: DeviceMemoryAttributes,
|
attrs: DeviceMemoryAttributes,
|
||||||
) -> Result<Self, Error> {
|
) -> Result<Self, Error> {
|
||||||
let inner = RawDeviceMemoryMapping::map(base.into_u64(), size, attrs)?;
|
let inner = unsafe { RawDeviceMemoryMapping::map(base.into_u64(), size, attrs)? };
|
||||||
let address = inner.address;
|
let address = inner.address;
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
inner: Arc::new(inner),
|
inner: Arc::new(inner),
|
||||||
@@ -78,7 +78,7 @@ impl<'a, T: Sized> DeviceMemoryIo<'a, T> {
|
|||||||
todo!();
|
todo!();
|
||||||
}
|
}
|
||||||
// TODO check align
|
// TODO check align
|
||||||
let value = &*(inner.address as *const T);
|
let value = unsafe { &*(inner.address as *const T) };
|
||||||
Ok(DeviceMemoryIo { inner, value })
|
Ok(DeviceMemoryIo { inner, value })
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,8 +94,8 @@ impl<'a, T: Sized> DeviceMemoryIo<'a, T> {
|
|||||||
attrs: DeviceMemoryAttributes,
|
attrs: DeviceMemoryAttributes,
|
||||||
) -> Result<DeviceMemoryIo<'a, [T]>, Error> {
|
) -> Result<DeviceMemoryIo<'a, [T]>, Error> {
|
||||||
let layout = Layout::array::<T>(count).unwrap();
|
let layout = Layout::array::<T>(count).unwrap();
|
||||||
let inner = RawDeviceMemoryMapping::map(base.into_u64(), layout.size(), attrs)?;
|
let inner = unsafe { RawDeviceMemoryMapping::map(base.into_u64(), layout.size(), attrs)? };
|
||||||
let value = core::slice::from_raw_parts(inner.address as *mut T, count);
|
let value = unsafe { core::slice::from_raw_parts(inner.address as *mut T, count) };
|
||||||
|
|
||||||
Ok(DeviceMemoryIo {
|
Ok(DeviceMemoryIo {
|
||||||
inner: Arc::new(inner),
|
inner: Arc::new(inner),
|
||||||
@@ -113,8 +113,8 @@ impl<'a, T: Sized> DeviceMemoryIo<'a, T> {
|
|||||||
base: PhysicalAddress,
|
base: PhysicalAddress,
|
||||||
attrs: DeviceMemoryAttributes,
|
attrs: DeviceMemoryAttributes,
|
||||||
) -> Result<DeviceMemoryIo<'a, T>, Error> {
|
) -> Result<DeviceMemoryIo<'a, T>, Error> {
|
||||||
let inner = RawDeviceMemoryMapping::map(base.into_u64(), size_of::<T>(), attrs)?;
|
let inner = unsafe { RawDeviceMemoryMapping::map(base.into_u64(), size_of::<T>(), attrs)? };
|
||||||
let value = &*(inner.address as *const T);
|
let value = unsafe { &*(inner.address as *const T) };
|
||||||
|
|
||||||
Ok(DeviceMemoryIo {
|
Ok(DeviceMemoryIo {
|
||||||
inner: Arc::new(inner),
|
inner: Arc::new(inner),
|
||||||
@@ -139,7 +139,7 @@ impl<'a, T: ?Sized> DeviceMemoryIo<'a, T> {
|
|||||||
|
|
||||||
DeviceMemoryIo {
|
DeviceMemoryIo {
|
||||||
inner: self.inner.clone(),
|
inner: self.inner.clone(),
|
||||||
value: &*value,
|
value: unsafe { &*value },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -175,8 +175,8 @@ impl<'a, T: Sized> DeviceMemoryIoMut<'a, T> {
|
|||||||
attrs: DeviceMemoryAttributes,
|
attrs: DeviceMemoryAttributes,
|
||||||
) -> Result<DeviceMemoryIoMut<'a, [T]>, Error> {
|
) -> Result<DeviceMemoryIoMut<'a, [T]>, Error> {
|
||||||
let layout = Layout::array::<T>(len).unwrap();
|
let layout = Layout::array::<T>(len).unwrap();
|
||||||
let inner = RawDeviceMemoryMapping::map(base.into_u64(), layout.size(), attrs)?;
|
let inner = unsafe { RawDeviceMemoryMapping::map(base.into_u64(), layout.size(), attrs)? };
|
||||||
let value = core::slice::from_raw_parts_mut(inner.address as *mut T, len);
|
let value = unsafe { core::slice::from_raw_parts_mut(inner.address as *mut T, len) };
|
||||||
|
|
||||||
Ok(DeviceMemoryIoMut { inner, value })
|
Ok(DeviceMemoryIoMut { inner, value })
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ unsafe impl GlobalAlloc for KernelAllocator {
|
|||||||
|
|
||||||
unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
|
unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
|
||||||
let ptr = NonNull::new(ptr).unwrap();
|
let ptr = NonNull::new(ptr).unwrap();
|
||||||
self.inner.lock().free(ptr, layout);
|
unsafe { self.inner.lock().free(ptr, layout) };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,4 @@
|
|||||||
#![feature(
|
#![feature(slice_ptr_get, maybe_uninit_as_bytes, negative_impls)]
|
||||||
slice_ptr_get,
|
|
||||||
step_trait,
|
|
||||||
const_trait_impl,
|
|
||||||
maybe_uninit_as_bytes,
|
|
||||||
negative_impls
|
|
||||||
)]
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
@@ -46,7 +40,7 @@ impl TableAllocator for TableAllocatorImpl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn free_page_table(address: PhysicalAddress) {
|
unsafe fn free_page_table(address: PhysicalAddress) {
|
||||||
phys::free_page(address)
|
unsafe { phys::free_page(address) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,7 +132,7 @@ impl<T> PageBox<T, GlobalPhysicalAllocator> {
|
|||||||
/// Unsafe: converts a raw physical address back into a [PageBox]. Only intended to be used
|
/// Unsafe: converts a raw physical address back into a [PageBox]. Only intended to be used
|
||||||
/// for allocations previously converted to [PhysicalAddress] via [PageBox::into_physical_raw].
|
/// for allocations previously converted to [PhysicalAddress] via [PageBox::into_physical_raw].
|
||||||
pub unsafe fn from_physical_raw(address: PhysicalAddress) -> PageBox<T> {
|
pub unsafe fn from_physical_raw(address: PhysicalAddress) -> PageBox<T> {
|
||||||
PageBox::from_physical_raw_in(address)
|
unsafe { PageBox::from_physical_raw_in(address) }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_slice(slice: &[T]) -> Result<PageBox<[T]>, Error>
|
pub fn from_slice(slice: &[T]) -> Result<PageBox<[T]>, Error>
|
||||||
@@ -335,7 +329,7 @@ impl<T, A: PhysicalMemoryAllocator<Address = PhysicalAddress>> PageBox<MaybeUnin
|
|||||||
// 1. MaybeUninit<T> is transparent
|
// 1. MaybeUninit<T> is transparent
|
||||||
// 2. self.value still points to the same memory and is not deallocated
|
// 2. self.value still points to the same memory and is not deallocated
|
||||||
let page_count = self.page_count;
|
let page_count = self.page_count;
|
||||||
let value = MaybeUninit::assume_init_mut(&mut *self.value);
|
let value = unsafe { MaybeUninit::assume_init_mut(&mut *self.value) };
|
||||||
|
|
||||||
// Prevent deallocation of the PageBox with MaybeUninit
|
// Prevent deallocation of the PageBox with MaybeUninit
|
||||||
core::mem::forget(self);
|
core::mem::forget(self);
|
||||||
@@ -363,7 +357,7 @@ impl<T, A: PhysicalMemoryAllocator<Address = PhysicalAddress>> PageBox<[MaybeUni
|
|||||||
// 1. MaybeUninit<T> is transparent
|
// 1. MaybeUninit<T> is transparent
|
||||||
// 2. self.value still points to the same memory and is not deallocated
|
// 2. self.value still points to the same memory and is not deallocated
|
||||||
let page_count = self.page_count;
|
let page_count = self.page_count;
|
||||||
let value = (&mut *self.value).assume_init_mut();
|
let value = unsafe { (&mut *self.value).assume_init_mut() };
|
||||||
|
|
||||||
core::mem::forget(self);
|
core::mem::forget(self);
|
||||||
|
|
||||||
@@ -380,7 +374,7 @@ impl<T, A: PhysicalMemoryAllocator<Address = PhysicalAddress>> PageBox<[MaybeUni
|
|||||||
///
|
///
|
||||||
/// See [MaybeUninit::slice_assume_init_ref]
|
/// See [MaybeUninit::slice_assume_init_ref]
|
||||||
pub unsafe fn assume_init_slice_ref(&self) -> &[T] {
|
pub unsafe fn assume_init_slice_ref(&self) -> &[T] {
|
||||||
(&*self.value).assume_init_ref()
|
unsafe { (&*self.value).assume_init_ref() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a mutable reference to the slice data with [MaybeUninit] removed.
|
/// Returns a mutable reference to the slice data with [MaybeUninit] removed.
|
||||||
@@ -389,7 +383,7 @@ impl<T, A: PhysicalMemoryAllocator<Address = PhysicalAddress>> PageBox<[MaybeUni
|
|||||||
///
|
///
|
||||||
/// See [MaybeUninit::slice_assume_init_mut]
|
/// See [MaybeUninit::slice_assume_init_mut]
|
||||||
pub unsafe fn assume_init_slice_mut(&mut self) -> &mut [T] {
|
pub unsafe fn assume_init_slice_mut(&mut self) -> &mut [T] {
|
||||||
(&mut *self.value).assume_init_mut()
|
unsafe { (&mut *self.value).assume_init_mut() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Fills a slice of MaybeUninit<T> with zeroes.
|
/// Fills a slice of MaybeUninit<T> with zeroes.
|
||||||
@@ -400,7 +394,7 @@ impl<T, A: PhysicalMemoryAllocator<Address = PhysicalAddress>> PageBox<[MaybeUni
|
|||||||
/// trivial types.
|
/// trivial types.
|
||||||
pub unsafe fn zero(p: &mut Self) {
|
pub unsafe fn zero(p: &mut Self) {
|
||||||
let ptr = p.as_mut_ptr() as *mut u8;
|
let ptr = p.as_mut_ptr() as *mut u8;
|
||||||
let slice = core::slice::from_raw_parts_mut(ptr, p.page_count * L3_PAGE_SIZE);
|
let slice = unsafe { core::slice::from_raw_parts_mut(ptr, p.page_count * L3_PAGE_SIZE) };
|
||||||
slice.fill(0);
|
slice.fill(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,10 +49,12 @@ impl PhysicalMemoryManager {
|
|||||||
page_count: usize,
|
page_count: usize,
|
||||||
) -> PhysicalMemoryManager {
|
) -> PhysicalMemoryManager {
|
||||||
let bitmap_len = page_count.div_ceil(BITMAP_WORD_SIZE);
|
let bitmap_len = page_count.div_ceil(BITMAP_WORD_SIZE);
|
||||||
let mut bitmap = PhysicalRefMut::<'static, _, KernelTableManagerImpl>::map_slice(
|
let mut bitmap = unsafe {
|
||||||
bitmap_phys_base,
|
PhysicalRefMut::<'static, _, KernelTableManagerImpl>::map_slice(
|
||||||
bitmap_len,
|
bitmap_phys_base,
|
||||||
);
|
bitmap_len,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
bitmap.fill(BitmapWord::MAX);
|
bitmap.fill(BitmapWord::MAX);
|
||||||
|
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ impl PhysicalMemoryAllocator for GlobalPhysicalAllocator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn free_page(page: Self::Address) {
|
unsafe fn free_page(page: Self::Address) {
|
||||||
free_page(page)
|
unsafe { free_page(page) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -111,7 +111,7 @@ pub fn stats() -> SystemMemoryStats {
|
|||||||
///
|
///
|
||||||
/// `addr` must be a page-aligned physical address previously allocated by this implementation.
|
/// `addr` must be a page-aligned physical address previously allocated by this implementation.
|
||||||
pub unsafe fn free_page(addr: PhysicalAddress) {
|
pub unsafe fn free_page(addr: PhysicalAddress) {
|
||||||
PHYSICAL_MEMORY.get().lock().free_page(addr)
|
unsafe { PHYSICAL_MEMORY.get().lock().free_page(addr) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn physical_memory_range<I: Iterator<Item = PhysicalMemoryRegion>>(
|
fn physical_memory_range<I: Iterator<Item = PhysicalMemoryRegion>>(
|
||||||
@@ -208,13 +208,15 @@ pub unsafe fn init_from_iter<I: Iterator<Item = PhysicalMemoryRegion> + Clone>(
|
|||||||
000000:?:libk_mm::phys:207: page_bitmap_phys_base=0x80060000
|
000000:?:libk_mm::phys:207: page_bitmap_phys_base=0x80060000
|
||||||
000000:?:libk_mm::phys:208: total_count=32768
|
000000:?:libk_mm::phys:208: total_count=32768
|
||||||
*/
|
*/
|
||||||
let mut manager = PhysicalMemoryManager::new(
|
let mut manager = unsafe {
|
||||||
page_bitmap_phys_base,
|
PhysicalMemoryManager::new(
|
||||||
phys_start
|
page_bitmap_phys_base,
|
||||||
.try_into_usize()
|
phys_start
|
||||||
.expect("Memory start didn't fit in usize"),
|
.try_into_usize()
|
||||||
total_count,
|
.expect("Memory start didn't fit in usize"),
|
||||||
);
|
total_count,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
let mut collected = 0;
|
let mut collected = 0;
|
||||||
const MAX_MEMORY: usize = 256 * 1024;
|
const MAX_MEMORY: usize = 256 * 1024;
|
||||||
@@ -245,7 +247,7 @@ pub unsafe fn init_from_iter<I: Iterator<Item = PhysicalMemoryRegion> + Clone>(
|
|||||||
fn kernel_physical_memory_region() -> PhysicalMemoryRegion {
|
fn kernel_physical_memory_region() -> PhysicalMemoryRegion {
|
||||||
use core::ptr::addr_of;
|
use core::ptr::addr_of;
|
||||||
|
|
||||||
extern "C" {
|
unsafe extern "C" {
|
||||||
static __kernel_start: u8;
|
static __kernel_start: u8;
|
||||||
static __kernel_end: u8;
|
static __kernel_end: u8;
|
||||||
}
|
}
|
||||||
@@ -259,17 +261,17 @@ fn kernel_physical_memory_region() -> PhysicalMemoryRegion {
|
|||||||
PhysicalMemoryRegion { base, size }
|
PhysicalMemoryRegion { base, size }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[unsafe(no_mangle)]
|
||||||
fn __allocate_page() -> Result<PhysicalAddress, Error> {
|
fn __allocate_page() -> Result<PhysicalAddress, Error> {
|
||||||
alloc_page()
|
alloc_page()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[unsafe(no_mangle)]
|
||||||
fn __allocate_contiguous_pages(count: usize) -> Result<PhysicalAddress, Error> {
|
fn __allocate_contiguous_pages(count: usize) -> Result<PhysicalAddress, Error> {
|
||||||
alloc_pages_contiguous(count)
|
alloc_pages_contiguous(count)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[unsafe(no_mangle)]
|
||||||
unsafe fn __free_page(page: PhysicalAddress) {
|
unsafe fn __free_page(page: PhysicalAddress) {
|
||||||
free_page(page)
|
unsafe { free_page(page) }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -185,7 +185,7 @@ impl<TA: TableAllocator> Inner<TA> {
|
|||||||
let offset = (pfn - origin_pfn) * L3_PAGE_SIZE;
|
let offset = (pfn - origin_pfn) * L3_PAGE_SIZE;
|
||||||
let virt = pfn * L3_PAGE_SIZE;
|
let virt = pfn * L3_PAGE_SIZE;
|
||||||
|
|
||||||
if let Ok((phys, dirty)) = self.table.unmap_page(virt) {
|
if let Ok((phys, dirty)) = unsafe { self.table.unmap_page(virt) } {
|
||||||
backing.release_page(offset as u64, phys, dirty)?;
|
backing.release_page(offset as u64, phys, dirty)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -284,7 +284,7 @@ impl<TA: TableAllocator> Inner<TA> {
|
|||||||
let offset = ((pfn - origin_pfn) * L3_PAGE_SIZE) as u64;
|
let offset = ((pfn - origin_pfn) * L3_PAGE_SIZE) as u64;
|
||||||
|
|
||||||
let virt = pfn * L3_PAGE_SIZE;
|
let virt = pfn * L3_PAGE_SIZE;
|
||||||
let (phys, dirty) = match self.table.unmap_page(virt) {
|
let (phys, dirty) = match unsafe { self.table.unmap_page(virt) } {
|
||||||
Ok(res) => res,
|
Ok(res) => res,
|
||||||
Err(Error::DoesNotExist) => continue,
|
Err(Error::DoesNotExist) => continue,
|
||||||
Err(error) => return Err(error),
|
Err(error) => return Err(error),
|
||||||
@@ -319,7 +319,7 @@ impl<TA: TableAllocator> Inner<TA> {
|
|||||||
})?;
|
})?;
|
||||||
|
|
||||||
// Drop the tables
|
// Drop the tables
|
||||||
self.table.clear();
|
unsafe { self.table.clear() };
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -546,7 +546,7 @@ impl<TA: TableAllocator> ProcessAddressSpace<TA> {
|
|||||||
|
|
||||||
let mut lock = self.inner.lock();
|
let mut lock = self.inner.lock();
|
||||||
|
|
||||||
lock.unmap_range(address, size / L3_PAGE_SIZE)
|
unsafe { lock.unmap_range(address, size / L3_PAGE_SIZE) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the physical address of the translation table along with its ASID
|
/// Returns the physical address of the translation table along with its ASID
|
||||||
|
|||||||
@@ -1,11 +1,5 @@
|
|||||||
#![no_std]
|
#![no_std]
|
||||||
#![feature(
|
#![feature(linked_list_cursors, async_fn_traits, allocator_api)]
|
||||||
linked_list_cursors,
|
|
||||||
async_fn_traits,
|
|
||||||
allocator_api,
|
|
||||||
const_trait_impl,
|
|
||||||
str_from_utf16_endian
|
|
||||||
)]
|
|
||||||
#![allow(clippy::new_without_default)]
|
#![allow(clippy::new_without_default)]
|
||||||
|
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
|
|||||||
@@ -4,13 +4,8 @@
|
|||||||
#![feature(
|
#![feature(
|
||||||
option_get_or_try_insert_with,
|
option_get_or_try_insert_with,
|
||||||
async_fn_traits,
|
async_fn_traits,
|
||||||
new_range_api,
|
|
||||||
associated_type_defaults,
|
associated_type_defaults,
|
||||||
step_trait,
|
|
||||||
const_trait_impl,
|
|
||||||
slice_ptr_get,
|
|
||||||
never_type,
|
never_type,
|
||||||
allocator_api,
|
|
||||||
trait_alias,
|
trait_alias,
|
||||||
arbitrary_self_types,
|
arbitrary_self_types,
|
||||||
slice_split_once,
|
slice_split_once,
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "test_mod"
|
name = "test_mod"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2024"
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
crate-type = ["dylib"]
|
crate-type = ["dylib"]
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ static mut DTB_PHYSICAL_ADDRESS: PhysicalAddress = PhysicalAddress::ZERO;
|
|||||||
unsafe extern "C" fn relocate_kernel(image_base: i64, rela_start: usize, rela_end: usize) {
|
unsafe extern "C" fn relocate_kernel(image_base: i64, rela_start: usize, rela_end: usize) {
|
||||||
let rela_count = (rela_end - rela_start) / size_of::<Elf64_Rela>();
|
let rela_count = (rela_end - rela_start) / size_of::<Elf64_Rela>();
|
||||||
let rela_ptr: *const Elf64_Rela = core::ptr::with_exposed_provenance(rela_start);
|
let rela_ptr: *const Elf64_Rela = core::ptr::with_exposed_provenance(rela_start);
|
||||||
let rela_table = core::slice::from_raw_parts(rela_ptr, rela_count);
|
let rela_table = unsafe { core::slice::from_raw_parts(rela_ptr, rela_count) };
|
||||||
|
|
||||||
for rela in rela_table {
|
for rela in rela_table {
|
||||||
let slot: *mut i64 =
|
let slot: *mut i64 =
|
||||||
@@ -56,7 +56,7 @@ unsafe extern "C" fn relocate_kernel(image_base: i64, rela_start: usize, rela_en
|
|||||||
_ => ArchitectureImpl::halt(),
|
_ => ArchitectureImpl::halt(),
|
||||||
};
|
};
|
||||||
|
|
||||||
slot.write_volatile(value);
|
unsafe { slot.write_volatile(value) };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,12 +82,14 @@ unsafe fn leave_el2(pc: usize, sp: usize, x0: usize) -> ! {
|
|||||||
|
|
||||||
ELR_EL2.set(pc as u64);
|
ELR_EL2.set(pc as u64);
|
||||||
SP_EL1.set(sp as u64);
|
SP_EL1.set(sp as u64);
|
||||||
core::arch::asm!("eret", in("x0") x0, options(noreturn));
|
unsafe { core::arch::asm!("eret", in("x0") x0, options(noreturn)) };
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn long_jump(pc: usize, sp: usize) -> ! {
|
unsafe fn long_jump(pc: usize, sp: usize) -> ! {
|
||||||
core::arch::asm!("mov sp, {sp}; br {pc}", sp = in(reg) sp, pc = in(reg) pc, options(noreturn));
|
unsafe {
|
||||||
|
core::arch::asm!("mov sp, {sp}; br {pc}", sp = in(reg) sp, pc = in(reg) pc, options(noreturn))
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe extern "C" fn bsp_entry_upper() -> ! {
|
unsafe extern "C" fn bsp_entry_upper() -> ! {
|
||||||
@@ -100,12 +102,12 @@ unsafe extern "C" fn bsp_entry_upper() -> ! {
|
|||||||
atomic::fence(Ordering::SeqCst);
|
atomic::fence(Ordering::SeqCst);
|
||||||
let rela_start = (&raw const __rela_start).addr();
|
let rela_start = (&raw const __rela_start).addr();
|
||||||
let rela_end = (&raw const __rela_end).addr();
|
let rela_end = (&raw const __rela_end).addr();
|
||||||
let image_base = (KERNEL_VIRT_OFFSET as u64 + KERNEL_LOAD_BASE) as i64;
|
let image_base = unsafe { (KERNEL_VIRT_OFFSET as u64 + KERNEL_LOAD_BASE) as i64 };
|
||||||
relocate_kernel(image_base, rela_start, rela_end);
|
unsafe { relocate_kernel(image_base, rela_start, rela_end) };
|
||||||
atomic::fence(Ordering::SeqCst);
|
atomic::fence(Ordering::SeqCst);
|
||||||
|
|
||||||
// Setup memory management (using DTB from lower half)
|
// Setup memory management (using DTB from lower half)
|
||||||
if let Err(error) = PLATFORM.init_memory_management(DTB_PHYSICAL_ADDRESS) {
|
if let Err(error) = unsafe { PLATFORM.init_memory_management(DTB_PHYSICAL_ADDRESS) } {
|
||||||
let _ = error;
|
let _ = error;
|
||||||
ArchitectureImpl::halt();
|
ArchitectureImpl::halt();
|
||||||
}
|
}
|
||||||
@@ -126,7 +128,7 @@ unsafe extern "C" fn bsp_entry_upper() -> ! {
|
|||||||
runtime::init_task_queue();
|
runtime::init_task_queue();
|
||||||
|
|
||||||
// Initialize the BSP CPU + the devices
|
// Initialize the BSP CPU + the devices
|
||||||
if PLATFORM.init_platform(true).is_err() {
|
if unsafe { PLATFORM.init_platform(true).is_err() } {
|
||||||
ArchitectureImpl::halt();
|
ArchitectureImpl::halt();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -159,15 +161,17 @@ unsafe extern "C" fn ap_entry_upper() -> ! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsafe extern "C" fn bsp_entry_el1() -> ! {
|
unsafe extern "C" fn bsp_entry_el1() -> ! {
|
||||||
setup_cpu_common();
|
unsafe {
|
||||||
mem::init_lower(true);
|
setup_cpu_common();
|
||||||
let pc = (bsp_entry_upper as *const ()).addr() + KERNEL_VIRT_OFFSET;
|
mem::init_lower(true);
|
||||||
let sp = BSP_STACK.top_addr() + KERNEL_VIRT_OFFSET;
|
let pc = (bsp_entry_upper as *const ()).addr() + KERNEL_VIRT_OFFSET;
|
||||||
long_jump(pc, sp)
|
let sp = BSP_STACK.top_addr() + KERNEL_VIRT_OFFSET;
|
||||||
|
long_jump(pc, sp)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe extern "C" fn bsp_entry_el2() -> ! {
|
unsafe extern "C" fn bsp_entry_el2() -> ! {
|
||||||
leave_el2((bsp_entry_el1 as *const ()).addr(), BSP_STACK.top_addr(), 0)
|
unsafe { leave_el2((bsp_entry_el1 as *const ()).addr(), BSP_STACK.top_addr(), 0) }
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe extern "C" fn ap_entry_el1(sp: usize) -> ! {
|
unsafe extern "C" fn ap_entry_el1(sp: usize) -> ! {
|
||||||
@@ -175,18 +179,18 @@ unsafe extern "C" fn ap_entry_el1(sp: usize) -> ! {
|
|||||||
const AP_STACK_PAGES: usize = 8;
|
const AP_STACK_PAGES: usize = 8;
|
||||||
|
|
||||||
setup_cpu_common();
|
setup_cpu_common();
|
||||||
mem::init_lower(false);
|
unsafe { mem::init_lower(false) };
|
||||||
|
|
||||||
let stack_pages = phys::alloc_pages_contiguous(AP_STACK_PAGES).unwrap();
|
let stack_pages = phys::alloc_pages_contiguous(AP_STACK_PAGES).unwrap();
|
||||||
let stack_base = stack_pages.virtualize();
|
let stack_base = stack_pages.virtualize();
|
||||||
let sp = stack_base + L3::SIZE * AP_STACK_PAGES;
|
let sp = stack_base + L3::SIZE * AP_STACK_PAGES;
|
||||||
|
|
||||||
let pc = (ap_entry_upper as *const ()).addr() + KERNEL_VIRT_OFFSET;
|
let pc = (ap_entry_upper as *const ()).addr() + KERNEL_VIRT_OFFSET;
|
||||||
long_jump(pc, sp)
|
unsafe { long_jump(pc, sp) }
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe extern "C" fn ap_entry_el2(sp: usize) -> ! {
|
unsafe extern "C" fn ap_entry_el2(sp: usize) -> ! {
|
||||||
leave_el2((ap_entry_el1 as *const ()).addr(), sp, sp)
|
unsafe { leave_el2((ap_entry_el1 as *const ()).addr(), sp, sp) }
|
||||||
}
|
}
|
||||||
|
|
||||||
global_asm!(
|
global_asm!(
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ unsafe fn perform_ptw<F: Fn(u32, EntryType)>(virt: usize, handler: F) {
|
|||||||
|
|
||||||
// Strip ASID
|
// Strip ASID
|
||||||
let ttbr_phys = PhysicalAddress::from_u64(ttbr_phys & !(0xFFFF << 48));
|
let ttbr_phys = PhysicalAddress::from_u64(ttbr_phys & !(0xFFFF << 48));
|
||||||
let Some(l1) = PageTable::<L1>::from_physical(ttbr_phys) else {
|
let Some(l1) = (unsafe { PageTable::<L1>::from_physical(ttbr_phys) }) else {
|
||||||
handler(0, EntryType::Invalid);
|
handler(0, EntryType::Invalid);
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
@@ -60,14 +60,14 @@ unsafe fn perform_ptw<F: Fn(u32, EntryType)>(virt: usize, handler: F) {
|
|||||||
let l2 = l1.walk(l1i);
|
let l2 = l1.walk(l1i);
|
||||||
handler(1, l2);
|
handler(1, l2);
|
||||||
let l2 = match l2 {
|
let l2 = match l2 {
|
||||||
EntryType::Table(_, l2) => PageTable::<L2>::from_physical(l2).unwrap(),
|
EntryType::Table(_, l2) => unsafe { PageTable::<L2>::from_physical(l2).unwrap() },
|
||||||
_ => return,
|
_ => return,
|
||||||
};
|
};
|
||||||
|
|
||||||
let l3 = l2.walk(l2i);
|
let l3 = l2.walk(l2i);
|
||||||
handler(2, l3);
|
handler(2, l3);
|
||||||
let l3 = match l3 {
|
let l3 = match l3 {
|
||||||
EntryType::Table(_, l3) => PageTable::<L3>::from_physical(l3).unwrap(),
|
EntryType::Table(_, l3) => unsafe { PageTable::<L3>::from_physical(l3).unwrap() },
|
||||||
_ => return,
|
_ => return,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -164,7 +164,7 @@ impl LocalInterruptController for Gic {
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn init_ap(&self) -> Result<(), Error> {
|
unsafe fn init_ap(&self) -> Result<(), Error> {
|
||||||
self.gicc.init();
|
unsafe { self.gicc.init() };
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -223,30 +223,32 @@ impl Gic {
|
|||||||
gicc_base: PhysicalAddress,
|
gicc_base: PhysicalAddress,
|
||||||
) -> Result<Self, Error> {
|
) -> Result<Self, Error> {
|
||||||
log::debug!("Init GIC: gicd={:#x}, gicc={:#x}", gicd_base, gicc_base);
|
log::debug!("Init GIC: gicd={:#x}, gicc={:#x}", gicd_base, gicc_base);
|
||||||
let gicd_mmio = Arc::new(RawDeviceMemoryMapping::map(
|
unsafe {
|
||||||
gicd_base.into_u64(),
|
let gicd_mmio = Arc::new(RawDeviceMemoryMapping::map(
|
||||||
0x1000,
|
gicd_base.into_u64(),
|
||||||
Default::default(),
|
0x1000,
|
||||||
)?);
|
Default::default(),
|
||||||
let gicd_mmio_shared = DeviceMemoryIo::from_raw(gicd_mmio.clone())?;
|
)?);
|
||||||
let gicd_mmio_banked = DeviceMemoryIo::from_raw(gicd_mmio)?;
|
let gicd_mmio_shared = DeviceMemoryIo::from_raw(gicd_mmio.clone())?;
|
||||||
let gicc_mmio = DeviceMemoryIo::map(gicc_base, Default::default())?;
|
let gicd_mmio_banked = DeviceMemoryIo::from_raw(gicd_mmio)?;
|
||||||
|
let gicc_mmio = DeviceMemoryIo::map(gicc_base, Default::default())?;
|
||||||
|
|
||||||
let gicd = Gicd::new(gicd_mmio_shared, gicd_mmio_banked);
|
let gicd = Gicd::new(gicd_mmio_shared, gicd_mmio_banked);
|
||||||
let gicc = Gicc::new(gicc_mmio);
|
let gicc = Gicc::new(gicc_mmio);
|
||||||
|
|
||||||
gicd.init();
|
gicd.init();
|
||||||
gicc.init();
|
gicc.init();
|
||||||
|
|
||||||
// self.gicd.init(gicd);
|
// self.gicd.init(gicd);
|
||||||
// self.gicc.init(gicc);
|
// self.gicc.init(gicc);
|
||||||
let table = FixedInterruptTable::new(MAX_IRQ);
|
let table = FixedInterruptTable::new(MAX_IRQ);
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
gicd,
|
gicd,
|
||||||
gicc,
|
gicc,
|
||||||
table, // table: IrqSafeRwLock::new(FixedInterruptTable::new()),
|
table, // table: IrqSafeRwLock::new(FixedInterruptTable::new()),
|
||||||
})
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ impl Platform for AArch64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let dt = self.dt.get();
|
let dt = self.dt.get();
|
||||||
if let Err(error) = smp::start_ap_cores(dt) {
|
if let Err(error) = unsafe { smp::start_ap_cores(dt) } {
|
||||||
log::error!("Could not initialize AP CPUs: {:?}", error);
|
log::error!("Could not initialize AP CPUs: {:?}", error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -93,20 +93,22 @@ impl Platform for AArch64 {
|
|||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
unsafe fn reset(&self) -> ! {
|
unsafe fn reset(&self) -> ! {
|
||||||
if let Some(reset) = self.reset.try_get() {
|
unsafe {
|
||||||
reset.reset()
|
if let Some(reset) = self.reset.try_get() {
|
||||||
} else {
|
reset.reset()
|
||||||
let psci = self.psci.get();
|
} else {
|
||||||
psci.reset()
|
let psci = self.psci.get();
|
||||||
|
psci.reset()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn power_off(&self) -> Result<!, Error> {
|
unsafe fn power_off(&self) -> Result<!, Error> {
|
||||||
Self::halt_aps()?;
|
unsafe { Self::halt_aps() }?;
|
||||||
|
|
||||||
if let Some(psci) = self.psci.try_get() {
|
if let Some(psci) = self.psci.try_get() {
|
||||||
log::info!("Powering off");
|
log::info!("Powering off");
|
||||||
psci.power_off()
|
unsafe { psci.power_off() }
|
||||||
} else {
|
} else {
|
||||||
log::warn!("No power off method, halting");
|
log::warn!("No power off method, halting");
|
||||||
ArchitectureImpl::halt();
|
ArchitectureImpl::halt();
|
||||||
@@ -160,8 +162,9 @@ impl AArch64 {
|
|||||||
dtb_address: PhysicalAddress,
|
dtb_address: PhysicalAddress,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let dtb: PhysicalRef<[u8]> =
|
let dtb: PhysicalRef<[u8]> =
|
||||||
PhysicalRef::map_slice(dtb_address, DeviceTree::MIN_HEADER_SIZE);
|
unsafe { PhysicalRef::map_slice(dtb_address, DeviceTree::MIN_HEADER_SIZE) };
|
||||||
let dtb_size = DeviceTree::read_totalsize(&dtb[..]).map_err(|_| Error::InvalidArgument)?;
|
let dtb_size =
|
||||||
|
unsafe { DeviceTree::read_totalsize(&dtb[..]).map_err(|_| Error::InvalidArgument) }?;
|
||||||
|
|
||||||
reserve_region(
|
reserve_region(
|
||||||
"dtb",
|
"dtb",
|
||||||
@@ -171,8 +174,8 @@ impl AArch64 {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
let dtb: PhysicalRef<[u8]> = PhysicalRef::map_slice(dtb_address, dtb_size);
|
let dtb: PhysicalRef<[u8]> = unsafe { PhysicalRef::map_slice(dtb_address, dtb_size) };
|
||||||
let dt = DeviceTree::from_raw(dtb.as_ptr().addr())?;
|
let dt = unsafe { DeviceTree::from_raw(dtb.as_ptr().addr()) }?;
|
||||||
|
|
||||||
// Setup initrd from the dt
|
// Setup initrd from the dt
|
||||||
let initrd = dt.chosen_initrd();
|
let initrd = dt.chosen_initrd();
|
||||||
@@ -194,7 +197,7 @@ impl AArch64 {
|
|||||||
let dt = self.dt.init(dt);
|
let dt = self.dt.init(dt);
|
||||||
|
|
||||||
// Initialize the physical memory
|
// Initialize the physical memory
|
||||||
phys::init_from_iter(dt.memory_regions())?;
|
unsafe { phys::init_from_iter(dt.memory_regions()) }?;
|
||||||
|
|
||||||
// Setup initrd
|
// Setup initrd
|
||||||
if let Some((initrd_start, initrd_end)) = initrd {
|
if let Some((initrd_start, initrd_end)) = initrd {
|
||||||
@@ -254,7 +257,7 @@ impl AArch64 {
|
|||||||
let per_cpu = PerCpuData {
|
let per_cpu = PerCpuData {
|
||||||
gic: OneTimeInit::new(),
|
gic: OneTimeInit::new(),
|
||||||
};
|
};
|
||||||
Cpu::init_local(None, per_cpu);
|
unsafe { Cpu::init_local(None, per_cpu) };
|
||||||
|
|
||||||
if is_bsp {
|
if is_bsp {
|
||||||
atomic::compiler_fence(Ordering::SeqCst);
|
atomic::compiler_fence(Ordering::SeqCst);
|
||||||
@@ -266,7 +269,7 @@ impl AArch64 {
|
|||||||
config::parse_boot_arguments(bootargs);
|
config::parse_boot_arguments(bootargs);
|
||||||
|
|
||||||
// Will register drivers
|
// Will register drivers
|
||||||
call_init_array();
|
unsafe { call_init_array() };
|
||||||
|
|
||||||
// Create device tree sysfs nodes
|
// Create device tree sysfs nodes
|
||||||
device_tree::util::create_sysfs_nodes(dt);
|
device_tree::util::create_sysfs_nodes(dt);
|
||||||
@@ -280,7 +283,7 @@ impl AArch64 {
|
|||||||
|
|
||||||
unflatten_device_tree(dt);
|
unflatten_device_tree(dt);
|
||||||
|
|
||||||
Self::setup_chosen_stdout(dt).ok();
|
unsafe { Self::setup_chosen_stdout(dt).ok() };
|
||||||
|
|
||||||
if let Some(machine) = machine_name {
|
if let Some(machine) = machine_name {
|
||||||
log::info!("Running on {machine:?}");
|
log::info!("Running on {machine:?}");
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ impl CpuEnableMethod {
|
|||||||
Error::DoesNotExist
|
Error::DoesNotExist
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
psci.start_cpu(id, ip, sp)
|
unsafe { psci.start_cpu(id, ip, sp) }
|
||||||
}
|
}
|
||||||
&Self::SpinTable(cpu_release_addr) => {
|
&Self::SpinTable(cpu_release_addr) => {
|
||||||
// Store a stack for the CPU
|
// Store a stack for the CPU
|
||||||
@@ -91,7 +91,7 @@ impl CpuEnableMethod {
|
|||||||
// Make the CPU jump to __aarch64_ap_spin_table_entry first
|
// Make the CPU jump to __aarch64_ap_spin_table_entry first
|
||||||
let release_ptr =
|
let release_ptr =
|
||||||
ptr::with_exposed_provenance_mut::<u64>(cpu_release_addr.virtualize());
|
ptr::with_exposed_provenance_mut::<u64>(cpu_release_addr.virtualize());
|
||||||
let release_atomic = AtomicU64::from_ptr(release_ptr);
|
let release_atomic = unsafe { AtomicU64::from_ptr(release_ptr) };
|
||||||
let spin_entry_addr =
|
let spin_entry_addr =
|
||||||
(__aarch64_ap_spin_table_entry as *const ()).addr() - KERNEL_VIRT_OFFSET;
|
(__aarch64_ap_spin_table_entry as *const ()).addr() - KERNEL_VIRT_OFFSET;
|
||||||
|
|
||||||
@@ -146,7 +146,7 @@ pub unsafe fn start_ap_cores(dt: &DeviceTree) -> Result<(), Error> {
|
|||||||
barrier::dsb(barrier::ISH);
|
barrier::dsb(barrier::ISH);
|
||||||
barrier::isb(barrier::SY);
|
barrier::isb(barrier::SY);
|
||||||
|
|
||||||
if let Err(error) = cpu.enable_method.start_cpu(cpu.id as usize, ip, sp) {
|
if let Err(error) = unsafe { cpu.enable_method.start_cpu(cpu.id as usize, ip, sp) } {
|
||||||
log::error!("Couldn't start cpu{} up: {:?}", cpu.id, error);
|
log::error!("Couldn't start cpu{} up: {:?}", cpu.id, error);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ pub trait Platform {
|
|||||||
/// The caller must ensure it is actually safe to reset, i.e. no critical processes will be
|
/// The caller must ensure it is actually safe to reset, i.e. no critical processes will be
|
||||||
/// aborted and no data will be lost.
|
/// aborted and no data will be lost.
|
||||||
unsafe fn reset(&self) -> ! {
|
unsafe fn reset(&self) -> ! {
|
||||||
ArchitectureImpl::set_interrupt_mask(true);
|
unsafe { ArchitectureImpl::set_interrupt_mask(true) };
|
||||||
loop {
|
loop {
|
||||||
ArchitectureImpl::wait_for_interrupt();
|
ArchitectureImpl::wait_for_interrupt();
|
||||||
}
|
}
|
||||||
@@ -59,7 +59,7 @@ pub trait Platform {
|
|||||||
/// The caller must ensure it is actually safe to power down, i.e. no critical processes will be
|
/// The caller must ensure it is actually safe to power down, i.e. no critical processes will be
|
||||||
/// aborted and no data will be lost.
|
/// aborted and no data will be lost.
|
||||||
unsafe fn power_off(&self) -> Result<!, Error> {
|
unsafe fn power_off(&self) -> Result<!, Error> {
|
||||||
ArchitectureImpl::set_interrupt_mask(true);
|
unsafe { ArchitectureImpl::set_interrupt_mask(true) };
|
||||||
loop {
|
loop {
|
||||||
ArchitectureImpl::wait_for_interrupt();
|
ArchitectureImpl::wait_for_interrupt();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ impl<const N: usize> BootStack<N> {
|
|||||||
unsafe extern "C" fn relocate_kernel(image_base: i64, rela_start: usize, rela_end: usize) {
|
unsafe extern "C" fn relocate_kernel(image_base: i64, rela_start: usize, rela_end: usize) {
|
||||||
let rela_count = (rela_end - rela_start) / size_of::<Elf64_Rela>();
|
let rela_count = (rela_end - rela_start) / size_of::<Elf64_Rela>();
|
||||||
let rela_ptr: *const Elf64_Rela = core::ptr::with_exposed_provenance(rela_start);
|
let rela_ptr: *const Elf64_Rela = core::ptr::with_exposed_provenance(rela_start);
|
||||||
let rela_table = core::slice::from_raw_parts(rela_ptr, rela_count);
|
let rela_table = unsafe { core::slice::from_raw_parts(rela_ptr, rela_count) };
|
||||||
|
|
||||||
for rela in rela_table {
|
for rela in rela_table {
|
||||||
let slot: *mut i64 =
|
let slot: *mut i64 =
|
||||||
@@ -53,12 +53,20 @@ unsafe extern "C" fn relocate_kernel(image_base: i64, rela_start: usize, rela_en
|
|||||||
_ => ArchitectureImpl::halt(),
|
_ => ArchitectureImpl::halt(),
|
||||||
};
|
};
|
||||||
|
|
||||||
slot.write_volatile(value);
|
unsafe { slot.write_volatile(value) };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn long_jump(pc: usize, sp: usize, a0: usize) -> ! {
|
unsafe fn long_jump(pc: usize, sp: usize, a0: usize) -> ! {
|
||||||
core::arch::asm!("mv sp, {sp}; jr {pc}", in("a0") a0, sp = in(reg) sp, pc = in(reg) pc, options(noreturn))
|
unsafe {
|
||||||
|
core::arch::asm!(
|
||||||
|
"mv sp, {sp}; jr {pc}",
|
||||||
|
in("a0") a0,
|
||||||
|
sp = in(reg) sp,
|
||||||
|
pc = in(reg) pc,
|
||||||
|
options(noreturn)
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe extern "C" fn bsp_entry_upper() -> ! {
|
unsafe extern "C" fn bsp_entry_upper() -> ! {
|
||||||
@@ -71,8 +79,8 @@ unsafe extern "C" fn bsp_entry_upper() -> ! {
|
|||||||
atomic::fence(Ordering::SeqCst);
|
atomic::fence(Ordering::SeqCst);
|
||||||
let rela_start = (&raw const __rela_start).addr();
|
let rela_start = (&raw const __rela_start).addr();
|
||||||
let rela_end = (&raw const __rela_end).addr();
|
let rela_end = (&raw const __rela_end).addr();
|
||||||
let image_base = (KERNEL_VIRT_OFFSET as u64 + KERNEL_LOAD_BASE) as i64;
|
let image_base = unsafe { (KERNEL_VIRT_OFFSET as u64 + KERNEL_LOAD_BASE) as i64 };
|
||||||
relocate_kernel(image_base, rela_start, rela_end);
|
unsafe { relocate_kernel(image_base, rela_start, rela_end) };
|
||||||
atomic::fence(Ordering::SeqCst);
|
atomic::fence(Ordering::SeqCst);
|
||||||
|
|
||||||
debug::init_logger();
|
debug::init_logger();
|
||||||
@@ -80,13 +88,13 @@ unsafe extern "C" fn bsp_entry_upper() -> ! {
|
|||||||
|
|
||||||
log::info!("Starting riscv64 upper half");
|
log::info!("Starting riscv64 upper half");
|
||||||
|
|
||||||
if DTB_ADDRESS.is_zero() {
|
if unsafe { DTB_ADDRESS.is_zero() } {
|
||||||
log::error!("No device tree provided");
|
log::error!("No device tree provided");
|
||||||
// No DTB provided
|
// No DTB provided
|
||||||
ArchitectureImpl::halt();
|
ArchitectureImpl::halt();
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Err(error) = PLATFORM.init_memory_management(DTB_ADDRESS) {
|
if let Err(error) = unsafe { PLATFORM.init_memory_management(DTB_ADDRESS) } {
|
||||||
log::error!("Failed to initialize memory management: {error:?}");
|
log::error!("Failed to initialize memory management: {error:?}");
|
||||||
ArchitectureImpl::halt();
|
ArchitectureImpl::halt();
|
||||||
}
|
}
|
||||||
@@ -96,7 +104,7 @@ unsafe extern "C" fn bsp_entry_upper() -> ! {
|
|||||||
|
|
||||||
runtime::init_task_queue();
|
runtime::init_task_queue();
|
||||||
|
|
||||||
if let Err(error) = PLATFORM.init_platform(BOOT_HART_ID as u32, 0, true) {
|
if let Err(error) = unsafe { PLATFORM.init_platform(BOOT_HART_ID as u32, 0, true) } {
|
||||||
log::error!("Failed to initialize the platform: {error:?}");
|
log::error!("Failed to initialize the platform: {error:?}");
|
||||||
ArchitectureImpl::halt();
|
ArchitectureImpl::halt();
|
||||||
}
|
}
|
||||||
@@ -105,20 +113,22 @@ unsafe extern "C" fn bsp_entry_upper() -> ! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsafe extern "C" fn bsp_smode_entry() -> ! {
|
unsafe extern "C" fn bsp_smode_entry() -> ! {
|
||||||
mem::enable_mmu();
|
unsafe {
|
||||||
let pc = (bsp_entry_upper as *const ()).addr() + KERNEL_VIRT_OFFSET;
|
mem::enable_mmu();
|
||||||
let sp = (&raw const BOOT_STACK).addr() + BOOT_STACK_SIZE + KERNEL_VIRT_OFFSET;
|
let pc = (bsp_entry_upper as *const ()).addr() + KERNEL_VIRT_OFFSET;
|
||||||
long_jump(pc, sp, 0)
|
let sp = (&raw const BOOT_STACK).addr() + BOOT_STACK_SIZE + KERNEL_VIRT_OFFSET;
|
||||||
|
long_jump(pc, sp, 0)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe extern "C" fn ap_smode_upper(context: PhysicalAddress) -> ! {
|
unsafe extern "C" fn ap_smode_upper(context: PhysicalAddress) -> ! {
|
||||||
let hart_id = {
|
let hart_id = {
|
||||||
let context = PageBox::<SecondaryContext>::from_physical_raw(context);
|
let context = unsafe { PageBox::<SecondaryContext>::from_physical_raw(context) };
|
||||||
context.hart_id
|
context.hart_id
|
||||||
};
|
};
|
||||||
let queue_index = CPU_COUNT.fetch_add(1, Ordering::Acquire);
|
let queue_index = CPU_COUNT.fetch_add(1, Ordering::Acquire);
|
||||||
|
|
||||||
if let Err(error) = PLATFORM.init_platform(hart_id as u32, queue_index, false) {
|
if let Err(error) = unsafe { PLATFORM.init_platform(hart_id as u32, queue_index, false) } {
|
||||||
log::error!("Secondary hart init error: {error:?}");
|
log::error!("Secondary hart init error: {error:?}");
|
||||||
ArchitectureImpl::halt();
|
ArchitectureImpl::halt();
|
||||||
}
|
}
|
||||||
@@ -128,11 +138,13 @@ unsafe extern "C" fn ap_smode_upper(context: PhysicalAddress) -> ! {
|
|||||||
|
|
||||||
unsafe extern "C" fn ap_smode_entry(context: PhysicalAddress, sp: PhysicalAddress) -> ! {
|
unsafe extern "C" fn ap_smode_entry(context: PhysicalAddress, sp: PhysicalAddress) -> ! {
|
||||||
compiler_fence(Ordering::SeqCst);
|
compiler_fence(Ordering::SeqCst);
|
||||||
mem::enable_mmu();
|
unsafe {
|
||||||
compiler_fence(Ordering::SeqCst);
|
mem::enable_mmu();
|
||||||
let pc = (ap_smode_upper as *const ()).addr() + KERNEL_VIRT_OFFSET;
|
compiler_fence(Ordering::SeqCst);
|
||||||
let sp = sp.virtualize();
|
let pc = (ap_smode_upper as *const ()).addr() + KERNEL_VIRT_OFFSET;
|
||||||
long_jump(pc, sp, context.into_usize())
|
let sp = sp.virtualize();
|
||||||
|
long_jump(pc, sp, context.into_usize())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
global_asm!(
|
global_asm!(
|
||||||
|
|||||||
@@ -186,7 +186,7 @@ unsafe fn smode_exception_handler(frame: &mut TrapFrame) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsafe extern "C" fn smode_interrupt_handler(frame: *mut TrapFrame) {
|
unsafe extern "C" fn smode_interrupt_handler(frame: *mut TrapFrame) {
|
||||||
let frame = &mut *frame;
|
let frame = unsafe { &mut *frame };
|
||||||
let smode = frame.sstatus & (1 << 8) != 0;
|
let smode = frame.sstatus & (1 << 8) != 0;
|
||||||
|
|
||||||
match frame.scause & !(1 << 63) {
|
match frame.scause & !(1 << 63) {
|
||||||
@@ -204,24 +204,26 @@ unsafe extern "C" fn smode_interrupt_handler(frame: *mut TrapFrame) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !smode && let Some(thread) = Thread::get_current() {
|
if !smode && let Some(thread) = Thread::get_current() {
|
||||||
thread.handle_pending_signals(frame);
|
unsafe { thread.handle_pending_signals(frame) };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe extern "C" fn smode_general_trap_handler(frame: *mut TrapFrame) {
|
unsafe extern "C" fn smode_general_trap_handler(frame: *mut TrapFrame) {
|
||||||
let frame = &mut *frame;
|
let frame = unsafe { &mut *frame };
|
||||||
|
|
||||||
let interrupt = frame.scause & (1 << 63) != 0;
|
let interrupt = frame.scause & (1 << 63) != 0;
|
||||||
let smode = frame.sstatus & (1 << 8) != 0;
|
let smode = frame.sstatus & (1 << 8) != 0;
|
||||||
|
|
||||||
match (interrupt, smode) {
|
unsafe {
|
||||||
(true, _) => smode_interrupt_handler(frame),
|
match (interrupt, smode) {
|
||||||
(false, true) => smode_exception_handler(frame),
|
(true, _) => smode_interrupt_handler(frame),
|
||||||
(false, false) => umode_exception_handler(frame),
|
(false, true) => smode_exception_handler(frame),
|
||||||
|
(false, false) => umode_exception_handler(frame),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !smode && let Some(thread) = Thread::get_current() {
|
if !smode && let Some(thread) = Thread::get_current() {
|
||||||
thread.handle_pending_signals(frame);
|
unsafe { thread.handle_pending_signals(frame) };
|
||||||
}
|
}
|
||||||
mem::tlb_flush_full();
|
mem::tlb_flush_full();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,8 +77,9 @@ impl Riscv64 {
|
|||||||
&'static self,
|
&'static self,
|
||||||
dtb_address: PhysicalAddress,
|
dtb_address: PhysicalAddress,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let dtb = PhysicalRef::<u8>::map_slice(dtb_address, DeviceTree::MIN_HEADER_SIZE);
|
let dtb = unsafe { PhysicalRef::<u8>::map_slice(dtb_address, DeviceTree::MIN_HEADER_SIZE) };
|
||||||
let dtb_size = DeviceTree::read_totalsize(&dtb[..]).map_err(|_| Error::InvalidArgument)?;
|
let dtb_size =
|
||||||
|
unsafe { DeviceTree::read_totalsize(&dtb[..]).map_err(|_| Error::InvalidArgument) }?;
|
||||||
|
|
||||||
// // Unmap the lower half
|
// // Unmap the lower half
|
||||||
// mem::setup_fixed_tables();
|
// mem::setup_fixed_tables();
|
||||||
@@ -93,8 +94,8 @@ impl Riscv64 {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
let dtb = PhysicalRef::<u8>::map_slice(dtb_address, dtb_size);
|
let dtb = unsafe { PhysicalRef::<u8>::map_slice(dtb_address, dtb_size) };
|
||||||
let dt = DeviceTree::from_raw(dtb.as_ptr().addr())?;
|
let dt = unsafe { DeviceTree::from_raw(dtb.as_ptr().addr()) }?;
|
||||||
|
|
||||||
// Reserve memory regions specified in the DTB
|
// Reserve memory regions specified in the DTB
|
||||||
log::info!("Reserved memory:");
|
log::info!("Reserved memory:");
|
||||||
@@ -122,7 +123,7 @@ impl Riscv64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Initialize the physical memory
|
// Initialize the physical memory
|
||||||
phys::init_from_iter(dt.memory_regions())?;
|
unsafe { phys::init_from_iter(dt.memory_regions()) }?;
|
||||||
|
|
||||||
self.dt.init(dt);
|
self.dt.init(dt);
|
||||||
|
|
||||||
@@ -160,14 +161,14 @@ impl Riscv64 {
|
|||||||
bootstrap: is_bsp,
|
bootstrap: is_bsp,
|
||||||
queue_index,
|
queue_index,
|
||||||
};
|
};
|
||||||
Cpu::init_local(Some(hart_id), per_cpu);
|
unsafe { Cpu::init_local(Some(hart_id), per_cpu) };
|
||||||
|
|
||||||
assert_eq!(Cpu::local().id(), hart_id);
|
assert_eq!(Cpu::local().id(), hart_id);
|
||||||
|
|
||||||
exception::init_smode_exceptions();
|
exception::init_smode_exceptions();
|
||||||
|
|
||||||
if is_bsp {
|
if is_bsp {
|
||||||
call_init_array();
|
unsafe { call_init_array() };
|
||||||
|
|
||||||
unsafe extern "C" {
|
unsafe extern "C" {
|
||||||
static __kernel_start: u8;
|
static __kernel_start: u8;
|
||||||
@@ -196,7 +197,7 @@ impl Riscv64 {
|
|||||||
if let Err(error) = Self::setup_clock_timebase(dt) {
|
if let Err(error) = Self::setup_clock_timebase(dt) {
|
||||||
log::error!("Could not setup clock timebase from device tree: {error:?}");
|
log::error!("Could not setup clock timebase from device tree: {error:?}");
|
||||||
}
|
}
|
||||||
if let Err(error) = Self::setup_chosen_stdout(dt) {
|
if let Err(error) = unsafe { Self::setup_chosen_stdout(dt) } {
|
||||||
log::error!("chosen-stdout setup error: {error:?}");
|
log::error!("chosen-stdout setup error: {error:?}");
|
||||||
} else {
|
} else {
|
||||||
libk::debug::disable_early_sinks();
|
libk::debug::disable_early_sinks();
|
||||||
|
|||||||
@@ -347,7 +347,8 @@ impl LocalApic {
|
|||||||
///
|
///
|
||||||
/// Only meant to be called once per processor during their init.
|
/// Only meant to be called once per processor during their init.
|
||||||
pub unsafe fn new() -> Self {
|
pub unsafe fn new() -> Self {
|
||||||
let regs = DeviceMemoryIo::<Regs>::map(Self::base(), Default::default()).unwrap();
|
let regs =
|
||||||
|
unsafe { DeviceMemoryIo::<Regs>::map(Self::base(), Default::default()).unwrap() };
|
||||||
|
|
||||||
let id = regs.Id.read(Id::ApicId);
|
let id = regs.Id.read(Id::ApicId);
|
||||||
|
|
||||||
|
|||||||
@@ -65,16 +65,18 @@ unsafe extern "C" fn irq_handler(vector: usize, frame: *mut IrqFrame) {
|
|||||||
unreachable!("Got a weird IRQ with vector {}", vector);
|
unreachable!("Got a weird IRQ with vector {}", vector);
|
||||||
}
|
}
|
||||||
|
|
||||||
let cpu = Cpu::local();
|
unsafe {
|
||||||
let frame = &mut *frame;
|
let cpu = Cpu::local();
|
||||||
|
let frame = &mut *frame;
|
||||||
|
|
||||||
if let Ok(intc) = external_interrupt_controller() {
|
if let Ok(intc) = external_interrupt_controller() {
|
||||||
intc.handle_specific_irq(vector);
|
intc.handle_specific_irq(vector);
|
||||||
}
|
}
|
||||||
cpu.local_apic().clear_interrupt();
|
cpu.local_apic().clear_interrupt();
|
||||||
|
|
||||||
if let Some(thread) = Thread::get_current() {
|
if let Some(thread) = Thread::get_current() {
|
||||||
thread.handle_pending_signals(frame);
|
thread.handle_pending_signals(frame);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,32 +85,36 @@ unsafe extern "C" fn msi_handler(vector: usize, frame: *mut IrqFrame) {
|
|||||||
unreachable!("Got a weird MSI with vector {}", vector);
|
unreachable!("Got a weird MSI with vector {}", vector);
|
||||||
}
|
}
|
||||||
|
|
||||||
let cpu = Cpu::local();
|
unsafe {
|
||||||
let frame = &mut *frame;
|
let cpu = Cpu::local();
|
||||||
|
let frame = &mut *frame;
|
||||||
|
|
||||||
cpu.local_apic().handle_msi(vector);
|
cpu.local_apic().handle_msi(vector);
|
||||||
cpu.local_apic().clear_interrupt();
|
cpu.local_apic().clear_interrupt();
|
||||||
|
|
||||||
if let Some(thread) = Thread::get_current() {
|
if let Some(thread) = Thread::get_current() {
|
||||||
thread.handle_pending_signals(frame);
|
thread.handle_pending_signals(frame);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe extern "C" fn local_timer_irq_handler(frame: *mut IrqFrame) {
|
unsafe extern "C" fn local_timer_irq_handler(frame: *mut IrqFrame) {
|
||||||
let frame = &mut *frame;
|
unsafe {
|
||||||
|
let frame = &mut *frame;
|
||||||
|
|
||||||
runtime::tick();
|
runtime::tick();
|
||||||
|
|
||||||
let cpu = Cpu::local();
|
let cpu = Cpu::local();
|
||||||
// Clear interrupt before switching, because otherwise we won't receive the next one
|
// Clear interrupt before switching, because otherwise we won't receive the next one
|
||||||
cpu.local_apic().clear_interrupt();
|
cpu.local_apic().clear_interrupt();
|
||||||
|
|
||||||
if let Some(queue) = cpu.try_get_scheduler() {
|
if let Some(queue) = cpu.try_get_scheduler() {
|
||||||
queue.yield_cpu();
|
queue.yield_cpu();
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(thread) = Thread::get_current() {
|
if let Some(thread) = Thread::get_current() {
|
||||||
thread.handle_pending_signals(frame);
|
thread.handle_pending_signals(frame);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -99,15 +99,17 @@ static YBOOT_DATA: LoadProtocolV1 = LoadProtocolV1 {
|
|||||||
};
|
};
|
||||||
|
|
||||||
unsafe fn init_dummy_cpu() {
|
unsafe fn init_dummy_cpu() {
|
||||||
static UNINIT_CPU_INNER: usize = 0;
|
unsafe {
|
||||||
static UNINIT_CPU_PTR: &usize = &UNINIT_CPU_INNER;
|
static UNINIT_CPU_INNER: usize = 0;
|
||||||
|
static UNINIT_CPU_PTR: &usize = &UNINIT_CPU_INNER;
|
||||||
|
|
||||||
// Point %gs to a dummy structure so that Cpu::get_local() works properly even before the CPU
|
// Point %gs to a dummy structure so that Cpu::get_local() works properly even before the CPU
|
||||||
// data structure is initialized
|
// data structure is initialized
|
||||||
MSR_IA32_KERNEL_GS_BASE.set(&UNINIT_CPU_PTR as *const _ as u64);
|
MSR_IA32_KERNEL_GS_BASE.set(&UNINIT_CPU_PTR as *const _ as u64);
|
||||||
core::arch::asm!("swapgs");
|
core::arch::asm!("swapgs");
|
||||||
MSR_IA32_KERNEL_GS_BASE.set(&UNINIT_CPU_PTR as *const _ as u64);
|
MSR_IA32_KERNEL_GS_BASE.set(&UNINIT_CPU_PTR as *const _ as u64);
|
||||||
core::arch::asm!("swapgs");
|
core::arch::asm!("swapgs");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Application processor entry point
|
/// Application processor entry point
|
||||||
|
|||||||
@@ -252,7 +252,7 @@ pub unsafe fn init_exceptions(cpu_index: usize) {
|
|||||||
static __x86_64_exception_vectors: [usize; 32];
|
static __x86_64_exception_vectors: [usize; 32];
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i, &entry) in __x86_64_exception_vectors.iter().enumerate() {
|
for (i, &entry) in unsafe { __x86_64_exception_vectors.iter().enumerate() } {
|
||||||
idt[i] = Entry::new(entry, 0x08, Entry::PRESENT | Entry::INT32);
|
idt[i] = Entry::new(entry, 0x08, Entry::PRESENT | Entry::INT32);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -265,7 +265,9 @@ pub unsafe fn init_exceptions(cpu_index: usize) {
|
|||||||
offset: idt.as_ptr().addr(),
|
offset: idt.as_ptr().addr(),
|
||||||
};
|
};
|
||||||
|
|
||||||
core::arch::asm!("wbinvd; lidt ({0})", in(reg) &idtr, options(att_syntax));
|
unsafe {
|
||||||
|
core::arch::asm!("wbinvd; lidt ({0})", in(reg) &idtr, options(att_syntax));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
global_asm!(
|
global_asm!(
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ impl Platform for X86_64 {
|
|||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
smp::start_ap_cores(&pinfo);
|
unsafe { smp::start_ap_cores(&pinfo) };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -165,15 +165,17 @@ impl X86_64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn init_physical_memory_from_yboot(data: &LoadProtocolV1) -> Result<(), Error> {
|
unsafe fn init_physical_memory_from_yboot(data: &LoadProtocolV1) -> Result<(), Error> {
|
||||||
let mmap = PhysicalRef::<AvailableMemoryRegion>::map_slice(
|
unsafe {
|
||||||
PhysicalAddress::from_u64(data.memory_map.address),
|
let mmap = PhysicalRef::<AvailableMemoryRegion>::map_slice(
|
||||||
data.memory_map.len as usize,
|
PhysicalAddress::from_u64(data.memory_map.address),
|
||||||
);
|
data.memory_map.len as usize,
|
||||||
|
);
|
||||||
|
|
||||||
phys::init_from_iter(mmap.as_ref().iter().map(|reg| PhysicalMemoryRegion {
|
phys::init_from_iter(mmap.as_ref().iter().map(|reg| PhysicalMemoryRegion {
|
||||||
base: PhysicalAddress::from_u64(reg.start_address),
|
base: PhysicalAddress::from_u64(reg.start_address),
|
||||||
size: reg.page_count as usize * L3::SIZE,
|
size: reg.page_count as usize * L3::SIZE,
|
||||||
}))
|
}))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn init_memory_management(
|
unsafe fn init_memory_management(
|
||||||
@@ -183,7 +185,9 @@ impl X86_64 {
|
|||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let have_1gib_pages = enabled_features.ext_edx.contains(ExtEdxFeatures::PDPE1GB);
|
let have_1gib_pages = enabled_features.ext_edx.contains(ExtEdxFeatures::PDPE1GB);
|
||||||
|
|
||||||
mem::init_fixed_tables(have_1gib_pages, is_bsp);
|
unsafe {
|
||||||
|
mem::init_fixed_tables(have_1gib_pages, is_bsp);
|
||||||
|
}
|
||||||
|
|
||||||
if !is_bsp {
|
if !is_bsp {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
@@ -198,36 +202,41 @@ impl X86_64 {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
match self.boot_data.get() {
|
unsafe {
|
||||||
&BootData::YBoot(data) => Self::init_physical_memory_from_yboot(data)?,
|
match self.boot_data.get() {
|
||||||
|
&BootData::YBoot(data) => Self::init_physical_memory_from_yboot(data)?,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn init_platform(&'static self, cpu_id: usize) -> Result<(), Error> {
|
unsafe fn init_platform(&'static self, cpu_id: usize) -> Result<(), Error> {
|
||||||
let (available_features, enabled_features) = self.init_cpu_features();
|
let (available_features, enabled_features) = unsafe { self.init_cpu_features() };
|
||||||
|
|
||||||
PLATFORM
|
unsafe {
|
||||||
.init_memory_management(&enabled_features, cpu_id == 0)
|
PLATFORM
|
||||||
.expect("Could not initialize memory management");
|
.init_memory_management(&enabled_features, cpu_id == 0)
|
||||||
let local_apic = self.init_local_cpu(cpu_id, available_features, enabled_features);
|
.expect("Could not initialize memory management");
|
||||||
|
}
|
||||||
|
let local_apic =
|
||||||
|
unsafe { self.init_local_cpu(cpu_id, available_features, enabled_features) };
|
||||||
|
|
||||||
if cpu_id == 0 {
|
if cpu_id == 0 {
|
||||||
self.setup_from_boot_data()?;
|
unsafe { self.setup_from_boot_data()? };
|
||||||
|
|
||||||
// TODO yboot doesn't yet pass any command line options
|
// TODO yboot doesn't yet pass any command line options
|
||||||
let cmdline = self.boot_data.get().cmdline();
|
let cmdline = self.boot_data.get().cmdline();
|
||||||
let mut early = x86::init_platform_early(cmdline)?;
|
let mut early = x86::init_platform_early(cmdline)?;
|
||||||
|
|
||||||
if !config::get().x86.disable_boot_fb
|
if !config::get().x86.disable_boot_fb
|
||||||
&& let Err(error) = self.init_framebuffer()
|
&& let Err(error) = unsafe { self.init_framebuffer() }
|
||||||
{
|
{
|
||||||
log::error!("Could not initialize boot framebuffer: {error:?}");
|
log::error!("Could not initialize boot framebuffer: {error:?}");
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(acpi) = self.acpi.try_get() {
|
if let Some(acpi) = self.acpi.try_get() {
|
||||||
self.init_platform_from_acpi(acpi, local_apic)?;
|
unsafe { self.init_platform_from_acpi(acpi, local_apic)? };
|
||||||
}
|
}
|
||||||
|
|
||||||
if !config::get().x86_64.disable_hpet {
|
if !config::get().x86_64.disable_hpet {
|
||||||
@@ -236,7 +245,7 @@ impl X86_64 {
|
|||||||
log::info!("HPET disabled by config");
|
log::info!("HPET disabled by config");
|
||||||
}
|
}
|
||||||
|
|
||||||
call_init_array();
|
unsafe { call_init_array() };
|
||||||
|
|
||||||
x86::init_platform_devices(early);
|
x86::init_platform_devices(early);
|
||||||
|
|
||||||
@@ -289,24 +298,26 @@ impl X86_64 {
|
|||||||
available_features: CpuFeatures,
|
available_features: CpuFeatures,
|
||||||
enabled_features: CpuFeatures,
|
enabled_features: CpuFeatures,
|
||||||
) -> Arc<LocalApic> {
|
) -> Arc<LocalApic> {
|
||||||
let local_apic = Arc::new(LocalApic::new());
|
unsafe {
|
||||||
let tss_address = gdt::init();
|
let local_apic = Arc::new(LocalApic::new());
|
||||||
exception::init_exceptions(cpu_id);
|
let tss_address = gdt::init();
|
||||||
|
exception::init_exceptions(cpu_id);
|
||||||
|
|
||||||
let cpu_data = PerCpuData {
|
let cpu_data = PerCpuData {
|
||||||
this: null_mut(),
|
this: null_mut(),
|
||||||
tss_address,
|
tss_address,
|
||||||
tmp_address: 0,
|
tmp_address: 0,
|
||||||
local_apic: local_apic.clone(),
|
local_apic: local_apic.clone(),
|
||||||
available_features,
|
available_features,
|
||||||
enabled_features,
|
enabled_features,
|
||||||
};
|
};
|
||||||
|
|
||||||
Cpu::init_local(Some(cpu_id as _), cpu_data);
|
Cpu::init_local(Some(cpu_id as _), cpu_data);
|
||||||
|
|
||||||
syscall::init_syscall();
|
syscall::init_syscall();
|
||||||
|
|
||||||
local_apic
|
local_apic
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn setup_from_boot_data(&self) -> Result<(), Error> {
|
unsafe fn setup_from_boot_data(&self) -> Result<(), Error> {
|
||||||
@@ -315,16 +326,17 @@ impl X86_64 {
|
|||||||
// Already reserved in set_boot_data()
|
// Already reserved in set_boot_data()
|
||||||
x86::set_initrd(data, false);
|
x86::set_initrd(data, false);
|
||||||
|
|
||||||
self.init_acpi_from_rsdp(data.rsdp_address as usize)
|
unsafe { self.init_acpi_from_rsdp(data.rsdp_address as usize) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn init_acpi_from_rsdp(&self, rsdp: usize) -> Result<(), Error> {
|
unsafe fn init_acpi_from_rsdp(&self, rsdp: usize) -> Result<(), Error> {
|
||||||
let acpi_tables = AcpiTables::from_rsdp(AcpiHandlerImpl, rsdp).map_err(|err| {
|
let acpi_tables =
|
||||||
log::error!("Could not initialize ACPI tables: {:?}", err);
|
unsafe { AcpiTables::from_rsdp(AcpiHandlerImpl, rsdp) }.map_err(|err| {
|
||||||
Error::InvalidArgument
|
log::error!("Could not initialize ACPI tables: {:?}", err);
|
||||||
})?;
|
Error::InvalidArgument
|
||||||
|
})?;
|
||||||
self.acpi.init(acpi_tables);
|
self.acpi.init(acpi_tables);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -405,14 +417,16 @@ impl X86_64 {
|
|||||||
_ => PixelFormat::R8G8B8A8,
|
_ => PixelFormat::R8G8B8A8,
|
||||||
};
|
};
|
||||||
|
|
||||||
let framebuffer = LinearFramebuffer::from_physical_bits(
|
let framebuffer = unsafe {
|
||||||
PhysicalAddress::from_u64(info.res_address),
|
LinearFramebuffer::from_physical_bits(
|
||||||
info.res_size as usize,
|
PhysicalAddress::from_u64(info.res_address),
|
||||||
info.res_stride as usize,
|
info.res_size as usize,
|
||||||
info.res_width,
|
info.res_stride as usize,
|
||||||
info.res_height,
|
info.res_width,
|
||||||
format,
|
info.res_height,
|
||||||
)?;
|
format,
|
||||||
|
)?
|
||||||
|
};
|
||||||
|
|
||||||
Some(Arc::new(framebuffer))
|
Some(Arc::new(framebuffer))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,14 +55,16 @@ unsafe fn start_ap_core(apic_id: u32) {
|
|||||||
entry: (ap_entry as *const ()).addr(),
|
entry: (ap_entry as *const ()).addr(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut data_ref = PhysicalRefMut::<ApBootstrapData>::map(AP_BOOTSTRAP_DATA);
|
let mut data_ref = unsafe { PhysicalRefMut::<ApBootstrapData>::map(AP_BOOTSTRAP_DATA) };
|
||||||
*data_ref = data;
|
*data_ref = data;
|
||||||
|
|
||||||
let cpu_count = CPU_COUNT.load(Ordering::Acquire);
|
let cpu_count = CPU_COUNT.load(Ordering::Acquire);
|
||||||
|
|
||||||
// Send an IPI to wake up the AP
|
// Send an IPI to wake up the AP
|
||||||
core::arch::asm!("wbinvd");
|
unsafe {
|
||||||
bsp_apic.wakeup_cpu(apic_id, AP_BOOTSTRAP_CODE);
|
core::arch::asm!("wbinvd");
|
||||||
|
bsp_apic.wakeup_cpu(apic_id, AP_BOOTSTRAP_CODE);
|
||||||
|
}
|
||||||
|
|
||||||
while cpu_count == CPU_COUNT.load(Ordering::Acquire) {
|
while cpu_count == CPU_COUNT.load(Ordering::Acquire) {
|
||||||
core::hint::spin_loop();
|
core::hint::spin_loop();
|
||||||
@@ -87,27 +89,29 @@ pub unsafe fn start_ap_cores(info: &ProcessorInfo<AcpiAllocator>) {
|
|||||||
let mut identity_l1 = PageTable::<L1>::new_zeroed::<TableAllocatorImpl>().unwrap();
|
let mut identity_l1 = PageTable::<L1>::new_zeroed::<TableAllocatorImpl>().unwrap();
|
||||||
let mut identity_l2 = PageTable::<L2>::new_zeroed::<TableAllocatorImpl>().unwrap();
|
let mut identity_l2 = PageTable::<L2>::new_zeroed::<TableAllocatorImpl>().unwrap();
|
||||||
|
|
||||||
identity_l1[0] =
|
unsafe {
|
||||||
PageEntry::<L1>::table(identity_l2.as_physical_address(), PageAttributes::WRITABLE);
|
identity_l1[0] =
|
||||||
identity_l2[0] = PageEntry::<L2>::block(PhysicalAddress::ZERO, PageAttributes::WRITABLE);
|
PageEntry::<L1>::table(identity_l2.as_physical_address(), PageAttributes::WRITABLE);
|
||||||
|
identity_l2[0] = PageEntry::<L2>::block(PhysicalAddress::ZERO, PageAttributes::WRITABLE);
|
||||||
|
|
||||||
fixed::KERNEL_PML4[0] =
|
fixed::KERNEL_PML4[0] =
|
||||||
PageEntry::table(identity_l1.as_physical_address(), PageAttributes::WRITABLE);
|
PageEntry::table(identity_l1.as_physical_address(), PageAttributes::WRITABLE);
|
||||||
|
|
||||||
// Load AP_BOOTSTRAP_CODE
|
// Load AP_BOOTSTRAP_CODE
|
||||||
let mut code_ref = PhysicalRefMut::map_slice(AP_BOOTSTRAP_CODE, AP_BOOTSTRAP_BIN.len());
|
let mut code_ref = PhysicalRefMut::map_slice(AP_BOOTSTRAP_CODE, AP_BOOTSTRAP_BIN.len());
|
||||||
code_ref.copy_from_slice(AP_BOOTSTRAP_BIN);
|
code_ref.copy_from_slice(AP_BOOTSTRAP_BIN);
|
||||||
|
|
||||||
for ap in aps.iter() {
|
for ap in aps.iter() {
|
||||||
if ap.is_ap && ap.state == ProcessorState::WaitingForSipi {
|
if ap.is_ap && ap.state == ProcessorState::WaitingForSipi {
|
||||||
start_ap_core(ap.local_apic_id);
|
start_ap_core(ap.local_apic_id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Remove the identity-map
|
||||||
|
identity_l2[0] = PageEntry::INVALID;
|
||||||
|
flush_tlb_entry(0);
|
||||||
|
|
||||||
|
PageTable::free::<TableAllocatorImpl>(identity_l1);
|
||||||
|
PageTable::free::<TableAllocatorImpl>(identity_l2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove the identity-map
|
|
||||||
identity_l2[0] = PageEntry::INVALID;
|
|
||||||
flush_tlb_entry(0);
|
|
||||||
|
|
||||||
PageTable::free::<TableAllocatorImpl>(identity_l1);
|
|
||||||
PageTable::free::<TableAllocatorImpl>(identity_l2);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,16 +42,18 @@ impl Device for Psci {
|
|||||||
|
|
||||||
impl CpuBringupDevice for Psci {
|
impl CpuBringupDevice for Psci {
|
||||||
unsafe fn start_cpu(&self, id: usize, ip: usize, arg0: usize) -> Result<(), Error> {
|
unsafe fn start_cpu(&self, id: usize, ip: usize, arg0: usize) -> Result<(), Error> {
|
||||||
self.call(self.cpu_on as _, id as _, ip as _, arg0 as _);
|
unsafe { self.call(self.cpu_on as _, id as _, ip as _, arg0 as _) };
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ResetDevice for Psci {
|
impl ResetDevice for Psci {
|
||||||
unsafe fn reset(&self) -> ! {
|
unsafe fn reset(&self) -> ! {
|
||||||
ArchitectureImpl::set_interrupt_mask(true);
|
unsafe {
|
||||||
|
ArchitectureImpl::set_interrupt_mask(true);
|
||||||
|
|
||||||
self.call(Self::SYSTEM_RESET as _, 0, 0, 0);
|
self.call(Self::SYSTEM_RESET as _, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
ArchitectureImpl::wait_for_interrupt();
|
ArchitectureImpl::wait_for_interrupt();
|
||||||
@@ -65,12 +67,14 @@ impl Psci {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn call(&self, mut x0: u64, x1: u64, x2: u64, x3: u64) -> u64 {
|
unsafe fn call(&self, mut x0: u64, x1: u64, x2: u64, x3: u64) -> u64 {
|
||||||
match self.method {
|
unsafe {
|
||||||
CallMethod::Hvc => {
|
match self.method {
|
||||||
core::arch::asm!("hvc #0", inlateout("x0") x0, in("x1") x1, in("x2") x2, in("x3") x3)
|
CallMethod::Hvc => {
|
||||||
}
|
core::arch::asm!("hvc #0", inlateout("x0") x0, in("x1") x1, in("x2") x2, in("x3") x3)
|
||||||
CallMethod::Smc => {
|
}
|
||||||
core::arch::asm!("smc #0", inlateout("x0") x0, in("x1") x1, in("x2") x2, in("x3") x3)
|
CallMethod::Smc => {
|
||||||
|
core::arch::asm!("smc #0", inlateout("x0") x0, in("x1") x1, in("x2") x2, in("x3") x3)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
x0
|
x0
|
||||||
@@ -82,7 +86,7 @@ impl Psci {
|
|||||||
///
|
///
|
||||||
/// Unsafe: requires caller to perform all the necessary shutdown preparations.
|
/// Unsafe: requires caller to perform all the necessary shutdown preparations.
|
||||||
pub unsafe fn power_off(&self) -> Result<!, Error> {
|
pub unsafe fn power_off(&self) -> Result<!, Error> {
|
||||||
self.call(Self::SYSTEM_OFF as _, 0, 0, 0);
|
unsafe { self.call(Self::SYSTEM_OFF as _, 0, 0, 0) };
|
||||||
unreachable!()
|
unreachable!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ unsafe impl BlockAllocator for FileBlockAllocator {
|
|||||||
unsafe fn dealloc(block: NonNull<u8>) {
|
unsafe fn dealloc(block: NonNull<u8>) {
|
||||||
let page = block.as_ptr() as usize;
|
let page = block.as_ptr() as usize;
|
||||||
let physical = PhysicalAddress::from_virtualized(page);
|
let physical = PhysicalAddress::from_virtualized(page);
|
||||||
phys::free_page(physical);
|
unsafe { phys::free_page(physical) };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-21
@@ -1,23 +1,5 @@
|
|||||||
//! osdev-x kernel crate
|
//! osdev-x kernel crate
|
||||||
#![feature(
|
#![feature(arbitrary_self_types, rustc_private, never_type)]
|
||||||
step_trait,
|
|
||||||
decl_macro,
|
|
||||||
optimize_attribute,
|
|
||||||
const_trait_impl,
|
|
||||||
arbitrary_self_types,
|
|
||||||
linked_list_cursors,
|
|
||||||
rustc_private,
|
|
||||||
allocator_api,
|
|
||||||
trait_alias,
|
|
||||||
slice_ptr_get,
|
|
||||||
slice_split_once,
|
|
||||||
iter_collect_into,
|
|
||||||
iter_next_chunk,
|
|
||||||
exact_size_is_empty,
|
|
||||||
never_type,
|
|
||||||
format_args_nl,
|
|
||||||
associated_type_defaults
|
|
||||||
)]
|
|
||||||
#![allow(
|
#![allow(
|
||||||
clippy::new_without_default,
|
clippy::new_without_default,
|
||||||
clippy::fn_to_numeric_cast,
|
clippy::fn_to_numeric_cast,
|
||||||
@@ -25,8 +7,7 @@
|
|||||||
clippy::match_single_binding,
|
clippy::match_single_binding,
|
||||||
clippy::missing_transmute_annotations,
|
clippy::missing_transmute_annotations,
|
||||||
clippy::modulo_one,
|
clippy::modulo_one,
|
||||||
async_fn_in_trait,
|
async_fn_in_trait
|
||||||
unsafe_op_in_unsafe_fn
|
|
||||||
)]
|
)]
|
||||||
#![deny(missing_docs)]
|
#![deny(missing_docs)]
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
|||||||
+12
-10
@@ -17,13 +17,14 @@ pub const KERNEL_VIRT_OFFSET: usize = kernel_arch::KERNEL_VIRT_OFFSET;
|
|||||||
/// The caller must ensure the correct origin of the address, its alignment and that the access is
|
/// The caller must ensure the correct origin of the address, its alignment and that the access is
|
||||||
/// properly synchronized.
|
/// properly synchronized.
|
||||||
pub unsafe fn read_memory<T>(address: PhysicalAddress) -> T {
|
pub unsafe fn read_memory<T>(address: PhysicalAddress) -> T {
|
||||||
let io = DeviceMemoryMapping::map(address, size_of::<T>(), Default::default()).unwrap();
|
let io =
|
||||||
|
unsafe { DeviceMemoryMapping::map(address, size_of::<T>(), Default::default()).unwrap() };
|
||||||
let address = io.address();
|
let address = io.address();
|
||||||
|
|
||||||
if address.is_multiple_of(align_of::<T>()) {
|
if address.is_multiple_of(align_of::<T>()) {
|
||||||
(address as *const T).read_volatile()
|
unsafe { (address as *const T).read_volatile() }
|
||||||
} else {
|
} else {
|
||||||
(address as *const T).read_unaligned()
|
unsafe { (address as *const T).read_unaligned() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -34,32 +35,33 @@ pub unsafe fn read_memory<T>(address: PhysicalAddress) -> T {
|
|||||||
/// The caller must ensure the correct origin of the address, its alignment and that the access is
|
/// The caller must ensure the correct origin of the address, its alignment and that the access is
|
||||||
/// properly synchronized.
|
/// properly synchronized.
|
||||||
pub unsafe fn write_memory<T>(address: PhysicalAddress, value: T) {
|
pub unsafe fn write_memory<T>(address: PhysicalAddress, value: T) {
|
||||||
let io = DeviceMemoryMapping::map(address, size_of::<T>(), Default::default()).unwrap();
|
let io =
|
||||||
|
unsafe { DeviceMemoryMapping::map(address, size_of::<T>(), Default::default()).unwrap() };
|
||||||
let address = io.address();
|
let address = io.address();
|
||||||
|
|
||||||
if address.is_multiple_of(align_of::<T>()) {
|
if address.is_multiple_of(align_of::<T>()) {
|
||||||
(address as *mut T).write_volatile(value)
|
unsafe { (address as *mut T).write_volatile(value) }
|
||||||
} else {
|
} else {
|
||||||
(address as *mut T).write_unaligned(value)
|
unsafe { (address as *mut T).write_unaligned(value) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unsafe(no_mangle)]
|
#[unsafe(no_mangle)]
|
||||||
unsafe extern "C" fn memcpy(p0: *mut c_void, p1: *const c_void, len: usize) -> *mut c_void {
|
unsafe extern "C" fn memcpy(p0: *mut c_void, p1: *const c_void, len: usize) -> *mut c_void {
|
||||||
compiler_builtins::mem::memcpy(p0 as _, p1 as _, len) as _
|
unsafe { compiler_builtins::mem::memcpy(p0 as _, p1 as _, len) as _ }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unsafe(no_mangle)]
|
#[unsafe(no_mangle)]
|
||||||
unsafe extern "C" fn memcmp(p0: *const c_void, p1: *const c_void, len: usize) -> i32 {
|
unsafe extern "C" fn memcmp(p0: *const c_void, p1: *const c_void, len: usize) -> i32 {
|
||||||
compiler_builtins::mem::memcmp(p0 as _, p1 as _, len)
|
unsafe { compiler_builtins::mem::memcmp(p0 as _, p1 as _, len) }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unsafe(no_mangle)]
|
#[unsafe(no_mangle)]
|
||||||
unsafe extern "C" fn memmove(dst: *mut c_void, src: *const c_void, len: usize) -> *mut c_void {
|
unsafe extern "C" fn memmove(dst: *mut c_void, src: *const c_void, len: usize) -> *mut c_void {
|
||||||
compiler_builtins::mem::memmove(dst as _, src as _, len) as _
|
unsafe { compiler_builtins::mem::memmove(dst as _, src as _, len) as _ }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unsafe(no_mangle)]
|
#[unsafe(no_mangle)]
|
||||||
unsafe extern "C" fn memset(dst: *mut c_void, val: i32, len: usize) -> *mut c_void {
|
unsafe extern "C" fn memset(dst: *mut c_void, val: i32, len: usize) -> *mut c_void {
|
||||||
compiler_builtins::mem::memset(dst as _, val, len) as _
|
unsafe { compiler_builtins::mem::memset(dst as _, val, len) as _ }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -75,5 +75,5 @@ pub unsafe fn enter() -> ! {
|
|||||||
let queue = CpuQueue::for_cpu(cpu.queue_index());
|
let queue = CpuQueue::for_cpu(cpu.queue_index());
|
||||||
cpu.set_scheduler(queue);
|
cpu.set_scheduler(queue);
|
||||||
|
|
||||||
queue.enter()
|
unsafe { queue.enter() }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ pub unsafe fn call_init_array() {
|
|||||||
}
|
}
|
||||||
let size = (end - base.addr()) / size_of::<InitFn>();
|
let size = (end - base.addr()) / size_of::<InitFn>();
|
||||||
|
|
||||||
let init_array: &[InitFn] = core::slice::from_raw_parts(base.cast(), size);
|
let init_array: &[InitFn] = unsafe { core::slice::from_raw_parts(base.cast(), size) };
|
||||||
|
|
||||||
for function in init_array {
|
for function in init_array {
|
||||||
function();
|
function();
|
||||||
|
|||||||
@@ -1,18 +1,14 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "abi-lib"
|
name = "abi-lib"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2024"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
core = { version = "1.0.0", optional = true, package = "rustc-std-workspace-core" }
|
core = { version = "1.0.0", optional = true, package = "rustc-std-workspace-core" }
|
||||||
compiler_builtins = { version = "0.1", optional = true }
|
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = []
|
default = []
|
||||||
rustc-dep-of-std = [
|
rustc-dep-of-std = ["core"]
|
||||||
"core",
|
|
||||||
"compiler_builtins/rustc-dep-of-std",
|
|
||||||
]
|
|
||||||
|
|
||||||
[lints.rust]
|
[lints.rust]
|
||||||
unexpected_cfgs = { level = "allow", check-cfg = ['cfg(rust_analyzer)'] }
|
unexpected_cfgs = { level = "allow", check-cfg = ['cfg(rust_analyzer)'] }
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "abi-serde"
|
name = "abi-serde"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2024"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
compiler_builtins = { version = "0.1", optional = true }
|
|
||||||
core = { version = "1.0.0", optional = true, package = "rustc-std-workspace-core" }
|
core = { version = "1.0.0", optional = true, package = "rustc-std-workspace-core" }
|
||||||
rustc_std_alloc = { version = "1.0.0", optional = true, package = "rustc-std-workspace-alloc" }
|
rustc_std_alloc = { version = "1.0.0", optional = true, package = "rustc-std-workspace-alloc" }
|
||||||
|
|
||||||
@@ -13,7 +12,6 @@ default = []
|
|||||||
rustc-dep-of-std = [
|
rustc-dep-of-std = [
|
||||||
"core",
|
"core",
|
||||||
"rustc_std_alloc",
|
"rustc_std_alloc",
|
||||||
"compiler_builtins/rustc-dep-of-std",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[lints]
|
[lints]
|
||||||
|
|||||||
+1
-3
@@ -1,7 +1,7 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "yggdrasil-abi"
|
name = "yggdrasil-abi"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2024"
|
||||||
authors = ["Mark Poliakov <mark@alnyan.me>"]
|
authors = ["Mark Poliakov <mark@alnyan.me>"]
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
@@ -9,7 +9,6 @@ authors = ["Mark Poliakov <mark@alnyan.me>"]
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
core = { version = "1.0.0", optional = true, package = "rustc-std-workspace-core" }
|
core = { version = "1.0.0", optional = true, package = "rustc-std-workspace-core" }
|
||||||
rustc_std_alloc = { version = "1.0.0", optional = true, package = "rustc-std-workspace-alloc" }
|
rustc_std_alloc = { version = "1.0.0", optional = true, package = "rustc-std-workspace-alloc" }
|
||||||
compiler_builtins = { version = "0.1", optional = true }
|
|
||||||
|
|
||||||
abi-serde = { path = "../abi-serde" }
|
abi-serde = { path = "../abi-serde" }
|
||||||
|
|
||||||
@@ -33,7 +32,6 @@ serde_kernel = ["serde", "serde/alloc"]
|
|||||||
rustc-dep-of-std = [
|
rustc-dep-of-std = [
|
||||||
"core",
|
"core",
|
||||||
"rustc_std_alloc",
|
"rustc_std_alloc",
|
||||||
"compiler_builtins/rustc-dep-of-std",
|
|
||||||
"abi-lib/rustc-dep-of-std",
|
"abi-lib/rustc-dep-of-std",
|
||||||
"abi-serde/rustc-dep-of-std"
|
"abi-serde/rustc-dep-of-std"
|
||||||
]
|
]
|
||||||
|
|||||||
+1
-1
@@ -8,7 +8,7 @@
|
|||||||
incomplete_features,
|
incomplete_features,
|
||||||
stable_features
|
stable_features
|
||||||
)]
|
)]
|
||||||
#![feature(trace_macros, const_trait_impl, ip_in_core)]
|
#![feature(ip_in_core)]
|
||||||
#![warn(missing_docs)]
|
#![warn(missing_docs)]
|
||||||
|
|
||||||
#[cfg(all(any(feature = "alloc", test), not(feature = "rustc-dep-of-std")))]
|
#[cfg(all(any(feature = "alloc", test), not(feature = "rustc-dep-of-std")))]
|
||||||
|
|||||||
@@ -54,6 +54,14 @@ impl SystemTime {
|
|||||||
nanoseconds: 0,
|
nanoseconds: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Minimum representable system time
|
||||||
|
pub const MIN: Self = Self::ZERO;
|
||||||
|
/// Maximum representable system time
|
||||||
|
pub const MAX: Self = Self {
|
||||||
|
seconds: u64::MAX,
|
||||||
|
nanoseconds: 999999999,
|
||||||
|
};
|
||||||
|
|
||||||
/// Constructs a new [SystemTime] from seconds and nanoseconds, without performing
|
/// Constructs a new [SystemTime] from seconds and nanoseconds, without performing
|
||||||
/// any adjustments.
|
/// any adjustments.
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "libutil"
|
name = "libutil"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2024"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
|
||||||
|
|||||||
@@ -1,15 +1,13 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "libyalloc"
|
name = "libyalloc"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2024"
|
||||||
authors = ["Mark Poliakov <mark@alnyan.me>"]
|
authors = ["Mark Poliakov <mark@alnyan.me>"]
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
core = { version = "1.0.0", optional = true, package = "rustc-std-workspace-core" }
|
core = { version = "1.0.0", optional = true, package = "rustc-std-workspace-core" }
|
||||||
compiler_builtins = { version = "0.1", optional = true }
|
|
||||||
|
|
||||||
|
|
||||||
[target.'cfg(unix)'.dependencies]
|
[target.'cfg(unix)'.dependencies]
|
||||||
libc = { version = "0.2.140", default-features = false }
|
libc = { version = "0.2.140", default-features = false }
|
||||||
@@ -22,8 +20,6 @@ global = []
|
|||||||
dep-of-kernel = []
|
dep-of-kernel = []
|
||||||
rustc-dep-of-std = [
|
rustc-dep-of-std = [
|
||||||
"core",
|
"core",
|
||||||
"compiler_builtins",
|
|
||||||
"compiler_builtins/rustc-dep-of-std",
|
|
||||||
"libc/rustc-dep-of-std",
|
"libc/rustc-dep-of-std",
|
||||||
"yggdrasil-rt/rustc-dep-of-std"
|
"yggdrasil-rt/rustc-dep-of-std"
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ where
|
|||||||
unsafe fn free(&mut self, ptr: NonNull<u8>) {
|
unsafe fn free(&mut self, ptr: NonNull<u8>) {
|
||||||
let mut node = self.head;
|
let mut node = self.head;
|
||||||
while let Some(mut bucket) = node {
|
while let Some(mut bucket) = node {
|
||||||
let bucket = bucket.as_mut();
|
let bucket = unsafe { bucket.as_mut() };
|
||||||
|
|
||||||
if let (true, _last) = bucket.free(ptr) {
|
if let (true, _last) = bucket.free(ptr) {
|
||||||
// TODO free the node if last?
|
// TODO free the node if last?
|
||||||
@@ -137,16 +137,18 @@ impl<P: PageProvider> BucketAllocator<P> {
|
|||||||
pub unsafe fn free(&mut self, ptr: NonNull<u8>, layout: Layout) {
|
pub unsafe fn free(&mut self, ptr: NonNull<u8>, layout: Layout) {
|
||||||
let aligned = layout.pad_to_align();
|
let aligned = layout.pad_to_align();
|
||||||
|
|
||||||
match aligned.size() {
|
unsafe {
|
||||||
size if size <= 32 => self.buckets_32.free(ptr),
|
match aligned.size() {
|
||||||
size if size <= 64 => self.buckets_64.free(ptr),
|
size if size <= 32 => self.buckets_32.free(ptr),
|
||||||
size if size <= 128 => self.buckets_128.free(ptr),
|
size if size <= 64 => self.buckets_64.free(ptr),
|
||||||
size if size <= 256 => self.buckets_256.free(ptr),
|
size if size <= 128 => self.buckets_128.free(ptr),
|
||||||
size if size <= 512 => self.buckets_512.free(ptr),
|
size if size <= 256 => self.buckets_256.free(ptr),
|
||||||
size if size <= 1024 => self.buckets_1024.free(ptr),
|
size if size <= 512 => self.buckets_512.free(ptr),
|
||||||
size => {
|
size if size <= 1024 => self.buckets_1024.free(ptr),
|
||||||
assert_eq!(usize::from(ptr.addr()) % sys::PAGE_SIZE, 0);
|
size => {
|
||||||
P::unmap_pages(ptr, size.div_ceil(sys::PAGE_SIZE));
|
assert_eq!(usize::from(ptr.addr()) % sys::PAGE_SIZE, 0);
|
||||||
|
P::unmap_pages(ptr, size.div_ceil(sys::PAGE_SIZE));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ unsafe impl GlobalAlloc for GlobalAllocator {
|
|||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
|
unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
|
||||||
let ptr = NonNull::new(ptr).expect("Invalid pointer");
|
let ptr = NonNull::new(ptr).expect("Invalid pointer");
|
||||||
GLOBAL_ALLOCATOR.lock().free(ptr, layout);
|
unsafe { GLOBAL_ALLOCATOR.lock().free(ptr, layout) };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -33,7 +33,7 @@ unsafe impl Allocator for GlobalAllocator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout) {
|
unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout) {
|
||||||
GLOBAL_ALLOCATOR.lock().free(ptr, layout);
|
unsafe { GLOBAL_ALLOCATOR.lock().free(ptr, layout) };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,8 +2,6 @@
|
|||||||
generic_const_exprs,
|
generic_const_exprs,
|
||||||
arbitrary_self_types,
|
arbitrary_self_types,
|
||||||
let_chains,
|
let_chains,
|
||||||
test,
|
|
||||||
allocator_api,
|
|
||||||
unsigned_is_multiple_of
|
unsigned_is_multiple_of
|
||||||
)]
|
)]
|
||||||
#![cfg_attr(not(test), no_std)]
|
#![cfg_attr(not(test), no_std)]
|
||||||
@@ -13,6 +11,8 @@
|
|||||||
clippy::new_without_default,
|
clippy::new_without_default,
|
||||||
stable_features
|
stable_features
|
||||||
)]
|
)]
|
||||||
|
#![cfg_attr(test, feature(test))]
|
||||||
|
#![cfg_attr(feature = "global", feature(allocator_api))]
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
extern crate test;
|
extern crate test;
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ pub trait NonNullExt<T> {
|
|||||||
|
|
||||||
impl<T> NonNullExt<T> for NonNull<T> {
|
impl<T> NonNullExt<T> for NonNull<T> {
|
||||||
unsafe fn add_ext(self, offset: usize) -> Self {
|
unsafe fn add_ext(self, offset: usize) -> Self {
|
||||||
NonNull::new_unchecked(self.as_ptr().add(offset))
|
unsafe { NonNull::new_unchecked(self.as_ptr().add(offset)) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "qemu"
|
name = "qemu"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2024"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "yggdrasil-rt"
|
name = "yggdrasil-rt"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2024"
|
||||||
authors = ["Mark Poliakov <mark@alnyan.me>"]
|
authors = ["Mark Poliakov <mark@alnyan.me>"]
|
||||||
build = "build.rs"
|
build = "build.rs"
|
||||||
|
|
||||||
@@ -10,7 +10,6 @@ yggdrasil-abi = { path = "../abi", features = ["alloc"] }
|
|||||||
|
|
||||||
core = { version = "1.0.0", optional = true, package = "rustc-std-workspace-core" }
|
core = { version = "1.0.0", optional = true, package = "rustc-std-workspace-core" }
|
||||||
alloc = { version = "1.0.0", optional = true, package = "rustc-std-workspace-alloc" }
|
alloc = { version = "1.0.0", optional = true, package = "rustc-std-workspace-alloc" }
|
||||||
compiler_builtins = { version = "0.1", optional = true }
|
|
||||||
libm = { git = "https://git.alnyan.me/yggdrasil/libm.git", optional = true }
|
libm = { git = "https://git.alnyan.me/yggdrasil/libm.git", optional = true }
|
||||||
|
|
||||||
abi-lib = { path = "../abi-lib" }
|
abi-lib = { path = "../abi-lib" }
|
||||||
@@ -27,7 +26,7 @@ __tls_get_addr = []
|
|||||||
rustc-dep-of-std = [
|
rustc-dep-of-std = [
|
||||||
"core",
|
"core",
|
||||||
"alloc",
|
"alloc",
|
||||||
"compiler_builtins/rustc-dep-of-std",
|
"__tls_get_addr",
|
||||||
"yggdrasil-abi/rustc-dep-of-std",
|
"yggdrasil-abi/rustc-dep-of-std",
|
||||||
"abi-lib/rustc-dep-of-std",
|
"abi-lib/rustc-dep-of-std",
|
||||||
"abi-serde/rustc-dep-of-std",
|
"abi-serde/rustc-dep-of-std",
|
||||||
|
|||||||
@@ -28,11 +28,25 @@ fn build_libm() {
|
|||||||
|
|
||||||
let mut build = cc::Build::new();
|
let mut build = cc::Build::new();
|
||||||
|
|
||||||
|
let rust_target = env::var("TARGET").unwrap();
|
||||||
|
let cc_target = match rust_target.as_ref() {
|
||||||
|
"x86_64-unknown-none" | "x86_64-unknown-yggdrasil" => "x86_64-unknown-none",
|
||||||
|
"aarch64-unknown-none" | "aarch64-unknown-yggdrasil" => "aarch64-unknown-none",
|
||||||
|
"riscv64-unknown-yggdrasil" | "riscv64-unknown-none" => "riscv64-unknown-none",
|
||||||
|
_ => todo!("{rust_target:?}"),
|
||||||
|
};
|
||||||
|
|
||||||
build
|
build
|
||||||
.compiler("clang")
|
.compiler("clang")
|
||||||
.flag("-ffreestanding")
|
.flag("-ffreestanding")
|
||||||
.flag("-nostdlib");
|
.flag("-nostdlib");
|
||||||
|
|
||||||
|
if cc_target == "riscv64-unknown-none" {
|
||||||
|
build.flag("--target=riscv64-unknown-none");
|
||||||
|
} else {
|
||||||
|
build.target(cc_target);
|
||||||
|
}
|
||||||
|
|
||||||
add_file(&mut build, "libm/e_fmodf.c");
|
add_file(&mut build, "libm/e_fmodf.c");
|
||||||
add_file(&mut build, "libm/e_hypotf.c");
|
add_file(&mut build, "libm/e_hypotf.c");
|
||||||
add_file(&mut build, "libm/e_log.c");
|
add_file(&mut build, "libm/e_log.c");
|
||||||
|
|||||||
@@ -8,13 +8,14 @@
|
|||||||
generic_const_exprs,
|
generic_const_exprs,
|
||||||
maybe_uninit_array_assume_init
|
maybe_uninit_array_assume_init
|
||||||
)]
|
)]
|
||||||
|
#![allow(unused_features)]
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![warn(missing_docs)]
|
#![warn(missing_docs)]
|
||||||
#![allow(nonstandard_style, clippy::new_without_default, incomplete_features)]
|
#![allow(nonstandard_style, clippy::new_without_default, incomplete_features)]
|
||||||
|
|
||||||
#[cfg(not(rust_analyzer))]
|
// #[cfg(not(any(rust_analyzer, test)))]
|
||||||
#[allow(unused_extern_crates)]
|
// #[allow(unused_extern_crates)]
|
||||||
extern crate compiler_builtins;
|
// extern crate compiler_builtins;
|
||||||
|
|
||||||
#[allow(unused_extern_crates)]
|
#[allow(unused_extern_crates)]
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user