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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
#define FOOLOS_MODULE_NAME "smp"
#include "lib/logger/log.h"
#include <stdint.h>
#include "smp.h"
#include "mem.h"
#include "spinlock.h"
#include "x86.h"
#define FOOLOS_APIC_SPUR_INT 0x00f0
#define FOOLOS_APIC_INT_COMMAND_LOW 0x0300
#define FOOLOS_APIC_INT_COMMAND_HIGH 0x0310
// some multiprocessor shit that should move away TODO
uint32_t c1,c2,c3;
volatile uint8_t proc;
uint32_t cpu_counter[SMP_MAX_PROC];
extern
void smp_main()
{
// int_install();
// x86_int_enable();
switch_to_user_mode();
while(1);
uint32_t ebp=pmmngr_alloc_block()+4095;
asm volatile("mov %0, %%ebp"::"r"(ebp));
asm volatile("mov %ebp, %esp");
asm volatile("jmp kernel_ap");
proc=c1=c2=c3=0;
for(int i=0;i<SMP_MAX_PROC;i++)cpu_counter[i]=0;
}
void kernel_ap()
{
proc++;
uint8_t p=proc;
while(1)
{
cpu_counter[p]++;
lock_spin(0);
if(cpu_counter[p]%1000000==0)log(FOOLOS_MODULE_NAME,FOOLOS_LOG_DEBUG,"cpu[%d] %d",p,cpu_counter[p]);
lock_release(0);
}
}
void smp_log_procdata(smp_processors *procdata)
{
log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"---- smp -----");
for(int i=0;i<procdata->processors;i++)
{
log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"cpu %d, apic_id: 0x%X, bps: %s, apic_addr:0x%08X",i,procdata->local_apic_id[i],i==procdata->boot?"yes":"no",procdata->local_apic_address);
}
}
// this will start all our application processors!
void smp_start_aps(smp_processors *pros,char *path)
{
//lets copy the binary into mbr
fs_content(path,0x7000,0x100); // copy 0x100 bytes to 0x7000
// tell them where to enter (agreed adress at 0x8010)
uint32_t *entry=0x8010;
*entry=smp_main;
//bsp (boot processor) enables its local apic
uint32_t *reg=pros->local_apic_address+FOOLOS_APIC_SPUR_INT;
// *reg=0xffffffff; // all bits 1 and interrupt 255
for(int i=0;i<pros->processors;i++)
{
if(pros->boot==i)continue;
log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"starting cpu %d",i);
uint8_t dest=pros->local_apic_id[i];
reg=pros->local_apic_address+FOOLOS_APIC_INT_COMMAND_HIGH;
*reg=dest<<24; // destination apic.
reg=pros->local_apic_address+FOOLOS_APIC_INT_COMMAND_LOW;
*reg=(5<<8)|(1<<14); // 101 INIT
// do we really neet this?
// TODO!!
// todo: use some real sleep (not implemented yet :( )
//sleep(30);
// start proc 0x7 = 0x7000; etc..
*reg=(6<<8)|(1<<14)|0x7; // 110 SIPI
//bsp (boot processor) enables its local apic
uint32_t *reg=pros->local_apic_address+FOOLOS_APIC_SPUR_INT;
// *reg=0xffffffff; // all bits 1 and interrupt 255
}
}
|