summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md2
-rw-r--r--asm/asm_int.h1
-rw-r--r--asm/asm_int.s2
-rw-r--r--asm/asm_mp.asm5
-rw-r--r--kernel/gdt.c19
-rw-r--r--kernel/interrupts.c14
-rw-r--r--kernel/kernel.c11
-rw-r--r--kernel/kernel.h3
-rw-r--r--kernel/kmalloc.c12
-rw-r--r--kernel/smp.c81
-rw-r--r--kernel/smp.h2
-rw-r--r--userspace/foolshell.c2
12 files changed, 116 insertions, 38 deletions
diff --git a/README.md b/README.md
index 565a742..efd3a29 100644
--- a/README.md
+++ b/README.md
@@ -98,7 +98,7 @@ Discontinued Features
Todos
-----
-* cpuid
+* cpuid (i686) check apic?
* lapic / spurious . ioapic
* newlib reentrant struct!!
* Interrupts between BSP and APS ?
diff --git a/asm/asm_int.h b/asm/asm_int.h
index 4133fbf..25ab885 100644
--- a/asm/asm_int.h
+++ b/asm/asm_int.h
@@ -17,6 +17,7 @@ void int15();
void int128(); // syscalls
void int129(); // scheduler
+void int200(); // apic timer
void int255(); // unhandled
void exc0();
diff --git a/asm/asm_int.s b/asm/asm_int.s
index 94785bc..f7107de 100644
--- a/asm/asm_int.s
+++ b/asm/asm_int.s
@@ -18,6 +18,7 @@
.global int128
.global int129
+.global int200
.global int255
.global exc0
@@ -157,6 +158,7 @@ int128: intx ack0 $128 interrupt_handler
int129: intx ack0 $129 interrupt_handler
int255: intx ack0 $255 interrupt_handler
+int200: intx ack0 $200 interrupt_handler
exc0: excx $0 exception_handle
exc1: excx $1 exception_handle
diff --git a/asm/asm_mp.asm b/asm/asm_mp.asm
index a2dcee0..5e5259e 100644
--- a/asm/asm_mp.asm
+++ b/asm/asm_mp.asm
@@ -1,6 +1,7 @@
global smp_start
global LLOCK
extern smp_main
+global gdt_descriptor
; master boot record for application processors
smp_start:
@@ -84,5 +85,5 @@ gdt_descriptor:
dw gdt_end-gdt_start-1
dd gdt_start
-CODE_SEG equ gdt_code - gdt_start
-DATA_SEG equ gdt_data - gdt_start
+;CODE_SEG equ gdt_code - gdt_start
+;DATA_SEG equ gdt_data - gdt_start
diff --git a/kernel/gdt.c b/kernel/gdt.c
index d1ed382..c91524a 100644
--- a/kernel/gdt.c
+++ b/kernel/gdt.c
@@ -5,18 +5,16 @@
#include <stdint.h>
#define GDT_SIZE 6
-static uint8_t gdt_struct[GDT_SIZE*8]; // GLOBAL DESCRIPTOR TABLE
-uint64_t gdt_descriptor;
//https://wiki.osdev.org/Task_State_Segment
-tss_struct sys_tss; //Define the TSS as a global structure
+tss_struct sys_tss[SMP_MAX_PROC]; //Define the TSS as a global structure
void install_tss(uint32_t esp0){
// now fill each value
// set values necessary
- sys_tss.ss0 = 0x10; //kernel data
- sys_tss.esp0 = esp0;
+ sys_tss[0].ss0 = 0x10; //kernel data
+ sys_tss[0].esp0 = esp0;
// now set the IO bitmap (not necessary, so set above limit)
// sys_tss.iomap = ( unsigned short ) sizeof( tss_struct );
@@ -97,6 +95,8 @@ void encodeGdtEntry(uint8_t *target, GDT source)
void gdt_init()
{
+
+ static int last_cpu=0;
/*
Pr=1 Privl 1 Exec DC RW Ac
0x9A == 1001 1010 == 1 00 1 1 0 1 0
@@ -105,6 +105,8 @@ void gdt_init()
0xF2 == 1111 0010 == 1 11 1 0 0 1 0
*/
+//static uint8_t gdt_struct[GDT_SIZE*8]; // GLOBAL DESCRIPTOR TABLE
+ uint8_t *gdt_struct=kballoc(1); //[GDT_SIZE*8]; // GLOBAL DESCRIPTOR TABLE
GDT myGDT[GDT_SIZE];
//selector 0x0
@@ -133,7 +135,7 @@ void gdt_init()
myGDT[4].type=0xF2;
//TSS 0x28
- myGDT[5].base=&sys_tss; //tss start
+ myGDT[5].base=&sys_tss[last_cpu++]; //tss start
myGDT[5].limit=sizeof(tss_struct); //tss end
myGDT[5].type=0x89;
@@ -144,5 +146,10 @@ void gdt_init()
// update tss entry
install_tss(0);
+ setup_gdt(gdt_struct);
+
+}
+void setup_gdt(uint8_t *gdt_struct)
+{
asm_setup_gdt(&gdt_struct[0],8*GDT_SIZE);
}
diff --git a/kernel/interrupts.c b/kernel/interrupts.c
index 4eb2a35..f93de9e 100644
--- a/kernel/interrupts.c
+++ b/kernel/interrupts.c
@@ -6,7 +6,7 @@
#include "asm_x86.h"
/** The size of our interrupts table */
-#define INT_MAX 255
+#define INT_MAX 256 // 0-255
/** The interrupt descriptor table */
static struct int_desc
@@ -83,6 +83,10 @@ uint32_t interrupt_handler(uint32_t esp, uint32_t irq)
if(irq==0 || irq==129)esp=my_scheduler(esp,-1); // autoschedule
+ if(irq==200){
+ klog("tick");
+ writeAPIC(0xB0,0); // apic EOI
+ }
if(irq==255)kpanic("Unhandled Interrupt!");
return esp;
@@ -107,8 +111,8 @@ void show_selector_error(uint32_t err)
{
klog("Selector Error Details:");
klog("External Event: %x",err&0b1);
- klog("Location: %x",err&0b110);
- klog("Selector: %x",err&0b1111111111111000);
+ klog("Location: 0x%x (0-GDT/1-IDT/2-LDT/3-IDT)",err&0b110);
+ klog("Selector: 0x%x",err&0b1111111111111000);
}
void show_page_fault_error(uint32_t error_code)
@@ -242,9 +246,13 @@ void interrupts_init(uint16_t sel)
// System Calls / they can be called from ring3 (0b11)
int_install_ir(0x80, 0b11101110, 0x08,&int128);
+
// Wake Scheduler
int_install_ir(0x81, 0b11101110, 0x08,&int129);
+ // APIC Timer
+ int_install_ir(200, 0b11101110, 0x08,&int200);
+
// install IVT
int_install();
}
diff --git a/kernel/kernel.c b/kernel/kernel.c
index 493fb93..30949f8 100644
--- a/kernel/kernel.c
+++ b/kernel/kernel.c
@@ -42,11 +42,6 @@ void kernel_main(uint32_t eax,uint32_t ebx)
multiboot_information *info;
info=get_multiboot(eax, ebx);
- klog("Symmetrical Multi Processing (SMP) init ... ");
- smp_processors procdata;
-// if(!acpi_find(&procdata)&&!mp_find(&procdata))kpanic("No ACPI or MP found!");
- if(!acpi_find(&procdata))("No ACPI found!");
-
klog("Memory init ... ");
uint32_t kernel_blocks=mem_init(info);
@@ -56,9 +51,13 @@ void kernel_main(uint32_t eax,uint32_t ebx)
klog("Interrupt Vector Table (IVT) init ...");
interrupts_init(0x08);
+ klog("Symmetrical Multi Processing (SMP) init ... ");
+ smp_processors procdata;
+// if(!mp_find(&procdata))kpanic("No MP found!");
+ if(!acpi_find(&procdata))kpanic("No ACPI found!");
+
// Start the other Processors (before paging because apic addr etc..?)
//TODO: remap apic !!! Check commented out sleep ()!!!
- // https://wiki.osdev.org/Symmetric_Multiprocessing
klog("Symmetric Multi Processing (SMP) start ... ");
smp_log_procdata(&procdata);
smp_start_aps(&procdata);
diff --git a/kernel/kernel.h b/kernel/kernel.h
index 4c480e5..e1a33d2 100644
--- a/kernel/kernel.h
+++ b/kernel/kernel.h
@@ -19,10 +19,13 @@
#define KMALLOC_MEM_SIZE 1024*1024*8 // 8MB for in kernel-memory
#define NUMBER_SPINLOCKS 16
#define SPINLOCK_LOG 0
+#define SPINLOCK_ALLOC 1
#define S1(x) #x
#define S2(x) S1(x)
+#define SMP_MAX_PROC 32
+
// __FUNCTION__ ?
#define kpanic(...) {log(__FILE__,0," \033[41;37m--PANIC--\033[37;40m " __VA_ARGS__ ); while(1);}
#define klog(...) log(__FILE__ ":" S2(__LINE__), 10, __VA_ARGS__)
diff --git a/kernel/kmalloc.c b/kernel/kmalloc.c
index ec714c4..6a5812a 100644
--- a/kernel/kmalloc.c
+++ b/kernel/kmalloc.c
@@ -1,7 +1,7 @@
-
#include "kmalloc.h"
#include "kernel.h"
+#include "spinlock.h"
static uint8_t data[KMALLOC_MEM_SIZE]; // bytes
@@ -32,11 +32,15 @@ static void kmallocinit()
uint32_t kballoc(uint32_t size)
{
size*=4096;
+
+ spinlock_spin(SPINLOCK_ALLOC);
+
+ if(!init)kmallocinit();
- if(!init)kmallocinit();
+ uint32_t old=next;
+ next+=size;
- uint32_t old=next;
- next+=size;
+ spinlock_release(SPINLOCK_ALLOC);
if(next>=first+KMALLOC_MEM_SIZE)
{
diff --git a/kernel/smp.c b/kernel/smp.c
index ea926ca..3709ed5 100644
--- a/kernel/smp.c
+++ b/kernel/smp.c
@@ -1,7 +1,9 @@
-#include "kernel/kernel.h"
+#include "kernel.h"
// http://www.intel.com/content/dam/doc/specification-update/64-architecture-x2apic-specification.pdf
// http://download.intel.com/design/chipsets/datashts/29056601.pdf
// http://www.scs.stanford.edu/05au-cs240c/lab/ia32/IA32-3.pdf
+// https://wiki.osdev.org/Symmetric_Multiprocessing
+// https://wiki.osdev.org/APIC_timer
#include <stdint.h>
#include "smp.h"
@@ -14,6 +16,32 @@
#define FOOLOS_APIC_INT_COMMAND_HIGH 0x0310
#define FOOLOS_APIC_ID 0x020
+#define APIC_APICID 0x20
+#define APIC_APICVER 0x30
+#define APIC_TASKPRIOR 0x80
+#define APIC_EOI 0x0B0
+#define APIC_LDR 0x0D0
+#define APIC_DFR 0x0E0
+#define APIC_SPURIOUS 0x0F0
+#define APIC_ESR 0x280
+#define APIC_ICRL 0x300
+#define APIC_ICRH 0x310
+#define APIC_LVT_TMR 0x320
+#define APIC_LVT_PERF 0x340
+#define APIC_LVT_LINT0 0x350
+#define APIC_LVT_LINT1 0x360
+#define APIC_LVT_ERR 0x370
+#define APIC_TMRINITCNT 0x380
+#define APIC_TMRCURRCNT 0x390
+#define APIC_TMRDIV 0x3E0
+#define APIC_LAST 0x38F
+#define APIC_DISABLE 0x10000
+#define APIC_SW_ENABLE 0x100
+#define APIC_CPUFOCUS 0x200
+#define APIC_NMI (4<<8)
+#define TMR_PERIODIC 0x20000
+#define TMR_BASEDIV (1<<20)
+
// some multiprocessor shit that should move away TODO
uint32_t c1,c2,c3;
volatile uint8_t proc;
@@ -24,35 +52,58 @@ extern uint32_t LLOCK;
void smp_main()
{
+ // setup stack
uint32_t ebp=kballoc(1);
asm volatile("mov %0, %%ebp"::"r"(ebp));
asm volatile("mov %ebp, %esp");
asm volatile("jmp kernel_ap");
}
+void writeAPIC(uint32_t offset, uint32_t value)
+{
+ uint32_t *reg;
+ reg=local_apic_addr+offset;
+ *reg=value;
+}
+
+uint32_t readAPIC(uint32_t offset)
+{
+ uint32_t *reg;
+ reg=local_apic_addr+offset;
+ uint32_t value=*reg;
+ return value;
+}
+
void kernel_ap()
{
- LLOCK=0;
uint32_t *reg;
reg=local_apic_addr+FOOLOS_APIC_ID;
- klog("smp local apic id: %d",(*reg));
+ klog("smp local apic id: 0x%08X",(*reg));
- // // // *reg=local_apic_addr+FOOLOS_APIC_SPUR_INT;
- // // // *reg|=0x100;//0xffffffff; // all bits 1 and interrupt 255
-// *reg=0;//xffffffff; // all bits 1 and interrupt 255
+ reg=local_apic_addr+FOOLOS_APIC_SPUR_INT;
+ klog("svr value: 0x%08X",(*reg));
+ *reg|=0x100; // enable APIC
int_install();
+ gdt_init();
+
+ uint32_t countdown=0x0fffffff;
+ writeAPIC(APIC_TMRDIV, 0x3);
+ writeAPIC(APIC_LVT_TMR, 200 | TMR_PERIODIC);
+ writeAPIC(APIC_TMRINITCNT, countdown);
+
x86_sti();
+ LLOCK=0; // release lock, so next ap can continue...
- while(1){
- klog("%d",*reg);
- for(int i=0;i<1000000000;i++);
- }
+ while(1)
+ {
+ asm("hlt");
+ klog("tack: 0x%08X: 0x%08X",readAPIC(FOOLOS_APIC_ID), readAPIC(APIC_TMRCURRCNT));
+ }
// switch_to_user_mode();
-// int x=1/0;
/*
while(1);
@@ -95,8 +146,10 @@ void smp_log_procdata(smp_processors *procdata)
}
// this will start all our application processors!
-void smp_start_aps(smp_processors *pros,char *path)
+void smp_start_aps(smp_processors *pros)
{
+
+ // TODO: check if local APIC is present via CPUID (P6 (i686) and above)
local_apic_addr=pros->local_apic_address;
//bsp (boot processor) enables its local apic
@@ -105,7 +158,7 @@ void smp_start_aps(smp_processors *pros,char *path)
// *reg=0;
uint32_t *reg=local_apic_addr+FOOLOS_APIC_ID;
- klog("local apic id: 0x%08X",(*reg));
+ klog("bsp local apic id: 0x%08X",(*reg));
for(int i=0;i<pros->processors;i++)
{
@@ -125,7 +178,7 @@ void smp_start_aps(smp_processors *pros,char *path)
// todo: use some real sleep (not implemented yet :( )
//sleep(30);
- // start proc 0x7 = 0x7000;
+ // start proc 0x7 = at addr 0x7000;
*reg=(6<<8)|(1<<14)|0x7; // 110 SIPI
}
}
diff --git a/kernel/smp.h b/kernel/smp.h
index 256d451..61058fc 100644
--- a/kernel/smp.h
+++ b/kernel/smp.h
@@ -1,7 +1,7 @@
#ifndef SMP_H
#define SMP_H
-#define SMP_MAX_PROC 32
+#include "kernel.h"
typedef struct
{
diff --git a/userspace/foolshell.c b/userspace/foolshell.c
index 86c083c..09d6d32 100644
--- a/userspace/foolshell.c
+++ b/userspace/foolshell.c
@@ -96,7 +96,7 @@ int main(int argc, char **argv)
//fgets(buf,255,stdin);
//buf[strlen(buf)-1]=0; // remove \n
- printf("[%s]",buf);
+ //printf("[%s]",buf);
process(buf);
}