summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorMichal Idziorek <m.i@gmx.at>2014-09-03 00:15:51 +0200
committerMichal Idziorek <m.i@gmx.at>2014-09-03 00:15:51 +0200
commitaad04a2208fbde8db2c1a81d6057c1ac4edb390e (patch)
tree87f3b47c5f85d6c7c5921e799571b42906d0eb0a /kernel
parent1a3a3a20773a5664c653a8aebcd10d288962285b (diff)
ACPI support !
Diffstat (limited to 'kernel')
-rw-r--r--kernel/acpi.c166
-rw-r--r--kernel/floppy.c22
-rw-r--r--kernel/kernel.c77
-rw-r--r--kernel/mp.c112
-rw-r--r--kernel/shell.c2
-rw-r--r--kernel/smp.c52
-rw-r--r--kernel/smp.h15
-rw-r--r--kernel/task.c18
-rw-r--r--kernel/x86.c9
9 files changed, 348 insertions, 125 deletions
diff --git a/kernel/acpi.c b/kernel/acpi.c
new file mode 100644
index 0000000..da16be8
--- /dev/null
+++ b/kernel/acpi.c
@@ -0,0 +1,166 @@
+// Advanced Configuration and Power Interface
+// http://wiki.xomb.org/index.php?title=ACPI_Tables
+
+#define FOOLOS_MODULE_NAME "acpi"
+
+#include "lib/logger/log.h"
+#include "lib/int/stdint.h"
+#include "lib/bool/bool.h"
+#include "smp.h"
+
+
+typedef struct acpi_rsdt_struct
+{
+ char sig[4];
+ uint32_t length;
+ uint8_t revision;
+ uint8_t checksum;
+ char oemid[6];
+ char oemtabid[8];
+ uint32_t oemrevision;
+ uint32_t vendor;
+ uint32_t rev;
+}acpi_rsdt;
+
+typedef struct aspi_rsdp_struct
+{
+ char sig[8]; //signature
+ uint8_t checksum;
+ char oem[6];
+ uint8_t revision;
+
+ uint32_t ptr_rsdt;
+ uint32_t length;
+
+ uint64_t ptr_xsdt; //same info but with 64bit pointers (preferred)
+ uint8_t checksum_ext;
+ uint8_t reserved[3];
+
+}acpi_rsdp;
+
+typedef struct
+{
+ char sig[4];
+ uint32_t length;
+ uint8_t rev;
+ uint8_t checksum;
+ char oemid[6];
+ char oemtableid[8];
+ char oemrev[4];
+ char creatorid[4];
+ char creatorrev[4];
+ uint32_t apic_local;
+ uint32_t flags;
+
+}acpi_madt;
+
+uint8_t *apci_get_next_entry(uint8_t *addr,smp_processors *procdata)
+{
+
+ log(FOOLOS_MODULE_NAME,FOOLOS_LOG_DEBUG,"Examining MADT Entry at 0x%08X",addr);
+
+ if(*addr==0)
+ {
+ log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"MADT Entry: LocalAPIC");
+ // usable
+ if(addr[4]&1)
+ {
+ if(procdata->processors>=SMP_MAX_PROC)
+ panic(FOOLOS_MODULE_NAME,"we do not support that many processors. recompile with higher SMP_MAX_PROC.");
+
+ procdata->local_apic_id[procdata->processors]=addr[3];
+ procdata->processors++;
+ }
+
+ }
+ else if(*addr==1)
+ {
+ log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"MADT Entry: IO APIC");
+ }
+ else if(*addr==2)log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"MADT Entry: Interrupt Source Override");
+ else log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"MADT Entry: type:0x%X",*addr);
+
+ return addr+addr[1];
+}
+
+
+void acpi_check_madt(uint32_t *madt,smp_processors *procdata)
+{
+ acpi_madt *table=*madt;
+
+ log(FOOLOS_MODULE_NAME,FOOLOS_LOG_DEBUG,"Looking for MADT Table at %08X.",table);
+ if(strcmp("APIC",table->sig,4))
+ {
+ log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"Found MADT Table at 0x%08X",table);
+ uint8_t *end=table;
+ end+=table->length;
+
+ uint8_t *entry=table;
+ entry+=sizeof(acpi_madt);
+
+ procdata->local_apic_address=table->apic_local;
+
+ while(entry<end)
+ {
+ entry=apci_get_next_entry(entry,procdata);
+ }
+
+
+ }
+}
+
+void acpi_read_rsdt(acpi_rsdt *rsdt,smp_processors *procdata)
+{
+ log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"Reading RSDT Table at 0x%08X",rsdt);
+
+ if(!strcmp("RSDT",rsdt->sig,4))
+ panic(FOOLOS_MODULE_NAME,"Signature MISMATCH!");
+
+ int entries=(rsdt->length-sizeof(acpi_rsdt))/4;
+ uint32_t *first=rsdt;
+ first+=sizeof(acpi_rsdt)/4;
+
+ log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"Entries: %d",entries);
+ log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"Looking for MADT Table");
+ for(int i=0;i<entries;i++)
+ {
+
+ acpi_check_madt(first,procdata);
+ first++;
+ }
+
+}
+
+// search for the RSDB table in
+// 0x7ffff - 0x9ffff (max)
+// 0xe0000 - 0xfffff
+
+bool acpi_find(smp_processors *procdata)
+{
+ log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"Looking for RSDP Table");
+ char *search=0x7ffff; //will be 16 bit aligned;
+
+ while(search<=0xfffff)
+ {
+ if(strcmp("RSD PTR ",search,8)) // notice trailing space in "RSD PTR "
+ {
+ uint8_t checksum=0;
+ for(int i=0;i<20;i++)
+ checksum+=search[i];
+
+ if(checksum==0)
+ {
+ log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"RSDP Table found at 0x%08X",search);
+ acpi_rsdp *rsdp=search;
+ acpi_read_rsdt(rsdp->ptr_rsdt,procdata);
+ return true;
+ }
+ }
+
+ search++;
+
+ if(search==0xa0000)search=0xe0000;
+
+ }
+ return false;
+}
diff --git a/kernel/floppy.c b/kernel/floppy.c
index e6d2d11..e00e96b 100644
--- a/kernel/floppy.c
+++ b/kernel/floppy.c
@@ -16,19 +16,22 @@
*
*/
-#include "x86.h"
-
-#include "../lib/logger/log.h" // logger facilities
#define FOOLOS_MODULE_NAME "floppy"
+#ifdef FOOLOS_COMPILE_FLOPPY
+
+#include "lib/logger/log.h"
+
+#include "x86.h"
+
#define FLPY_SECTORS_PER_TRACK 18
void flpydsk_send_command (uint8_t cmd);
void flpydsk_wait_irq ();
void flpydsk_check_int (uint32_t* st0, uint32_t* cyl);
-static volatile int _CurrentDrive=0;
-static volatile uint8_t _FloppyDiskIRQ = 0;
+static volatile int _CurrentDrive;
+static volatile uint8_t _FloppyDiskIRQ;
// temporary dma hack
//! initialize DMA to use phys addr 1k-64k
@@ -158,14 +161,6 @@ void flpydsk_write_ccr (uint8_t val) {
x86_outb (FLPYDSK_CTRL, val);
}
-void sleep(int i)
-{
- i*=1000000;
- for(;i>0;i--)
- {
-
- }
-}
void flpydsk_motor_on()
{
@@ -561,3 +556,4 @@ void floppy_init()
}
+#endif
diff --git a/kernel/kernel.c b/kernel/kernel.c
index 373eea1..bf4daac 100644
--- a/kernel/kernel.c
+++ b/kernel/kernel.c
@@ -1,8 +1,9 @@
#define FOOLOS_MODULE_NAME "kernel"
-#include "x86.h"
-#include "console.h"
-#include "../lib/logger/log.h" // logger facilities
+#include "lib/logger/log.h" // logger facilities
+#include "lib/int/stdint.h"
+#include "lib/bool/bool.h"
+#include "smp.h"
// TODO: WHHYY can i compile it without the includes!???
@@ -11,31 +12,44 @@
// todo: move somewhere else!?
void int_clock_handler();
void int_kb_handler();
-void int_floppy_handler();
+//void int_floppy_handler();
uint32_t read_eip();
-
+void kernel_ap()
+{
+ uint32_t cpu_counter=0;
+ uint32_t ebp;
+ asm volatile("mov %%ebp,%0":"=r"(ebp));
+// log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"initial ebp: 0x%08X",ebp);
+ int proc=ebp-0xffffff;
+ proc/=-0x400;
+ while(1)PutString("%d", proc*100,580,0b1111100000000000, (cpu_counter++));
+}
//
// KERNEL MAIN
-//
+
// this is the very heart of our operating system!
//
+volatile uint8_t proc;
+
void kernel_main(uint32_t initial_stack, int mp)
{
-
-
// catch the APs (Application Processors)
if(mp==1)
{
- volatile static uint16_t proc=1;
+ uint32_t ebp=0xffffff-proc*0x400;
+ proc++;
- int p=proc;
- uint32_t cpu_counter=0;
- while(1)PutString("mp: %d", 200,580,0b1111100000000000, (cpu_counter++));
+ asm volatile("mov %0, %%ebp"::"r"(ebp));
+ asm volatile("mov %ebp, %esp");
+ asm volatile("jmp kernel_ap");
+
}
+ proc=0;
+
//
// We want to get output to the screen as fast as possible!
//
@@ -56,7 +70,7 @@ void kernel_main(uint32_t initial_stack, int mp)
// our video memory
//
- uint32_t vesa_physbase=vesa_init(0x8300,0x8400,0x7200);
+ uint32_t vesa_physbase=vesa_init(0x8300,0x8400,0x7600);
//
@@ -71,8 +85,31 @@ void kernel_main(uint32_t initial_stack, int mp)
// This currently uses the MP Floating Pointer Struct.
// Should support APCI in future too.
//
+
+ smp_processors procdata1;
+ smp_processors procdata2;
+ smp_processors procdata;
+
- if(!init_mp()) panic(FOOLOS_MODULE_NAME,"Can not Find _MP_");
+ // try to find acpi tables
+ bool succ_acpi=acpi_find(&procdata1);
+
+ // fallback to mp tables
+ bool succ_mp=mp_find(&procdata2);
+
+ if(!succ_acpi&&!succ_mp)
+ panic(FOOLOS_MODULE_NAME,"ACPI and MP search failed! I do not want to continue!");
+
+ if(succ_acpi)procdata=procdata1;
+ else procdata=procdata2;
+
+ // multiprocessing!
+
+ smp_log_procdata(&procdata1);
+ smp_log_procdata(&procdata2);
+ smp_start_aps(&procdata);
+
+
//
// Setup PIC
@@ -118,11 +155,12 @@ void kernel_main(uint32_t initial_stack, int mp)
int_install_ir(33, 0b10001110, 0x08,&int_kb_handler);
// install floppy interrupt handler (irq 6 => 38)
- int_install_ir(38, 0b10001110, 0x08,&int_floppy_handler);
+ //int_install_ir(38, 0b10001110, 0x08,&int_floppy_handler);
// now we can enable interrupts back again
int_enable();
+
//
// Scan the PCI Bus
//
@@ -148,7 +186,6 @@ void kernel_main(uint32_t initial_stack, int mp)
shell_init();
-
//
// Initialize Multitasking
//
@@ -156,6 +193,7 @@ void kernel_main(uint32_t initial_stack, int mp)
// round robin style.
//
+// smp_log_procdata(&procdata1);
task_init();
@@ -163,12 +201,7 @@ void kernel_main(uint32_t initial_stack, int mp)
// Just hang here.
//
- while(1)
- {
- static uint32_t cpu1_counter=0;
- PutString("cpu1counter: %d", 10,560,0b1111100000000000, (cpu1_counter++));
- cpu1_counter++;
- }
+ while(1) ;
}
diff --git a/kernel/mp.c b/kernel/mp.c
index e7e811b..f240597 100644
--- a/kernel/mp.c
+++ b/kernel/mp.c
@@ -3,10 +3,8 @@
#include "x86.h"
#include "lib/logger/log.h" // logger facilities
#include "lib/bool/bool.h"
+#include "smp.h"
-#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
@@ -63,33 +61,33 @@ typedef struct proc_struct
}proc_entry;
-uint32_t local_apic;
-
-int processors;
-uint8_t apic_id[4];
-
-
-
//entries are sorted. (otherwise ignore. bochs!)
-uint8_t *walk_mp_table(uint8_t *start_addr)
+uint8_t *walk_mp_table(uint8_t *start_addr,smp_processors *smp)
{
- /*
- 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);
-
+ // that is a processor
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");
+ 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");
+
+ // that is a enabled processor
+ if(pro->cpu_bits&1)
+ {
+ if(smp->processors>=SMP_MAX_PROC)
+ panic(FOOLOS_MODULE_NAME,"we do not support that many processors. recompile with higher SMP_MAX_PROC.");
+
+ smp->local_apic_id[smp->processors]=pro->apic_id;
+ // that is the bootstrap processor
+ if(pro->cpu_bits&2)smp->boot=smp->processors;
+ smp->processors++;
+
+ }
return start_addr+20;
}
@@ -97,61 +95,36 @@ uint8_t *walk_mp_table(uint8_t *start_addr)
return start_addr+8;
}
-void show_mp_conf(mp_config *addr)
+void do_mp_conf(mp_config *addr,smp_processors *procdata)
{
char buf[]="XXXX";
uint32_t *buf_addr=buf;
*buf_addr=addr->sig;
- processors=0;
-
log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"mp_config table 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);
log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"mp_config # of entries: %d",addr->entries);
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);
+
+ uint8_t *start_addr=addr;
+ start_addr+=44;
- 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=0x7000;
- *startpos=0xfeeb;
- */
-
- sleep(10);
-
- log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"STARTING proc 2");
-
- *reg=(6<<8)|(1<<14)|0x7; // 110 SIPI
+ procdata->processors=0;
+ procdata->local_apic_address=addr->local_apic;
- uint8_t *start_addr=addr;
- start_addr+=44;
for(int i=0;i<addr->entries;i++)
{
-// log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"go 0x%08X",start_addr);
- start_addr=walk_mp_table(start_addr);
-
+ start_addr=walk_mp_table(start_addr,procdata);
}
+
+
}
-bool show_mp_fps(mp_fps *addr)
+bool do_mp_fps(mp_fps *addr,smp_processors *procdata)
{
if(addr->length!=1)return false;
@@ -167,38 +140,23 @@ bool show_mp_fps(mp_fps *addr)
log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"f1: %02X",addr->features1);
if(addr->features1!=0)panic(FOOLOS_MODULE_NAME,"Intel default config not supported yet!");
- show_mp_conf(addr->conf);
+ do_mp_conf(addr->conf,procdata);
return true;
}
-bool check_mp(uint8_t *addr)
-{
- char test[]="_MP_";
-
- for(int i=0;i<4;i++)
- {
- if(test[i]!=*(addr+i))return false;
-
- }
-
- return true;
-
-}
-
-
// todo: check checksum,version etc. and narrow down search
-bool init_mp()
+bool mp_find(smp_processors *procdata)
{
log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"Looking for Mp Floating Ponter Struct...");
uint8_t *addr=0x8000;
while(addr<=0xfffff)
{
- if(check_mp(addr))
+ if(strcmp("_MP_",addr,4))
{
// log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"Found at 0x%04X",addr);
- if(show_mp_fps(addr))return true;
+ if(do_mp_fps(addr,procdata))return true;
}
addr++;
}
@@ -206,10 +164,10 @@ bool init_mp()
addr=0x190000-1025;
while(addr<=0x190000+1024)
{
- if(check_mp(addr))
+ if(strcmp("_MP_",addr,4))
{
// log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"Found at 0x%04X",addr);
- if(show_mp_fps(addr))return true;
+ if(do_mp_fps(addr,procdata))return true;
}
addr++;
}
diff --git a/kernel/shell.c b/kernel/shell.c
index 6a4a0aa..0dd9dc0 100644
--- a/kernel/shell.c
+++ b/kernel/shell.c
@@ -68,7 +68,7 @@ void shell_execute()
}
else if(1==strcmp(command,"READ",0))
{
- uint8_t *read= flpydsk_read_sector (10);
+// uint8_t *read= flpydsk_read_sector (10);
}
else
{
diff --git a/kernel/smp.c b/kernel/smp.c
new file mode 100644
index 0000000..58e37a5
--- /dev/null
+++ b/kernel/smp.c
@@ -0,0 +1,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
+ }
+}
+
+
diff --git a/kernel/smp.h b/kernel/smp.h
new file mode 100644
index 0000000..ebf007d
--- /dev/null
+++ b/kernel/smp.h
@@ -0,0 +1,15 @@
+#define SMP_MAX_PROC 32
+
+typedef struct
+{
+
+ uint8_t boot; //which processor in array is bsp
+ // (boot strap processor)
+
+ uint8_t processors; // total number of usable processors
+
+ uint32_t local_apic_address;// same for every processor
+
+ uint32_t local_apic_id[SMP_MAX_PROC]; // unique for every processor
+
+}smp_processors;
diff --git a/kernel/task.c b/kernel/task.c
index b1c2657..b94d5e4 100644
--- a/kernel/task.c
+++ b/kernel/task.c
@@ -10,31 +10,25 @@ int started;
void task_test1()
{
- uint16_t c1;
+ uint32_t c;
while(1)
{
- c1++;
- asm("cli");
-
- PutString("cpu1 / task1: %03d", 0,560,0xffffff, c1/100);
-
- asm("sti");
+ c++;
+ while(1)PutString("task0: %d", 00,500,0b1111100000000000, (c++));
}
}
void task_test2()
{
- uint16_t c2;
+ uint32_t c;
while(1)
{
- c2++;
- asm("cli");
- PutString("cpu1 / task2: %03d", 0,580,0xffffff, c2/100);
+ c++;
+ while(1)PutString("task1: %d", 200,500,0b1111100000000000, (c++));
- asm("sti");
}
}
diff --git a/kernel/x86.c b/kernel/x86.c
index 5e44424..8473bcc 100644
--- a/kernel/x86.c
+++ b/kernel/x86.c
@@ -1,5 +1,14 @@
#include "x86.h"
+//TODO!!!
+void sleep(int i)
+{
+ i*=1000000;
+ for(;i>0;i--)
+ {
+
+ }
+}
// get control registers (cr0-cr4)
uint32_t x86_get_cr0()