summaryrefslogtreecommitdiff
path: root/kernel/smp.c
blob: b3856818624eddeb0b73501a4cca42e57cb9ff1a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#include "kernel.h"
#include "smp.h"

#include <stdint.h>
#include "gdt.h"
#include "mem.h"
#include "vmem.h"
#include "interrupts.h"
#include "kmalloc.h"
#include "spinlock.h"
#include "asm_x86.h"
#include "asm_pit.h"
#include "asm_smp.h"
#include "apic.h"
#include "vesa.h"


void smp_main()
{
    // setup stack and jump to kernel_ap();
    uint32_t ebp=kballoc(1);
    asm volatile("mov %0, %%ebp"::"r"(ebp));
    asm volatile("mov %ebp, %esp");
    asm volatile("jmp kernel_ap");
}

void kernel_ap()
{

    klog("Install Interrupt Vector Table (IVT) on CPU with lapic_id=0x%x ...",apic_id());
    interrupts_install();

    klog("Install Global Descriptor Table (GDT) on CPU with lapic_id=0x%x ...",apic_id());
    gdt_init();

    klog("Setup Paging on CPU with lapic_id=0x%x ...",apic_id());
    struct pdirectory_struct *dir=vmem_kernel_dir();
    x86_set_page_directory(dir);
    x86_paging_enable();

    apic_enable();

    //1024 pages from here on are mapped per cpu for testing! TODO: dynamic.
    uint32_t *cpu_mem=VMEM_CPU_PRIVATE; 
    cpu_mem[0]=apic_id();
    
    klog("Setup the LAPIC Timer on CPU with lapic_id=0x%x ...",apic_id());
    apic_init_timer(1);// freq 1HZ

    klog("Enable Interrupts on CPU with lapic_id=0x%x ...",apic_id());
    x86_sti();

    asm_smp_unlock();

    cpu_mem[1]=0;

    while(1){
	PutString("cpu cnt: %d",10,10+apic_id()*20,0xff0000,cpu_mem[1]++);
	asm("hlt");
    }
}

// this will start all our application processors!
void smp_start_aps(acpi_information *pros)
{
        for(int i=0;i<pros->processors;i++)
	{
	    if(pros->boot==i)continue; // skib bsp

	    uint8_t dest=pros->local_apic_id[i];
	    klog("starting cpu %d (destination apic id: 0x%x) ",i,dest);
	    apic_sipi(dest,0x7); // start on 0x7000
	}
}