Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Reformatted respecting cargo fmt --all
  • Loading branch information
Radu-Voinea committed Oct 7, 2024
commit 09b195ddc3b254b67b18212d6cc0829e49dbd3cf
158 changes: 79 additions & 79 deletions docs/apic_example/src/apic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,70 +16,70 @@ lazy_static! {
#[repr(isize)]
#[allow(dead_code)]
pub enum APICOffset {
// RESERVED = 0x00
// RESERVED = 0x10
Ir = 0x20, // ID Register
Vr = 0x30, // Version Register
// RESERVED = 0x40
// RESERVED = 0x50
// RESERVED = 0x60
// RESERVED = 0x70
Tpr = 0x80, // Text Priority Register
Apr = 0x90, // Arbitration Priority Register
Ppr = 0xA0, // Processor Priority Register
Eoi = 0xB0, // End of Interrupt
Rrd = 0xC0, // Remote Read Register
Ldr = 0xD0, // Logical Destination Register
Dfr = 0xE0, // DFR
Svr = 0xF0, // Spurious (Interrupt) Vector Register
Isr1 = 0x100, // In-Service Register 1
Isr2 = 0x110, // In-Service Register 2
Isr3 = 0x120, // In-Service Register 3
Isr4 = 0x130, // In-Service Register 4
Isr5 = 0x140, // In-Service Register 5
Isr6 = 0x150, // In-Service Register 6
Isr7 = 0x160, // In-Service Register 7
Isr8 = 0x170, // In-Service Register 8
Tmr1 = 0x180, // Trigger Mode Register 1
Tmr2 = 0x190, // Trigger Mode Register 2
Tmr3 = 0x1A0, // Trigger Mode Register 3
Tmr4 = 0x1B0, // Trigger Mode Register 4
Tmr5 = 0x1C0, // Trigger Mode Register 5
Tmr6 = 0x1D0, // Trigger Mode Register 6
Tmr7 = 0x1E0, // Trigger Mode Register 7
Tmr8 = 0x1F0, // Trigger Mode Register 8
Irr1 = 0x200, // Interrupt Request Register 1
Irr2 = 0x210, // Interrupt Request Register 2
Irr3 = 0x220, // Interrupt Request Register 3
Irr4 = 0x230, // Interrupt Request Register 4
Irr5 = 0x240, // Interrupt Request Register 5
Irr6 = 0x250, // Interrupt Request Register 6
Irr7 = 0x260, // Interrupt Request Register 7
Irr8 = 0x270, // Interrupt Request Register 8
Esr = 0x280, // Error Status Register
// RESERVED = 0x290
// RESERVED = 0x2A0
// RESERVED = 0x2B0
// RESERVED = 0x2C0
// RESERVED = 0x2D0
// RESERVED = 0x2E0
LvtCmci = 0x2F0, // LVT Corrected Machine Check Interrupt (CMCI) Register
Icr1 = 0x300, // Interrupt Command Register 1
Icr2 = 0x310, // Interrupt Command Register 2
LvtT = 0x320, // LVT Timer Register
LvtTsr = 0x330, // LVT Thermal Sensor Register
LvtPmcr = 0x340, // LVT Performance Monitoring Counters Register
R0x00 = 0x0, // RESERVED = 0x00
R0x10 = 0x10, // RESERVED = 0x10
Ir = 0x20, // ID Register
Vr = 0x30, // Version Register
R0x40 = 0x40, // RESERVED = 0x40
R0x50 = 0x50, // RESERVED = 0x50
R0x60 = 0x60, // RESERVED = 0x60
R0x70 = 0x70, // RESERVED = 0x70
Tpr = 0x80, // Text Priority Register
Apr = 0x90, // Arbitration Priority Register
Ppr = 0xA0, // Processor Priority Register
Eoi = 0xB0, // End of Interrupt
Rrd = 0xC0, // Remote Read Register
Ldr = 0xD0, // Logical Destination Register
Dfr = 0xE0, // DFR
Svr = 0xF0, // Spurious (Interrupt) Vector Register
Isr1 = 0x100, // In-Service Register 1
Isr2 = 0x110, // In-Service Register 2
Isr3 = 0x120, // In-Service Register 3
Isr4 = 0x130, // In-Service Register 4
Isr5 = 0x140, // In-Service Register 5
Isr6 = 0x150, // In-Service Register 6
Isr7 = 0x160, // In-Service Register 7
Isr8 = 0x170, // In-Service Register 8
Tmr1 = 0x180, // Trigger Mode Register 1
Tmr2 = 0x190, // Trigger Mode Register 2
Tmr3 = 0x1A0, // Trigger Mode Register 3
Tmr4 = 0x1B0, // Trigger Mode Register 4
Tmr5 = 0x1C0, // Trigger Mode Register 5
Tmr6 = 0x1D0, // Trigger Mode Register 6
Tmr7 = 0x1E0, // Trigger Mode Register 7
Tmr8 = 0x1F0, // Trigger Mode Register 8
Irr1 = 0x200, // Interrupt Request Register 1
Irr2 = 0x210, // Interrupt Request Register 2
Irr3 = 0x220, // Interrupt Request Register 3
Irr4 = 0x230, // Interrupt Request Register 4
Irr5 = 0x240, // Interrupt Request Register 5
Irr6 = 0x250, // Interrupt Request Register 6
Irr7 = 0x260, // Interrupt Request Register 7
Irr8 = 0x270, // Interrupt Request Register 8
Esr = 0x280, // Error Status Register
R0x290 = 0x290, // RESERVED = 0x290
R0x2A0 = 0x2A0, // RESERVED = 0x2A0
R0x2B0 = 0x2B0, // RESERVED = 0x2B0
R0x2C0 = 0x2C0, // RESERVED = 0x2C0
R0x2D0 = 0x2D0, // RESERVED = 0x2D0
R0x2E0 = 0x2E0, // RESERVED = 0x2E0
LvtCmci = 0x2F0, // LVT Corrected Machine Check Interrupt (CMCI) Register
Icr1 = 0x300, // Interrupt Command Register 1
Icr2 = 0x310, // Interrupt Command Register 2
LvtT = 0x320, // LVT Timer Register
LvtTsr = 0x330, // LVT Thermal Sensor Register
LvtPmcr = 0x340, // LVT Performance Monitoring Counters Register
LvtLint0 = 0x350, // LVT LINT0 Register
LvtLint1 = 0x360, // LVT LINT1 Register
LvtE = 0x370, // LVT Error Register
Ticr = 0x380, // Initial Count Register (for Timer)
Tccr = 0x390, // Current Count Register (for Timer)
// RESERVED = 0x3A0
// RESERVED = 0x3B0
// RESERVED = 0x3C0
// RESERVED = 0x3D0
Tdcr = 0x3E0, // Divide Configuration Register (for Timer)
// RESERVED = 0x3F0
LvtE = 0x370, // LVT Error Register
Ticr = 0x380, // Initial Count Register (for Timer)
Tccr = 0x390, // Current Count Register (for Timer)
R0x3A0 = 0x3A0, // RESERVED = 0x3A0
R0x3B0 = 0x3B0, // RESERVED = 0x3B0
R0x3C0 = 0x3C0, // RESERVED = 0x3C0
R0x3D0 = 0x3D0, // RESERVED = 0x3D0
Tdcr = 0x3E0, // Divide Configuration Register (for Timer)
R0x3F0 = 0x3F0, // RESERVED = 0x3F0
}

pub struct LAPICAddress {
Expand All @@ -92,7 +92,7 @@ unsafe impl Sync for LAPICAddress {}
impl LAPICAddress {
pub fn new() -> Self {
Self {
address: core::ptr::null_mut()
address: core::ptr::null_mut(),
}
}
}
Expand All @@ -103,7 +103,9 @@ pub struct AcpiHandlerImpl {

impl AcpiHandlerImpl {
pub fn new(physical_memory_offset: VirtAddr) -> Self {
Self { physical_memory_offset }
Self {
physical_memory_offset,
}
}
}

Expand Down Expand Up @@ -142,13 +144,16 @@ impl AcpiHandler for AcpiHandlerImpl {
}

pub unsafe fn init(
rsdp: usize, physical_memory_offset: VirtAddr,
rsdp: usize,
physical_memory_offset: VirtAddr,
mapper: &mut impl Mapper<Size4KiB>,
frame_allocator: &mut impl FrameAllocator<Size4KiB>,
) {
let handler = AcpiHandlerImpl::new(physical_memory_offset);
let acpi_tables = AcpiTables::from_rsdp(handler, rsdp).expect("Failed to parse ACPI tables");
let platform_info = acpi_tables.platform_info().expect("Failed to get platform info");
let platform_info = acpi_tables
.platform_info()
.expect("Failed to get platform info");
match platform_info.interrupt_model {
acpi::InterruptModel::Apic(apic) => {
let io_apic_address = apic.io_apics[0].address;
Expand All @@ -173,11 +178,7 @@ unsafe fn init_local_apic(
mapper: &mut impl Mapper<Size4KiB>,
frame_allocator: &mut impl FrameAllocator<Size4KiB>,
) {
let virtual_address = map_apic(
local_apic_addr as u64,
mapper,
frame_allocator,
);
let virtual_address = map_apic(local_apic_addr as u64, mapper, frame_allocator);

let lapic_pointer = virtual_address.as_mut_ptr::<u32>();
LAPIC_ADDR.lock().address = lapic_pointer;
Expand Down Expand Up @@ -210,19 +211,16 @@ unsafe fn init_io_apic(
mapper: &mut impl Mapper<Size4KiB>,
frame_allocator: &mut impl FrameAllocator<Size4KiB>,
) {
let virt_addr = map_apic(
ioapic_address as u64,
mapper,
frame_allocator,
);
let virt_addr = map_apic(ioapic_address as u64, mapper, frame_allocator);

let ioapic_pointer = virt_addr.as_mut_ptr::<u32>();

ioapic_pointer.offset(0).write_volatile(0x12);
ioapic_pointer.offset(4).write_volatile(InterruptIndex::Keyboard as u8 as u32);
ioapic_pointer
.offset(4)
.write_volatile(InterruptIndex::Keyboard as u8 as u32);
}


fn map_apic(
physical_address: u64,
mapper: &mut impl Mapper<Size4KiB>,
Expand Down Expand Up @@ -259,6 +257,8 @@ fn disable_pic() {
pub fn end_interrupt() {
unsafe {
let lapic_ptr = LAPIC_ADDR.lock().address;
lapic_ptr.offset(APICOffset::Eoi as isize / 4).write_volatile(0);
lapic_ptr
.offset(APICOffset::Eoi as isize / 4)
.write_volatile(0);
}
}
3 changes: 1 addition & 2 deletions docs/apic_example/src/frame_allocator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ impl BootInfoFrameAllocator {
next: 0,
}
}
pub fn usable_frames(&self) -> impl Iterator<Item=PhysFrame> {
pub fn usable_frames(&self) -> impl Iterator<Item = PhysFrame> {
let regions = self.memory_map.iter();

let usable_regions = regions.filter(|region| region.kind == Usable);
Expand Down Expand Up @@ -49,4 +49,3 @@ fn active_level4_table(physical_memory_offset: VirtAddr) -> &'static mut PageTab

unsafe { &mut *page_table_pointer }
}

12 changes: 8 additions & 4 deletions docs/apic_example/src/idt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,21 @@ pub extern "x86-interrupt" fn handle_breakpoint(stack_frame: InterruptStackFrame
info!("Breakpoint hit:\n{:#?}", stack_frame);
}

pub extern "x86-interrupt" fn handle_double_fault(stack_frame: InterruptStackFrame, _error_code: u64) -> ! {
pub extern "x86-interrupt" fn handle_double_fault(
stack_frame: InterruptStackFrame,
_error_code: u64,
) -> ! {
info!("\nDouble fault:\n{:#?}", stack_frame);

loop {
hlt()
}
}

pub extern "x86-interrupt" fn handle_page_fault(stack_frame: InterruptStackFrame, error_code: PageFaultErrorCode) {
pub extern "x86-interrupt" fn handle_page_fault(
stack_frame: InterruptStackFrame,
error_code: PageFaultErrorCode,
) {
info!("Exception : Page Fault");
info!("Accessed address : {:?}", Cr2::read());
info!("ErrorCode : {:?}", error_code);
Expand All @@ -69,5 +75,3 @@ pub extern "x86-interrupt" fn handle_keyboard(_stack_frame: InterruptStackFrame)

apic::end_interrupt();
}


15 changes: 10 additions & 5 deletions docs/apic_example/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@
#![no_main]

extern crate alloc;
mod frame_allocator;
mod apic;
mod idt;
mod frame_allocator;
mod gdt;
mod idt;

use x86_64::instructions::hlt;
use crate::frame_allocator::BootInfoFrameAllocator;
use bootloader_api::config::Mapping;
use bootloader_api::{entry_point, BootInfo};
use x86_64::instructions::hlt;
use x86_64::structures::paging::OffsetPageTable;
use x86_64::VirtAddr;

Expand All @@ -37,10 +37,15 @@ pub fn kernel_main(boot_info: &'static mut BootInfo) -> ! {

gdt::init();
unsafe {
apic::init(rsdp.expect("Failed to get RSDP address") as usize, physical_memory_offset, &mut mapper, &mut frame_allocator);
apic::init(
rsdp.expect("Failed to get RSDP address") as usize,
physical_memory_offset,
&mut mapper,
&mut frame_allocator,
);
}

loop {
hlt()
}
}
}
Loading