summaryrefslogtreecommitdiff
path: root/kernel/mp.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/mp.c')
-rw-r--r--kernel/mp.c71
1 files changed, 67 insertions, 4 deletions
diff --git a/kernel/mp.c b/kernel/mp.c
index 602aca2..fc6288c 100644
--- a/kernel/mp.c
+++ b/kernel/mp.c
@@ -3,6 +3,10 @@
#include "x86.h"
#include "../lib/logger/log.h" // logger facilities
+#define FOOLOS_APIC_SPUR_INT 0x00f0
+#define FOOLOS_APIC_INT_COMMAND_LOW 0x0300
+#define FOOLOS_APIC_INT_COMMAND_HIGH 0x0310
+
typedef struct mp_fps_struct
{
@@ -47,15 +51,48 @@ typedef struct mp_config_struct
+typedef struct proc_struct
+{
+ uint8_t type; //0=processor
+ uint8_t apic_id;
+ uint8_t apic_ver;
+ uint8_t cpu_bits;
+ uint32_t cpu_sig;
+ uint32_t cpu_flags;
+
+}proc_entry;
+
+uint32_t local_apic;
+
+int processors;
+uint8_t apic_id[4];
+
-//entries are sorted, but we do not care.
+
+//entries are sorted. (otherwise ignore. bochs!)
uint8_t *walk_mp_table(uint8_t *start_addr)
{
+ /*
+ static int last=0;
+ if(*start_addr<last)return;
+ last=*start_addr;
+ */
+
if(*start_addr==0x0||*start_addr==0x2)
log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"entry type: %d",*start_addr);
- if(*start_addr==0x00)return start_addr+20;
+
+ if(*start_addr==0x00)
+ {
+ proc_entry *pro=start_addr;
+ log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"local apic id: %02X",pro->apic_id);
+ log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"cpu enabled bit: %s",pro->cpu_bits&1?"yes":"no");
+ log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"bootstrap cpu bit: %s",pro->cpu_bits&2?"yes":"no");
+
+ return start_addr+20;
+ }
+
return start_addr+8;
}
@@ -65,6 +102,8 @@ void show_mp_conf(mp_config *addr)
uint32_t *buf_addr=buf;
*buf_addr=addr->sig;
+ processors=0;
+
log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"mp_config tabel addr: %08X",addr);
log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"mp_config signature: %s",buf);
log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"mp_config version: %02X",addr->version);
@@ -72,6 +111,30 @@ void show_mp_conf(mp_config *addr)
log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"mp_config local apic addr: 0x%08X",addr->local_apic);
log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"mp_config tabel length: %d",addr->length);
+ local_apic=addr->local_apic;
+
+ //bsp (boot processor) enables its local apic
+ uint32_t *reg=addr->local_apic+FOOLOS_APIC_SPUR_INT;
+ *reg=0xffffffff; // all bits 1 and interrupt 255
+
+ reg=addr->local_apic+FOOLOS_APIC_INT_COMMAND_HIGH;
+ *reg=1<<24; // destination apic 1!
+
+ reg=addr->local_apic+FOOLOS_APIC_INT_COMMAND_LOW;
+ //*reg=(5<<8)&(1<<14)&99;
+ //*reg=(6<<8)|(1<<14)|1;
+ *reg=(5<<8)|(1<<14); // 101 INIT
+
+ uint16_t *startpos=0xa000;
+ *startpos=0xfeeb;
+
+ sleep(10);
+
+ log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"STARTING proc 2");
+
+ *reg=(6<<8)|(1<<14)|0xa; // 110 SIPI
+
+
uint8_t *start_addr=addr;
start_addr+=44;
for(int i=0;i<addr->entries;i++)
@@ -127,7 +190,7 @@ bool find_mp()
{
if(check_mp(addr))
{
- log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"Found at 0x%04X",addr);
+ // log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"Found at 0x%04X",addr);
show_mp_fps(addr);
}
addr++;
@@ -138,7 +201,7 @@ bool find_mp()
{
if(check_mp(addr))
{
- log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"Found at 0x%04X",addr);
+ // log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"Found at 0x%04X",addr);
show_mp_fps(addr);
}
addr++;