summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichal Idziorek <m.i@gmx.at>2014-09-01 00:30:20 +0200
committerMichal Idziorek <m.i@gmx.at>2014-09-01 00:30:20 +0200
commit45fc98575a57dc9709c7a66a243b121c5f11bf2c (patch)
tree75f6c0cf59abe5eb43ef7dd9577a826a1d8f2527
parentbbbb277f3dd0de3a1b41073e8c8d22e15ddec5ed (diff)
continued multiprocessing
-rw-r--r--README.md1
-rw-r--r--bochsrc6
-rw-r--r--boot/mbr.asm3
-rw-r--r--kernel/mp.c71
4 files changed, 74 insertions, 7 deletions
diff --git a/README.md b/README.md
index f6ad3ea..8a0a931 100644
--- a/README.md
+++ b/README.md
@@ -71,6 +71,7 @@ Some things I would like to add someday:
* let processors sleep if there is no work
* switch from PIC to APIC!
* use ACPI instead of MP spec.
+* install idt for second processor!
Issues
------
diff --git a/bochsrc b/bochsrc
index b0b22da..cf19501 100644
--- a/bochsrc
+++ b/bochsrc
@@ -463,11 +463,11 @@ clock: sync=realtime, time0=local
# make it "/dev/null" (Unix) or "nul" (win32). :^(
#
# Examples:
- log: ./bochs.out
+# log: ./bochs.out
# log: /dev/tty
#=======================================================================
#log: /dev/stdout
-#log: ./bochs.log
+log: ./bochs.log
#=======================================================================
# LOGPREFIX:
@@ -510,7 +510,7 @@ clock: sync=realtime, time0=local
panic: action=ask
error: action=report
info: action=report
-debug: action=ignore
+debug: action=report
#debug: action=report
#pass: action=fatal
diff --git a/boot/mbr.asm b/boot/mbr.asm
index 45cfd85..c565f33 100644
--- a/boot/mbr.asm
+++ b/boot/mbr.asm
@@ -53,6 +53,9 @@ VESA_MODE_INFO equ 0x8400
VESA_MODE_SELECT equ 0x4114
;
jmp boot_16 ;start boot process
+ db 'X'
+jmp $ ;entry for other processors ;)
+ db 'X'
;
;;SOME Global Data, mainly info/error strings
BOOT_DRIVE:
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++;