[SMP] Boot Application Processors
This commit is contained in:
parent
f356cc8f95
commit
6a2bef5517
@ -4,6 +4,9 @@
|
|||||||
#include <msr.h>
|
#include <msr.h>
|
||||||
#include <sse.h>
|
#include <sse.h>
|
||||||
#include <scheduler.h>
|
#include <scheduler.h>
|
||||||
|
#include <mem.h>
|
||||||
|
#include <gdt.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
cpu_t cpus[MAX_NUMCPU];
|
cpu_t cpus[MAX_NUMCPU];
|
||||||
unsigned int num_cpu = 0;
|
unsigned int num_cpu = 0;
|
||||||
@ -19,6 +22,11 @@ void cpu_add(uint64_t id, uint64_t apic)
|
|||||||
cpu->id = id;
|
cpu->id = id;
|
||||||
cpu->apic_id = apic;
|
cpu->apic_id = apic;
|
||||||
cpu->is_bsp = (num_cpu)?0:1;
|
cpu->is_bsp = (num_cpu)?0:1;
|
||||||
|
|
||||||
|
cpu->current_thread = 0;
|
||||||
|
cpu->current_state = (num_cpu)?CPU_STOPPED:CPU_STARTED;
|
||||||
|
cpu->kernel_stack = (num_cpu)?kmalloc(PAGE_SIZE) + PAGE_SIZE:0;
|
||||||
|
|
||||||
num_cpu++;
|
num_cpu++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,6 +52,15 @@ void cpu_init()
|
|||||||
asm("swapgs");
|
asm("swapgs");
|
||||||
init_cpu();
|
init_cpu();
|
||||||
|
|
||||||
|
vmm_set_page(0, TRAMPOLINE_ADDR, TRAMPOLINE_ADDR, PAGE_PRESENT | PAGE_WRITE);
|
||||||
|
memcpy((void *)TRAMPOLINE_ADDR, &trampoline, PAGE_SIZE);
|
||||||
|
vmm_set_page(0, V2P(&BootGDT), V2P(&BootGDT), PAGE_PRESENT);
|
||||||
|
for(unsigned int i = 0; i < num_cpu; i++)
|
||||||
|
{
|
||||||
|
ap_init(&cpus[i]);
|
||||||
|
}
|
||||||
|
vmm_set_page(0, TRAMPOLINE_ADDR, 0, 0);
|
||||||
|
|
||||||
debug_info("CPU - Status\n");
|
debug_info("CPU - Status\n");
|
||||||
for(unsigned int i = 0; i < num_cpu; i++)
|
for(unsigned int i = 0; i < num_cpu; i++)
|
||||||
{
|
{
|
||||||
|
50
kernel/cpu/smp.c
Normal file
50
kernel/cpu/smp.c
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
#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()
|
||||||
|
{
|
||||||
|
debug_ok("STARTED CPU:%x\n", get_cpu()->id);
|
||||||
|
for(;;)asm("hlt");
|
||||||
|
}
|
110
kernel/cpu/trampoline.S
Normal file
110
kernel/cpu/trampoline.S
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
#include <mem.h>
|
||||||
|
#include <cpu.h>
|
||||||
|
#include <msr.h>
|
||||||
|
#define TRAMPOLINE_OFFSET TRAMPOLINE_ADDR - trampoline
|
||||||
|
|
||||||
|
.intel_syntax noprefix
|
||||||
|
.global trampoline
|
||||||
|
.section .text
|
||||||
|
.code16
|
||||||
|
trampoline:
|
||||||
|
|
||||||
|
cli
|
||||||
|
mov ax, 0x0
|
||||||
|
mov ds, ax
|
||||||
|
mov es, ax
|
||||||
|
mov fs, ax
|
||||||
|
mov gs, ax
|
||||||
|
mov ss, ax
|
||||||
|
|
||||||
|
lidt [ap_boot_idt + TRAMPOLINE_OFFSET]
|
||||||
|
lgdt [ap_boot_gdtp + TRAMPOLINE_OFFSET]
|
||||||
|
|
||||||
|
mov eax, cr0
|
||||||
|
or al, 0x1
|
||||||
|
mov cr0, eax
|
||||||
|
|
||||||
|
jmp 0x8:start_32 + TRAMPOLINE_OFFSET
|
||||||
|
|
||||||
|
.code32
|
||||||
|
start_32:
|
||||||
|
mov ax, 0x10
|
||||||
|
mov ds, ax
|
||||||
|
mov es, ax
|
||||||
|
mov fs, ax
|
||||||
|
mov gs, ax
|
||||||
|
mov ss, ax
|
||||||
|
|
||||||
|
mov eax, cr4
|
||||||
|
or eax, 1<<5
|
||||||
|
mov cr4, eax
|
||||||
|
|
||||||
|
mov eax, offset V2P(BootP4)
|
||||||
|
mov cr3, eax
|
||||||
|
|
||||||
|
mov ecx, 0xC0000080
|
||||||
|
rdmsr
|
||||||
|
or eax, 1<<8
|
||||||
|
wrmsr
|
||||||
|
|
||||||
|
mov eax, cr0
|
||||||
|
or eax, 1<<31
|
||||||
|
mov cr0, eax
|
||||||
|
|
||||||
|
lgdt V2P(BootGDTp)
|
||||||
|
|
||||||
|
mov ax, 0x10
|
||||||
|
mov ds, ax
|
||||||
|
mov es, ax
|
||||||
|
mov ss, ax
|
||||||
|
|
||||||
|
jmp 0x8:start_64 + TRAMPOLINE_OFFSET
|
||||||
|
.code64
|
||||||
|
start_64:
|
||||||
|
movabs rax, offset start_longmode
|
||||||
|
jmp rax
|
||||||
|
start_longmode:
|
||||||
|
|
||||||
|
movabs rax, ap_gs_base
|
||||||
|
mov rdx, rax
|
||||||
|
shr rdx, 32
|
||||||
|
mov ecx, MSR_REG_KERNEL_GS
|
||||||
|
wrmsr
|
||||||
|
swapgs
|
||||||
|
|
||||||
|
movq [gs:GS_OFFSET_STATE], CPU_SIPI_REC
|
||||||
|
.ap_sync_loop:
|
||||||
|
cmpq [gs:GS_OFFSET_STATE], CPU_SIPI_REC
|
||||||
|
je .ap_sync_loop
|
||||||
|
|
||||||
|
mov rsp, gs:GS_OFFSET_STACK
|
||||||
|
push 0
|
||||||
|
mov rbp, rsp
|
||||||
|
push 0
|
||||||
|
popf
|
||||||
|
|
||||||
|
.extern ap_start
|
||||||
|
call ap_start
|
||||||
|
|
||||||
|
|
||||||
|
.align 16
|
||||||
|
ap_boot_gdt:
|
||||||
|
.long 0x00000000, 0x00000000
|
||||||
|
.long 0x0000FFFF, 0x00CF9A00
|
||||||
|
.long 0x0000FFFF, 0x00CF9200
|
||||||
|
.align 16
|
||||||
|
ap_boot_gdtp:
|
||||||
|
.short 3*8-1
|
||||||
|
.long ap_boot_gdt + TRAMPOLINE_OFFSET
|
||||||
|
|
||||||
|
.align 16
|
||||||
|
ap_boot_idt:
|
||||||
|
.short 0
|
||||||
|
.long 0
|
||||||
|
.long 0
|
||||||
|
|
||||||
|
.global ap_gs_base
|
||||||
|
ap_gs_base:
|
||||||
|
.long 0x00000000, 0x00000000
|
||||||
|
trampoline_end:
|
||||||
|
nop
|
@ -2,7 +2,17 @@
|
|||||||
|
|
||||||
#define MAX_NUMCPU 64
|
#define MAX_NUMCPU 64
|
||||||
|
|
||||||
|
#define CPU_STOPPED 0
|
||||||
|
#define CPU_SIPI_SENT 1
|
||||||
|
#define CPU_SIPI_REC 2
|
||||||
|
#define CPU_STARTED 3
|
||||||
|
#define CPU_FAILED 4
|
||||||
|
|
||||||
|
#define TRAMPOLINE_ADDR 0x1000
|
||||||
|
|
||||||
#define GS_OFFSET_CPU 0
|
#define GS_OFFSET_CPU 0
|
||||||
|
#define GS_OFFSET_STATE 40
|
||||||
|
#define GS_OFFSET_STACK 48
|
||||||
|
|
||||||
#ifndef __ASSEMBLER__
|
#ifndef __ASSEMBLER__
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
@ -17,6 +27,8 @@ typedef struct cpu_t
|
|||||||
uint64_t apic_id;
|
uint64_t apic_id;
|
||||||
uint64_t apic_ticks_per_us;
|
uint64_t apic_ticks_per_us;
|
||||||
uint64_t is_bsp;
|
uint64_t is_bsp;
|
||||||
|
uint64_t current_state; // 40
|
||||||
|
void *kernel_stack; // 48
|
||||||
thread_t *current_thread;
|
thread_t *current_thread;
|
||||||
thread_t *last_thread;
|
thread_t *last_thread;
|
||||||
process_t *current_process;
|
process_t *current_process;
|
||||||
@ -31,7 +43,11 @@ extern unsigned int num_cpu;
|
|||||||
void acpi_init();
|
void acpi_init();
|
||||||
void cpu_add(uint64_t id, uint64_t apic);
|
void cpu_add(uint64_t id, uint64_t apic);
|
||||||
void cpu_init();
|
void cpu_init();
|
||||||
|
void init_cpu();
|
||||||
cpu_t *get_cpu();
|
cpu_t *get_cpu();
|
||||||
|
void ap_init(cpu_t *cpu);
|
||||||
|
|
||||||
|
void trampoline();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user