#![doc = include_str!("../README.md")]
#![no_std]
#![no_main]
#![feature(abi_x86_interrupt)]
#![feature(let_chains)]
#![feature(naked_functions)]
#![allow(clippy::assertions_on_constants)]
#![allow(clippy::redundant_pattern_matching)]
use core::arch::global_asm;
use core::panic::PanicInfo;
use multiboot as mb;
#[macro_use]
mod device;
#[macro_use]
mod arch;
mod assignments;
mod gdt;
#[cfg(feature = "graphics")]
mod graphics;
mod interrupts;
mod multiboot;
mod threading;
mod user;
mod util;
use device::cga::Window;
use device::KEYBOARD;
use crate::arch::acpi::Acpi;
#[cfg(feature = "smp")]
use crate::arch::smp;
use crate::arch::{cpu, int};
use crate::device::{DBG, KOUT};
#[cfg(feature = "smp")]
const MAX_CPUS: usize = 4;
#[cfg(not(feature = "smp"))]
const MAX_CPUS: usize = 1;
#[cfg(not(feature = "graphics"))]
const FLAGS: u32 = mb::Header::PAGE_ALIGN | mb::Header::MEM_INFO;
#[cfg(feature = "graphics")]
const FLAGS: u32 = mb::Header::PAGE_ALIGN | mb::Header::MEM_INFO | mb::Header::VIDEO_MODE;
const SCREEN_WIDTH: usize = 1280;
const SCREEN_HEIGHT: usize = 1024;
#[link_section = ".multiboot"]
#[no_mangle]
pub static MBOOT: mb::Header = mb::Header::new(FLAGS, SCREEN_WIDTH as _, SCREEN_HEIGHT as _, 32);
#[no_mangle]
pub static mut MBOOT_SIG: u32 = 0;
#[no_mangle]
pub static mut MBOOT_PTR: u32 = 0;
global_asm!(include_str!("start.s"), options(raw));
#[allow(unused)]
extern "C" {
static KERNEL_BEGIN: u8;
static KERNEL_END: u8;
static start_high: u8;
}
const STACK_S: usize = 16 * 1024;
#[no_mangle]
pub static STACK_SIZE: usize = STACK_S;
#[no_mangle]
pub static mut INIT_STACKS: [[u32; STACK_S / 4]; MAX_CPUS] = [[0; STACK_S / 4]; MAX_CPUS];
#[no_mangle]
pub extern "C" fn main() -> ! {
if cpu::online() == 0 {
Window::whole().clear();
unsafe { DBG.clear() };
unsafe { KOUT.clear() };
println!("Hello World!");
let acpi = Acpi::load().unwrap();
serial!("global int");
#[allow(unused_variables)]
let cpus = interrupts::setup_global(acpi);
interrupts::setup_local();
unsafe { KEYBOARD.init() };
#[cfg(feature = "smp")]
if cpus > 1 {
smp::boot();
while cpu::online().count_ones() < cpus as u32 {
core::hint::spin_loop();
}
}
} else {
interrupts::setup_local();
}
loop {
int::enable(false);
cpu::halt();
}
}
#[panic_handler]
fn panic(info: &PanicInfo) -> ! {
serial!(force: "{info}");
debug!("{info}");
loop {
int::enable(false);
cpu::halt();
}
}