Removed proc macros(for now) as kernel items are pretty much useless, added untested interrupts stuff
This commit is contained in:
parent
9e6897d8ba
commit
842a2b23fe
16 changed files with 108 additions and 309 deletions
|
@ -5,7 +5,6 @@ edition = "2024"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
paste = "1.0.15"
|
paste = "1.0.15"
|
||||||
aphrodite_proc_macros = { path = "./aphrodite_proc_macros"}
|
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
opt-level = "z"
|
opt-level = "z"
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
[package]
|
|
||||||
name = "aphrodite_proc_macros"
|
|
||||||
version = "0.1.0"
|
|
||||||
edition = "2024"
|
|
||||||
|
|
||||||
[lib]
|
|
||||||
proc-macro = true
|
|
||||||
path = "../src/proc_macros/mod.rs"
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
quote = "1.0.38"
|
|
||||||
syn = { version = "2.0.98", features = ["full"] }
|
|
||||||
aphrodite_common = { path = "../aphrodite_common" }
|
|
||||||
proc-macro2 = "1.0.93"
|
|
|
@ -19,7 +19,7 @@
|
||||||
real_check=false
|
real_check=false
|
||||||
|
|
||||||
if [[ "$HAVE_GETOPT" = "true" ]]; then
|
if [[ "$HAVE_GETOPT" = "true" ]]; then
|
||||||
LONGOPTS=real_check
|
LONGOPTS=real_check,real-check
|
||||||
OPTIONS=c
|
OPTIONS=c
|
||||||
|
|
||||||
PARSED=$(getopt --options=$OPTIONS --longoptions=$LONGOPTS --name "$0" -- "$@") || (
|
PARSED=$(getopt --options=$OPTIONS --longoptions=$LONGOPTS --name "$0" -- "$@") || (
|
||||||
|
@ -30,7 +30,7 @@
|
||||||
|
|
||||||
while true; do
|
while true; do
|
||||||
case "$1" in
|
case "$1" in
|
||||||
-c|--real_check)
|
-c|--real_check|--real-check)
|
||||||
real_check=true
|
real_check=true
|
||||||
shift
|
shift
|
||||||
;;
|
;;
|
||||||
|
|
|
@ -14,6 +14,7 @@ VERSION=generate
|
||||||
CONFIG_DISABLE_MULTIBOOT2_SUPPORT=false
|
CONFIG_DISABLE_MULTIBOOT2_SUPPORT=false
|
||||||
|
|
||||||
# Panic behavior. When debugging, generally halt on panic is more useful.
|
# Panic behavior. When debugging, generally halt on panic is more useful.
|
||||||
|
# Halt on panic takes priority over spin on panic if both are enabled.
|
||||||
CONFIG_HALT_ON_PANIC=true
|
CONFIG_HALT_ON_PANIC=true
|
||||||
CONFIG_SPIN_ON_PANIC=false
|
CONFIG_SPIN_ON_PANIC=false
|
||||||
|
|
||||||
|
|
|
@ -23,28 +23,22 @@ pub mod interrupts {
|
||||||
pub const USER_SYSCALL_VECTOR: u16 = 0xA0;
|
pub const USER_SYSCALL_VECTOR: u16 = 0xA0;
|
||||||
|
|
||||||
/// Returns whether interrupts are enabled or not.
|
/// Returns whether interrupts are enabled or not.
|
||||||
#[aphrodite_proc_macros::kernel_item(InterruptsCheck)]
|
|
||||||
fn interrupts_enabled() -> bool { false }
|
fn interrupts_enabled() -> bool { false }
|
||||||
|
|
||||||
/// Enables interrupts.
|
/// Enables interrupts.
|
||||||
#[aphrodite_proc_macros::kernel_item(InterruptsEnable)]
|
|
||||||
fn enable_interrupts() {}
|
fn enable_interrupts() {}
|
||||||
|
|
||||||
/// Disables interrupts.
|
/// Disables interrupts.
|
||||||
#[aphrodite_proc_macros::kernel_item(InterruptsDisable)]
|
|
||||||
fn disable_interrupts() {}
|
fn disable_interrupts() {}
|
||||||
|
|
||||||
/// Disables interrupts and a value that can be used to restore them
|
/// Disables interrupts and a value that can be used to restore them
|
||||||
/// with [restore_irq].
|
/// with [restore_irq].
|
||||||
#[aphrodite_proc_macros::kernel_item(InterruptsPop)]
|
|
||||||
fn pop_irq() -> u64 { 0 }
|
fn pop_irq() -> u64 { 0 }
|
||||||
|
|
||||||
/// Restores interrupts after a [pop_irq] call.
|
/// Restores interrupts after a [pop_irq] call.
|
||||||
#[aphrodite_proc_macros::kernel_item(InterruptsRestore)]
|
|
||||||
fn restore_irq(_irq: u64) {}
|
fn restore_irq(_irq: u64) {}
|
||||||
|
|
||||||
/// Activates an IDT.
|
/// Activates an IDT.
|
||||||
#[aphrodite_proc_macros::kernel_item(ActivateIDT)]
|
|
||||||
fn activate_idt(_idt: Idt) {}
|
fn activate_idt(_idt: Idt) {}
|
||||||
|
|
||||||
/// An IDT.
|
/// An IDT.
|
||||||
|
|
|
@ -9,10 +9,14 @@ use alloc::vec::Vec;
|
||||||
/// The GDTR. Used internally in [activate_gdt].
|
/// The GDTR. Used internally in [activate_gdt].
|
||||||
#[repr(C, packed)]
|
#[repr(C, packed)]
|
||||||
struct Gdtr {
|
struct Gdtr {
|
||||||
|
// raw pointer to the GDT
|
||||||
base: *const u8,
|
base: *const u8,
|
||||||
|
// size of the GDT in bytes
|
||||||
size: usize,
|
size: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Activates the GDT using `lgdt`. Does NOT, I repeat, does NOT change the
|
||||||
|
/// segment registers!
|
||||||
pub unsafe fn activate_gdt(ptr: *const [u8]) {
|
pub unsafe fn activate_gdt(ptr: *const [u8]) {
|
||||||
let gdtr = Gdtr {
|
let gdtr = Gdtr {
|
||||||
base: ptr as *const u8,
|
base: ptr as *const u8,
|
||||||
|
|
36
kernel/src/kernel/arch/x86/interrupt_impls.rs
Normal file
36
kernel/src/kernel/arch/x86/interrupt_impls.rs
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
//! Implementations of interrupts.
|
||||||
|
#![cfg(target_arch = "x86")]
|
||||||
|
#![allow(undefined_naked_function_abi)] // special calling convention anyway
|
||||||
|
|
||||||
|
use core::arch::naked_asm;
|
||||||
|
|
||||||
|
macro_rules! int_wrapper {
|
||||||
|
($func:block, $num:expr) => {
|
||||||
|
paste::paste! {
|
||||||
|
/// autogenerated interrupt wrapper
|
||||||
|
#[naked]
|
||||||
|
pub unsafe fn [< int $num >]() {
|
||||||
|
unsafe {
|
||||||
|
naked_asm!(
|
||||||
|
"pushad",
|
||||||
|
"cld",
|
||||||
|
"call {}",
|
||||||
|
"popad",
|
||||||
|
"iret",
|
||||||
|
sym [< int $num _rust >]
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// autogenerated interrupt body
|
||||||
|
unsafe extern "C" fn [< int $num _rust >]() $func
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
int_wrapper!(
|
||||||
|
{
|
||||||
|
super::output::sdebugsln("Interrupt handler #0 ran");
|
||||||
|
},
|
||||||
|
0
|
||||||
|
);
|
|
@ -9,7 +9,6 @@ use core::mem::MaybeUninit;
|
||||||
pub const USER_SYSCALL_VECTOR: u16 = 0xA0;
|
pub const USER_SYSCALL_VECTOR: u16 = 0xA0;
|
||||||
|
|
||||||
/// Returns whether interrupts are enabled or not.
|
/// Returns whether interrupts are enabled or not.
|
||||||
#[aphrodite_proc_macros::kernel_item(InterruptsCheck)]
|
|
||||||
pub fn interrupts_enabled() -> bool {
|
pub fn interrupts_enabled() -> bool {
|
||||||
let flags: u32;
|
let flags: u32;
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -22,7 +21,6 @@ pub fn interrupts_enabled() -> bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Disables interrupts.
|
/// Disables interrupts.
|
||||||
#[aphrodite_proc_macros::kernel_item(InterruptsDisable)]
|
|
||||||
pub fn disable_interrupts() { unsafe { asm!("cli") } }
|
pub fn disable_interrupts() { unsafe { asm!("cli") } }
|
||||||
|
|
||||||
/// PoppedInterrupts implements drop and restores the interrupts upon being
|
/// PoppedInterrupts implements drop and restores the interrupts upon being
|
||||||
|
@ -37,7 +35,6 @@ impl Drop for PoppedInterrupts {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Disables interrupts and returns the value of them.
|
/// Disables interrupts and returns the value of them.
|
||||||
#[aphrodite_proc_macros::kernel_item(InterruptsPop)]
|
|
||||||
pub fn pop_irq() -> PoppedInterrupts {
|
pub fn pop_irq() -> PoppedInterrupts {
|
||||||
let flags: u32;
|
let flags: u32;
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -51,7 +48,6 @@ pub fn pop_irq() -> PoppedInterrupts {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Restores interrupts after a [pop_irq] call.
|
/// Restores interrupts after a [pop_irq] call.
|
||||||
#[aphrodite_proc_macros::kernel_item(InterruptsRestore)]
|
|
||||||
pub fn restore_irq(flags: PoppedInterrupts) {
|
pub fn restore_irq(flags: PoppedInterrupts) {
|
||||||
let flags = flags.0;
|
let flags = flags.0;
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -76,7 +72,7 @@ unsafe fn load_idt(base: *const u8, size: usize) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub(super) struct IdtEntry {
|
pub struct IdtEntry {
|
||||||
pub offset_high: u16,
|
pub offset_high: u16,
|
||||||
pub data: u16,
|
pub data: u16,
|
||||||
pub segment: u16,
|
pub segment: u16,
|
||||||
|
@ -108,8 +104,7 @@ impl From<IdtEntry> for RawIdtEntry {
|
||||||
///
|
///
|
||||||
/// # Panics
|
/// # Panics
|
||||||
/// Panics if the global allocator has not been setup
|
/// Panics if the global allocator has not been setup
|
||||||
#[aphrodite_proc_macros::kernel_item(ActivateIDT)]
|
pub unsafe fn activate_idt(idt: Idt) {
|
||||||
fn activate_idt(idt: Idt) {
|
|
||||||
let mut entries = alloc::vec::Vec::new();
|
let mut entries = alloc::vec::Vec::new();
|
||||||
for i in 0..idt.len {
|
for i in 0..idt.len {
|
||||||
if idt.using_raw[i] {
|
if idt.using_raw[i] {
|
||||||
|
@ -195,7 +190,7 @@ fn activate_idt(idt: Idt) {
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub struct Idt {
|
pub struct Idt {
|
||||||
vectors: [u16; 256],
|
vectors: [u16; 256],
|
||||||
funcs: [MaybeUninit<fn()>; 256],
|
funcs: [MaybeUninit<unsafe fn()>; 256],
|
||||||
user_callable: [bool; 256],
|
user_callable: [bool; 256],
|
||||||
exception: [bool; 256],
|
exception: [bool; 256],
|
||||||
raw_entries: [IdtEntry; 256],
|
raw_entries: [IdtEntry; 256],
|
||||||
|
@ -207,7 +202,7 @@ pub struct Idt {
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub struct IdtBuilder {
|
pub struct IdtBuilder {
|
||||||
vectors: [u16; 256],
|
vectors: [u16; 256],
|
||||||
funcs: [MaybeUninit<fn()>; 256],
|
funcs: [MaybeUninit<unsafe fn()>; 256],
|
||||||
user_callable: [bool; 256],
|
user_callable: [bool; 256],
|
||||||
exception: [bool; 256],
|
exception: [bool; 256],
|
||||||
raw_entries: [IdtEntry; 256],
|
raw_entries: [IdtEntry; 256],
|
||||||
|
@ -238,7 +233,7 @@ impl IdtBuilder {
|
||||||
pub fn add_fn(
|
pub fn add_fn(
|
||||||
&mut self,
|
&mut self,
|
||||||
vector: u16,
|
vector: u16,
|
||||||
func: fn(),
|
func: unsafe fn(),
|
||||||
user_callable: bool,
|
user_callable: bool,
|
||||||
exception: bool,
|
exception: bool,
|
||||||
) -> &mut Self {
|
) -> &mut Self {
|
||||||
|
|
|
@ -1,180 +0,0 @@
|
||||||
//! Hardware-level memory sections. Unimplemented for certain hardware, x86
|
|
||||||
//! implements with GDT.
|
|
||||||
#![cfg(target_arch = "x86")]
|
|
||||||
|
|
||||||
use core::arch::asm;
|
|
||||||
|
|
||||||
use alloc::vec;
|
|
||||||
use alloc::vec::Vec;
|
|
||||||
|
|
||||||
use crate::memsections::*;
|
|
||||||
|
|
||||||
use super::gdt::{GDTEntry, write_gdt_entries};
|
|
||||||
|
|
||||||
/// A list of memory sections. Create one with [MemorySectionBuilder].
|
|
||||||
pub struct MemorySections {
|
|
||||||
sections: Vec<MemorySection>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[repr(packed)]
|
|
||||||
struct GDTR {
|
|
||||||
address: u32,
|
|
||||||
size: u16,
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe impl crate::memsections::MemorySections for MemorySections {
|
|
||||||
unsafe fn write(self) -> Result<(), crate::Error<'static>> {
|
|
||||||
let mut entries: Vec<GDTEntry> = vec![];
|
|
||||||
|
|
||||||
for section in self.sections {
|
|
||||||
let mut section: MemorySection = section;
|
|
||||||
// rust-analyzer doesn't want to cooperate and recognize that section is already
|
|
||||||
// MemorySection, so I'm telling it here.
|
|
||||||
fn make_entry(section: &mut MemorySection, entries: &mut Vec<GDTEntry>) {
|
|
||||||
if section.length == 0 {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let mut len = section.length as u32;
|
|
||||||
while len > 0xFFFFF {
|
|
||||||
len -= 0xFFFFF;
|
|
||||||
}
|
|
||||||
let mut access = 0b10000001u8;
|
|
||||||
match section.owner {
|
|
||||||
Owner::Kernelspace => {
|
|
||||||
access |= 0b0000000;
|
|
||||||
},
|
|
||||||
Owner::Modulespace => {
|
|
||||||
access |= 0b0100000;
|
|
||||||
},
|
|
||||||
Owner::Userspace => {
|
|
||||||
access |= 0b1100000;
|
|
||||||
},
|
|
||||||
}
|
|
||||||
if let SectionType::TaskSection { busy } = section.section_type {
|
|
||||||
access |= 0b00000;
|
|
||||||
if busy {
|
|
||||||
access |= 0x9;
|
|
||||||
} else {
|
|
||||||
access |= 0xB;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
access |= 0b10000;
|
|
||||||
if let SectionType::CodeSection {
|
|
||||||
can_powerful_sections_jump,
|
|
||||||
} = section.section_type
|
|
||||||
{
|
|
||||||
access |= 0b1000;
|
|
||||||
if can_powerful_sections_jump {
|
|
||||||
access |= 0b100;
|
|
||||||
}
|
|
||||||
if section.readable {
|
|
||||||
access |= 0b10;
|
|
||||||
}
|
|
||||||
} else if section.section_type == SectionType::DataSection {
|
|
||||||
access |= 0b0000;
|
|
||||||
if section.writable {
|
|
||||||
access |= 0b10;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let flags = 0b1100u8;
|
|
||||||
|
|
||||||
let entry = GDTEntry {
|
|
||||||
limit: len,
|
|
||||||
base: section.address as u32,
|
|
||||||
access,
|
|
||||||
flags,
|
|
||||||
};
|
|
||||||
if section.length > 0xFFFFF {
|
|
||||||
section.length -= 0xFFFFF;
|
|
||||||
}
|
|
||||||
entries.push(entry);
|
|
||||||
}
|
|
||||||
while section.length > 0xFFFFF {
|
|
||||||
make_entry(&mut section, &mut entries);
|
|
||||||
}
|
|
||||||
make_entry(&mut section, &mut entries);
|
|
||||||
}
|
|
||||||
unsafe {
|
|
||||||
let _ = super::interrupts::pop_irq();
|
|
||||||
|
|
||||||
let segment_entries: Vec<GDTEntry> = entries.clone();
|
|
||||||
|
|
||||||
let ptr = write_gdt_entries(entries)?;
|
|
||||||
|
|
||||||
let gdtr = GDTR {
|
|
||||||
address: ptr as *const u8 as usize as u32,
|
|
||||||
size: (ptr.len() - 1) as u16,
|
|
||||||
};
|
|
||||||
|
|
||||||
let addr = &gdtr as *const GDTR as *const () as usize as u32;
|
|
||||||
|
|
||||||
asm!(
|
|
||||||
"lgdt eax",
|
|
||||||
in("eax") addr
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut code_segment = 0u16;
|
|
||||||
let mut code_set = false;
|
|
||||||
let mut data_segment = 0u16;
|
|
||||||
let mut data_set = false;
|
|
||||||
|
|
||||||
let mut i = 0;
|
|
||||||
for entry in segment_entries {
|
|
||||||
let entry: GDTEntry = entry;
|
|
||||||
i += 1;
|
|
||||||
if code_set && data_set {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if entry.access & 0b11000 == 0b11000 && !code_set {
|
|
||||||
code_segment = i - 1;
|
|
||||||
code_set = true;
|
|
||||||
} else if entry.access & 0b10000 == 0b10000 && !data_set {
|
|
||||||
data_segment = i - 1;
|
|
||||||
data_set = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
asm!(
|
|
||||||
"jmp bx:2 ; `#[deny(named_asm_labels)]` on by default; see <https://doc.rust-lang.org/nightly/rust-by-example/unsafe/asm.html#labels>
|
|
||||||
2: ; ax is already loaded with the correct value from rustland
|
|
||||||
mov ds, ax
|
|
||||||
mov es, ax
|
|
||||||
mov fs, ax
|
|
||||||
mov gs, ax
|
|
||||||
mov ss, ax",
|
|
||||||
in("bx") code_segment,
|
|
||||||
in("ax") data_segment,
|
|
||||||
options(preserves_flags, nomem, nostack)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A memory section builder.
|
|
||||||
pub struct MemorySectionBuilder {
|
|
||||||
sections: Vec<MemorySection>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl MemorySectionBuilder {
|
|
||||||
/// Create a new MemorySectionBuilder.
|
|
||||||
pub fn new() -> Self { MemorySectionBuilder { sections: vec![] } }
|
|
||||||
|
|
||||||
/// Adds a section to this MemorySectionBuilder.
|
|
||||||
pub fn add_section(&mut self, section: MemorySection) -> &mut Self {
|
|
||||||
self.sections.push(section);
|
|
||||||
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Finishes this MemorySectionBuilder and returns a MemorySections.
|
|
||||||
pub fn finish(self) -> MemorySections {
|
|
||||||
MemorySections {
|
|
||||||
sections: self.sections,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -5,8 +5,8 @@ use core::arch::asm;
|
||||||
|
|
||||||
pub mod egatext;
|
pub mod egatext;
|
||||||
mod gdt;
|
mod gdt;
|
||||||
|
mod interrupt_impls;
|
||||||
pub mod interrupts;
|
pub mod interrupts;
|
||||||
pub mod memory;
|
|
||||||
pub mod output;
|
pub mod output;
|
||||||
pub mod paging;
|
pub mod paging;
|
||||||
pub mod ports;
|
pub mod ports;
|
||||||
|
@ -92,10 +92,10 @@ pub fn initalize_rtc() {
|
||||||
unsafe { RTC_INITALIZED = true }
|
unsafe { RTC_INITALIZED = true }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sleep(seconds: u32) { initalize_rtc(); }
|
|
||||||
|
|
||||||
pub fn alloc_available_boot() {
|
pub fn alloc_available_boot() {
|
||||||
let irq = pop_irq();
|
let irq = pop_irq();
|
||||||
|
{
|
||||||
|
// GDT
|
||||||
let mut entries = vec![];
|
let mut entries = vec![];
|
||||||
entries.push(gdt::GDT_NULL_ENTRY);
|
entries.push(gdt::GDT_NULL_ENTRY);
|
||||||
entries.push(GDTEntry {
|
entries.push(GDTEntry {
|
||||||
|
@ -103,16 +103,52 @@ pub fn alloc_available_boot() {
|
||||||
base: 0,
|
base: 0,
|
||||||
access: 0b10011011,
|
access: 0b10011011,
|
||||||
flags: 0b1100,
|
flags: 0b1100,
|
||||||
}); // kernel code segment
|
}); // kernel code segment, segment 0x08
|
||||||
entries.push(GDTEntry {
|
entries.push(GDTEntry {
|
||||||
limit: 0,
|
limit: 0,
|
||||||
base: 0,
|
base: 0,
|
||||||
access: 0b10010011,
|
access: 0b10010011,
|
||||||
flags: 0b1100,
|
flags: 0b1100,
|
||||||
}); //
|
}); // kernel data segment, segment 0x10
|
||||||
|
entries.push(GDTEntry {
|
||||||
|
limit: 0,
|
||||||
|
base: 0,
|
||||||
|
access: 0b11111011,
|
||||||
|
flags: 0b1100,
|
||||||
|
}); // user code segment, segment 0x18
|
||||||
|
entries.push(GDTEntry {
|
||||||
|
limit: 0,
|
||||||
|
base: 0,
|
||||||
|
access: 0b11110011,
|
||||||
|
flags: 0b1100,
|
||||||
|
}); // user data segment, segment 0x20
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
gdt::activate_gdt(gdt::write_gdt_entries(entries).unwrap());
|
gdt::activate_gdt(gdt::write_gdt_entries(entries).unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
asm!(
|
||||||
|
"jmp 0x08:2",
|
||||||
|
"2:",
|
||||||
|
"mov ax, 0x10",
|
||||||
|
"mov ds, ax",
|
||||||
|
"mov es, ax",
|
||||||
|
"mov fs, ax",
|
||||||
|
"mov gs, ax",
|
||||||
|
"mov ss, ax",
|
||||||
|
out("ax") _
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
// IDT
|
||||||
|
let idt = self::interrupts::IdtBuilder::new()
|
||||||
|
.add_fn(0, interrupt_impls::int0, false, true)
|
||||||
|
.finish();
|
||||||
|
unsafe {
|
||||||
|
interrupts::activate_idt(idt);
|
||||||
|
}
|
||||||
|
}
|
||||||
restore_irq(irq);
|
restore_irq(irq);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,8 +3,6 @@
|
||||||
|
|
||||||
use core::arch::asm;
|
use core::arch::asm;
|
||||||
|
|
||||||
use aphrodite_proc_macros::kernel_item;
|
|
||||||
|
|
||||||
/// One page directory entry. Use [PageDirectoryEntry::create_fourmb] or
|
/// One page directory entry. Use [PageDirectoryEntry::create_fourmb] or
|
||||||
/// [PageDirectoryEntry::create_other] to make these.
|
/// [PageDirectoryEntry::create_other] to make these.
|
||||||
pub enum PageDirectoryEntry {
|
pub enum PageDirectoryEntry {
|
||||||
|
@ -120,11 +118,9 @@ static mut PAGE_DIRECTORY: PageDirectoryEntry =
|
||||||
PageDirectoryEntry::create_other(0, false, 0, false, false, false, false, false, false, false);
|
PageDirectoryEntry::create_other(0, false, 0, false, false, false, false, false, false, false);
|
||||||
|
|
||||||
/// Initalize paging.
|
/// Initalize paging.
|
||||||
#[kernel_item(PagingInit)]
|
|
||||||
pub fn initalize_paging() {}
|
pub fn initalize_paging() {}
|
||||||
|
|
||||||
/// Disables paging by clearing bit 31 in the cr0 register.
|
/// Disables paging by clearing bit 31 in the cr0 register.
|
||||||
#[kernel_item(PagingDeinit)]
|
|
||||||
pub fn disable_paging() {
|
pub fn disable_paging() {
|
||||||
unsafe {
|
unsafe {
|
||||||
asm!(
|
asm!(
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//! Config-related stuff.
|
//! Config-related stuff.
|
||||||
|
|
||||||
/// C
|
/// Get configurations as a certain type
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! cfg_int {
|
macro_rules! cfg_int {
|
||||||
($cfg:literal, $type:ident) => {
|
($cfg:literal, $type:ident) => {
|
||||||
|
|
|
@ -7,11 +7,8 @@ use crate::arch::output::*;
|
||||||
use crate::display::{COLOR_DEFAULT, NoneTextDisplay};
|
use crate::display::{COLOR_DEFAULT, NoneTextDisplay};
|
||||||
use crate::output::*;
|
use crate::output::*;
|
||||||
|
|
||||||
use aphrodite_proc_macros::*;
|
|
||||||
|
|
||||||
/// The real entrypoint to the kernel. `internel/arch/*/entry.rs` files
|
/// The real entrypoint to the kernel. `internel/arch/*/entry.rs` files
|
||||||
/// eventually call this.
|
/// eventually call this.
|
||||||
#[kernel_item(IndepBootEntry)]
|
|
||||||
fn indep_boot_entry(
|
fn indep_boot_entry(
|
||||||
display: Option<&dyn crate::display::TextDisplay>,
|
display: Option<&dyn crate::display::TextDisplay>,
|
||||||
#[allow(non_snake_case)] BI: &crate::boot::BootInfo,
|
#[allow(non_snake_case)] BI: &crate::boot::BootInfo,
|
||||||
|
@ -24,11 +21,11 @@ fn indep_boot_entry(
|
||||||
|
|
||||||
let display = display.unwrap_or(&NoneTextDisplay {});
|
let display = display.unwrap_or(&NoneTextDisplay {});
|
||||||
|
|
||||||
display.clear_screen(COLOR_DEFAULT);
|
display.clear_screen(COLOR_DEFAULT).unwrap();
|
||||||
sreset();
|
sreset();
|
||||||
|
|
||||||
let mem_map = BI.memory_map.unwrap();
|
let mem_map = BI.memory_map.unwrap();
|
||||||
crate::mem::MemMapAllocInit(mem_map).unwrap();
|
crate::mem::memory_map_alloc_init(mem_map).unwrap();
|
||||||
|
|
||||||
crate::arch::alloc_available_boot();
|
crate::arch::alloc_available_boot();
|
||||||
|
|
||||||
|
|
|
@ -9,8 +9,6 @@ use core::ptr::{NonNull, null_mut};
|
||||||
|
|
||||||
use crate::boot::{MemoryMap, MemoryType};
|
use crate::boot::{MemoryMap, MemoryType};
|
||||||
|
|
||||||
use aphrodite_proc_macros::*;
|
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
struct Allocation {
|
struct Allocation {
|
||||||
/// Whether this allocation is used. This is used so that the
|
/// Whether this allocation is used. This is used so that the
|
||||||
|
@ -65,7 +63,6 @@ static mut ALLOCATOR: MaybeMemoryMapAlloc<'static> = MaybeMemoryMapAlloc::new(No
|
||||||
static mut ALLOCATOR_MEMMAP: MaybeUninit<MemoryMap> = MaybeUninit::uninit();
|
static mut ALLOCATOR_MEMMAP: MaybeUninit<MemoryMap> = MaybeUninit::uninit();
|
||||||
static mut ALLOCATOR_INITALIZED: bool = false;
|
static mut ALLOCATOR_INITALIZED: bool = false;
|
||||||
|
|
||||||
#[kernel_item(MemMapAlloc)]
|
|
||||||
pub fn get_allocator() -> Option<&'static MemoryMapAlloc<'static>> {
|
pub fn get_allocator() -> Option<&'static MemoryMapAlloc<'static>> {
|
||||||
if unsafe { ALLOCATOR_INITALIZED } {
|
if unsafe { ALLOCATOR_INITALIZED } {
|
||||||
#[allow(static_mut_refs)]
|
#[allow(static_mut_refs)]
|
||||||
|
@ -90,8 +87,7 @@ pub unsafe fn get_allocator_unchecked() -> &'static MemoryMapAlloc<'static> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[kernel_item(MemMapAllocInit)]
|
pub fn memory_map_alloc_init(memmap: crate::boot::MemoryMap) -> Result<(), crate::Error<'static>> {
|
||||||
fn memory_map_alloc_init(memmap: crate::boot::MemoryMap) -> Result<(), crate::Error<'static>> {
|
|
||||||
#[allow(static_mut_refs)]
|
#[allow(static_mut_refs)]
|
||||||
unsafe {
|
unsafe {
|
||||||
ALLOCATOR_MEMMAP.write(memmap);
|
ALLOCATOR_MEMMAP.write(memmap);
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#![allow(internal_features)]
|
#![allow(internal_features)]
|
||||||
#![feature(core_intrinsics)]
|
#![feature(core_intrinsics)]
|
||||||
#![feature(vec_into_raw_parts)]
|
#![feature(vec_into_raw_parts)]
|
||||||
|
#![feature(naked_functions)]
|
||||||
|
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
|
|
||||||
|
|
|
@ -1,62 +0,0 @@
|
||||||
use proc_macro::TokenStream;
|
|
||||||
use quote::{ToTokens, quote};
|
|
||||||
use syn::parse::{Parse, ParseStream};
|
|
||||||
use syn::{ItemFn, Signature, Token};
|
|
||||||
|
|
||||||
struct KernelItemNameInput {
|
|
||||||
item: syn::Ident,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Parse for KernelItemNameInput {
|
|
||||||
fn parse(input: ParseStream) -> syn::Result<Self> {
|
|
||||||
let item: syn::Ident = input.parse()?;
|
|
||||||
Ok(KernelItemNameInput { item })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn to_tokens(signature: Signature, tokens: &mut proc_macro2::TokenStream) {
|
|
||||||
let ts = tokens;
|
|
||||||
signature.constness.to_tokens(ts);
|
|
||||||
signature.asyncness.to_tokens(ts);
|
|
||||||
signature.unsafety.to_tokens(ts);
|
|
||||||
signature.abi.to_tokens(ts);
|
|
||||||
signature.fn_token.to_tokens(ts);
|
|
||||||
signature.generics.to_tokens(ts);
|
|
||||||
signature.paren_token.surround(ts, |tokens| {
|
|
||||||
signature.inputs.to_tokens(tokens);
|
|
||||||
if let Some(variadic) = &signature.variadic {
|
|
||||||
if !signature.inputs.empty_or_trailing() {
|
|
||||||
<Token![,]>::default().to_tokens(tokens);
|
|
||||||
}
|
|
||||||
variadic.to_tokens(tokens);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
signature.output.to_tokens(ts);
|
|
||||||
signature.generics.where_clause.to_tokens(ts);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn to_token_stream(signature: Signature) -> proc_macro2::TokenStream {
|
|
||||||
let mut tokens = proc_macro2::TokenStream::new();
|
|
||||||
to_tokens(signature, &mut tokens);
|
|
||||||
tokens
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Implement a kernel item.
|
|
||||||
#[proc_macro_attribute]
|
|
||||||
pub fn kernel_item(attr: TokenStream, item: TokenStream) -> TokenStream {
|
|
||||||
let name: KernelItemNameInput = syn::parse_macro_input!(attr);
|
|
||||||
let item_name = name.item;
|
|
||||||
|
|
||||||
let input_fn = syn::parse_macro_input!(item as ItemFn);
|
|
||||||
let fn_name = input_fn.clone().sig.ident;
|
|
||||||
let fn_sig = to_token_stream(input_fn.clone().sig);
|
|
||||||
|
|
||||||
quote! {
|
|
||||||
/// The #item_name kernel item.
|
|
||||||
#[allow(non_upper_case_globals)]
|
|
||||||
pub const #item_name: #fn_sig = #fn_name;
|
|
||||||
|
|
||||||
#input_fn
|
|
||||||
}
|
|
||||||
.into()
|
|
||||||
}
|
|
Loading…
Add table
Add a link
Reference in a new issue