Moved away from PIC to APIC.

usermode
ondra05 2022-12-08 20:15:10 +01:00
parent 91baa44f36
commit 8f6c91ab9a
6 changed files with 67 additions and 23 deletions

39
Cargo.lock generated
View File

@ -122,6 +122,12 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[package]]
name = "bit"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b645c5c09a7d4035949cfce1a915785aaad6f17800c35fda8a8c311c491f284"
[[package]]
name = "bit_field"
version = "0.10.1"
@ -369,11 +375,11 @@ dependencies = [
"limine",
"linked_list_allocator",
"log",
"pic8259",
"slab",
"spin",
"uart_16550",
"versioning",
"x2apic",
"x86_64",
]
@ -497,13 +503,10 @@ dependencies = [
]
[[package]]
name = "pic8259"
version = "0.10.2"
name = "paste"
version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24ec21f514e2e16e94649f1d041ca4a7069b512c037ac156360652a775e6229d"
dependencies = [
"x86_64",
]
checksum = "b1de2e551fb905ac83f73f7aedf2f0cb4a0da7e35efa24a202a936269f1f18e1"
[[package]]
name = "pin-project-lite"
@ -596,6 +599,15 @@ dependencies = [
"getrandom",
]
[[package]]
name = "raw-cpuid"
version = "10.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a6823ea29436221176fe662da99998ad3b4db2c7f31e7b6f5fe43adccd6320bb"
dependencies = [
"bitflags",
]
[[package]]
name = "redox_syscall"
version = "0.2.16"
@ -995,6 +1007,19 @@ version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5"
[[package]]
name = "x2apic"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32b6a3e030cfc71d614954e1de6dcb09e40bf1437f620c27b4526f978bee912e"
dependencies = [
"bit",
"bitflags",
"paste",
"raw-cpuid",
"x86_64",
]
[[package]]
name = "x86_64"
version = "0.14.10"

View File

@ -17,6 +17,6 @@ features = ["alloc"]
[target.'cfg(target_arch = "x86_64")'.dependencies]
limine = "0.1"
pic8259 = "0.10"
uart_16550 = "0.2"
x86_64 = "0.14"
x2apic = "0.4"

View File

@ -1,25 +1,36 @@
use pic8259::ChainedPics;
use spin::{Lazy, Mutex};
use x2apic::lapic::{LocalApic, LocalApicBuilder};
use x86_64::structures::idt::{InterruptDescriptorTable, InterruptStackFrame, PageFaultErrorCode};
pub const PIC_1_OFFSET: u8 = 32;
pub const PIC_2_OFFSET: u8 = PIC_1_OFFSET + 8;
static PICS: Mutex<ChainedPics> =
Mutex::new(unsafe { ChainedPics::new(PIC_1_OFFSET, PIC_2_OFFSET) });
pub unsafe fn init() {
log::info!("Initialising IDT");
IDT.load();
PICS.lock().initialize();
Lazy::force(&LAPIC);
x86_64::instructions::interrupts::enable();
}
#[repr(u8)]
enum Interrupt {
Timer = PIC_1_OFFSET,
Timer = 32,
ApicErr = u8::MAX - 1,
Spurious = u8::MAX,
}
static LAPIC: Lazy<Mutex<LocalApic>> = Lazy::new(|| {
let mut lapic = LocalApicBuilder::new()
.timer_vector(Interrupt::Timer as usize)
.error_vector(Interrupt::ApicErr as usize)
.spurious_vector(Interrupt::Spurious as usize)
.set_xapic_base(
unsafe { x2apic::lapic::xapic_base() }
+ super::memory::HHDM_OFFSET.load(core::sync::atomic::Ordering::Relaxed),
)
.build()
.expect("failed to setup Local APIC");
unsafe { lapic.enable() };
Mutex::new(lapic)
});
static IDT: Lazy<InterruptDescriptorTable> = Lazy::new(|| {
let mut idt = InterruptDescriptorTable::new();
unsafe {
@ -44,9 +55,14 @@ extern "x86-interrupt" fn page_fault(
}
extern "x86-interrupt" fn timer(_: InterruptStackFrame) {
unsafe { eoi(Interrupt::Timer as u8) };
panic!("make timer not double fault");
unsafe { LAPIC.lock().end_of_interrupt() };
}
unsafe fn eoi(i: u8) {
PICS.lock().notify_end_of_interrupt(i);
extern "x86-interrupt" fn apic_err(_: InterruptStackFrame) {
panic!("Internal APIC error");
}
extern "x86-interrupt" fn spurious(_: InterruptStackFrame) {
unsafe { LAPIC.lock().end_of_interrupt() };
}

View File

@ -1,3 +1,4 @@
use core::sync::atomic::AtomicU64;
use limine::{LimineMemmapEntry, LimineMemoryMapEntryType};
use spin::{Mutex, Once};
use x86_64::{
@ -7,10 +8,12 @@ use x86_64::{
pub static PAGE_TABLE: Once<Mutex<OffsetPageTable>> = Once::new();
pub static FRAME_ALLOC: Once<Mutex<FrameAlloc>> = Once::new();
pub static HHDM_OFFSET: AtomicU64 = AtomicU64::new(0);
/// Initialise page table
pub unsafe fn init_pt(phys_base: VirtAddr) {
log::info!("Retrieving page table");
HHDM_OFFSET.store(phys_base.as_u64(), core::sync::atomic::Ordering::Relaxed);
PAGE_TABLE.call_once(|| {
Mutex::new(OffsetPageTable::new(
&mut *((phys_base

View File

@ -5,7 +5,7 @@ use x86_64::VirtAddr;
mod allocator;
mod gdt;
mod idt;
mod interrupts;
mod memory;
static SERIAL_CONSOLE: Mutex<SerialPort> = Mutex::new(unsafe { SerialPort::new(0x3f8) });
@ -37,7 +37,7 @@ unsafe extern "C" fn _kernel_start() -> ! {
allocator::init_alloc().expect("tried to initialise allocator");
gdt::init();
idt::init();
interrupts::init();
crate::kmain::kmain()
}

View File

@ -34,7 +34,7 @@ fn panic(info: &core::panic::PanicInfo) -> ! {
if let Some(loc) = info.location() {
let _ = crate::arch::serial_fmt(format_args!(
"Location: {} : {} / {}\r\n",
"Location: {}: {}, {}\r\n",
loc.file(),
loc.line(),
loc.column()