blob: 58e37a56547b9f4132acf232b2aad7e986b72c5c (
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
|
#define FOOLOS_MODULE_NAME "smp"
#include "lib/logger/log.h"
#include "lib/int/stdint.h"
#include "smp.h"
#define FOOLOS_APIC_SPUR_INT 0x00f0
#define FOOLOS_APIC_INT_COMMAND_LOW 0x0300
#define FOOLOS_APIC_INT_COMMAND_HIGH 0x0310
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 : local_apic_id: 0x%X bps: %s local_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)
{
//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: use some real sleep (not implemented yet :( )
sleep(10);
// start proc at 0x7000;
*reg=(6<<8)|(1<<14)|0x7; // 110 SIPI
}
}
|