x86_64: Use lapic as preempt source on bsp
This commit is contained in:
parent
5b0c5da5f5
commit
4a1b944525
@ -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();
|
||||
|
@ -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.
|
||||
*
|
||||
@ -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];
|
||||
|
||||
@ -234,6 +236,8 @@ void ap_main(void) {
|
||||
/* Inform BSP it can continue. */
|
||||
_ap_startup_flag = 1;
|
||||
|
||||
lapic_timer_initialize();
|
||||
|
||||
/* Enter scheduler */
|
||||
switch_next();
|
||||
}
|
||||
@ -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 */
|
||||
@ -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);
|
||||
@ -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;
|
||||
|
||||
@ -458,6 +461,8 @@ _toomany:
|
||||
|
||||
/* 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 */
|
||||
@ -465,6 +470,12 @@ _toomany:
|
||||
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();
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user