2023-05-06 06:50:24 -05:00
|
|
|
use {limine::SmpRequest, xml::XMLElement};
|
|
|
|
|
|
|
|
use embedded_graphics::pixelcolor::Rgb888;
|
|
|
|
|
|
|
|
use crate::{arch::x86_64::graphics::DISPLAY, kmain::DEVICE_TREE};
|
|
|
|
|
2023-03-30 16:43:04 -05:00
|
|
|
pub mod memory;
|
|
|
|
|
2023-05-06 06:50:24 -05:00
|
|
|
mod cpuid;
|
2023-03-30 16:43:04 -05:00
|
|
|
mod gdt;
|
2023-05-06 06:50:24 -05:00
|
|
|
mod graphics;
|
2023-04-07 16:44:33 -05:00
|
|
|
pub(crate) mod interrupts;
|
2023-03-30 16:43:04 -05:00
|
|
|
mod logging;
|
2023-05-06 06:50:24 -05:00
|
|
|
pub mod pci;
|
|
|
|
pub mod virtio;
|
2023-03-30 16:43:04 -05:00
|
|
|
|
2023-05-06 06:50:24 -05:00
|
|
|
pub use {logging::log, memory::PAGE_SIZE};
|
2023-03-30 16:43:04 -05:00
|
|
|
|
2023-05-06 06:50:24 -05:00
|
|
|
use {
|
|
|
|
crate::allocator,
|
|
|
|
limine::{HhdmRequest, KernelFileRequest, MemmapRequest, ModuleRequest},
|
|
|
|
x86_64::VirtAddr,
|
|
|
|
};
|
2023-03-30 16:43:04 -05:00
|
|
|
|
|
|
|
extern "C" {
|
|
|
|
fn _initial_kernel_heap_start();
|
|
|
|
fn _initial_kernel_heap_size();
|
|
|
|
}
|
|
|
|
|
|
|
|
const INITIAL_KERNEL_HEAP_START: *mut u8 = _initial_kernel_heap_start as _;
|
|
|
|
const INITIAL_KERNEL_HEAP_SIZE: *const () = _initial_kernel_heap_size as _;
|
|
|
|
|
|
|
|
#[no_mangle]
|
|
|
|
unsafe extern "C" fn _kernel_start() -> ! {
|
|
|
|
logging::init();
|
|
|
|
crate::logger::init().expect("failed to set logger");
|
|
|
|
log::info!("Initialising AKern {}", crate::VERSION);
|
|
|
|
|
|
|
|
static HDHM_REQ: HhdmRequest = HhdmRequest::new(0);
|
|
|
|
memory::init_pt(VirtAddr::new(
|
|
|
|
HDHM_REQ
|
|
|
|
.get_response()
|
|
|
|
.get()
|
|
|
|
.expect("tried to get physical memory mapping offset from Limine")
|
|
|
|
.offset,
|
|
|
|
));
|
|
|
|
|
|
|
|
allocator::init(INITIAL_KERNEL_HEAP_START, INITIAL_KERNEL_HEAP_SIZE as _);
|
|
|
|
|
|
|
|
static MMAP_REQ: MemmapRequest = MemmapRequest::new(0);
|
|
|
|
memory::initialize(
|
|
|
|
MMAP_REQ
|
|
|
|
.get_response()
|
|
|
|
.get()
|
|
|
|
.expect("tried to get memory map from Limine")
|
|
|
|
.memmap(),
|
|
|
|
);
|
|
|
|
|
|
|
|
gdt::init();
|
|
|
|
interrupts::init();
|
|
|
|
|
|
|
|
static KFILE_REQ: KernelFileRequest = KernelFileRequest::new(0);
|
|
|
|
static MOD_REQ: ModuleRequest = ModuleRequest::new(0);
|
2023-04-05 12:29:20 -05:00
|
|
|
|
2023-05-06 06:50:24 -05:00
|
|
|
static SMP: SmpRequest = SmpRequest::new(0);
|
|
|
|
let smp = SMP.get_response().get().unwrap();
|
|
|
|
use crate::alloc::string::ToString;
|
|
|
|
|
|
|
|
let cpuinfo = cpuid::master().unwrap();
|
|
|
|
let brand_string = cpuinfo.brand_string().unwrap_or("Unknown").to_string();
|
|
|
|
DEVICE_TREE.force_unlock();
|
|
|
|
|
|
|
|
pci::init();
|
|
|
|
|
|
|
|
let mut dt = DEVICE_TREE.lock();
|
|
|
|
|
|
|
|
let cpus = dt.devices.get_mut("CPUs").unwrap();
|
|
|
|
let mut cpu = XMLElement::new("cpu");
|
|
|
|
let core_count = smp.cpu_count.to_string();
|
|
|
|
cpu.set_attribute("core count", core_count);
|
|
|
|
cpu.set_attribute("brand string", brand_string);
|
|
|
|
|
|
|
|
let cpu_speed = 0;
|
|
|
|
|
|
|
|
cpu.set_attribute("speed", "Unknown");
|
|
|
|
|
|
|
|
if false {
|
|
|
|
// disable() // disable interrupts (if still not done)
|
|
|
|
let i = 0;
|
|
|
|
let start = cpuinfo.time_stamp_counter();
|
|
|
|
|
|
|
|
log::info!("{:?}", start.unwrap().invariant_tsc());
|
|
|
|
for x in 0..1000 {}
|
|
|
|
let end = cpuinfo.time_stamp_counter();
|
|
|
|
}
|
|
|
|
|
|
|
|
let mut cpu_features = xml::XMLElement::new("CPU Features");
|
|
|
|
{
|
|
|
|
let x2 = cpuinfo.x2apic();
|
|
|
|
let apic = cpuinfo.apic();
|
|
|
|
let avx = cpuinfo.avx();
|
|
|
|
|
|
|
|
cpu_features.set_attribute("apic", apic.to_string());
|
|
|
|
cpu_features.set_attribute("avx", apic.to_string());
|
|
|
|
cpu_features.set_attribute("x2apic", x2.to_string());
|
|
|
|
}
|
|
|
|
|
|
|
|
cpu.set_child(cpu_features);
|
|
|
|
cpus.push(cpu);
|
|
|
|
drop(dt);
|
|
|
|
|
|
|
|
// Graphics test
|
|
|
|
{
|
|
|
|
let mut dis = DISPLAY.lock();
|
|
|
|
use {able_graphics_library::raw_pixel, embedded_graphics::prelude::RgbColor};
|
|
|
|
|
|
|
|
dis.set_color(Rgb888::GREEN);
|
|
|
|
|
|
|
|
dis.line(1, 1, 10, 10, 4);
|
|
|
|
dis.line(1, 200, 100, 10, 1);
|
|
|
|
dis.line(1, 1, 200, 10, 1);
|
|
|
|
}
|
|
|
|
|
2023-03-30 16:43:04 -05:00
|
|
|
crate::kmain::kmain(
|
|
|
|
KFILE_REQ
|
|
|
|
.get_response()
|
|
|
|
.get()
|
|
|
|
.and_then(|r| r.kernel_file.get())
|
|
|
|
.expect("failed to get kernel file from Limine")
|
|
|
|
.cmdline
|
|
|
|
.to_str()
|
|
|
|
.map(core::ffi::CStr::to_str)
|
|
|
|
.transpose()
|
|
|
|
.expect("expected valid cmdline string")
|
|
|
|
.unwrap_or_default(),
|
|
|
|
MOD_REQ
|
|
|
|
.get_response()
|
|
|
|
.get()
|
|
|
|
.and_then(|m| m.modules().get(0))
|
|
|
|
.map(|file| unsafe {
|
|
|
|
core::slice::from_raw_parts(
|
|
|
|
file.base.as_ptr().expect("invalid initrd"),
|
|
|
|
file.length as usize,
|
|
|
|
)
|
|
|
|
}),
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Spin loop
|
|
|
|
pub fn sloop() -> ! {
|
|
|
|
loop {
|
|
|
|
x86_64::instructions::hlt();
|
|
|
|
}
|
|
|
|
}
|
2023-04-07 16:44:33 -05:00
|
|
|
|
|
|
|
pub fn hardware_random_u64() -> u64 {
|
2023-05-06 06:50:24 -05:00
|
|
|
use {log::trace, rdrand::RdRand};
|
2023-04-07 16:44:33 -05:00
|
|
|
let gen = RdRand::new().unwrap();
|
|
|
|
let ret = gen.try_next_u64().unwrap();
|
|
|
|
trace!("Random {}", ret);
|
|
|
|
|
|
|
|
ret
|
|
|
|
}
|