Remove amd64_ platform prefix
This commit is contained in:
@@ -56,7 +56,7 @@ static size_t intr_src_override_entries = 0;
|
|||||||
static spin_lock_t lapic_calibration_lock = SPIN_LOCK_INIT;
|
static spin_lock_t lapic_calibration_lock = SPIN_LOCK_INIT;
|
||||||
|
|
||||||
/* Read IOAPIC */
|
/* Read IOAPIC */
|
||||||
static uint32_t amd64_ioapic_read (struct ioapic* ioapic, uint32_t reg) {
|
static uint32_t ioapic_read (struct ioapic* ioapic, uint32_t reg) {
|
||||||
spin_lock (&ioapic->lock);
|
spin_lock (&ioapic->lock);
|
||||||
*(volatile uint32_t*)ioapic->mmio_base = reg;
|
*(volatile uint32_t*)ioapic->mmio_base = reg;
|
||||||
uint32_t ret = *(volatile uint32_t*)(ioapic->mmio_base + 0x10);
|
uint32_t ret = *(volatile uint32_t*)(ioapic->mmio_base + 0x10);
|
||||||
@@ -65,7 +65,7 @@ static uint32_t amd64_ioapic_read (struct ioapic* ioapic, uint32_t reg) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Write IOAPIC */
|
/* Write IOAPIC */
|
||||||
static void amd64_ioapic_write (struct ioapic* ioapic, uint32_t reg, uint32_t value) {
|
static void ioapic_write (struct ioapic* ioapic, uint32_t reg, uint32_t value) {
|
||||||
spin_lock (&ioapic->lock);
|
spin_lock (&ioapic->lock);
|
||||||
*(volatile uint32_t*)ioapic->mmio_base = reg;
|
*(volatile uint32_t*)ioapic->mmio_base = reg;
|
||||||
*(volatile uint32_t*)(ioapic->mmio_base + 0x10) = value;
|
*(volatile uint32_t*)(ioapic->mmio_base + 0x10) = value;
|
||||||
@@ -73,12 +73,12 @@ static void amd64_ioapic_write (struct ioapic* ioapic, uint32_t reg, uint32_t va
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Find an IOAPIC corresposting to provided IRQ */
|
/* Find an IOAPIC corresposting to provided IRQ */
|
||||||
static struct ioapic* amd64_ioapic_find (uint32_t irq) {
|
static struct ioapic* ioapic_find (uint32_t irq) {
|
||||||
struct ioapic* ioapic = NULL;
|
struct ioapic* ioapic = NULL;
|
||||||
|
|
||||||
for (size_t i = 0; i < ioapic_entries; i++) {
|
for (size_t i = 0; i < ioapic_entries; i++) {
|
||||||
ioapic = &ioapics[i];
|
ioapic = &ioapics[i];
|
||||||
uint32_t version = amd64_ioapic_read (ioapic, 1);
|
uint32_t version = ioapic_read (ioapic, 1);
|
||||||
uint32_t max = ((version >> 16) & 0xFF);
|
uint32_t max = ((version >> 16) & 0xFF);
|
||||||
|
|
||||||
if ((irq >= ioapic->table_data.gsi_base) && (irq <= (ioapic->table_data.gsi_base + max)))
|
if ((irq >= ioapic->table_data.gsi_base) && (irq <= (ioapic->table_data.gsi_base + max)))
|
||||||
@@ -97,7 +97,7 @@ static struct ioapic* amd64_ioapic_find (uint32_t irq) {
|
|||||||
* flags - IOAPIC redirection flags.
|
* flags - IOAPIC redirection flags.
|
||||||
* lapic_id - Local APIC that will receive the interrupt.
|
* lapic_id - Local APIC that will receive the interrupt.
|
||||||
*/
|
*/
|
||||||
void amd64_ioapic_route_irq (uint32_t vec, uint32_t irq, uint64_t flags, uint64_t lapic_id) {
|
void ioapic_route_irq (uint32_t vec, uint32_t irq, uint64_t flags, uint64_t lapic_id) {
|
||||||
struct ioapic* ioapic = NULL;
|
struct ioapic* ioapic = NULL;
|
||||||
struct acpi_madt_interrupt_source_override* override;
|
struct acpi_madt_interrupt_source_override* override;
|
||||||
bool found_override = false;
|
bool found_override = false;
|
||||||
@@ -121,7 +121,7 @@ void amd64_ioapic_route_irq (uint32_t vec, uint32_t irq, uint64_t flags, uint64_
|
|||||||
|
|
||||||
uint32_t gsi = found_override ? override->gsi : irq;
|
uint32_t gsi = found_override ? override->gsi : irq;
|
||||||
|
|
||||||
ioapic = amd64_ioapic_find (gsi);
|
ioapic = ioapic_find (gsi);
|
||||||
DEBUG ("%p\n", ioapic);
|
DEBUG ("%p\n", ioapic);
|
||||||
|
|
||||||
if (ioapic == NULL)
|
if (ioapic == NULL)
|
||||||
@@ -129,12 +129,12 @@ void amd64_ioapic_route_irq (uint32_t vec, uint32_t irq, uint64_t flags, uint64_
|
|||||||
|
|
||||||
uint32_t irq_reg = ((gsi - ioapic->table_data.gsi_base) * 2) + 0x10;
|
uint32_t irq_reg = ((gsi - ioapic->table_data.gsi_base) * 2) + 0x10;
|
||||||
|
|
||||||
amd64_ioapic_write (ioapic, irq_reg + 1, (uint32_t)(calc_flags >> 32));
|
ioapic_write (ioapic, irq_reg + 1, (uint32_t)(calc_flags >> 32));
|
||||||
amd64_ioapic_write (ioapic, irq_reg, (uint32_t)calc_flags);
|
ioapic_write (ioapic, irq_reg, (uint32_t)calc_flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Find and initialize the IOAPIC */
|
/* Find and initialize the IOAPIC */
|
||||||
void amd64_ioapic_init (void) {
|
void ioapic_init (void) {
|
||||||
struct limine_hhdm_response* hhdm = limine_hhdm_request.response;
|
struct limine_hhdm_response* hhdm = limine_hhdm_request.response;
|
||||||
|
|
||||||
struct uacpi_table apic_table;
|
struct uacpi_table apic_table;
|
||||||
@@ -176,41 +176,39 @@ void amd64_ioapic_init (void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Get MMIO base of Local APIC */
|
/* Get MMIO base of Local APIC */
|
||||||
static uintptr_t amd64_lapic_base (void) { return thiscpu->lapic_mmio_base; }
|
static uintptr_t lapic_base (void) { return thiscpu->lapic_mmio_base; }
|
||||||
|
|
||||||
/* Write Local APIC */
|
/* Write Local APIC */
|
||||||
static void amd64_lapic_write (uint32_t reg, uint32_t value) {
|
static void lapic_write (uint32_t reg, uint32_t value) {
|
||||||
*(volatile uint32_t*)(amd64_lapic_base () + reg) = value;
|
*(volatile uint32_t*)(lapic_base () + reg) = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read Local APIC */
|
/* Read Local APIC */
|
||||||
static uint32_t amd64_lapic_read (uint32_t reg) {
|
static uint32_t lapic_read (uint32_t reg) { return *(volatile uint32_t*)(lapic_base () + reg); }
|
||||||
return *(volatile uint32_t*)(amd64_lapic_base () + reg);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get ID of Local APIC */
|
/* Get ID of Local APIC */
|
||||||
uint32_t amd64_lapic_id (void) { return amd64_lapic_read (LAPIC_ID) >> 24; }
|
uint32_t lapic_id (void) { return lapic_read (LAPIC_ID) >> 24; }
|
||||||
|
|
||||||
/* Send End of interrupt command to Local APIC */
|
/* Send End of interrupt command to Local APIC */
|
||||||
void amd64_lapic_eoi (void) { amd64_lapic_write (LAPIC_EOI, 0); }
|
void lapic_eoi (void) { lapic_write (LAPIC_EOI, 0); }
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Calibrate Local APIC to send interrupts in a set interval.
|
* Calibrate Local APIC to send interrupts in a set interval.
|
||||||
*
|
*
|
||||||
* us - Period length in microseconds
|
* us - Period length in microseconds
|
||||||
*/
|
*/
|
||||||
static uint32_t amd64_lapic_calibrate (uint32_t us) {
|
static uint32_t lapic_calibrate (uint32_t us) {
|
||||||
spin_lock (&lapic_calibration_lock);
|
spin_lock (&lapic_calibration_lock);
|
||||||
|
|
||||||
amd64_lapic_write (LAPIC_DCR, DIVIDER_VALUE);
|
lapic_write (LAPIC_DCR, DIVIDER_VALUE);
|
||||||
|
|
||||||
amd64_lapic_write (LAPIC_LVTTR, SCHED_PREEMPT_TIMER | (1 << 16));
|
lapic_write (LAPIC_LVTTR, SCHED_PREEMPT_TIMER | (1 << 16));
|
||||||
amd64_lapic_write (LAPIC_TIMICT, 0xFFFFFFFF);
|
lapic_write (LAPIC_TIMICT, 0xFFFFFFFF);
|
||||||
|
|
||||||
sleep_micro (us);
|
sleep_micro (us);
|
||||||
|
|
||||||
amd64_lapic_write (LAPIC_LVTTR, SCHED_PREEMPT_TIMER | (0 << 16));
|
lapic_write (LAPIC_LVTTR, SCHED_PREEMPT_TIMER | (0 << 16));
|
||||||
uint32_t ticks = 0xFFFFFFFF - amd64_lapic_read (LAPIC_TIMCCT);
|
uint32_t ticks = 0xFFFFFFFF - lapic_read (LAPIC_TIMCCT);
|
||||||
DEBUG ("timer ticks = %u\n", ticks);
|
DEBUG ("timer ticks = %u\n", ticks);
|
||||||
|
|
||||||
spin_unlock (&lapic_calibration_lock);
|
spin_unlock (&lapic_calibration_lock);
|
||||||
@@ -223,30 +221,30 @@ static uint32_t amd64_lapic_calibrate (uint32_t us) {
|
|||||||
*
|
*
|
||||||
* ticks - Initial tick count
|
* ticks - Initial tick count
|
||||||
*/
|
*/
|
||||||
static void amd64_lapic_start (uint32_t ticks) {
|
static void lapic_start (uint32_t ticks) {
|
||||||
amd64_lapic_write (LAPIC_DCR, DIVIDER_VALUE);
|
lapic_write (LAPIC_DCR, DIVIDER_VALUE);
|
||||||
amd64_lapic_write (LAPIC_TIMICT, ticks);
|
lapic_write (LAPIC_TIMICT, ticks);
|
||||||
amd64_lapic_write (LAPIC_LVTTR, SCHED_PREEMPT_TIMER | (1 << 17));
|
lapic_write (LAPIC_LVTTR, SCHED_PREEMPT_TIMER | (1 << 17));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize Local APIC, configure to send timer interrupts at a given period. See
|
* Initialize Local APIC, configure to send timer interrupts at a given period. See
|
||||||
* amd64_lapic_calibrate and amd64_lapic_start.
|
* lapic_calibrate and lapic_start.
|
||||||
*/
|
*/
|
||||||
void amd64_lapic_init (uint32_t us) {
|
void lapic_init (uint32_t us) {
|
||||||
struct limine_hhdm_response* hhdm = limine_hhdm_request.response;
|
struct limine_hhdm_response* hhdm = limine_hhdm_request.response;
|
||||||
|
|
||||||
amd64_wrmsr (MSR_APIC_BASE, amd64_rdmsr (MSR_APIC_BASE) | (1 << 11));
|
wrmsr (MSR_APIC_BASE, rdmsr (MSR_APIC_BASE) | (1 << 11));
|
||||||
|
|
||||||
uintptr_t lapic_paddr = amd64_rdmsr (MSR_APIC_BASE) & 0xFFFFF000;
|
uintptr_t lapic_paddr = rdmsr (MSR_APIC_BASE) & 0xFFFFF000;
|
||||||
thiscpu->lapic_mmio_base = lapic_paddr + (uintptr_t)hhdm->offset;
|
thiscpu->lapic_mmio_base = lapic_paddr + (uintptr_t)hhdm->offset;
|
||||||
|
|
||||||
mm_map_kernel_page (lapic_paddr, thiscpu->lapic_mmio_base, MM_PG_PRESENT | MM_PG_RW);
|
mm_map_kernel_page (lapic_paddr, thiscpu->lapic_mmio_base, MM_PG_PRESENT | MM_PG_RW);
|
||||||
|
|
||||||
amd64_lapic_write (LAPIC_SIVR, 0xFF | (1 << 8));
|
lapic_write (LAPIC_SIVR, 0xFF | (1 << 8));
|
||||||
|
|
||||||
thiscpu->lapic_ticks = amd64_lapic_calibrate (us);
|
thiscpu->lapic_ticks = lapic_calibrate (us);
|
||||||
amd64_lapic_start (thiscpu->lapic_ticks);
|
lapic_start (thiscpu->lapic_ticks);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -255,12 +253,12 @@ void amd64_lapic_init (uint32_t us) {
|
|||||||
* lapic_id - Target Local APIC
|
* lapic_id - Target Local APIC
|
||||||
* vec - Interrupt vector/IDT stub, which will be invoked by the IPI.
|
* vec - Interrupt vector/IDT stub, which will be invoked by the IPI.
|
||||||
*/
|
*/
|
||||||
void amd64_lapic_ipi (uint32_t lapic_id, uint32_t vec) {
|
void lapic_ipi (uint32_t lapic_id, uint32_t vec) {
|
||||||
/* wait for previous IPI to finish */
|
/* wait for previous IPI to finish */
|
||||||
while (amd64_lapic_read (LAPIC_ICR) & (1 << 12)) {
|
while (lapic_read (LAPIC_ICR) & (1 << 12)) {
|
||||||
__asm__ volatile ("pause");
|
__asm__ volatile ("pause");
|
||||||
}
|
}
|
||||||
|
|
||||||
amd64_lapic_write (LAPIC_ICR + 0x10, (lapic_id << 24));
|
lapic_write (LAPIC_ICR + 0x10, (lapic_id << 24));
|
||||||
amd64_lapic_write (LAPIC_ICR, vec);
|
lapic_write (LAPIC_ICR, vec);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,12 +3,12 @@
|
|||||||
|
|
||||||
#include <libk/std.h>
|
#include <libk/std.h>
|
||||||
|
|
||||||
void amd64_ioapic_route_irq (uint32_t vec, uint32_t irq, uint64_t flags, uint64_t lapic_id);
|
void ioapic_route_irq (uint32_t vec, uint32_t irq, uint64_t flags, uint64_t lapic_id);
|
||||||
void amd64_ioapic_init (void);
|
void ioapic_init (void);
|
||||||
|
|
||||||
uint32_t amd64_lapic_id (void);
|
uint32_t lapic_id (void);
|
||||||
void amd64_lapic_eoi (void);
|
void lapic_eoi (void);
|
||||||
void amd64_lapic_ipi (uint32_t lapic_id, uint32_t vec);
|
void lapic_ipi (uint32_t lapic_id, uint32_t vec);
|
||||||
void amd64_lapic_init (uint32_t us);
|
void lapic_init (uint32_t us);
|
||||||
|
|
||||||
#endif // _KERNEL_AMD64_APIC_H
|
#endif // _KERNEL_AMD64_APIC_H
|
||||||
|
|||||||
@@ -39,16 +39,16 @@ void bootmain (void) {
|
|||||||
|
|
||||||
struct cpu* bsp_cpu = cpu_make (mp->bsp_lapic_id, 0);
|
struct cpu* bsp_cpu = cpu_make (mp->bsp_lapic_id, 0);
|
||||||
|
|
||||||
amd64_init (bsp_cpu, false);
|
init_gdt_idt (bsp_cpu, false);
|
||||||
syscall_init ();
|
syscall_init ();
|
||||||
amd64_debug_init ();
|
debug_init ();
|
||||||
pmm_init ();
|
pmm_init ();
|
||||||
mm_init ();
|
mm_init ();
|
||||||
|
|
||||||
uacpi_setup_early_table_access ((void*)uacpi_memory_buffer, sizeof (uacpi_memory_buffer));
|
uacpi_setup_early_table_access ((void*)uacpi_memory_buffer, sizeof (uacpi_memory_buffer));
|
||||||
|
|
||||||
amd64_ioapic_init ();
|
ioapic_init ();
|
||||||
amd64_hpet_init ();
|
hpet_init ();
|
||||||
|
|
||||||
devices_init ();
|
devices_init ();
|
||||||
vfs_init ();
|
vfs_init ();
|
||||||
|
|||||||
@@ -17,25 +17,23 @@
|
|||||||
*/
|
*/
|
||||||
static spin_lock_t serial_lock = SPIN_LOCK_INIT;
|
static spin_lock_t serial_lock = SPIN_LOCK_INIT;
|
||||||
|
|
||||||
static bool debug_init = false;
|
static bool debug_is_init = false;
|
||||||
|
|
||||||
/* Block until TX buffer is empty */
|
/* Block until TX buffer is empty */
|
||||||
static bool amd64_debug_serial_tx_empty (void) {
|
static bool debug_serial_tx_empty (void) { return (bool)(inb (PORT_COM1 + 5) & 0x20); }
|
||||||
return (bool)(amd64_io_inb (PORT_COM1 + 5) & 0x20);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Write a single character to serial */
|
/* Write a single character to serial */
|
||||||
static void amd64_debug_serial_write (char x) {
|
static void debug_serial_write (char x) {
|
||||||
while (!amd64_debug_serial_tx_empty ())
|
while (!debug_serial_tx_empty ())
|
||||||
;
|
;
|
||||||
amd64_io_outb (PORT_COM1, (uint8_t)x);
|
outb (PORT_COM1, (uint8_t)x);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Formatted printing to serial. serial_lock ensures that all prints are atomic.
|
* Formatted printing to serial. serial_lock ensures that all prints are atomic.
|
||||||
*/
|
*/
|
||||||
void debugprintf (const char* fmt, ...) {
|
void debugprintf (const char* fmt, ...) {
|
||||||
if (!debug_init)
|
if (!debug_is_init)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
char buffer[BUFFER_SIZE];
|
char buffer[BUFFER_SIZE];
|
||||||
@@ -53,7 +51,7 @@ void debugprintf (const char* fmt, ...) {
|
|||||||
spin_lock (&serial_lock);
|
spin_lock (&serial_lock);
|
||||||
|
|
||||||
while (*p) {
|
while (*p) {
|
||||||
amd64_debug_serial_write (*p);
|
debug_serial_write (*p);
|
||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,14 +59,14 @@ void debugprintf (const char* fmt, ...) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize serial */
|
/* Initialize serial */
|
||||||
void amd64_debug_init (void) {
|
void debug_init (void) {
|
||||||
amd64_io_outb (PORT_COM1 + 1, 0x00);
|
outb (PORT_COM1 + 1, 0x00);
|
||||||
amd64_io_outb (PORT_COM1 + 3, 0x80);
|
outb (PORT_COM1 + 3, 0x80);
|
||||||
amd64_io_outb (PORT_COM1 + 0, 0x03);
|
outb (PORT_COM1 + 0, 0x03);
|
||||||
amd64_io_outb (PORT_COM1 + 1, 0x00);
|
outb (PORT_COM1 + 1, 0x00);
|
||||||
amd64_io_outb (PORT_COM1 + 3, 0x03);
|
outb (PORT_COM1 + 3, 0x03);
|
||||||
amd64_io_outb (PORT_COM1 + 2, 0xC7);
|
outb (PORT_COM1 + 2, 0xC7);
|
||||||
amd64_io_outb (PORT_COM1 + 4, 0x0B);
|
outb (PORT_COM1 + 4, 0x0B);
|
||||||
|
|
||||||
debug_init = true;
|
debug_is_init = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#ifndef _KERNEL_AMD64_DEBUG_H
|
#ifndef _KERNEL_AMD64_DEBUG_H
|
||||||
#define _KERNEL_AMD64_DEBUG_H
|
#define _KERNEL_AMD64_DEBUG_H
|
||||||
|
|
||||||
void amd64_debug_init (void);
|
void debug_init (void);
|
||||||
|
|
||||||
#endif // _KERNEL_AMD64_DEBUG_H
|
#endif // _KERNEL_AMD64_DEBUG_H
|
||||||
|
|||||||
@@ -31,26 +31,26 @@ static uint64_t hpet_period_fs;
|
|||||||
static spin_lock_t hpet_lock = SPIN_LOCK_INIT;
|
static spin_lock_t hpet_lock = SPIN_LOCK_INIT;
|
||||||
|
|
||||||
/* Read a HPET register. Assumes caller holds hpet_lock */
|
/* Read a HPET register. Assumes caller holds hpet_lock */
|
||||||
static uint64_t amd64_hpet_read64 (uint32_t reg) {
|
static uint64_t hpet_read64 (uint32_t reg) {
|
||||||
struct limine_hhdm_response* hhdm = limine_hhdm_request.response;
|
struct limine_hhdm_response* hhdm = limine_hhdm_request.response;
|
||||||
uintptr_t hpet_vaddr = hpet_paddr + (uintptr_t)hhdm->offset;
|
uintptr_t hpet_vaddr = hpet_paddr + (uintptr_t)hhdm->offset;
|
||||||
return *(volatile uint64_t*)(hpet_vaddr + reg);
|
return *(volatile uint64_t*)(hpet_vaddr + reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t amd64_hpet_read32 (uint32_t reg) {
|
static uint32_t hpet_read32 (uint32_t reg) {
|
||||||
struct limine_hhdm_response* hhdm = limine_hhdm_request.response;
|
struct limine_hhdm_response* hhdm = limine_hhdm_request.response;
|
||||||
uintptr_t hpet_vaddr = hpet_paddr + (uintptr_t)hhdm->offset;
|
uintptr_t hpet_vaddr = hpet_paddr + (uintptr_t)hhdm->offset;
|
||||||
return *(volatile uint32_t*)(hpet_vaddr + reg);
|
return *(volatile uint32_t*)(hpet_vaddr + reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write a HPET register. Assumes caller holds hpet_lock */
|
/* Write a HPET register. Assumes caller holds hpet_lock */
|
||||||
static void amd64_hpet_write64 (uint32_t reg, uint64_t value) {
|
static void hpet_write64 (uint32_t reg, uint64_t value) {
|
||||||
struct limine_hhdm_response* hhdm = limine_hhdm_request.response;
|
struct limine_hhdm_response* hhdm = limine_hhdm_request.response;
|
||||||
uintptr_t hpet_vaddr = hpet_paddr + (uintptr_t)hhdm->offset;
|
uintptr_t hpet_vaddr = hpet_paddr + (uintptr_t)hhdm->offset;
|
||||||
*(volatile uint64_t*)(hpet_vaddr + reg) = value;
|
*(volatile uint64_t*)(hpet_vaddr + reg) = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void amd64_hpet_write32 (uint32_t reg, uint32_t value) {
|
static void hpet_write32 (uint32_t reg, uint32_t value) {
|
||||||
struct limine_hhdm_response* hhdm = limine_hhdm_request.response;
|
struct limine_hhdm_response* hhdm = limine_hhdm_request.response;
|
||||||
uintptr_t hpet_vaddr = hpet_paddr + (uintptr_t)hhdm->offset;
|
uintptr_t hpet_vaddr = hpet_paddr + (uintptr_t)hhdm->offset;
|
||||||
*(volatile uint32_t*)(hpet_vaddr + reg) = value;
|
*(volatile uint32_t*)(hpet_vaddr + reg) = value;
|
||||||
@@ -58,18 +58,18 @@ static void amd64_hpet_write32 (uint32_t reg, uint32_t value) {
|
|||||||
|
|
||||||
/* Read current value of HPET_MCVR register. */
|
/* Read current value of HPET_MCVR register. */
|
||||||
|
|
||||||
static uint64_t amd64_hpet_read_counter (void) {
|
static uint64_t hpet_read_counter (void) {
|
||||||
uint64_t value;
|
uint64_t value;
|
||||||
spin_lock (&hpet_lock);
|
spin_lock (&hpet_lock);
|
||||||
|
|
||||||
if (!hpet_32bits)
|
if (!hpet_32bits)
|
||||||
value = amd64_hpet_read64 (HPET_MCVR);
|
value = hpet_read64 (HPET_MCVR);
|
||||||
else {
|
else {
|
||||||
uint32_t hi1, lo, hi2;
|
uint32_t hi1, lo, hi2;
|
||||||
do {
|
do {
|
||||||
hi1 = amd64_hpet_read32 (HPET_MCVR + 4);
|
hi1 = hpet_read32 (HPET_MCVR + 4);
|
||||||
lo = amd64_hpet_read32 (HPET_MCVR + 0);
|
lo = hpet_read32 (HPET_MCVR + 0);
|
||||||
hi2 = amd64_hpet_read32 (HPET_MCVR + 4);
|
hi2 = hpet_read32 (HPET_MCVR + 4);
|
||||||
} while (hi1 != hi2);
|
} while (hi1 != hi2);
|
||||||
|
|
||||||
value = ((uint64_t)hi1 << 32) | lo;
|
value = ((uint64_t)hi1 << 32) | lo;
|
||||||
@@ -80,14 +80,14 @@ static uint64_t amd64_hpet_read_counter (void) {
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void amd64_hpet_write_counter (uint64_t value) {
|
static void hpet_write_counter (uint64_t value) {
|
||||||
spin_lock (&hpet_lock);
|
spin_lock (&hpet_lock);
|
||||||
|
|
||||||
if (!hpet_32bits)
|
if (!hpet_32bits)
|
||||||
amd64_hpet_write64 (HPET_MCVR, value);
|
hpet_write64 (HPET_MCVR, value);
|
||||||
else {
|
else {
|
||||||
amd64_hpet_write32 (HPET_MCVR, (uint32_t)value);
|
hpet_write32 (HPET_MCVR, (uint32_t)value);
|
||||||
amd64_hpet_write32 (HPET_MCVR + 4, (uint32_t)(value >> 32));
|
hpet_write32 (HPET_MCVR + 4, (uint32_t)(value >> 32));
|
||||||
}
|
}
|
||||||
|
|
||||||
spin_unlock (&hpet_lock);
|
spin_unlock (&hpet_lock);
|
||||||
@@ -95,15 +95,15 @@ static void amd64_hpet_write_counter (uint64_t value) {
|
|||||||
|
|
||||||
/* Sleep for a given amount of microseconds. This time can last longer due to \ref hpet_lock being
|
/* Sleep for a given amount of microseconds. This time can last longer due to \ref hpet_lock being
|
||||||
* held. */
|
* held. */
|
||||||
void amd64_hpet_sleep_micro (uint64_t us) {
|
void hpet_sleep_micro (uint64_t us) {
|
||||||
if (hpet_period_fs == 0)
|
if (hpet_period_fs == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
uint64_t ticks_to_wait = (us * 1000ULL) / (hpet_period_fs / 1000000ULL);
|
uint64_t ticks_to_wait = (us * 1000ULL) / (hpet_period_fs / 1000000ULL);
|
||||||
uint64_t start = amd64_hpet_read_counter ();
|
uint64_t start = hpet_read_counter ();
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
uint64_t now = amd64_hpet_read_counter ();
|
uint64_t now = hpet_read_counter ();
|
||||||
|
|
||||||
if ((now - start) >= ticks_to_wait)
|
if ((now - start) >= ticks_to_wait)
|
||||||
break;
|
break;
|
||||||
@@ -113,7 +113,7 @@ void amd64_hpet_sleep_micro (uint64_t us) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize HPET */
|
/* Initialize HPET */
|
||||||
void amd64_hpet_init (void) {
|
void hpet_init (void) {
|
||||||
struct uacpi_table hpet_table;
|
struct uacpi_table hpet_table;
|
||||||
uacpi_status status = uacpi_table_find_by_signature (ACPI_HPET_SIGNATURE, &hpet_table);
|
uacpi_status status = uacpi_table_find_by_signature (ACPI_HPET_SIGNATURE, &hpet_table);
|
||||||
if (status != UACPI_STATUS_OK) {
|
if (status != UACPI_STATUS_OK) {
|
||||||
@@ -127,12 +127,12 @@ void amd64_hpet_init (void) {
|
|||||||
struct limine_hhdm_response* hhdm = limine_hhdm_request.response;
|
struct limine_hhdm_response* hhdm = limine_hhdm_request.response;
|
||||||
mm_map_kernel_page (hpet_paddr, (uintptr_t)hhdm->offset + hpet_paddr, MM_PG_PRESENT | MM_PG_RW);
|
mm_map_kernel_page (hpet_paddr, (uintptr_t)hhdm->offset + hpet_paddr, MM_PG_PRESENT | MM_PG_RW);
|
||||||
|
|
||||||
uint64_t caps = amd64_hpet_read64 (HPET_GCIDR);
|
uint64_t caps = hpet_read64 (HPET_GCIDR);
|
||||||
hpet_32bits = (caps & (1 << 13)) ? 0 : 1;
|
hpet_32bits = (caps & (1 << 13)) ? 0 : 1;
|
||||||
|
|
||||||
hpet_period_fs = (uint32_t)(caps >> 32);
|
hpet_period_fs = (uint32_t)(caps >> 32);
|
||||||
|
|
||||||
amd64_hpet_write64 (HPET_GCR, 0);
|
hpet_write64 (HPET_GCR, 0);
|
||||||
amd64_hpet_write_counter (0);
|
hpet_write_counter (0);
|
||||||
amd64_hpet_write64 (HPET_GCR, 1);
|
hpet_write64 (HPET_GCR, 1);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
#include <libk/std.h>
|
#include <libk/std.h>
|
||||||
|
|
||||||
void amd64_hpet_sleep_micro (uint64_t us);
|
void hpet_sleep_micro (uint64_t us);
|
||||||
void amd64_hpet_init (void);
|
void hpet_init (void);
|
||||||
|
|
||||||
#endif // _KERNEL_AMD64_HPET_H
|
#endif // _KERNEL_AMD64_HPET_H
|
||||||
|
|||||||
@@ -10,8 +10,8 @@
|
|||||||
#define TSS_PRESENT 0x89
|
#define TSS_PRESENT 0x89
|
||||||
|
|
||||||
/* Set a GDT entry */
|
/* Set a GDT entry */
|
||||||
static void amd64_gdt_set (volatile struct gdt_entry* ent, uint32_t base, uint32_t limit,
|
static void gdt_set (volatile struct gdt_entry* ent, uint32_t base, uint32_t limit, uint8_t acc,
|
||||||
uint8_t acc, uint8_t gran) {
|
uint8_t gran) {
|
||||||
ent->baselow = (base & 0xFFFF);
|
ent->baselow = (base & 0xFFFF);
|
||||||
ent->basemid = (base >> 16) & 0xFF;
|
ent->basemid = (base >> 16) & 0xFF;
|
||||||
ent->basehigh = (base >> 24) & 0xFF;
|
ent->basehigh = (base >> 24) & 0xFF;
|
||||||
@@ -21,7 +21,7 @@ static void amd64_gdt_set (volatile struct gdt_entry* ent, uint32_t base, uint32
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize GDT and TSS structures for a given CPU */
|
/* Initialize GDT and TSS structures for a given CPU */
|
||||||
static void amd64_gdt_init (struct cpu* cpu) {
|
static void gdt_init (struct cpu* cpu) {
|
||||||
volatile struct tss* tss = &cpu->tss;
|
volatile struct tss* tss = &cpu->tss;
|
||||||
volatile struct gdt_extended* gdt = &cpu->gdt;
|
volatile struct gdt_extended* gdt = &cpu->gdt;
|
||||||
|
|
||||||
@@ -36,12 +36,12 @@ static void amd64_gdt_init (struct cpu* cpu) {
|
|||||||
uint64_t tssbase = (uint64_t)tss;
|
uint64_t tssbase = (uint64_t)tss;
|
||||||
uint64_t tsslimit = sizeof (*tss) - 1;
|
uint64_t tsslimit = sizeof (*tss) - 1;
|
||||||
|
|
||||||
amd64_gdt_set (&gdt->old[0], 0, 0, 0, 0);
|
gdt_set (&gdt->old[0], 0, 0, 0, 0);
|
||||||
amd64_gdt_set (&gdt->old[1], 0, 0xFFFFF, 0x9A, 0xA0);
|
gdt_set (&gdt->old[1], 0, 0xFFFFF, 0x9A, 0xA0);
|
||||||
amd64_gdt_set (&gdt->old[2], 0, 0xFFFFF, 0x92, 0xC0);
|
gdt_set (&gdt->old[2], 0, 0xFFFFF, 0x92, 0xC0);
|
||||||
amd64_gdt_set (&gdt->old[3], 0, 0xFFFFF, 0xF2, 0xC0);
|
gdt_set (&gdt->old[3], 0, 0xFFFFF, 0xF2, 0xC0);
|
||||||
amd64_gdt_set (&gdt->old[4], 0, 0xFFFFF, 0xFA, 0xA0);
|
gdt_set (&gdt->old[4], 0, 0xFFFFF, 0xFA, 0xA0);
|
||||||
amd64_gdt_set (&gdt->tsslow, (tssbase & 0xFFFFFFFF), tsslimit, TSS_PRESENT | TSS, 0);
|
gdt_set (&gdt->tsslow, (tssbase & 0xFFFFFFFF), tsslimit, TSS_PRESENT | TSS, 0);
|
||||||
|
|
||||||
uint32_t tssbasehigh = (tssbase >> 32);
|
uint32_t tssbasehigh = (tssbase >> 32);
|
||||||
gdt->tsshigh.limitlow = (tssbasehigh & 0xFFFF);
|
gdt->tsshigh.limitlow = (tssbasehigh & 0xFFFF);
|
||||||
@@ -80,10 +80,10 @@ static void amd64_gdt_init (struct cpu* cpu) {
|
|||||||
* load_idt - Tell whether the IDT needs to be loaded. It only has to be loaded once on
|
* load_idt - Tell whether the IDT needs to be loaded. It only has to be loaded once on
|
||||||
* the BSP
|
* the BSP
|
||||||
*/
|
*/
|
||||||
void amd64_init (struct cpu* cpu, bool load_idt) {
|
void init_gdt_idt (struct cpu* cpu, bool load_idt) {
|
||||||
amd64_gdt_init (cpu);
|
gdt_init (cpu);
|
||||||
if (load_idt)
|
if (load_idt)
|
||||||
amd64_load_idt ();
|
idt_load ();
|
||||||
else
|
else
|
||||||
amd64_intr_init ();
|
intr_init ();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,6 @@
|
|||||||
|
|
||||||
#include <amd64/smp.h>
|
#include <amd64/smp.h>
|
||||||
|
|
||||||
void amd64_init (struct cpu* cpu, bool load_idt);
|
void init_gdt_idt (struct cpu* cpu, bool load_idt);
|
||||||
|
|
||||||
#endif // _KERNEL_AMD64_INIT_H
|
#endif // _KERNEL_AMD64_INIT_H
|
||||||
|
|||||||
@@ -62,33 +62,36 @@ ALIGNED (16) static volatile struct idt_entry idt_entries[IDT_ENTRIES_MAX];
|
|||||||
static volatile struct idt idt;
|
static volatile struct idt idt;
|
||||||
|
|
||||||
/* Remaps and disables old 8259 PIC, since we'll be using APIC. */
|
/* Remaps and disables old 8259 PIC, since we'll be using APIC. */
|
||||||
static void amd64_init_pic (void) {
|
static void pic_init (void) {
|
||||||
#define IO_OP(fn, ...) \
|
outb (PIC1_CMD, (ICW1_INIT | ICW1_ICW4));
|
||||||
fn (__VA_ARGS__); \
|
io_wait ();
|
||||||
amd64_io_wait ()
|
outb (PIC2_CMD, (ICW1_INIT | ICW1_ICW4));
|
||||||
|
io_wait ();
|
||||||
|
|
||||||
IO_OP (amd64_io_outb, PIC1_CMD, (ICW1_INIT | ICW1_ICW4));
|
outb (PIC1_DATA, 0x20);
|
||||||
IO_OP (amd64_io_outb, PIC2_CMD, (ICW1_INIT | ICW1_ICW4));
|
io_wait ();
|
||||||
|
outb (PIC2_DATA, 0x28);
|
||||||
|
io_wait ();
|
||||||
|
|
||||||
IO_OP (amd64_io_outb, PIC1_DATA, 0x20);
|
outb (PIC1_DATA, (1 << CASCADE_IRQ));
|
||||||
IO_OP (amd64_io_outb, PIC2_DATA, 0x28);
|
io_wait ();
|
||||||
|
outb (PIC2_DATA, 2);
|
||||||
|
io_wait ();
|
||||||
|
|
||||||
IO_OP (amd64_io_outb, PIC1_DATA, (1 << CASCADE_IRQ));
|
outb (PIC1_DATA, ICW4_8086);
|
||||||
IO_OP (amd64_io_outb, PIC2_DATA, 2);
|
io_wait ();
|
||||||
|
outb (PIC2_DATA, ICW4_8086);
|
||||||
IO_OP (amd64_io_outb, PIC1_DATA, ICW4_8086);
|
io_wait ();
|
||||||
IO_OP (amd64_io_outb, PIC2_DATA, ICW4_8086);
|
|
||||||
|
|
||||||
/* Disable */
|
/* Disable */
|
||||||
IO_OP (amd64_io_outb, PIC1_DATA, 0xFF);
|
outb (PIC1_DATA, 0xFF);
|
||||||
IO_OP (amd64_io_outb, PIC2_DATA, 0xFF);
|
io_wait ();
|
||||||
|
outb (PIC2_DATA, 0xFF);
|
||||||
#undef IO_OP
|
io_wait ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set IDT entry */
|
/* Set IDT entry */
|
||||||
static void amd64_idt_set (volatile struct idt_entry* ent, uint64_t handler, uint8_t flags,
|
static void idt_set (volatile struct idt_entry* ent, uint64_t handler, uint8_t flags, uint8_t ist) {
|
||||||
uint8_t ist) {
|
|
||||||
ent->intrlow = (handler & 0xFFFF);
|
ent->intrlow = (handler & 0xFFFF);
|
||||||
ent->kernel_cs = GDT_KCODE;
|
ent->kernel_cs = GDT_KCODE;
|
||||||
ent->ist = ist;
|
ent->ist = ist;
|
||||||
@@ -99,15 +102,15 @@ static void amd64_idt_set (volatile struct idt_entry* ent, uint64_t handler, uin
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Load the IDT */
|
/* Load the IDT */
|
||||||
void amd64_load_idt (void) { __asm__ volatile ("lidt %0" ::"m"(idt)); }
|
void idt_load (void) { __asm__ volatile ("lidt %0" ::"m"(idt)); }
|
||||||
|
|
||||||
/* Initialize IDT entries */
|
/* Initialize IDT entries */
|
||||||
static void amd64_idt_init (void) {
|
static void idt_init (void) {
|
||||||
memset ((void*)idt_entries, 0, sizeof (idt_entries));
|
memset ((void*)idt_entries, 0, sizeof (idt_entries));
|
||||||
|
|
||||||
#define IDT_ENTRY(n, ist) \
|
#define IDT_ENTRY(n, ist) \
|
||||||
extern void amd64_intr##n (void); \
|
extern void intr##n (void); \
|
||||||
amd64_idt_set (&idt_entries[(n)], (uint64_t)&amd64_intr##n, 0x8E, (ist))
|
idt_set (&idt_entries[(n)], (uint64_t)&intr##n, 0x8E, (ist))
|
||||||
/* clang-format off */
|
/* clang-format off */
|
||||||
IDT_ENTRY (0, 0); IDT_ENTRY (1, 0); IDT_ENTRY (2, 0); IDT_ENTRY (3, 0);
|
IDT_ENTRY (0, 0); IDT_ENTRY (1, 0); IDT_ENTRY (2, 0); IDT_ENTRY (3, 0);
|
||||||
IDT_ENTRY (4, 0); IDT_ENTRY (5, 0); IDT_ENTRY (6, 0); IDT_ENTRY (7, 0);
|
IDT_ENTRY (4, 0); IDT_ENTRY (5, 0); IDT_ENTRY (6, 0); IDT_ENTRY (7, 0);
|
||||||
@@ -131,11 +134,11 @@ static void amd64_idt_init (void) {
|
|||||||
idt.limit = sizeof (idt_entries) - 1;
|
idt.limit = sizeof (idt_entries) - 1;
|
||||||
idt.base = (uint64_t)idt_entries;
|
idt.base = (uint64_t)idt_entries;
|
||||||
|
|
||||||
amd64_load_idt ();
|
idt_load ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handle CPU exception and dump registers. If incoming CS has CPL3, kill the process. */
|
/* Handle CPU exception and dump registers. If incoming CS has CPL3, kill the process. */
|
||||||
static void amd64_intr_exception (struct saved_regs* regs) {
|
static void intr_exception (struct saved_regs* regs) {
|
||||||
DEBUG ("cpu exception %lu (%lu)\n", regs->trap, regs->error);
|
DEBUG ("cpu exception %lu (%lu)\n", regs->trap, regs->error);
|
||||||
|
|
||||||
uint64_t cr2;
|
uint64_t cr2;
|
||||||
@@ -169,8 +172,8 @@ static void amd64_intr_exception (struct saved_regs* regs) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Handle incoming interrupt, dispatch IRQ handlers. */
|
/* Handle incoming interrupt, dispatch IRQ handlers. */
|
||||||
void amd64_intr_handler (void* stack_ptr) {
|
void intr_handler (void* stack_ptr) {
|
||||||
amd64_load_kernel_cr3 ();
|
load_kernel_cr3 ();
|
||||||
|
|
||||||
struct saved_regs* regs = stack_ptr;
|
struct saved_regs* regs = stack_ptr;
|
||||||
|
|
||||||
@@ -184,9 +187,9 @@ void amd64_intr_handler (void* stack_ptr) {
|
|||||||
spin_unlock (&thiscpu->lock);
|
spin_unlock (&thiscpu->lock);
|
||||||
|
|
||||||
if (regs->trap <= 31) {
|
if (regs->trap <= 31) {
|
||||||
amd64_intr_exception (regs);
|
intr_exception (regs);
|
||||||
} else {
|
} else {
|
||||||
amd64_lapic_eoi ();
|
lapic_eoi ();
|
||||||
|
|
||||||
struct irq* irq = irq_find (regs->trap);
|
struct irq* irq = irq_find (regs->trap);
|
||||||
|
|
||||||
@@ -202,7 +205,7 @@ void amd64_intr_handler (void* stack_ptr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize interrupts */
|
/* Initialize interrupts */
|
||||||
void amd64_intr_init (void) {
|
void intr_init (void) {
|
||||||
amd64_init_pic ();
|
pic_init ();
|
||||||
amd64_idt_init ();
|
idt_init ();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ struct saved_regs {
|
|||||||
uint64_t ss;
|
uint64_t ss;
|
||||||
} PACKED;
|
} PACKED;
|
||||||
|
|
||||||
void amd64_load_idt (void);
|
void idt_load (void);
|
||||||
void amd64_intr_init (void);
|
void intr_init (void);
|
||||||
|
|
||||||
#endif // _KERNEL_AMD64_INTR_H
|
#endif // _KERNEL_AMD64_INTR_H
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#include <amd64/intr_defs.h>
|
#include <amd64/intr_defs.h>
|
||||||
#include <amd64/regsasm.h>
|
#include <amd64/regsasm.h>
|
||||||
|
|
||||||
.extern amd64_intr_handler
|
.extern intr_handler
|
||||||
|
|
||||||
#define err(z) \
|
#define err(z) \
|
||||||
pushq $z;
|
pushq $z;
|
||||||
@@ -11,8 +11,8 @@
|
|||||||
pushq $z;
|
pushq $z;
|
||||||
|
|
||||||
#define make_intr_stub(x, n) \
|
#define make_intr_stub(x, n) \
|
||||||
.global amd64_intr ## n; \
|
.global intr ## n; \
|
||||||
amd64_intr ## n:; \
|
intr ## n:; \
|
||||||
x(n); \
|
x(n); \
|
||||||
cli; \
|
cli; \
|
||||||
; \
|
; \
|
||||||
@@ -33,7 +33,7 @@
|
|||||||
subq $8, %rsp; \
|
subq $8, %rsp; \
|
||||||
andq $-16, %rsp; \
|
andq $-16, %rsp; \
|
||||||
; \
|
; \
|
||||||
callq amd64_intr_handler; \
|
callq intr_handler; \
|
||||||
; \
|
; \
|
||||||
movq %rbp, %rsp; \
|
movq %rbp, %rsp; \
|
||||||
; \
|
; \
|
||||||
|
|||||||
@@ -2,50 +2,44 @@
|
|||||||
#include <libk/std.h>
|
#include <libk/std.h>
|
||||||
|
|
||||||
/// Perform outb instruction (send 8-bit int)
|
/// Perform outb instruction (send 8-bit int)
|
||||||
void amd64_io_outb (uint16_t port, uint8_t v) {
|
void outb (uint16_t port, uint8_t v) { __asm__ volatile ("outb %1, %0" ::"dN"(port), "a"(v)); }
|
||||||
__asm__ volatile ("outb %1, %0" ::"dN"(port), "a"(v));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Perform outw instruction (send 16-bit int)
|
/// Perform outw instruction (send 16-bit int)
|
||||||
void amd64_io_outw (uint16_t port, uint16_t v) {
|
void outw (uint16_t port, uint16_t v) { __asm__ volatile ("outw %%ax, %%dx" ::"a"(v), "d"(port)); }
|
||||||
__asm__ volatile ("outw %%ax, %%dx" ::"a"(v), "d"(port));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Perform outl instruction (send 32-bit int)
|
/// Perform outl instruction (send 32-bit int)
|
||||||
void amd64_io_outl (uint16_t port, uint32_t v) {
|
void outl (uint16_t port, uint32_t v) { __asm__ volatile ("outl %%eax, %%dx" ::"d"(port), "a"(v)); }
|
||||||
__asm__ volatile ("outl %%eax, %%dx" ::"d"(port), "a"(v));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Perform outsw instruction (send a string)
|
/// Perform outsw instruction (send a string)
|
||||||
void amd64_io_outsw (uint16_t port, const void* addr, int cnt) {
|
void outsw (uint16_t port, const void* addr, int cnt) {
|
||||||
__asm__ volatile ("cld; rep outsw" : "+S"(addr), "+c"(cnt) : "d"(port) : "memory", "cc");
|
__asm__ volatile ("cld; rep outsw" : "+S"(addr), "+c"(cnt) : "d"(port) : "memory", "cc");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Perform inb instruction (receive 8-bit int)
|
/// Perform inb instruction (receive 8-bit int)
|
||||||
uint8_t amd64_io_inb (uint16_t port) {
|
uint8_t inb (uint16_t port) {
|
||||||
uint8_t r;
|
uint8_t r;
|
||||||
__asm__ volatile ("inb %1, %0" : "=a"(r) : "dN"(port));
|
__asm__ volatile ("inb %1, %0" : "=a"(r) : "dN"(port));
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Perform inw instruction (receive 16-bit int)
|
/// Perform inw instruction (receive 16-bit int)
|
||||||
uint16_t amd64_io_inw (uint16_t port) {
|
uint16_t inw (uint16_t port) {
|
||||||
uint16_t r;
|
uint16_t r;
|
||||||
__asm__ volatile ("inw %%dx, %%ax" : "=a"(r) : "d"(port));
|
__asm__ volatile ("inw %%dx, %%ax" : "=a"(r) : "d"(port));
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Perform inl instruction (receive 32-bit int)
|
/// Perform inl instruction (receive 32-bit int)
|
||||||
uint32_t amd64_io_inl (uint16_t port) {
|
uint32_t inl (uint16_t port) {
|
||||||
uint32_t r;
|
uint32_t r;
|
||||||
__asm__ volatile ("inl %%dx, %%eax" : "=a"(r) : "d"(port));
|
__asm__ volatile ("inl %%dx, %%eax" : "=a"(r) : "d"(port));
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Perform insw instruction (receive a string)
|
/// Perform insw instruction (receive a string)
|
||||||
void amd64_io_insw (uint16_t port, void* addr, int cnt) {
|
void insw (uint16_t port, void* addr, int cnt) {
|
||||||
__asm__ volatile ("cld; rep insw" : "+D"(addr), "+c"(cnt) : "d"(port) : "memory", "cc");
|
__asm__ volatile ("cld; rep insw" : "+D"(addr), "+c"(cnt) : "d"(port) : "memory", "cc");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// output a byte on port 0x80, which does a small IO delay
|
/// output a byte on port 0x80, which does a small IO delay
|
||||||
void amd64_io_wait (void) { amd64_io_outb (0x80, 0); }
|
void io_wait (void) { outb (0x80, 0); }
|
||||||
|
|||||||
@@ -3,14 +3,14 @@
|
|||||||
|
|
||||||
#include <libk/std.h>
|
#include <libk/std.h>
|
||||||
|
|
||||||
void amd64_io_outb (uint16_t port, uint8_t v);
|
void outb (uint16_t port, uint8_t v);
|
||||||
void amd64_io_outw (uint16_t port, uint16_t v);
|
void outw (uint16_t port, uint16_t v);
|
||||||
void amd64_io_outl (uint16_t port, uint32_t v);
|
void outl (uint16_t port, uint32_t v);
|
||||||
void amd64_io_outsw (uint16_t port, const void* addr, int cnt);
|
void outsw (uint16_t port, const void* addr, int cnt);
|
||||||
uint8_t amd64_io_inb (uint16_t port);
|
uint8_t inb (uint16_t port);
|
||||||
uint16_t amd64_io_inw (uint16_t port);
|
uint16_t inw (uint16_t port);
|
||||||
uint32_t amd64_io_inl (uint16_t port);
|
uint32_t inl (uint16_t port);
|
||||||
void amd64_io_insw (uint16_t port, void* addr, int cnt);
|
void insw (uint16_t port, void* addr, int cnt);
|
||||||
void amd64_io_wait (void);
|
void io_wait (void);
|
||||||
|
|
||||||
#endif // _KERNEL_AMD64_IO_H
|
#endif // _KERNEL_AMD64_IO_H
|
||||||
|
|||||||
@@ -30,15 +30,15 @@ void mm_kernel_lock (void) { spin_lock (&kernel_pd_lock); }
|
|||||||
void mm_kernel_unlock (void) { spin_lock (&kernel_pd_lock); }
|
void mm_kernel_unlock (void) { spin_lock (&kernel_pd_lock); }
|
||||||
|
|
||||||
/* Get current value of CR3 register */
|
/* Get current value of CR3 register */
|
||||||
static uintptr_t amd64_current_cr3 (void) {
|
static uintptr_t current_cr3 (void) {
|
||||||
uintptr_t cr3;
|
uintptr_t cr3;
|
||||||
__asm__ volatile ("movq %%cr3, %0" : "=r"(cr3)::"memory");
|
__asm__ volatile ("movq %%cr3, %0" : "=r"(cr3)::"memory");
|
||||||
return cr3;
|
return cr3;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Load kernel CR3 as current CR3 */
|
/* Load kernel CR3 as current CR3 */
|
||||||
void amd64_load_kernel_cr3 (void) {
|
void load_kernel_cr3 (void) {
|
||||||
uintptr_t cr3 = amd64_current_cr3 ();
|
uintptr_t cr3 = current_cr3 ();
|
||||||
|
|
||||||
if (cr3 != kernel_pd.cr3_paddr) {
|
if (cr3 != kernel_pd.cr3_paddr) {
|
||||||
__asm__ volatile ("movq %0, %%cr3" ::"r"(kernel_pd.cr3_paddr) : "memory");
|
__asm__ volatile ("movq %0, %%cr3" ::"r"(kernel_pd.cr3_paddr) : "memory");
|
||||||
@@ -48,7 +48,7 @@ void amd64_load_kernel_cr3 (void) {
|
|||||||
struct pd* mm_get_kernel_pd (void) { return &kernel_pd; }
|
struct pd* mm_get_kernel_pd (void) { return &kernel_pd; }
|
||||||
|
|
||||||
/* Extract PML info from virtual address */
|
/* Extract PML info from virtual address */
|
||||||
static struct pg_index amd64_mm_page_index (uint64_t vaddr) {
|
static struct pg_index mm_page_index (uint64_t vaddr) {
|
||||||
struct pg_index ret;
|
struct pg_index ret;
|
||||||
|
|
||||||
ret.pml4 = ((vaddr >> 39) & 0x1FF);
|
ret.pml4 = ((vaddr >> 39) & 0x1FF);
|
||||||
@@ -60,7 +60,7 @@ static struct pg_index amd64_mm_page_index (uint64_t vaddr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Walk paging tables and allocate necessary structures along the way */
|
/* Walk paging tables and allocate necessary structures along the way */
|
||||||
static uint64_t* amd64_mm_next_table (uint64_t* table, uint64_t entry_idx, bool alloc) {
|
static uint64_t* mm_next_table (uint64_t* table, uint64_t entry_idx, bool alloc) {
|
||||||
uint64_t entry = table[entry_idx];
|
uint64_t entry = table[entry_idx];
|
||||||
physaddr_t paddr;
|
physaddr_t paddr;
|
||||||
|
|
||||||
@@ -87,7 +87,7 @@ static uint64_t* amd64_mm_next_table (uint64_t* table, uint64_t entry_idx, bool
|
|||||||
return (uint64_t*)((uintptr_t)hhdm->offset + (uintptr_t)paddr);
|
return (uint64_t*)((uintptr_t)hhdm->offset + (uintptr_t)paddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool amd64_mm_is_table_empty (uint64_t* table) {
|
static bool mm_is_table_empty (uint64_t* table) {
|
||||||
for (size_t i = 0; i < 512; i++) {
|
for (size_t i = 0; i < 512; i++) {
|
||||||
if (table[i] & AMD64_PG_PRESENT)
|
if (table[i] & AMD64_PG_PRESENT)
|
||||||
return false;
|
return false;
|
||||||
@@ -96,7 +96,7 @@ static bool amd64_mm_is_table_empty (uint64_t* table) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Convert generic memory management subsystem flags into AMD64-specific flags */
|
/* Convert generic memory management subsystem flags into AMD64-specific flags */
|
||||||
static uint64_t amd64_mm_resolve_flags (uint32_t generic) {
|
static uint64_t mm_resolve_flags (uint32_t generic) {
|
||||||
uint64_t flags = 0;
|
uint64_t flags = 0;
|
||||||
|
|
||||||
flags |= ((generic & MM_PG_PRESENT) ? AMD64_PG_PRESENT : 0);
|
flags |= ((generic & MM_PG_PRESENT) ? AMD64_PG_PRESENT : 0);
|
||||||
@@ -107,41 +107,41 @@ static uint64_t amd64_mm_resolve_flags (uint32_t generic) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Reload the current CR3 value ON A LOCAL CPU */
|
/* Reload the current CR3 value ON A LOCAL CPU */
|
||||||
static void amd64_reload_cr3 (void) {
|
static void reload_cr3 (void) {
|
||||||
uint64_t cr3;
|
uint64_t cr3;
|
||||||
__asm__ volatile ("movq %%cr3, %0; movq %0, %%cr3" : "=r"(cr3)::"memory");
|
__asm__ volatile ("movq %%cr3, %0; movq %0, %%cr3" : "=r"(cr3)::"memory");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Map physical address to virtual address with flags. TLB needs to be flushed afterwards. */
|
/* Map physical address to virtual address with flags. TLB needs to be flushed afterwards. */
|
||||||
void mm_map_page (struct pd* pd, uintptr_t paddr, uintptr_t vaddr, uint32_t flags) {
|
void mm_map_page (struct pd* pd, uintptr_t paddr, uintptr_t vaddr, uint32_t flags1) {
|
||||||
struct limine_hhdm_response* hhdm = limine_hhdm_request.response;
|
struct limine_hhdm_response* hhdm = limine_hhdm_request.response;
|
||||||
|
|
||||||
uint64_t amd64_flags = amd64_mm_resolve_flags (flags);
|
uint64_t flags = mm_resolve_flags (flags1);
|
||||||
|
|
||||||
uint64_t* pml4 = (uint64_t*)(pd->cr3_paddr + (uintptr_t)hhdm->offset);
|
uint64_t* pml4 = (uint64_t*)(pd->cr3_paddr + (uintptr_t)hhdm->offset);
|
||||||
struct pg_index pg_index = amd64_mm_page_index (vaddr);
|
struct pg_index pg_index = mm_page_index (vaddr);
|
||||||
|
|
||||||
uint64_t* pml3 = amd64_mm_next_table (pml4, pg_index.pml4, true);
|
uint64_t* pml3 = mm_next_table (pml4, pg_index.pml4, true);
|
||||||
if (pml3 == NULL)
|
if (pml3 == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
uint64_t* pml2 = amd64_mm_next_table (pml3, pg_index.pml3, true);
|
uint64_t* pml2 = mm_next_table (pml3, pg_index.pml3, true);
|
||||||
if (pml2 == NULL)
|
if (pml2 == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
uint64_t* pml1 = amd64_mm_next_table (pml2, pg_index.pml2, true);
|
uint64_t* pml1 = mm_next_table (pml2, pg_index.pml2, true);
|
||||||
if (pml1 == NULL)
|
if (pml1 == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
uint64_t* pte = &pml1[pg_index.pml1];
|
uint64_t* pte = &pml1[pg_index.pml1];
|
||||||
|
|
||||||
*pte = ((paddr & ~0xFFFULL) | (amd64_flags & 0x7ULL));
|
*pte = ((paddr & ~0xFFFULL) | (flags & 0x7ULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Map a page into kernel page directory */
|
/* Map a page into kernel page directory */
|
||||||
void mm_map_kernel_page (uintptr_t paddr, uintptr_t vaddr, uint32_t flags) {
|
void mm_map_kernel_page (uintptr_t paddr, uintptr_t vaddr, uint32_t flags) {
|
||||||
mm_map_page (&kernel_pd, paddr, vaddr, flags);
|
mm_map_page (&kernel_pd, paddr, vaddr, flags);
|
||||||
amd64_reload_cr3 ();
|
reload_cr3 ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Unmap a virtual address. TLB needs to be flushed afterwards */
|
/* Unmap a virtual address. TLB needs to be flushed afterwards */
|
||||||
@@ -149,17 +149,17 @@ void mm_unmap_page (struct pd* pd, uintptr_t vaddr) {
|
|||||||
struct limine_hhdm_response* hhdm = limine_hhdm_request.response;
|
struct limine_hhdm_response* hhdm = limine_hhdm_request.response;
|
||||||
|
|
||||||
uint64_t* pml4 = (uint64_t*)(pd->cr3_paddr + (uintptr_t)hhdm->offset);
|
uint64_t* pml4 = (uint64_t*)(pd->cr3_paddr + (uintptr_t)hhdm->offset);
|
||||||
struct pg_index pg_index = amd64_mm_page_index (vaddr);
|
struct pg_index pg_index = mm_page_index (vaddr);
|
||||||
|
|
||||||
uint64_t* pml3 = amd64_mm_next_table (pml4, pg_index.pml4, false);
|
uint64_t* pml3 = mm_next_table (pml4, pg_index.pml4, false);
|
||||||
if (pml3 == NULL)
|
if (pml3 == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
uint64_t* pml2 = amd64_mm_next_table (pml3, pg_index.pml3, false);
|
uint64_t* pml2 = mm_next_table (pml3, pg_index.pml3, false);
|
||||||
if (pml2 == NULL)
|
if (pml2 == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
uint64_t* pml1 = amd64_mm_next_table (pml2, pg_index.pml2, false);
|
uint64_t* pml1 = mm_next_table (pml2, pg_index.pml2, false);
|
||||||
if (pml1 == NULL)
|
if (pml1 == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -168,17 +168,17 @@ void mm_unmap_page (struct pd* pd, uintptr_t vaddr) {
|
|||||||
if ((*pte) & AMD64_PG_PRESENT)
|
if ((*pte) & AMD64_PG_PRESENT)
|
||||||
*pte = 0;
|
*pte = 0;
|
||||||
|
|
||||||
if (amd64_mm_is_table_empty (pml1)) {
|
if (mm_is_table_empty (pml1)) {
|
||||||
uintptr_t pml1_phys = pml2[pg_index.pml2] & ~0xFFFULL;
|
uintptr_t pml1_phys = pml2[pg_index.pml2] & ~0xFFFULL;
|
||||||
pmm_free (pml1_phys, 1);
|
pmm_free (pml1_phys, 1);
|
||||||
pml2[pg_index.pml2] = 0;
|
pml2[pg_index.pml2] = 0;
|
||||||
|
|
||||||
if (amd64_mm_is_table_empty (pml2)) {
|
if (mm_is_table_empty (pml2)) {
|
||||||
uintptr_t pml2_phys = pml3[pg_index.pml3] & ~0xFFFULL;
|
uintptr_t pml2_phys = pml3[pg_index.pml3] & ~0xFFFULL;
|
||||||
pmm_free (pml2_phys, 1);
|
pmm_free (pml2_phys, 1);
|
||||||
pml3[pg_index.pml3] = 0;
|
pml3[pg_index.pml3] = 0;
|
||||||
|
|
||||||
if (amd64_mm_is_table_empty (pml3)) {
|
if (mm_is_table_empty (pml3)) {
|
||||||
uintptr_t pml3_phys = pml4[pg_index.pml4] & ~0xFFFULL;
|
uintptr_t pml3_phys = pml4[pg_index.pml4] & ~0xFFFULL;
|
||||||
pmm_free (pml3_phys, 1);
|
pmm_free (pml3_phys, 1);
|
||||||
pml4[pg_index.pml4] = 0;
|
pml4[pg_index.pml4] = 0;
|
||||||
@@ -190,7 +190,7 @@ void mm_unmap_page (struct pd* pd, uintptr_t vaddr) {
|
|||||||
/* Unmap a page from kernel page directory */
|
/* Unmap a page from kernel page directory */
|
||||||
void mm_unmap_kernel_page (uintptr_t vaddr) {
|
void mm_unmap_kernel_page (uintptr_t vaddr) {
|
||||||
mm_unmap_page (&kernel_pd, vaddr);
|
mm_unmap_page (&kernel_pd, vaddr);
|
||||||
amd64_reload_cr3 ();
|
reload_cr3 ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate a userspace-ready page directory */
|
/* Allocate a userspace-ready page directory */
|
||||||
@@ -216,17 +216,17 @@ bool mm_validate (struct pd* pd, uintptr_t vaddr) {
|
|||||||
bool ret = false;
|
bool ret = false;
|
||||||
|
|
||||||
uint64_t* pml4 = (uint64_t*)(pd->cr3_paddr + (uintptr_t)hhdm->offset);
|
uint64_t* pml4 = (uint64_t*)(pd->cr3_paddr + (uintptr_t)hhdm->offset);
|
||||||
struct pg_index pg_index = amd64_mm_page_index (vaddr);
|
struct pg_index pg_index = mm_page_index (vaddr);
|
||||||
|
|
||||||
uint64_t* pml3 = amd64_mm_next_table (pml4, pg_index.pml4, false);
|
uint64_t* pml3 = mm_next_table (pml4, pg_index.pml4, false);
|
||||||
if (pml3 == NULL)
|
if (pml3 == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
uint64_t* pml2 = amd64_mm_next_table (pml3, pg_index.pml3, false);
|
uint64_t* pml2 = mm_next_table (pml3, pg_index.pml3, false);
|
||||||
if (pml2 == NULL)
|
if (pml2 == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
uint64_t* pml1 = amd64_mm_next_table (pml2, pg_index.pml2, false);
|
uint64_t* pml1 = mm_next_table (pml2, pg_index.pml2, false);
|
||||||
if (pml1 == NULL)
|
if (pml1 == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
@@ -292,17 +292,17 @@ uintptr_t mm_v2p (struct pd* pd, uintptr_t vaddr) {
|
|||||||
uintptr_t ret = 0;
|
uintptr_t ret = 0;
|
||||||
|
|
||||||
uint64_t* pml4 = (uint64_t*)(pd->cr3_paddr + (uintptr_t)hhdm->offset);
|
uint64_t* pml4 = (uint64_t*)(pd->cr3_paddr + (uintptr_t)hhdm->offset);
|
||||||
struct pg_index pg_index = amd64_mm_page_index (vaddr);
|
struct pg_index pg_index = mm_page_index (vaddr);
|
||||||
|
|
||||||
uint64_t* pml3 = amd64_mm_next_table (pml4, pg_index.pml4, false);
|
uint64_t* pml3 = mm_next_table (pml4, pg_index.pml4, false);
|
||||||
if (pml3 == NULL)
|
if (pml3 == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
uint64_t* pml2 = amd64_mm_next_table (pml3, pg_index.pml3, false);
|
uint64_t* pml2 = mm_next_table (pml3, pg_index.pml3, false);
|
||||||
if (pml2 == NULL)
|
if (pml2 == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
uint64_t* pml1 = amd64_mm_next_table (pml2, pg_index.pml2, false);
|
uint64_t* pml1 = mm_next_table (pml2, pg_index.pml2, false);
|
||||||
if (pml1 == NULL)
|
if (pml1 == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
@@ -318,4 +318,4 @@ done:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize essentials for the AMD64 memory management subsystem */
|
/* Initialize essentials for the AMD64 memory management subsystem */
|
||||||
void mm_init (void) { kernel_pd.cr3_paddr = amd64_current_cr3 (); }
|
void mm_init (void) { kernel_pd.cr3_paddr = current_cr3 (); }
|
||||||
|
|||||||
@@ -10,6 +10,6 @@ struct pd {
|
|||||||
uintptr_t cr3_paddr;
|
uintptr_t cr3_paddr;
|
||||||
};
|
};
|
||||||
|
|
||||||
void amd64_load_kernel_cr3 (void);
|
void load_kernel_cr3 (void);
|
||||||
|
|
||||||
#endif // _KERNEL_AMD64_MM_H
|
#endif // _KERNEL_AMD64_MM_H
|
||||||
|
|||||||
@@ -2,14 +2,14 @@
|
|||||||
#include <libk/std.h>
|
#include <libk/std.h>
|
||||||
|
|
||||||
/// Read a model-specific register
|
/// Read a model-specific register
|
||||||
uint64_t amd64_rdmsr (uint32_t msr) {
|
uint64_t rdmsr (uint32_t msr) {
|
||||||
uint32_t low, high;
|
uint32_t low, high;
|
||||||
__asm__ volatile ("rdmsr" : "=a"(low), "=d"(high) : "c"(msr));
|
__asm__ volatile ("rdmsr" : "=a"(low), "=d"(high) : "c"(msr));
|
||||||
return ((uint64_t)high << 32 | (uint64_t)low);
|
return ((uint64_t)high << 32 | (uint64_t)low);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Write a model-specific register
|
/// Write a model-specific register
|
||||||
void amd64_wrmsr (uint32_t msr, uint64_t value) {
|
void wrmsr (uint32_t msr, uint64_t value) {
|
||||||
uint32_t low = (uint32_t)(value & 0xFFFFFFFF);
|
uint32_t low = (uint32_t)(value & 0xFFFFFFFF);
|
||||||
uint32_t high = (uint32_t)(value >> 32);
|
uint32_t high = (uint32_t)(value >> 32);
|
||||||
__asm__ volatile ("wrmsr" ::"c"(msr), "a"(low), "d"(high));
|
__asm__ volatile ("wrmsr" ::"c"(msr), "a"(low), "d"(high));
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
#include <libk/std.h>
|
#include <libk/std.h>
|
||||||
|
|
||||||
uint64_t amd64_rdmsr (uint32_t msr);
|
uint64_t rdmsr (uint32_t msr);
|
||||||
void amd64_wrmsr (uint32_t msr, uint64_t value);
|
void wrmsr (uint32_t msr, uint64_t value);
|
||||||
|
|
||||||
#endif // _KERNEL_AMD64_MSR_H
|
#endif // _KERNEL_AMD64_MSR_H
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#include <amd64/regsasm.h>
|
#include <amd64/regsasm.h>
|
||||||
|
|
||||||
.global amd64_do_sched
|
.global do_sched1
|
||||||
amd64_do_sched:
|
do_sched1:
|
||||||
movq %rsi, %cr3
|
movq %rsi, %cr3
|
||||||
movq %rdi, %rsp
|
movq %rdi, %rsp
|
||||||
pop_regs
|
pop_regs
|
||||||
|
|||||||
@@ -2,6 +2,6 @@
|
|||||||
#define _KERNEL_AMD64_SCHED_H
|
#define _KERNEL_AMD64_SCHED_H
|
||||||
|
|
||||||
/// Perform process context switch
|
/// Perform process context switch
|
||||||
void amd64_do_sched (void* regs, void* cr3);
|
void do_sched1 (void* regs, void* cr3);
|
||||||
|
|
||||||
#endif // _KERNEL_AMD64_SCHED_H
|
#endif // _KERNEL_AMD64_SCHED_H
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ void do_sched (struct proc* proc, spin_lock_t* cpu_lock) {
|
|||||||
|
|
||||||
thiscpu->tss.rsp0 = proc->pdata.kernel_stack;
|
thiscpu->tss.rsp0 = proc->pdata.kernel_stack;
|
||||||
thiscpu->syscall_kernel_stack = proc->pdata.kernel_stack;
|
thiscpu->syscall_kernel_stack = proc->pdata.kernel_stack;
|
||||||
amd64_wrmsr (MSR_FS_BASE, proc->pdata.fs_base);
|
wrmsr (MSR_FS_BASE, proc->pdata.fs_base);
|
||||||
|
|
||||||
void* cr3 = (void*)proc->procgroup->pd.cr3_paddr;
|
void* cr3 = (void*)proc->procgroup->pd.cr3_paddr;
|
||||||
struct saved_regs regs;
|
struct saved_regs regs;
|
||||||
@@ -22,5 +22,5 @@ void do_sched (struct proc* proc, spin_lock_t* cpu_lock) {
|
|||||||
spin_unlock (&proc->lock);
|
spin_unlock (&proc->lock);
|
||||||
spin_unlock (cpu_lock);
|
spin_unlock (cpu_lock);
|
||||||
|
|
||||||
amd64_do_sched ((void*)®s, cr3);
|
do_sched1 ((void*)®s, cr3);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,13 +34,13 @@ struct cpu* cpu_make (uint64_t lapic_id, uint64_t acpi_id) {
|
|||||||
cpu->acpi_id = acpi_id;
|
cpu->acpi_id = acpi_id;
|
||||||
cpu->lapic_id = lapic_id;
|
cpu->lapic_id = lapic_id;
|
||||||
|
|
||||||
amd64_wrmsr (MSR_GS_BASE, (uint64_t)cpu);
|
wrmsr (MSR_GS_BASE, (uint64_t)cpu);
|
||||||
|
|
||||||
return cpu;
|
return cpu;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct cpu* cpu_get (void) {
|
struct cpu* cpu_get (void) {
|
||||||
struct cpu* ptr = (struct cpu*)amd64_rdmsr (MSR_GS_BASE);
|
struct cpu* ptr = (struct cpu*)rdmsr (MSR_GS_BASE);
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,7 +50,7 @@ void cpu_request_sched (struct cpu* cpu) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
amd64_lapic_ipi (cpu->lapic_id, CPU_REQUEST_SCHED);
|
lapic_ipi (cpu->lapic_id, CPU_REQUEST_SCHED);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct cpu* cpu_find_lightest (void) {
|
struct cpu* cpu_find_lightest (void) {
|
||||||
@@ -74,15 +74,15 @@ struct cpu* cpu_find_lightest (void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Bootstrap code for non-BSP CPUs
|
/// Bootstrap code for non-BSP CPUs
|
||||||
static void amd64_smp_bootstrap (struct limine_mp_info* mp_info) {
|
static void smp_bootstrap (struct limine_mp_info* mp_info) {
|
||||||
amd64_load_kernel_cr3 ();
|
load_kernel_cr3 ();
|
||||||
|
|
||||||
struct cpu* cpu = cpu_make (mp_info->lapic_id, mp_info->processor_id);
|
struct cpu* cpu = cpu_make (mp_info->lapic_id, mp_info->processor_id);
|
||||||
|
|
||||||
amd64_init (cpu, true); /* gdt + idt */
|
init_gdt_idt (cpu, true); /* gdt + idt */
|
||||||
syscall_init ();
|
syscall_init ();
|
||||||
|
|
||||||
amd64_lapic_init (1000);
|
lapic_init (1000);
|
||||||
|
|
||||||
DEBUG ("CPU %u is online!\n", thiscpu->id);
|
DEBUG ("CPU %u is online!\n", thiscpu->id);
|
||||||
|
|
||||||
@@ -97,7 +97,7 @@ static void amd64_smp_bootstrap (struct limine_mp_info* mp_info) {
|
|||||||
|
|
||||||
/// Initialize SMP subsystem for AMD64. Start AP CPUs
|
/// Initialize SMP subsystem for AMD64. Start AP CPUs
|
||||||
void smp_init (void) {
|
void smp_init (void) {
|
||||||
amd64_lapic_init (1000);
|
lapic_init (1000);
|
||||||
|
|
||||||
struct limine_mp_response* mp = limine_mp_request.response;
|
struct limine_mp_response* mp = limine_mp_request.response;
|
||||||
|
|
||||||
@@ -105,7 +105,7 @@ void smp_init (void) {
|
|||||||
|
|
||||||
for (size_t i = 0; i < mp->cpu_count; i++) {
|
for (size_t i = 0; i < mp->cpu_count; i++) {
|
||||||
if (mp->cpus[i]->processor_id != thiscpu->acpi_id) {
|
if (mp->cpus[i]->processor_id != thiscpu->acpi_id) {
|
||||||
mp->cpus[i]->goto_address = &amd64_smp_bootstrap;
|
mp->cpus[i]->goto_address = &smp_bootstrap;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
.global amd64_spin
|
.global spin
|
||||||
amd64_spin:
|
spin:
|
||||||
hlt
|
hlt
|
||||||
jmp amd64_spin
|
jmp spin
|
||||||
|
|||||||
@@ -14,10 +14,10 @@
|
|||||||
#include <sys/smp.h>
|
#include <sys/smp.h>
|
||||||
#include <syscall/syscall.h>
|
#include <syscall/syscall.h>
|
||||||
|
|
||||||
extern void amd64_syscall_entry (void);
|
extern void syscall_entry (void);
|
||||||
|
|
||||||
uintptr_t amd64_syscall_dispatch (void* stack_ptr) {
|
uintptr_t syscall_dispatch (void* stack_ptr) {
|
||||||
amd64_load_kernel_cr3 ();
|
load_kernel_cr3 ();
|
||||||
struct saved_regs* regs = stack_ptr;
|
struct saved_regs* regs = stack_ptr;
|
||||||
|
|
||||||
spin_lock (&thiscpu->lock);
|
spin_lock (&thiscpu->lock);
|
||||||
@@ -57,8 +57,8 @@ uintptr_t amd64_syscall_dispatch (void* stack_ptr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void syscall_init (void) {
|
void syscall_init (void) {
|
||||||
amd64_wrmsr (MSR_STAR, ((uint64_t)GDT_KCODE << 32) | ((uint64_t)(GDT_KDATA | 0x03) << 48));
|
wrmsr (MSR_STAR, ((uint64_t)GDT_KCODE << 32) | ((uint64_t)(GDT_KDATA | 0x03) << 48));
|
||||||
amd64_wrmsr (MSR_LSTAR, (uint64_t)&amd64_syscall_entry);
|
wrmsr (MSR_LSTAR, (uint64_t)&syscall_entry);
|
||||||
amd64_wrmsr (MSR_SYSCALL_MASK, (1ULL << 9));
|
wrmsr (MSR_SYSCALL_MASK, (1ULL << 9));
|
||||||
amd64_wrmsr (MSR_EFER, amd64_rdmsr (MSR_EFER) | EFER_SCE);
|
wrmsr (MSR_EFER, rdmsr (MSR_EFER) | EFER_SCE);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
#include <amd64/regsasm.h>
|
#include <amd64/regsasm.h>
|
||||||
|
|
||||||
.extern amd64_syscall_dispatch
|
.extern syscall_dispatch
|
||||||
|
|
||||||
.global amd64_syscall_entry
|
.global syscall_entry
|
||||||
amd64_syscall_entry:
|
syscall_entry:
|
||||||
cli
|
cli
|
||||||
|
|
||||||
movq %rsp, %gs:0
|
movq %rsp, %gs:0
|
||||||
@@ -35,7 +35,7 @@ amd64_syscall_entry:
|
|||||||
subq $8, %rsp
|
subq $8, %rsp
|
||||||
andq $-16, %rsp
|
andq $-16, %rsp
|
||||||
|
|
||||||
callq amd64_syscall_dispatch
|
callq syscall_dispatch
|
||||||
|
|
||||||
movq %rbp, %rsp
|
movq %rbp, %rsp
|
||||||
|
|
||||||
|
|||||||
@@ -3,4 +3,4 @@
|
|||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
|
||||||
/// Sleep for given amount of microseconds
|
/// Sleep for given amount of microseconds
|
||||||
void sleep_micro (size_t us) { amd64_hpet_sleep_micro (us); }
|
void sleep_micro (size_t us) { hpet_sleep_micro (us); }
|
||||||
|
|||||||
@@ -134,11 +134,11 @@ static int32_t ps2kb_keycode (void) {
|
|||||||
static uint8_t* charcode[4] = {normalmap, shiftmap, ctlmap, ctlmap};
|
static uint8_t* charcode[4] = {normalmap, shiftmap, ctlmap, ctlmap};
|
||||||
uint32_t st, data, c;
|
uint32_t st, data, c;
|
||||||
|
|
||||||
st = amd64_io_inb (KB_CTL_STATUS);
|
st = inb (KB_CTL_STATUS);
|
||||||
if (!(st & KB_DATA_IN_BUF)) {
|
if (!(st & KB_DATA_IN_BUF)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
data = amd64_io_inb (KB_DATA);
|
data = inb (KB_DATA);
|
||||||
|
|
||||||
if (data == 0xe0) {
|
if (data == 0xe0) {
|
||||||
shift |= KB_E0ESC;
|
shift |= KB_E0ESC;
|
||||||
@@ -237,22 +237,22 @@ int ps2kb_read_key (struct device* device, struct proc* proc, struct reschedule_
|
|||||||
bool ps2kb_init (struct device* device, void* arg) {
|
bool ps2kb_init (struct device* device, void* arg) {
|
||||||
(void)device, (void)arg;
|
(void)device, (void)arg;
|
||||||
|
|
||||||
amd64_ioapic_route_irq (PS2KB, 1, 0, thiscpu->lapic_id);
|
ioapic_route_irq (PS2KB, 1, 0, thiscpu->lapic_id);
|
||||||
irq_attach (&ps2kb_irq, NULL, PS2KB);
|
irq_attach (&ps2kb_irq, NULL, PS2KB);
|
||||||
|
|
||||||
ringbuffer_init (&ps2kb_ringbuffer, PS2KB_RINGBUFFER_MAX, sizeof (uint8_t));
|
ringbuffer_init (&ps2kb_ringbuffer, PS2KB_RINGBUFFER_MAX, sizeof (uint8_t));
|
||||||
|
|
||||||
while (amd64_io_inb (KB_CTL_STATUS) & KB_DATA_IN_BUF)
|
while (inb (KB_CTL_STATUS) & KB_DATA_IN_BUF)
|
||||||
amd64_io_inb (KB_DATA);
|
inb (KB_DATA);
|
||||||
|
|
||||||
amd64_io_outb (KB_CTL_STATUS, 0x20);
|
outb (KB_CTL_STATUS, 0x20);
|
||||||
|
|
||||||
uint8_t cb = amd64_io_inb (KB_DATA);
|
uint8_t cb = inb (KB_DATA);
|
||||||
cb |= 0x01;
|
cb |= 0x01;
|
||||||
cb |= 0x40;
|
cb |= 0x40;
|
||||||
|
|
||||||
amd64_io_outb (KB_CTL_STATUS, 0x60);
|
outb (KB_CTL_STATUS, 0x60);
|
||||||
amd64_io_outb (KB_DATA, cb);
|
outb (KB_DATA, cb);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,6 @@
|
|||||||
#ifndef _KERNEL_SYS_SPIN_H
|
#ifndef _KERNEL_SYS_SPIN_H
|
||||||
#define _KERNEL_SYS_SPIN_H
|
#define _KERNEL_SYS_SPIN_H
|
||||||
|
|
||||||
#if defined(__x86_64__)
|
void spin (void);
|
||||||
extern void amd64_spin (void);
|
|
||||||
#define spin amd64_spin
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // _KERNEL_SYS_SPIN_H
|
#endif // _KERNEL_SYS_SPIN_H
|
||||||
|
|||||||
Reference in New Issue
Block a user