56 lines
1.3 KiB
C
56 lines
1.3 KiB
C
#include <stdint.h>
|
|
#include <int.h>
|
|
#include <mem.h>
|
|
#include <debug.h>
|
|
#include <cpu.h>
|
|
#include <string.h>
|
|
#include <apic.h>
|
|
#include <pit.h>
|
|
|
|
extern uint64_t smp_stack_top;
|
|
extern uint64_t ap_gs_base;
|
|
|
|
void ap_init(cpu_t *cpu)
|
|
{
|
|
debug_info("SMP - Starting up processor %x\n", cpu->id);
|
|
if(!cpu->current_state == CPU_STOPPED)
|
|
return;
|
|
// Send INIT command
|
|
apic_interrupt(cpu->id, APIC_INT_LEVEL_ASSERT, APIC_INT_TYPE_INIT, 0);
|
|
// Wait 10 ms
|
|
pit_delay(10);
|
|
|
|
// Write cpu data position to trampoline
|
|
ap_gs_base = (uint64_t) cpu;
|
|
|
|
cpu->current_state = CPU_SIPI_SENT;
|
|
apic_interrupt(cpu->id, APIC_INT_LEVEL_ASSERT, APIC_INT_TYPE_STARTUP, TRAMPOLINE_ADDR/PAGE_SIZE);
|
|
pit_delay(10);
|
|
|
|
if(cpu->current_state != CPU_SIPI_REC)
|
|
{
|
|
cpu->current_state = CPU_SIPI_SENT;
|
|
apic_interrupt(cpu->id, APIC_INT_LEVEL_ASSERT, APIC_INT_TYPE_STARTUP, TRAMPOLINE_ADDR/PAGE_SIZE);
|
|
pit_delay(100);
|
|
}
|
|
|
|
if(cpu->current_state != CPU_SIPI_REC)
|
|
{
|
|
debug_error("SMP - Starting cpu %x failed\n", cpu->id);
|
|
cpu->current_state = CPU_FAILED;
|
|
return;
|
|
}
|
|
cpu->current_state = CPU_STARTED;
|
|
}
|
|
|
|
void ap_start()
|
|
{
|
|
init_cpu();
|
|
while(!all_ap_started);
|
|
cpu_t *cpu = get_cpu();
|
|
debug_ok("STARTED CPU:%x\n", cpu->id);
|
|
schedule();
|
|
debug_error("PANIC: SMP - This line should be unreachable\n");
|
|
for(;;)asm("hlt");
|
|
}
|