Skip to content

Commit

Permalink
x86_64: Use lapic as preempt source on bsp
Browse files Browse the repository at this point in the history
  • Loading branch information
klange committed Jan 21, 2024
1 parent 5b0c5da commit 4a1b944
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 28 deletions.
4 changes: 1 addition & 3 deletions kernel/arch/x86_64/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -477,14 +477,12 @@ int kmain(struct multiboot * mboot, uint32_t mboot_mag, void* esp, uint64_t base
framebuffer_initialize();
fbterm_initialize();

/* Start up other cores and enable an appropriate preempt source. */
smp_initialize();

/* Decompress and mount all initial ramdisks. */
mount_multiboot_ramdisks(mboot_struct);

/* Set up preempt source */
pit_initialize();

/* Install generic PC device drivers. */
ps2hid_install();
serial_initialize();
Expand Down
61 changes: 36 additions & 25 deletions kernel/arch/x86_64/smp.c
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,27 @@ void load_processor_info(void) {
asm volatile ("wrmsr" : : "c"(0xC0000084), "d"(0), "a"(0x700)); /* SFMASK: Direction flag, interrupt flag, trap flag are all cleared */
}

static void lapic_timer_initialize(void) {
/* Enable our spurious vector register */
*((volatile uint32_t*)(lapic_final + 0x0F0)) = 0x127;
*((volatile uint32_t*)(lapic_final + 0x320)) = 0x7b;
*((volatile uint32_t*)(lapic_final + 0x3e0)) = 1;

/* Time our APIC timer against the TSC */
uint64_t before = arch_perf_timer();
*((volatile uint32_t*)(lapic_final + 0x380)) = 1000000;
while (*((volatile uint32_t*)(lapic_final + 0x390)));
uint64_t after = arch_perf_timer();

uint64_t ms = (after-before)/arch_cpu_mhz();
uint64_t target = 10000000000UL / ms;

/* Enable our APIC timer to send periodic wakeup signals */
*((volatile uint32_t*)(lapic_final + 0x3e0)) = 1;
*((volatile uint32_t*)(lapic_final + 0x320)) = 0x7b | 0x20000;
*((volatile uint32_t*)(lapic_final + 0x380)) = target;
}

/**
* @brief C entrypoint for APs, called by the bootstrap.
*
Expand All @@ -202,25 +223,6 @@ void ap_main(void) {
fpu_initialize();
pat_initialize();

/* Enable our spurious vector register */
*((volatile uint32_t*)(lapic_final + 0x0F0)) = 0x127;
*((volatile uint32_t*)(lapic_final + 0x320)) = 0x7b;
*((volatile uint32_t*)(lapic_final + 0x3e0)) = 1;

/* Time our APIC timer against the TSC */
uint64_t before = arch_perf_timer();
*((volatile uint32_t*)(lapic_final + 0x380)) = 1000000;
while (*((volatile uint32_t*)(lapic_final + 0x390)));
uint64_t after = arch_perf_timer();

uint64_t ms = (after-before)/arch_cpu_mhz();
uint64_t target = 10000000000UL / ms;

/* Enable our APIC timer to send periodic wakeup signals */
*((volatile uint32_t*)(lapic_final + 0x3e0)) = 1;
*((volatile uint32_t*)(lapic_final + 0x320)) = 0x7b | 0x20000;
*((volatile uint32_t*)(lapic_final + 0x380)) = target;

/* Set our pml pointers */
this_core->current_pml = &init_page_region[0];

Expand All @@ -234,6 +236,8 @@ void ap_main(void) {
/* Inform BSP it can continue. */
_ap_startup_flag = 1;

lapic_timer_initialize();

/* Enter scheduler */
switch_next();
}
Expand Down Expand Up @@ -366,7 +370,7 @@ void smp_initialize(void) {
/* Did we still not find our table? */
if (!good) {
dprintf("smp: No RSD PTR found\n");
return;
goto _pit_fallback;
}

/* Map the ACPI RSDP */
Expand All @@ -382,11 +386,11 @@ void smp_initialize(void) {
/* Did the checksum fail? */
if (check != 0 && !args_present("noacpichecksum")) {
dprintf("smp: Bad checksum on RSDP (add 'noacpichecksum' to ignore this)\n");
return; /* bad checksum */
goto _pit_fallback; /* bad checksum */
}

/* Was SMP disabled by a commandline flag? */
if (args_present("nosmp")) return;
if (args_present("nosmp")) goto _pit_fallback;

/* Map the RSDT from the address given by the RSDP */
struct rsdt * rsdt = mmu_map_from_physical(rsdp->rsdt_address);
Expand Down Expand Up @@ -419,12 +423,11 @@ void smp_initialize(void) {
}

_toomany:
processor_count = cores;

if (!lapic_base) return;
if (!lapic_base) goto _pit_fallback;

/* Allocate a virtual address with which we can poke the lapic */
lapic_final = (uintptr_t)mmu_map_mmio_region(lapic_base, 0x1000);
lapic_timer_initialize();

if (cores <= 1) return;

Expand Down Expand Up @@ -458,13 +461,21 @@ void smp_initialize(void) {

/* Wait for AP to signal it is ready before starting next AP */
do { asm volatile ("pause" : : : "memory"); } while (!_ap_startup_flag);

processor_count++;
}

/* Copy data back */
memcpy(mmu_map_from_physical(0x1000), mmu_map_from_physical(tmp_space), 0x1000);
mmu_frame_clear(tmp_space);

dprintf("smp: enabled with %d cores\n", cores);
return;

_pit_fallback:
dprintf("pit: falling back to pit as preempt source\n");
extern void pit_initialize(void);
pit_initialize();
}

/**
Expand Down

0 comments on commit 4a1b944

Please sign in to comment.