[SMP] Cpu initialization cleanup
This commit is contained in:
parent
664379b35c
commit
f356cc8f95
@ -5,6 +5,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <multiboot.h>
|
#include <multiboot.h>
|
||||||
#include <int.h>
|
#include <int.h>
|
||||||
|
#include <cpu.h>
|
||||||
|
|
||||||
RSDP_st *find_rsdp()
|
RSDP_st *find_rsdp()
|
||||||
{
|
{
|
||||||
@ -80,6 +81,8 @@ void parse_MADT(SDT_header *header)
|
|||||||
if(f->proc.flags & 0x1)
|
if(f->proc.flags & 0x1)
|
||||||
{
|
{
|
||||||
debug(" enabled");
|
debug(" enabled");
|
||||||
|
// Add processor and LAPIC to list
|
||||||
|
cpu_add(f->proc.proc_ID, f->proc.APIC_ID);
|
||||||
}
|
}
|
||||||
debug("\n");
|
debug("\n");
|
||||||
break;
|
break;
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
#include <gdt.h>
|
#include <gdt.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
#include <cpu.h>
|
||||||
|
|
||||||
uint64_t gdt[5];
|
#define GDT cpu->gdt
|
||||||
struct gdtp_st gdt_p;
|
#define GDTP cpu->gdt_p
|
||||||
#define GDT gdt
|
|
||||||
#define GDTP gdt_p
|
|
||||||
|
|
||||||
|
|
||||||
void gdt_init()
|
void gdt_init()
|
||||||
{
|
{
|
||||||
|
cpu_t *cpu = get_cpu();
|
||||||
|
|
||||||
GDT[0] = 0;
|
GDT[0] = 0;
|
||||||
GDT[SEG_KCODE/8] = (uint64_t)(GDT_PRESENT | GDT_CODEDATA | GDT_WRITE | GDT_EXECUTE | GDT_64BIT);
|
GDT[SEG_KCODE/8] = (uint64_t)(GDT_PRESENT | GDT_CODEDATA | GDT_WRITE | GDT_EXECUTE | GDT_64BIT);
|
||||||
|
@ -1,23 +1,17 @@
|
|||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
#include <int.h>
|
|
||||||
#include <multiboot.h>
|
#include <multiboot.h>
|
||||||
#include <mem.h>
|
#include <mem.h>
|
||||||
#include <gdt.h>
|
|
||||||
#include <scheduler.h>
|
#include <scheduler.h>
|
||||||
#include <thread.h>
|
#include <thread.h>
|
||||||
#include <process.h>
|
#include <process.h>
|
||||||
#include <cpuid.h>
|
#include <cpu.h>
|
||||||
#include <acpi.h>
|
|
||||||
#include <apic.h>
|
|
||||||
#include <sse.h>
|
|
||||||
#include <timer.h>
|
#include <timer.h>
|
||||||
#include <pit.h>
|
|
||||||
|
|
||||||
void thread_function()
|
void thread_function()
|
||||||
{
|
{
|
||||||
while(1)
|
while(1)
|
||||||
{
|
{
|
||||||
debug((char *)0x10000);
|
;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -32,16 +26,9 @@ int kmain(uint64_t multiboot_magic, void *multiboot_data)
|
|||||||
multiboot_init(multiboot_magic, P2V(multiboot_data));
|
multiboot_init(multiboot_magic, P2V(multiboot_data));
|
||||||
vmm_init();
|
vmm_init();
|
||||||
pmm_init();
|
pmm_init();
|
||||||
gdt_init();
|
cpu_init();
|
||||||
scheduler_init();
|
|
||||||
pic_init();
|
|
||||||
acpi_init();
|
|
||||||
apic_init();
|
|
||||||
ioapic_init();
|
|
||||||
sse_init();
|
|
||||||
pit_init();
|
pit_init();
|
||||||
|
|
||||||
|
|
||||||
process_t *p1 = process_spawn(0);
|
process_t *p1 = process_spawn(0);
|
||||||
process_t *p2 = process_spawn(p1);
|
process_t *p2 = process_spawn(p1);
|
||||||
|
|
||||||
|
52
kernel/cpu/cpu.c
Normal file
52
kernel/cpu/cpu.c
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
#include <cpu.h>
|
||||||
|
#include <debug.h>
|
||||||
|
#include <apic.h>
|
||||||
|
#include <msr.h>
|
||||||
|
#include <sse.h>
|
||||||
|
#include <scheduler.h>
|
||||||
|
|
||||||
|
cpu_t cpus[MAX_NUMCPU];
|
||||||
|
unsigned int num_cpu = 0;
|
||||||
|
|
||||||
|
void cpu_add(uint64_t id, uint64_t apic)
|
||||||
|
{
|
||||||
|
if(num_cpu >= MAX_NUMCPU)
|
||||||
|
return;
|
||||||
|
|
||||||
|
cpu_t *cpu = &cpus[num_cpu];
|
||||||
|
memset(cpu, 0, sizeof(cpu_t));
|
||||||
|
cpu->cpu = (uint64_t)cpu;
|
||||||
|
cpu->id = id;
|
||||||
|
cpu->apic_id = apic;
|
||||||
|
cpu->is_bsp = (num_cpu)?0:1;
|
||||||
|
num_cpu++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void init_cpu()
|
||||||
|
{
|
||||||
|
cpu_t *cpu = get_cpu();
|
||||||
|
debug_info("CPU - Initializing CPU %x\n", cpu->id);
|
||||||
|
|
||||||
|
interrupt_init();
|
||||||
|
apic_init();
|
||||||
|
gdt_init();
|
||||||
|
sse_init();
|
||||||
|
scheduler_init();
|
||||||
|
}
|
||||||
|
|
||||||
|
void cpu_init()
|
||||||
|
{
|
||||||
|
acpi_init();
|
||||||
|
pic_init();
|
||||||
|
ioapic_init();
|
||||||
|
|
||||||
|
msr_write(MSR_REG_KERNEL_GS, cpus[0].cpu);
|
||||||
|
asm("swapgs");
|
||||||
|
init_cpu();
|
||||||
|
|
||||||
|
debug_info("CPU - Status\n");
|
||||||
|
for(unsigned int i = 0; i < num_cpu; i++)
|
||||||
|
{
|
||||||
|
debug(" CPU id:%x lapic:%x\n", cpus[i].id, cpus[i].apic_id);
|
||||||
|
}
|
||||||
|
}
|
6
kernel/cpu/get_cpu.S
Normal file
6
kernel/cpu/get_cpu.S
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#include <cpu.h>
|
||||||
|
.intel_syntax noprefix
|
||||||
|
.global get_cpu
|
||||||
|
get_cpu:
|
||||||
|
mov rax, gs:GS_OFFSET_CPU
|
||||||
|
ret
|
37
kernel/include/cpu.h
Normal file
37
kernel/include/cpu.h
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define MAX_NUMCPU 64
|
||||||
|
|
||||||
|
#define GS_OFFSET_CPU 0
|
||||||
|
|
||||||
|
#ifndef __ASSEMBLER__
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <gdt.h>
|
||||||
|
#include <process.h>
|
||||||
|
#include <thread.h>
|
||||||
|
|
||||||
|
typedef struct cpu_t
|
||||||
|
{
|
||||||
|
uint64_t cpu;
|
||||||
|
uint64_t id;
|
||||||
|
uint64_t apic_id;
|
||||||
|
uint64_t apic_ticks_per_us;
|
||||||
|
uint64_t is_bsp;
|
||||||
|
thread_t *current_thread;
|
||||||
|
thread_t *last_thread;
|
||||||
|
process_t *current_process;
|
||||||
|
uint64_t gdt[5];
|
||||||
|
struct gdtp_st gdt_p;
|
||||||
|
thread_t *scheduler;
|
||||||
|
}__attribute__((packed)) cpu_t;
|
||||||
|
|
||||||
|
extern cpu_t cpus[];
|
||||||
|
extern unsigned int num_cpu;
|
||||||
|
|
||||||
|
void acpi_init();
|
||||||
|
void cpu_add(uint64_t id, uint64_t apic);
|
||||||
|
void cpu_init();
|
||||||
|
cpu_t *get_cpu();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
@ -3,6 +3,7 @@ typedef struct process_st process_t;
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <thread.h>
|
#include <thread.h>
|
||||||
#include <mem.h>
|
#include <mem.h>
|
||||||
|
#include <cpu.h>
|
||||||
|
|
||||||
typedef struct process_st
|
typedef struct process_st
|
||||||
{
|
{
|
||||||
@ -23,9 +24,8 @@ typedef struct process_st
|
|||||||
|
|
||||||
#define process_alive(proc) ((proc)->state == PROC_STATE_READY || (proc)->state == PROC_STATE_RUNNING)
|
#define process_alive(proc) ((proc)->state == PROC_STATE_READY || (proc)->state == PROC_STATE_RUNNING)
|
||||||
|
|
||||||
process_t *current_process;
|
#define get_current_process() (get_cpu()->current_process)
|
||||||
#define get_current_process() (current_process)
|
#define set_current_process(proc) (get_cpu()->current_process = (proc))
|
||||||
#define set_current_process(proc) (current_process = (proc))
|
|
||||||
|
|
||||||
process_t *process_spawn(process_t *parent);
|
process_t *process_spawn(process_t *parent);
|
||||||
void process_attach(process_t *proc, thread_t *th);
|
void process_attach(process_t *proc, thread_t *th);
|
||||||
|
@ -4,6 +4,7 @@ typedef struct thread_st thread_t;
|
|||||||
#include <list.h>
|
#include <list.h>
|
||||||
#include <process.h>
|
#include <process.h>
|
||||||
#include <int.h>
|
#include <int.h>
|
||||||
|
#include <cpu.h>
|
||||||
|
|
||||||
#define THREAD_STACK_SIZE 0x1000-sizeof(thread_t)
|
#define THREAD_STACK_SIZE 0x1000-sizeof(thread_t)
|
||||||
|
|
||||||
@ -40,9 +41,8 @@ typedef struct thread_stack_st
|
|||||||
thread_t tcb;
|
thread_t tcb;
|
||||||
} thread_stack_t;
|
} thread_stack_t;
|
||||||
|
|
||||||
thread_t *current_thread;
|
#define get_current_thread() (get_cpu()->current_thread)
|
||||||
#define get_current_thread() (current_thread)
|
#define set_current_thread(new) (get_cpu()->current_thread = (new))
|
||||||
#define set_current_thread(new) (current_thread = (new))
|
|
||||||
|
|
||||||
thread_t *new_thread(void (*func)(void));
|
thread_t *new_thread(void (*func)(void));
|
||||||
void switch_thread(thread_t *old, thread_t *new);
|
void switch_thread(thread_t *old, thread_t *new);
|
||||||
|
@ -46,8 +46,6 @@
|
|||||||
#define APIC(reg) apic[reg/4]
|
#define APIC(reg) apic[reg/4]
|
||||||
uint32_t volatile *apic = P2V(APIC_BASE);
|
uint32_t volatile *apic = P2V(APIC_BASE);
|
||||||
|
|
||||||
uint32_t apic_ticks_per_us;
|
|
||||||
|
|
||||||
void apic_interrupt(uint8_t destination, uint8_t level, uint8_t type, uint8_t vector)
|
void apic_interrupt(uint8_t destination, uint8_t level, uint8_t type, uint8_t vector)
|
||||||
{
|
{
|
||||||
uint64_t data = ((level & 0x1)<<14) | ((type & 0x7)<<8) | vector;
|
uint64_t data = ((level & 0x1)<<14) | ((type & 0x7)<<8) | vector;
|
||||||
@ -69,7 +67,7 @@ registers_t *apic_timer_handler(registers_t *r)
|
|||||||
void apic_timer(uint64_t us)
|
void apic_timer(uint64_t us)
|
||||||
{
|
{
|
||||||
APIC(R_TIMER_DIV) = TIMER_DIV1;
|
APIC(R_TIMER_DIV) = TIMER_DIV1;
|
||||||
APIC(R_TIMER_INIT) = us*apic_ticks_per_us;
|
APIC(R_TIMER_INIT) = us*get_cpu()->apic_ticks_per_us;
|
||||||
APIC(R_TIMER_LVT) = TIMER_LVT_ONESHOT | INT_APIC_TIMER;
|
APIC(R_TIMER_LVT) = TIMER_LVT_ONESHOT | INT_APIC_TIMER;
|
||||||
}
|
}
|
||||||
void apic_timer_stop()
|
void apic_timer_stop()
|
||||||
@ -91,7 +89,6 @@ uint32_t calibrate_apic_timer(uint32_t resolution)
|
|||||||
|
|
||||||
void apic_init()
|
void apic_init()
|
||||||
{
|
{
|
||||||
debug_info("APIC - APIC_BASE MSR: %x\n", msr_read(MSR_APIC_BASE));
|
|
||||||
// Enable APIC by setting the enable bit in the APIC MSR
|
// Enable APIC by setting the enable bit in the APIC MSR
|
||||||
msr_write(MSR_APIC_BASE, msr_read(MSR_APIC_BASE) | APIC_MSR_ENABLE);
|
msr_write(MSR_APIC_BASE, msr_read(MSR_APIC_BASE) | APIC_MSR_ENABLE);
|
||||||
|
|
||||||
@ -106,9 +103,7 @@ void apic_init()
|
|||||||
APIC(R_EOI) = 0;
|
APIC(R_EOI) = 0;
|
||||||
|
|
||||||
// Calibrate timer
|
// Calibrate timer
|
||||||
apic_ticks_per_us = calibrate_apic_timer(100);
|
get_cpu()->apic_ticks_per_us = calibrate_apic_timer(100);
|
||||||
debug_info("APIC - ticks per us:%d\n", apic_ticks_per_us);
|
|
||||||
debug(" corresponds to processor frequency: %d MHz\n", apic_ticks_per_us);
|
|
||||||
|
|
||||||
// Register temporary timer handler to go off every 10 ms
|
// Register temporary timer handler to go off every 10 ms
|
||||||
register_int_handler(INT_APIC_TIMER, apic_timer_handler);
|
register_int_handler(INT_APIC_TIMER, apic_timer_handler);
|
||||||
|
@ -7,9 +7,10 @@
|
|||||||
LIST(thread_t, ready_queue);
|
LIST(thread_t, ready_queue);
|
||||||
|
|
||||||
thread_t *scheduler_th;
|
thread_t *scheduler_th;
|
||||||
thread_t *last_thread = 0;
|
#define get_last_thread() (get_cpu()->last_thread)
|
||||||
#define get_last_thread() (last_thread)
|
#define set_last_thread(new) (get_cpu()->last_thread = (new))
|
||||||
#define set_last_thread(new) (last_thread = (new))
|
|
||||||
|
int scheduler_started = 0;
|
||||||
|
|
||||||
void scheduler_insert(thread_t *th)
|
void scheduler_insert(thread_t *th)
|
||||||
{
|
{
|
||||||
@ -66,7 +67,7 @@ void scheduler()
|
|||||||
switch_process(new->process);
|
switch_process(new->process);
|
||||||
sse_restore(new->sse_registers);
|
sse_restore(new->sse_registers);
|
||||||
apic_timer(1000000);
|
apic_timer(1000000);
|
||||||
switch_thread(scheduler_th, new);
|
switch_thread(get_cpu()->scheduler, new);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,7 +76,7 @@ void schedule()
|
|||||||
// This function handles swithing to the next thread in the ready queue
|
// This function handles swithing to the next thread in the ready queue
|
||||||
|
|
||||||
thread_t *old = get_current_thread();
|
thread_t *old = get_current_thread();
|
||||||
if(old == scheduler_th)
|
if(old == get_cpu()->scheduler)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(old)
|
if(old)
|
||||||
@ -84,11 +85,15 @@ void schedule()
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch_process(0);
|
switch_process(0);
|
||||||
switch_thread(old, scheduler_th);
|
switch_thread(old, get_cpu()->scheduler);
|
||||||
}
|
}
|
||||||
|
|
||||||
void scheduler_init()
|
void scheduler_init()
|
||||||
|
{
|
||||||
|
if(!scheduler_started)
|
||||||
{
|
{
|
||||||
LIST_HEAD_INIT(ready_queue);
|
LIST_HEAD_INIT(ready_queue);
|
||||||
scheduler_th = new_thread(scheduler);
|
scheduler_started = 1;
|
||||||
|
}
|
||||||
|
get_cpu()->scheduler = new_thread(scheduler);
|
||||||
}
|
}
|
||||||
|
@ -6,8 +6,6 @@
|
|||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
#include <registers.h>
|
#include <registers.h>
|
||||||
|
|
||||||
thread_t *current_thread = 0;
|
|
||||||
|
|
||||||
uint64_t tid = 1;
|
uint64_t tid = 1;
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user