diff options
| -rw-r--r-- | Makefile | 1 | ||||
| -rw-r--r-- | README.md | 2 | ||||
| -rw-r--r-- | asm/asm_int.s | 49 | ||||
| -rw-r--r-- | asm/asm_mp.asm | 6 | ||||
| -rw-r--r-- | asm/asm_x86.s | 6 | ||||
| -rw-r--r-- | driver/serial.c | 5 | ||||
| -rw-r--r-- | kernel/acpi.c | 20 | ||||
| -rw-r--r-- | kernel/interrupts.c | 130 | ||||
| -rw-r--r-- | kernel/kernel.c | 1 | ||||
| -rw-r--r-- | kernel/kernel.h | 1 | ||||
| -rw-r--r-- | kernel/log.c | 6 | ||||
| -rw-r--r-- | kernel/smp.c | 28 | ||||
| -rw-r--r-- | kernel/spinlock.c | 13 | ||||
| -rw-r--r-- | kernel/spinlock.h | 12 | ||||
| -rw-r--r-- | userspace/exception.c | 4 |
15 files changed, 179 insertions, 105 deletions
@@ -27,6 +27,7 @@ CFLAGS+=-O0 CFLAGS+=-I. CFLAGS+=-I/home/miguel/temp/foolos/usr/i686-foolos/include/ CFLAGS+=-I./asm +CFLAGS+=-I./kernel CFLAGS+=-gstabs #CFLAGS+=-fstack-protector-all @@ -98,6 +98,8 @@ Discontinued Features Todos ----- +* cpuid +* lapic / spurious . ioapic * newlib reentrant struct!! * Interrupts between BSP and APS ? * Do not forget to flush TLB diff --git a/asm/asm_int.s b/asm/asm_int.s index 566b646..94785bc 100644 --- a/asm/asm_int.s +++ b/asm/asm_int.s @@ -103,7 +103,7 @@ push \num // pass in this interrupt number push %eax // pass in original %esp (saved just few lines before) - call \func + call \func // call aligned mov %eax,%esp // use the %esp we got from c function pop %gs // pop everything back... @@ -125,8 +125,13 @@ .endm -.macro excx func - call \func +.macro excx num func + mov %esp,%eax // remember THIS stack position + and $-16,%esp // padding to align stack on 16byte boundary before CALL + sub $8,%esp // ... + push \num // pass in this interrupt number + push %eax // pass in original %esp (saved just few lines before) + call \func // call aligned jmp . .endm @@ -153,22 +158,22 @@ int129: intx ack0 $129 interrupt_handler int255: intx ack0 $255 interrupt_handler -exc0: excx exception_handle_0 -exc1: excx exception_handle_1 -exc2: excx exception_handle_2 -exc3: excx exception_handle_3 -exc4: excx exception_handle_4 -exc5: excx exception_handle_5 -exc6: excx exception_handle_6 -exc7: excx exception_handle_7 -exc8: excx exception_handle_8 -exc9: excx exception_handle_9 -exc10: excx exception_handle_10 -exc11: excx exception_handle_11 -exc12: excx exception_handle_12 -exc13: excx exception_handle_13 -exc14: excx exception_handle_14 -exc15: excx exception_handle_15 -exc16: excx exception_handle_16 -exc17: excx exception_handle_17 -exc18: excx exception_handle_18 +exc0: excx $0 exception_handle +exc1: excx $1 exception_handle +exc2: excx $2 exception_handle +exc3: excx $3 exception_handle +exc4: excx $4 exception_handle +exc5: excx $5 exception_handle +exc6: excx $6 exception_handle +exc7: excx $7 exception_handle +exc8: excx $8 exception_handle +exc9: excx $9 exception_handle +exc10: excx $10 exception_handle +exc11: excx $11 exception_handle +exc12: excx $12 exception_handle +exc13: excx $13 exception_handle +exc14: excx $14 exception_handle +exc15: excx $15 exception_handle +exc16: excx $16 exception_handle +exc17: excx $17 exception_handle +exc18: excx $18 exception_handle diff --git a/asm/asm_mp.asm b/asm/asm_mp.asm index c4eb4a9..a2dcee0 100644 --- a/asm/asm_mp.asm +++ b/asm/asm_mp.asm @@ -1,7 +1,8 @@ global smp_start +global LLOCK extern smp_main + ; master boot record for application processors -;[org 0x7000] smp_start: [bits 16] @@ -41,6 +42,9 @@ boot_32_pm: cmp eax,1 je boot_32_pm + mov ebp, 0x7000 + mov esp, ebp + call smp_main jmp $ ; should never be reached diff --git a/asm/asm_x86.s b/asm/asm_x86.s index 35052b1..3481ec2 100644 --- a/asm/asm_x86.s +++ b/asm/asm_x86.s @@ -123,9 +123,9 @@ set_cr4: ret x86_xchg: - mov 8(%esp), %eax // addr - mov 4(%esp), %edx // value - xchg %edx, (%eax) //LOCK protocol impemented anyway + mov 8(%esp), %eax // value + mov 4(%esp), %edx // addr + xchg %eax, (%edx) //LOCK protocol impemented anyway ret x86_invlpg: diff --git a/driver/serial.c b/driver/serial.c index 8a5dd2e..4e43251 100644 --- a/driver/serial.c +++ b/driver/serial.c @@ -1,6 +1,5 @@ -#include "driver/serial.h" - -#include "asm_x86.h" // provides x86_inb() and x86_outb() +#include "serial.h" +#include "asm_x86.h" // provides x86_inb() and x86_outb() /** COM1 Port */ static const PORT=0x3f8; diff --git a/kernel/acpi.c b/kernel/acpi.c index 084c193..f5c18ca 100644 --- a/kernel/acpi.c +++ b/kernel/acpi.c @@ -62,7 +62,7 @@ uint8_t *apci_get_next_entry(uint8_t *addr,smp_processors *procdata) if(*addr==0) { - klog("MADT Entry: LocalAPIC ()"); + klog("Type 0: LocalAPIC (enabled=%d)",addr[4]&1); // usable if(addr[4]&1) { @@ -78,10 +78,18 @@ uint8_t *apci_get_next_entry(uint8_t *addr,smp_processors *procdata) } else if(*addr==1) { - klog("MADT Entry: IO APIC 0x%08X",addr[4]); + klog("Type 1: IO APIC (id=%d) (addr=0x%08X) (base=%d)",addr[2], *((uint32_t*)&addr[4]),*((uint32_t*)&addr[8])); } - else if(*addr==2)klog("MADT Entry: Interrupt Source Override"); - else klog("MADT Entry: type:0x%X",*addr); + else if(*addr==2){ + klog("Type 2: Interrupt Source Override (bus src=%d) (irq src=%d) (global=%d) (flags=%d)",addr[2],addr[3],*((uint32_t*)&addr[4]),*((uint16_t*)&addr[8])); + + } + else if(*addr==4){ + klog("Type 4: Non-maskable interrupts (proc id=%d) (flags=%d) (LINT#=%d)",addr[2],*((uint16_t*)&addr[3]),addr[5]); + + } + else if(*addr==5){kpanic("Entry Type 5 : Local APIC Address Override. 64-bit address??");} + else kpanic("MADT Entry: type:0x%X",*addr); return addr+addr[1]; } @@ -102,14 +110,14 @@ void acpi_check_madt(uint32_t *madt,smp_processors *procdata) entry+=sizeof(acpi_madt); procdata->local_apic_address=table->apic_local; + klog("Local Apic Address: 0x%08X",table->apic_local); procdata->flags=table->flags; + klog("Flags (Dual 8259): %d",table->flags); while(entry<end) { entry=apci_get_next_entry(entry,procdata); } - - } } diff --git a/kernel/interrupts.c b/kernel/interrupts.c index 501ccd4..4eb2a35 100644 --- a/kernel/interrupts.c +++ b/kernel/interrupts.c @@ -94,68 +94,102 @@ void errlog(uint32_t error_code) klog("error_code: 0x%08X",error_code); } -void defklog(uint32_t eip, uint16_t cs, uint32_t flags) +void defklog(uint32_t esp) { - klog("eip: 0x%08X",eip); - klog("segment: 0x%08X",cs); - klog("eflags: 0x%08X",flags); + klog("EXCEPTION: eip: 0x%08X",*(uint32_t *)esp); + esp+=4; + klog("EXCEPTION: segment: 0x%08X",*(uint16_t *)esp); + esp+=4; + klog("EXCPETION: eflags: 0x%08X",*(uint32_t *)esp); } -void show_error(uint32_t err) +void show_selector_error(uint32_t err) { - klog("interrupt error code: 0x%08x",err); - klog("External Event: %x",err&0b001); + klog("Selector Error Details:"); + klog("External Event: %x",err&0b1); klog("Location: %x",err&0b110); klog("Selector: %x",err&0b1111111111111000); } -// - -void int_default() +void show_page_fault_error(uint32_t error_code) { - klog("default handler"); - kpanic("unhandled interrupt (is this a panic or should just iognore?)"); -} - -void exception_handle_0(){ kpanic("Divide by 0"); } -void exception_handle_1(){ kpanic("Single step (debugger)"); } -void exception_handle_2(){ kpanic("Non Maskable Interrupt"); } -void exception_handle_3(){ kpanic("Breakpoint (debugger)"); } -void exception_handle_4(){ kpanic("Overflow"); } -void exception_handle_5(){ kpanic("Bounds check"); } -void exception_handle_6(){ kpanic("Undefined OP Code"); } -void exception_handle_7(){ kpanic("No coprocessor"); } -void exception_handle_8(){ kpanic("Double Fault"); } -void exception_handle_9(){ kpanic("Coprocessor Segment Overrun"); } -void exception_handle_10(){ kpanic("Invalid TSS"); } -void exception_handle_11(){ kpanic("Segment Not Present"); } -void exception_handle_12(){ kpanic("Stack Segment Overrun"); } - -void exception_handle_13(uint32_t error_code,uint32_t eip,uint16_t cs,uint16_t unused, uint32_t flags) -{ - errlog(error_code); - defklog(eip,cs,flags); - - kpanic("Exception: Fault: General Protection Fault"); + klog("Page Fault Error Details:"); + klog("error_code_P (Present): %d",error_code&1?1:0); + klog("error_code_W/R (Write): %d",error_code&2?1:0); + klog("error_code_U/S (User): %d",error_code&4?1:0); + klog("error_code_RSVD (Reserved Write) : %d",error_code&8?1:0); + klog("error_code_I/D (Instruction Fetch): %d",error_code&16?1:0); + klog("at addr: 0x%08X",x86_get_cr(2)); } -void exception_handle_14(uint32_t error_code,uint32_t eip,uint16_t cs,uint16_t unused, uint32_t flags) +void exception_handle(uint32_t esp, uint32_t irq) { - errlog(error_code); - klog("error_code_P: %d",error_code&1?1:0); - klog("error_code_W/R: %d",error_code&2?1:0); - klog("error_code_U/S: %d",error_code&4?1:0); - klog("error_code_RSVD: %d",error_code&8?1:0); - klog("error_code_I/D: %d",error_code&16?1:0); - klog("at addr: 0x%08X",x86_get_cr(2)); - defklog(eip,cs,flags); - kpanic("Exception: Fault: Page Fault"); + uint32_t error_code=0; + + klog("EXCEPTION: vector nr.: %d",irq); + + switch(irq){ //this interrupts push also an error_code + case 8: + case 10: + case 11: + case 12: + case 13: + case 14: + case 17: + case 30: + error_code = *(uint32_t *)esp; + esp+=4; + } + klog("EXCEPTION: error_code: %d",irq); + defklog(esp); + + switch(irq){ + case 0: + kpanic("Divide by 0"); + case 1: + kpanic("Single step (debugger)"); + case 2: + kpanic("Non Maskable Interrupt"); + case 3: + kpanic("Breakpoint (debugger)"); + case 4: + kpanic("Overflow"); + case 5: + kpanic("Bounds check"); + case 6: + kpanic("Undefined OP Code"); + case 7: + kpanic("No coprocessor"); + case 8: + kpanic("Double Fault"); + case 9: + kpanic("Coprocessor Segment Overrun"); + case 10: + show_selector_error(error_code); + kpanic("Invalid TSS"); + case 11: + show_selector_error(error_code); + kpanic("Segment Not Present"); + case 12: + show_selector_error(error_code); + kpanic("Stack Segment Overrun"); + case 13: + show_selector_error(error_code); + kpanic("Exception: Fault: General Protection Fault"); + case 14: + show_page_fault_error(error_code); + kpanic("Exception: Fault: Page Fault"); + case 15: + kpanic("RESERVED"); + case 16: + kpanic("Coprocessor error"); + case 17: + kpanic("Alignment Check"); + case 18: + kpanic("Machine Check"); + } } -void exception_handle_15(){ kpanic("Unassigned"); } -void exception_handle_16(){ kpanic("Coprocessor error"); } -void exception_handle_17(){ kpanic("Alignment Check"); } -void exception_handle_18(){ kpanic("Machine Check"); } // set default handler for all interrupts for a start void interrupts_init(uint16_t sel) diff --git a/kernel/kernel.c b/kernel/kernel.c index bf6910d..493fb93 100644 --- a/kernel/kernel.c +++ b/kernel/kernel.c @@ -1,5 +1,4 @@ #include <stdint.h> - #include "kernel/kernel.h" #include "kernel/mem.h" diff --git a/kernel/kernel.h b/kernel/kernel.h index f73c116..4c480e5 100644 --- a/kernel/kernel.h +++ b/kernel/kernel.h @@ -18,6 +18,7 @@ #define KMALLOC_MEM_SIZE 1024*1024*8 // 8MB for in kernel-memory #define NUMBER_SPINLOCKS 16 +#define SPINLOCK_LOG 0 #define S1(x) #x #define S2(x) S1(x) diff --git a/kernel/log.c b/kernel/log.c index c7c1bb7..b0eeab5 100644 --- a/kernel/log.c +++ b/kernel/log.c @@ -1,8 +1,12 @@ #include "log.h" +#include "kernel.h" + #include <stdarg.h> #include <stdbool.h> +#include "spinlock.h" + #include "kernel/kernel.h" #include "kernel/fifo.h" #include "driver/serial.h" @@ -43,7 +47,9 @@ void log(char *module_name, int prio, char *format_string, ...) tfp_sprintf(buf_log,"\033[36;40m%s\033[31;40m %s:\033[37;40m %s\n",buf_time,module_name,buf_info); + spinlock_spin(SPINLOCK_LOG); log_string(buf_log); + spinlock_release(SPINLOCK_LOG); } /* diff --git a/kernel/smp.c b/kernel/smp.c index 4aff013..ea926ca 100644 --- a/kernel/smp.c +++ b/kernel/smp.c @@ -20,29 +20,40 @@ volatile uint8_t proc; uint32_t cpu_counter[SMP_MAX_PROC]; uint32_t local_apic_addr; +extern uint32_t LLOCK; void smp_main() { + uint32_t ebp=kballoc(1); + asm volatile("mov %0, %%ebp"::"r"(ebp)); + asm volatile("mov %ebp, %esp"); + asm volatile("jmp kernel_ap"); +} -// klog("local apic_addr:0x%08X",local_apic_addr); +void kernel_ap() +{ + LLOCK=0; - // // uint32_t *reg=local_apic_addr+FOOLOS_APIC_ID; - //klog("local apic id: 0x%08X",(*reg)); + uint32_t *reg; + reg=local_apic_addr+FOOLOS_APIC_ID; + klog("smp local apic id: %d",(*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 int_install(); - + x86_sti(); - - - while(1)__asm__("hlt"); + while(1){ + klog("%d",*reg); + for(int i=0;i<1000000000;i++); + } // switch_to_user_mode(); // int x=1/0; + /* while(1); @@ -54,10 +65,11 @@ void smp_main() proc=c1=c2=c3=0; for(int i=0;i<SMP_MAX_PROC;i++)cpu_counter[i]=0; + */ } -void kernel_ap() +void kernel_ap_old() { proc++; uint8_t p=proc; diff --git a/kernel/spinlock.c b/kernel/spinlock.c index 03efa6e..b7ff6b7 100644 --- a/kernel/spinlock.c +++ b/kernel/spinlock.c @@ -1,26 +1,17 @@ #include "spinlock.h" - #include "kernel.h" #include "asm_x86.h" - static volatile uint32_t spinlocks[NUMBER_SPINLOCKS]; -void check_spinlocks() -{ - klog("Spinlocks at 0x%08X ",spinlocks); - for(int i=0;i<NUMBER_SPINLOCKS;i++) - klog("%d",spinlocks[i]); -} - -void lock_spin(uint32_t i) +void spinlock_spin(uint32_t i) { uint32_t *addr=spinlocks+i; while(x86_xchg(addr,1)); } -void lock_release(uint32_t i) +void spinlock_release(uint32_t i) { uint32_t *addr=spinlocks+i; asm("movb $0,%0"::"m"(*addr)); diff --git a/kernel/spinlock.h b/kernel/spinlock.h index 8ce2f57..daa1a50 100644 --- a/kernel/spinlock.h +++ b/kernel/spinlock.h @@ -1,6 +1,14 @@ /* * @file * + * Spinlock + * ======== + * + * Use this locks only for very short time! + * + * + * Ref + * --- * https://gcc.gnu.org/onlinedocs/gcc/_005f_005fatomic-Builtins.html */ @@ -9,7 +17,7 @@ #include <stdint.h> -void lock_spin(spinlock); -void lock_release(spinlock); +void spinlock_spin(uint32_t num); +void spinlock_release(uint32_t num); #endif diff --git a/userspace/exception.c b/userspace/exception.c new file mode 100644 index 0000000..4f72c86 --- /dev/null +++ b/userspace/exception.c @@ -0,0 +1,4 @@ +int main() +{ + return 10/0; +} |
