Fix user apps randomly crashing (APIC, GDT layout, syscall entry)
All checks were successful
Build documentation / build-and-deploy (push) Successful in 23s

This commit is contained in:
2026-01-14 19:51:18 +01:00
parent 0d8f9e565f
commit d1d772cb42
23 changed files with 276 additions and 204 deletions

View File

@@ -34,6 +34,8 @@
/* Divide config register */
#define LAPIC_DCR 0x3E0
#define DIVIDER_VALUE 0x0B
struct ioapic {
struct acpi_madt_ioapic table_data;
rw_spin_lock_t lock;
@@ -51,7 +53,7 @@ static size_t ioapic_entries = 0;
/* Count of actual interrupt source overrides */
static size_t intr_src_override_entries = 0;
static uint64_t lapic_ticks;
static spin_lock_t lapic_calibration_lock = SPIN_LOCK_INIT;
/* Read IOAPIC */
static uint32_t amd64_ioapic_read (struct ioapic* ioapic, uint32_t reg) {
@@ -117,18 +119,16 @@ void amd64_ioapic_route_irq (uint8_t vec, uint8_t irq, uint64_t flags, uint64_t
uint8_t mode = (((override->flags >> 2) & 0x03) == 0x03) ? 1 : 0;
calc_flags |= (uint64_t)mode << 15;
calc_flags |= (uint64_t)polarity << 13;
calc_flags |= flags;
} else {
calc_flags |= flags;
}
ioapic = amd64_ioapic_find (irq);
uint8_t gsi = found_override ? override->gsi : irq;
ioapic = amd64_ioapic_find (gsi);
if (ioapic == NULL)
return;
uint32_t irq_reg = ((irq - 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));
amd64_ioapic_write (ioapic, irq_reg, (uint32_t)calc_flags);
@@ -201,15 +201,20 @@ void amd64_lapic_eoi (void) { amd64_lapic_write (LAPIC_EOI, 0); }
* us - Period length in microseconds
*/
static uint32_t amd64_lapic_calibrate (uint32_t us) {
amd64_lapic_write (LAPIC_DCR, 0x0B);
spin_lock (&lapic_calibration_lock);
amd64_lapic_write (LAPIC_DCR, DIVIDER_VALUE);
amd64_lapic_write (LAPIC_LVTTR, SCHED_PREEMPT_TIMER | (1 << 16));
amd64_lapic_write (LAPIC_TIMICT, 0xFFFFFFFF);
sleep_micro (us);
amd64_lapic_write (LAPIC_LVTTR, SCHED_PREEMPT_TIMER | (0 << 16));
uint32_t ticks = 0xFFFFFFFF - amd64_lapic_read (LAPIC_TIMCCT);
DEBUG ("timer ticks = %u\n", ticks);
spin_unlock (&lapic_calibration_lock);
return ticks;
}
@@ -220,11 +225,9 @@ static uint32_t amd64_lapic_calibrate (uint32_t us) {
* ticks - Initial tick count
*/
static void amd64_lapic_start (uint32_t ticks) {
amd64_lapic_write (LAPIC_DCR, 0x0B);
amd64_lapic_write (LAPIC_LVTTR, SCHED_PREEMPT_TIMER | (1 << 17));
amd64_lapic_write (LAPIC_DCR, DIVIDER_VALUE);
amd64_lapic_write (LAPIC_TIMICT, ticks);
amd64_lapic_write (LAPIC_LVTTR, SCHED_PREEMPT_TIMER | (1 << 17) | (1 << 16));
}
/*
@@ -244,11 +247,8 @@ void amd64_lapic_init (uint32_t us) {
amd64_lapic_write (LAPIC_SIVR, 0xFF | (1 << 8));
if (thiscpu->id == 0) {
lapic_ticks = amd64_lapic_calibrate (us);
}
amd64_lapic_start (lapic_ticks);
thiscpu->lapic_ticks = amd64_lapic_calibrate (us);
amd64_lapic_start (thiscpu->lapic_ticks);
}
/*