Skip to content

Commit

Permalink
kern/misc: Add x2APIC support
Browse files Browse the repository at this point in the history
  • Loading branch information
mintsuki committed Jul 4, 2024
1 parent bb35959 commit 593c7f2
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 5 deletions.
2 changes: 2 additions & 0 deletions kernel/main.v
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,8 @@ pub fn kmain() {
idt.initialise()
isr.initialise()

x2apic_mode = smp_req.response.flags & 1 != 0

// Init terminal
term.initialise()
serial.early_initialise()
Expand Down
17 changes: 17 additions & 0 deletions kernel/modules/acpi/madt.v
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,16 @@ pub:
flags u32
}

@[packed]
struct MADTLocalX2Apic {
pub:
header MADTHeader
reserved [2]u8
x2apic_id u32
flags u32
processor_id u32
}

@[packed]
struct MADTIoApic {
pub:
Expand Down Expand Up @@ -61,6 +71,7 @@ pub:
__global (
madt &MADT
madt_local_apics []&MADTLocalApic
madt_local_x2apics []&MADTLocalX2Apic
madt_io_apics []&MADTIoApic
madt_isos []&MADTISO
madt_nmis []&MADTNMI
Expand All @@ -83,6 +94,12 @@ fn madt_init() {
println('acpi/madt: Found local APIC #${madt_local_apics.len}')
madt_local_apics << unsafe { &MADTLocalApic(header) }
}
9 {
if x2apic_mode {
println('acpi/madt: Found local x2APIC #${madt_local_x2apics.len}')
madt_local_x2apics << unsafe { &MADTLocalX2Apic(header) }
}
}
1 {
println('acpi/madt: Found IO APIC #${madt_io_apics.len}')
madt_io_apics << unsafe { &MADTIoApic(header) }
Expand Down
39 changes: 34 additions & 5 deletions kernel/modules/x86/apic/apic.v
Original file line number Diff line number Diff line change
Expand Up @@ -22,22 +22,47 @@ const (

__global (
lapic_base = u64(0)
x2apic_mode = bool(false)
)

fn lapic_read(reg u32) u32 {
fn xapic_read(reg u32) u32 {
if lapic_base == u64(0) {
lapic_base = u64(msr.rdmsr(0x1b) & 0xfffff000) + higher_half
}
return kio.mmin(&u32(lapic_base + reg))
}

fn lapic_write(reg u32, val u32) {
fn x2apic_read(reg u32) u64 {
return msr.rdmsr(0x800 + (reg >> 4))
}

fn xapic_write(reg u32, val u32) {
if lapic_base == u64(0) {
lapic_base = u64(msr.rdmsr(0x1b) & 0xfffff000) + higher_half
}
kio.mmout(&u32(lapic_base + reg), val)
}

fn x2apic_write(reg u32, val u64) {
msr.wrmsr(0x800 + (reg >> 4), val)
}

fn lapic_read(reg u32) u64 {
if x2apic_mode {
return x2apic_read(reg)
} else {
return xapic_read(reg)
}
}

fn lapic_write(reg u32, val u64) {
if x2apic_mode {
x2apic_write(reg, val)
} else {
xapic_write(reg, u32(val))
}
}

pub fn lapic_timer_stop() {
lapic_write(apic.lapic_reg_timer_initcnt, 0)
lapic_write(apic.lapic_reg_timer, (1 << 16))
Expand Down Expand Up @@ -86,9 +111,13 @@ pub fn lapic_eoi() {
lapic_write(apic.lapic_reg_eoi, 0)
}

pub fn lapic_send_ipi(lapic_id u8, vector u8) {
lapic_write(apic.lapic_reg_icr1, u32(lapic_id) << 24)
lapic_write(apic.lapic_reg_icr0, vector)
pub fn lapic_send_ipi(lapic_id u32, vector u8) {
if x2apic_mode {
x2apic_write(apic.lapic_reg_icr0, (u64(lapic_id) << 32) | vector)
} else {
xapic_write(apic.lapic_reg_icr1, u32(lapic_id) << 24)
xapic_write(apic.lapic_reg_icr0, vector)
}
}

fn io_apic_read(io_apic int, reg u32) u32 {
Expand Down
2 changes: 2 additions & 0 deletions kernel/modules/x86/smp/smp.v
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ __global (
@[_linker_section: '.requests']
__global (
volatile smp_req = limine.LimineSMPRequest{
flags: 1 // x2apic allowed
response: unsafe { nil }
}
)
Expand All @@ -28,6 +29,7 @@ pub fn initialise() {

println('smp: BSP LAPIC ID: ${smp_tag.bsp_lapic_id:x}')
println('smp: Total CPU count: ${smp_tag.cpu_count}')
println('smp: Using x2APIC: ${x2apic_mode}')

smp_info_array := smp_tag.cpus

Expand Down

0 comments on commit 593c7f2

Please sign in to comment.