Skip to content
Snippets Groups Projects
Commit ae2b2067 authored by Eemeli Lehtonen's avatar Eemeli Lehtonen
Browse files

SMP

parent 461c7fbc
No related branches found
No related tags found
No related merge requests found
Showing
with 190 additions and 25 deletions
...@@ -44,6 +44,7 @@ if [ "$(basename $KERNEL)" = "hyperion" ]; then ...@@ -44,6 +44,7 @@ if [ "$(basename $KERNEL)" = "hyperion" ]; then
-enable-kvm \ -enable-kvm \
-machine q35 \ -machine q35 \
-cpu qemu64 \ -cpu qemu64 \
-smp 8 \
-M smm=off \ -M smm=off \
-d int,guest_errors,cpu_reset \ -d int,guest_errors,cpu_reset \
-no-reboot \ -no-reboot \
...@@ -59,6 +60,7 @@ else ...@@ -59,6 +60,7 @@ else
-enable-kvm \ -enable-kvm \
-machine q35 \ -machine q35 \
-cpu qemu64 \ -cpu qemu64 \
-smp 8 \
-M smm=off \ -M smm=off \
-d int,guest_errors,cpu_reset \ -d int,guest_errors,cpu_reset \
-device isa-debug-exit,iobase=0xf4,iosize=0x04 \ -device isa-debug-exit,iobase=0xf4,iosize=0x04 \
......
...@@ -10,8 +10,8 @@ use std::{ ...@@ -10,8 +10,8 @@ use std::{
fn main() -> Result<(), Box<dyn Error>> { fn main() -> Result<(), Box<dyn Error>> {
let kernel = var("CARGO_PKG_NAME")?; let kernel = var("CARGO_PKG_NAME")?;
println!("cargo:rerun-if-env-changed=CARGO_PKG_NAME"); println!("cargo:rerun-if-env-changed=CARGO_PKG_NAME");
let arch = var("CARGO_CFG_TARGET_ARCH")?; //let arch = var("CARGO_CFG_TARGET_ARCH")?;
println!("cargo:rerun-if-env-changed=CARGO_CFG_TARGET_ARCH"); //println!("cargo:rerun-if-env-changed=CARGO_CFG_TARGET_ARCH");
let mut bootloader: Option<&'static str> = None; let mut bootloader: Option<&'static str> = None;
let mut set = |s| { let mut set = |s| {
...@@ -32,7 +32,7 @@ fn main() -> Result<(), Box<dyn Error>> { ...@@ -32,7 +32,7 @@ fn main() -> Result<(), Box<dyn Error>> {
set("multiboot2"); set("multiboot2");
if let Some(bootloader) = bootloader { if let Some(bootloader) = bootloader {
let script = format!("src/arch/{arch}/{bootloader}/link.ld"); let script = format!("src/boot/{bootloader}/link.ld");
println!("cargo:rustc-link-arg-bin={kernel}=--script={script}"); println!("cargo:rustc-link-arg-bin={kernel}=--script={script}");
println!("cargo:rerun-if-changed={script}"); println!("cargo:rerun-if-changed={script}");
} else { } else {
......
use super::idt::DOUBLE_FAULT_IST; use super::idt::DOUBLE_FAULT_IST;
use crate::debug; use crate::debug;
use spin::Lazy; use spin::{Lazy, Once};
use x86_64::{ use x86_64::{
instructions::tables::load_tss, instructions::tables::load_tss,
registers::segmentation::{Segment, CS, SS}, registers::segmentation::{Segment, CS, SS},
...@@ -15,7 +15,7 @@ use x86_64::{ ...@@ -15,7 +15,7 @@ use x86_64::{
pub fn init() { pub fn init() {
debug!("Initializing GDT"); debug!("Initializing GDT");
GDT.0.load(); GDT_ONCE.call_once(|| GDT.0.load());
unsafe { unsafe {
CS::set_reg(GDT.1.kc); CS::set_reg(GDT.1.kc);
...@@ -43,6 +43,7 @@ static GDT: Lazy<(GlobalDescriptorTable, SegmentSelectors)> = Lazy::new(|| { ...@@ -43,6 +43,7 @@ static GDT: Lazy<(GlobalDescriptorTable, SegmentSelectors)> = Lazy::new(|| {
// gdt.add_entry(Descriptor::user_data_segment()); // gdt.add_entry(Descriptor::user_data_segment());
(gdt, sel) (gdt, sel)
}); });
static GDT_ONCE: Once<()> = Once::new();
static TSS: Lazy<TaskStateSegment> = Lazy::new(|| { static TSS: Lazy<TaskStateSegment> = Lazy::new(|| {
let mut tss = TaskStateSegment::new(); let mut tss = TaskStateSegment::new();
......
#[cfg(feature = "multiboot1")] use crate::debug;
#[path = "multiboot1/mod.rs"]
pub mod boot; //
#[cfg(feature = "multiboot2")]
#[path = "multiboot2/mod.rs"]
pub mod boot;
#[cfg(feature = "bootboot")]
#[path = "bootboot/mod.rs"]
pub mod boot;
#[cfg(feature = "limine")]
#[path = "limine/mod.rs"]
pub mod boot;
pub use boot::*;
pub mod gdt; pub mod gdt;
pub mod idt; pub mod idt;
//
pub fn early_boot_cpu() {
gdt::init();
idt::init();
debug!("Re-enabling x86_64 interrupts");
x86_64::instructions::interrupts::enable();
}
pub fn early_per_cpu() {}
pub fn done() -> ! {
loop {
x86_64::instructions::hlt();
}
}
File moved
File moved
File moved
use crate::mem::Memmap;
use limine::{LimineMemmapRequest, LimineMemoryMapEntryType};
//
pub fn memmap() -> impl Iterator<Item = Memmap> {
static REQ: LimineMemmapRequest = LimineMemmapRequest::new(0);
const DEFAULT_MEMMAP: Memmap = Memmap {
base: u64::MAX,
len: 0u64,
};
REQ.get_response()
.get()
.into_iter()
.flat_map(|a| a.memmap())
.scan(DEFAULT_MEMMAP, |acc, memmap| {
// TODO: zero init reclaimable regions
if let LimineMemoryMapEntryType::Usable
// | LimineMemoryMapEntryType::AcpiReclaimable
// | LimineMemoryMapEntryType::BootloaderReclaimable
= memmap.typ
{
acc.base = memmap.base.min(acc.base);
acc.len += memmap.len;
Some(None)
} else if acc.len == 0 {
acc.base = u64::MAX;
Some(None)
} else {
Some(Some(core::mem::replace(acc, DEFAULT_MEMMAP)))
}
})
.flatten()
}
use super::{gdt, idt}; use crate::arch;
use crate::debug;
// //
pub use mem::memmap;
pub use term::_print; pub use term::_print;
// //
mod cmdline; mod cmdline;
mod framebuffer; mod framebuffer;
mod mem;
mod smp;
mod term; mod term;
// //
...@@ -17,21 +19,15 @@ mod term; ...@@ -17,21 +19,15 @@ mod term;
pub extern "C" fn _start() -> ! { pub extern "C" fn _start() -> ! {
crate::BOOTLOADER.call_once(|| "Limine"); crate::BOOTLOADER.call_once(|| "Limine");
cmdline::init();
framebuffer::init(); framebuffer::init();
cmdline::init();
gdt::init(); arch::early_boot_cpu();
idt::init(); arch::early_per_cpu();
debug!("Re-enabling x86_64 interrupts");
x86_64::instructions::interrupts::enable();
debug!("Calling general kernel_main");
crate::kernel_main() crate::kernel_main()
} }
pub fn done() -> ! { pub fn smp_init() {
loop { smp::init();
x86_64::instructions::hlt();
}
} }
use crate::{
arch,
smp::{smp_main, Cpu},
};
use limine::{LimineSmpInfo, LimineSmpRequest};
//
pub fn init() -> Cpu {
static REQ: LimineSmpRequest = LimineSmpRequest::new(0);
let mut boot = Cpu::new(0, 0);
for cpu in REQ
.get_response()
.get_mut()
.into_iter()
.flat_map(|resp| {
let bsp_lapic_id = resp.bsp_lapic_id;
resp.cpus().iter_mut().map(move |cpu| (bsp_lapic_id, cpu))
})
.filter_map(|(bsp_lapic_id, cpu)| {
if bsp_lapic_id == cpu.lapic_id {
boot = Cpu::from(&**cpu);
None
} else {
Some(cpu)
}
})
{
cpu.goto_address = smp_start;
}
boot
}
extern "C" fn smp_start(info: *const LimineSmpInfo) -> ! {
let info = unsafe { &*info };
arch::early_per_cpu();
smp_main(Cpu::from(info));
}
//
impl From<&LimineSmpInfo> for Cpu {
fn from(value: &LimineSmpInfo) -> Self {
Self::new(value.processor_id, value.lapic_id)
}
}
File moved
#[cfg(feature = "multiboot1")]
#[path = "multiboot1/mod.rs"]
mod boot;
#[cfg(feature = "multiboot2")]
#[path = "multiboot2/mod.rs"]
mod boot;
#[cfg(feature = "bootboot")]
#[path = "bootboot/mod.rs"]
mod boot;
#[cfg(feature = "limine")]
#[path = "limine/mod.rs"]
mod boot;
pub use boot::*;
File moved
File moved
File moved
File moved
...@@ -21,8 +21,7 @@ macro_rules! println { ...@@ -21,8 +21,7 @@ macro_rules! println {
macro_rules! log { macro_rules! log {
($level:expr, $($t:tt)*) => { ($level:expr, $($t:tt)*) => {
if $crate::log::test_log_level($level) { if $crate::log::test_log_level($level) {
$crate::log::_print_log_stamp($level, module_path!()); $crate::log::_print_log($level, module_path!(), format_args_nl!($($t)*));
$crate::println!($($t)*);
} }
}; };
} }
...@@ -91,7 +90,7 @@ pub fn test_log_level(level: LogLevel) -> bool { ...@@ -91,7 +90,7 @@ pub fn test_log_level(level: LogLevel) -> bool {
} }
#[doc(hidden)] #[doc(hidden)]
pub fn _print_log_stamp(level: LogLevel, module: &str) { pub fn _print_log(level: LogLevel, module: &str, args: Arguments) {
// if !LOGGER.color.load(Ordering::SeqCst) { // if !LOGGER.color.load(Ordering::SeqCst) {
// print!("[{level:?}]: ") // print!("[{level:?}]: ")
// } else { // } else {
...@@ -105,7 +104,7 @@ pub fn _print_log_stamp(level: LogLevel, module: &str) { ...@@ -105,7 +104,7 @@ pub fn _print_log_stamp(level: LogLevel, module: &str) {
}; };
print!( print!(
"{}{level} {} {}: ", "{}{level} {} {}: {args}",
'['.true_grey(), '['.true_grey(),
module.true_grey(), module.true_grey(),
']'.true_grey(), ']'.true_grey(),
...@@ -113,6 +112,11 @@ pub fn _print_log_stamp(level: LogLevel, module: &str) { ...@@ -113,6 +112,11 @@ pub fn _print_log_stamp(level: LogLevel, module: &str) {
// } // }
} }
#[doc(hidden)]
pub fn _print(args: Arguments) {
LOGGER.print(args)
}
// //
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
...@@ -203,7 +207,25 @@ impl Logger { ...@@ -203,7 +207,25 @@ impl Logger {
} }
} }
#[doc(hidden)] //
pub fn _print(args: Arguments) {
LOGGER.print(args) #[cfg(test)]
mod tests {
use super::{set_log_level, LogLevel};
#[test_case]
fn log_levels() {
set_log_level(LogLevel::Trace);
for level in LogLevel::ALL {
log!(level, "LOG TEST")
}
}
#[test_case]
fn log_chars() {
for c in 0..=255u8 {
print!("{}", c as char);
}
}
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment