apic broken pushing to debug
This commit is contained in:
@@ -0,0 +1,99 @@
|
|||||||
|
use core::arch::x86_64::__cpuid;
|
||||||
|
|
||||||
|
use x86_64::{
|
||||||
|
PhysAddr, VirtAddr,
|
||||||
|
instructions::port::Port,
|
||||||
|
registers::model_specific::Msr,
|
||||||
|
structures::paging::{
|
||||||
|
FrameAllocator, Mapper, Page, PageTableFlags, PhysFrame, Size4KiB, Translate,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::serial_print;
|
||||||
|
|
||||||
|
use super::{
|
||||||
|
cpu::model_specific_registers::*, memmap::PHYSICAL_MEMORY_OFFSET,
|
||||||
|
memory::FoundryOSFrameAllocator,
|
||||||
|
};
|
||||||
|
|
||||||
|
const IA32_APIC_BASE_MSR: u32 = 0x1b;
|
||||||
|
const IA32_APIC_BASE_MSR_BSP: u64 = 0x100;
|
||||||
|
const IA32_APIC_BASE_MSR_ENABLE: u64 = 0x800;
|
||||||
|
const IA32_APIC_BASE_MSR_DISABLE: u64 = !IA32_APIC_BASE_MSR_ENABLE;
|
||||||
|
|
||||||
|
const CPUID_FEAT_EDX_APIC: u64 = 1 << 9; // the cpuid instruction will return this flag if it supports APIC
|
||||||
|
|
||||||
|
const APIC_VIRTUAL_ADDRESS: u64 = 0xFEC00000;
|
||||||
|
|
||||||
|
fn set_apic_base_enable(apic: PhysAddr) {
|
||||||
|
let rax = (apic.as_u64() & 0xfffff0000) | IA32_APIC_BASE_MSR_ENABLE;
|
||||||
|
cpu_set_msr(IA32_APIC_BASE_MSR, rax);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_apic_base_disable(apic: PhysAddr) {
|
||||||
|
let rax = (apic.as_u64() & 0xfffff0000) & IA32_APIC_BASE_MSR_DISABLE;
|
||||||
|
cpu_set_msr(IA32_APIC_BASE_MSR, rax);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_apic_base() -> PhysAddr {
|
||||||
|
let mut value: u64 = 0;
|
||||||
|
cpu_get_msr(IA32_APIC_BASE_MSR, &mut value);
|
||||||
|
PhysAddr::new(value & 0xfffff0000)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write_apic_register(apic_base: &VirtAddr, reg: u8, value: u32) {
|
||||||
|
let apic_base = apic_base.as_u64();
|
||||||
|
let reg_addr = (apic_base & 0xFFFFF0000) + reg as u64;
|
||||||
|
unsafe { *(reg_addr as *mut u32) = value };
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_apic_register(apic_base: &VirtAddr, reg: u8) -> u32 {
|
||||||
|
let apic_base = apic_base.as_u64();
|
||||||
|
|
||||||
|
serial_print!("got apic base");
|
||||||
|
|
||||||
|
let reg_addr = (apic_base & 0xFFFFF0000) + reg as u64;
|
||||||
|
unsafe { *(reg_addr as *const u32) }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn check_apic() -> bool {
|
||||||
|
let res = unsafe { __cpuid(1) };
|
||||||
|
res.edx as u64 & CPUID_FEAT_EDX_APIC != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
unsafe fn phys_to_virt(phys: PhysAddr) -> VirtAddr {
|
||||||
|
let phys = phys.as_u64();
|
||||||
|
match phys.checked_add(*PHYSICAL_MEMORY_OFFSET) {
|
||||||
|
Some(virt) => VirtAddr::new(virt),
|
||||||
|
None => panic!("overflow"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn enable_apic() {
|
||||||
|
let apic_phys_addr = get_apic_base();
|
||||||
|
|
||||||
|
// let frame = PhysFrame::containing_address(apic_phys_addr);
|
||||||
|
// let flags: PageTableFlags = PageTableFlags::PRESENT | PageTableFlags::WRITABLE;
|
||||||
|
|
||||||
|
// unsafe {
|
||||||
|
// mapper.map_to(page, frame, flags, frame_allocator);
|
||||||
|
// }
|
||||||
|
|
||||||
|
set_apic_base_enable(apic_phys_addr);
|
||||||
|
|
||||||
|
// FIXME: this causes a page fault
|
||||||
|
// TODO: map to virtual memor
|
||||||
|
|
||||||
|
let apic_virt = unsafe { phys_to_virt(apic_phys_addr) };
|
||||||
|
|
||||||
|
let reg = read_apic_register(&apic_virt, 0xF0);
|
||||||
|
|
||||||
|
serial_print!("ok2");
|
||||||
|
|
||||||
|
write_apic_register(&apic_virt, 0xF0, reg | 0x100);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Apic {}
|
||||||
|
|
||||||
|
pub enum ApicVector {}
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
use libk::drivers::apic::enable_apic;
|
|
||||||
use libk::prelude::*;
|
use libk::prelude::*;
|
||||||
use pic8259::ChainedPics;
|
use pic8259::ChainedPics;
|
||||||
use x86_64::registers::control::Cr2;
|
use x86_64::registers::control::Cr2;
|
||||||
@@ -6,6 +5,7 @@ use x86_64::structures::idt::{InterruptDescriptorTable, InterruptStackFrame, Pag
|
|||||||
|
|
||||||
use spin::{Lazy, Mutex};
|
use spin::{Lazy, Mutex};
|
||||||
|
|
||||||
|
use super::apic::enable_apic;
|
||||||
use super::gdt;
|
use super::gdt;
|
||||||
|
|
||||||
static IDT: Lazy<InterruptDescriptorTable> = Lazy::new(|| {
|
static IDT: Lazy<InterruptDescriptorTable> = Lazy::new(|| {
|
||||||
@@ -52,12 +52,12 @@ impl InterruptIndex {
|
|||||||
|
|
||||||
pub fn init_idt() {
|
pub fn init_idt() {
|
||||||
IDT.load();
|
IDT.load();
|
||||||
// enable_apic();
|
enable_apic();
|
||||||
// TODO: fix apic
|
// TODO: fix apic
|
||||||
unsafe {
|
// unsafe {
|
||||||
PICS.lock().initialize();
|
// PICS.lock().initialize();
|
||||||
PICS.lock().write_masks(0xfc, 0xff);
|
// PICS.lock().write_masks(0xfc, 0xff);
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "x86-interrupt" fn breakpoint_handler(stack_frame: InterruptStackFrame) {
|
extern "x86-interrupt" fn breakpoint_handler(stack_frame: InterruptStackFrame) {
|
||||||
|
|||||||
@@ -1,17 +1,11 @@
|
|||||||
// use lib_alloc::allocator::FoundryAllocator;
|
// use lib_alloc::allocator::FoundryAllocator;
|
||||||
use limine::{memory_map::EntryType, response::MemoryMapResponse};
|
use limine::{memory_map::EntryType, response::MemoryMapResponse};
|
||||||
use x86_64::{
|
use x86_64::{
|
||||||
PhysAddr,
|
PhysAddr, VirtAddr,
|
||||||
VirtAddr,
|
|
||||||
// addr,
|
|
||||||
registers::control::Cr3,
|
registers::control::Cr3,
|
||||||
structures::paging::{
|
structures::paging::{
|
||||||
// page_table::FrameError,
|
FrameAllocator, Mapper, OffsetPageTable, Page, PageTable, PhysFrame, Size4KiB,
|
||||||
FrameAllocator,
|
page_table::FrameError,
|
||||||
OffsetPageTable,
|
|
||||||
PageTable,
|
|
||||||
PhysFrame,
|
|
||||||
Size4KiB,
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -5,3 +5,7 @@ pub mod interrupts;
|
|||||||
pub mod memory;
|
pub mod memory;
|
||||||
|
|
||||||
pub mod memmap;
|
pub mod memmap;
|
||||||
|
|
||||||
|
pub mod apic;
|
||||||
|
|
||||||
|
pub mod cpu;
|
||||||
|
|||||||
+12
-7
@@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
|
|
||||||
|
use arch::x86_64::apic::enable_apic;
|
||||||
use core::arch::asm;
|
use core::arch::asm;
|
||||||
use limine::BaseRevision;
|
use limine::BaseRevision;
|
||||||
|
|
||||||
@@ -71,25 +72,29 @@ pub fn boot() -> Result<(), &'static str> {
|
|||||||
gdt::init();
|
gdt::init();
|
||||||
println_log!("[Success]");
|
println_log!("[Success]");
|
||||||
|
|
||||||
print_log!(" Setting Up Interrupt Descriptor Table... ");
|
print_log!(" Initialising Memory Subsystem... ");
|
||||||
interrupts::init_idt();
|
let physical_memory_offset = VirtAddr::new(*memmap::PHYSICAL_MEMORY_OFFSET);
|
||||||
|
let mut l4_table = unsafe { memory::init(physical_memory_offset) };
|
||||||
println_log!("[Success]");
|
println_log!("[Success]");
|
||||||
|
|
||||||
print_log!(" Setting Up Page Table... ");
|
print_log!(" Setting Up Page Table... ");
|
||||||
let mut frame_allocator = unsafe { memory::FoundryOSFrameAllocator::init(memory_map) };
|
let mut frame_allocator = unsafe { memory::FoundryOSFrameAllocator::init(memory_map) };
|
||||||
println_log!("[Success]");
|
println_log!("[Success]");
|
||||||
|
|
||||||
print_log!(" Initialising Memory Subsystem... ");
|
|
||||||
let physical_memory_offset = VirtAddr::new(*memmap::PHYSICAL_MEMORY_OFFSET);
|
|
||||||
let mut l4_table = unsafe { memory::init(physical_memory_offset) };
|
|
||||||
println_log!("[Success]");
|
|
||||||
|
|
||||||
print_log!(" Initialising Heap... ");
|
print_log!(" Initialising Heap... ");
|
||||||
if init_heap(&mut l4_table, &mut frame_allocator).is_err() {
|
if init_heap(&mut l4_table, &mut frame_allocator).is_err() {
|
||||||
return Err("Failed to initialise heap: error");
|
return Err("Failed to initialise heap: error");
|
||||||
}
|
}
|
||||||
println_log!("[Success]");
|
println_log!("[Success]");
|
||||||
|
|
||||||
|
print_log!(" Initialising APIC");
|
||||||
|
enable_apic();
|
||||||
|
println_log!("[Success]");
|
||||||
|
|
||||||
|
print_log!(" Setting Up Interrupt Descriptor Table... ");
|
||||||
|
interrupts::init_idt();
|
||||||
|
println_log!("[Success]");
|
||||||
|
|
||||||
print_log!(" Enabling Interrupts... ");
|
print_log!(" Enabling Interrupts... ");
|
||||||
x86_64::instructions::interrupts::enable();
|
x86_64::instructions::interrupts::enable();
|
||||||
println_log!("[Success]");
|
println_log!("[Success]");
|
||||||
|
|||||||
@@ -1,49 +0,0 @@
|
|||||||
use core::arch::x86_64::__cpuid;
|
|
||||||
|
|
||||||
use x86_64::{PhysAddr, instructions::port::Port, registers::model_specific::Msr};
|
|
||||||
|
|
||||||
use super::cpu::model_specific_registers::*;
|
|
||||||
|
|
||||||
const IA32_APIC_BASE_MSR: u32 = 0x1b;
|
|
||||||
const IA32_APIC_BASE_MSR_BSP: u64 = 0x100;
|
|
||||||
const IA32_APIC_BASE_MSR_ENABLE: u64 = 0x800;
|
|
||||||
|
|
||||||
const CPUID_FEAT_EDX_APIC: u64 = 1 << 9; // the cpuid instruction will return this flag if it supports APIC
|
|
||||||
|
|
||||||
fn set_apic_base(apic: PhysAddr) {
|
|
||||||
let rax = (apic.as_u64() & 0xfffff0000) | IA32_APIC_BASE_MSR_ENABLE;
|
|
||||||
cpu_set_msr(IA32_APIC_BASE_MSR, rax);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_apic_base() -> PhysAddr {
|
|
||||||
let mut value: u64 = 0;
|
|
||||||
cpu_get_msr(IA32_APIC_BASE_MSR, &mut value);
|
|
||||||
PhysAddr::new(value & 0xfffff0000)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn write_apic_register(reg: u8, value: u32) {
|
|
||||||
let apic_base = get_apic_base().as_u64();
|
|
||||||
let reg_addr = (apic_base & 0xFFFFF0000) + reg as u64;
|
|
||||||
unsafe { *(reg_addr as *mut u32) = value };
|
|
||||||
}
|
|
||||||
|
|
||||||
fn read_apic_register(reg: u8) -> u32 {
|
|
||||||
let apic_base = get_apic_base().as_u64();
|
|
||||||
let reg_addr = (apic_base & 0xFFFFF0000) + reg as u64;
|
|
||||||
unsafe { *(reg_addr as *const u32) }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn check_apic() -> bool {
|
|
||||||
let res = unsafe { __cpuid(1) };
|
|
||||||
res.edx as u64 & CPUID_FEAT_EDX_APIC != 0
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn enable_apic() {
|
|
||||||
set_apic_base(get_apic_base());
|
|
||||||
|
|
||||||
write_apic_register(0xF0, read_apic_register(0xF0) | 0x100);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Apic {}
|
|
||||||
|
|
||||||
pub enum ApicVector {}
|
|
||||||
@@ -1,7 +1,5 @@
|
|||||||
pub mod io;
|
pub mod io;
|
||||||
pub mod kalloc;
|
pub mod kalloc;
|
||||||
|
|
||||||
pub mod apic;
|
|
||||||
pub mod async_io;
|
pub mod async_io;
|
||||||
pub mod cpu;
|
|
||||||
pub mod pic;
|
pub mod pic;
|
||||||
|
|||||||
Reference in New Issue
Block a user