diff options
| -rw-r--r-- | README.md | 2 | ||||
| -rw-r--r-- | asm/asm_pic.asm | 6 | ||||
| -rw-r--r-- | asm/asm_pit.s | 22 | ||||
| -rw-r--r-- | kernel/gdt.c | 5 | ||||
| -rw-r--r-- | kernel/interrupts.c | 2 | ||||
| -rw-r--r-- | kernel/kernel.c | 44 | ||||
| -rw-r--r-- | kernel/smp.c | 58 |
7 files changed, 88 insertions, 51 deletions
@@ -98,6 +98,8 @@ Discontinued Features Todos ----- +* ipxe (network drivers?) +* io_wait? * cpuid (i686) check apic? * lapic / spurious . ioapic * newlib reentrant struct!! diff --git a/asm/asm_pic.asm b/asm/asm_pic.asm index 2514be7..8a90fdf 100644 --- a/asm/asm_pic.asm +++ b/asm/asm_pic.asm @@ -78,6 +78,12 @@ in al, 0xA1 ; read in the primary PIC Interrupt Mask Register (IMR) and al, 0x00 ; 0xEF => 11101111b. This sets the IRQ4 bit (Bit 5) in AL out 0xA1, al ; write the value back into IMR +;disable + +;mov al, 0xff +;out 0xa1, al +;out 0x21, al + ret ;;;;;;;;;;;;;;;;;;;; diff --git a/asm/asm_pit.s b/asm/asm_pit.s index 8be29cb..28fd784 100644 --- a/asm/asm_pit.s +++ b/asm/asm_pit.s @@ -49,7 +49,7 @@ asm_pit_tick: .macro asm_pit_sleep val - mov $0x00110000, %al // chan 0 / mode 0 + mov $0b00110000, %al // chan 0 / mode 0 outb %al,$0x43 // LSB first @@ -57,18 +57,20 @@ asm_pit_tick: out %al, $0x40 xchg %ah,%al out %al, $0x40 - - // check if finished - mov $0xE2, %al - outb %al,$0x43 //sleep until finished - //7th bit determines if finished + //7th bit (0-7) determines if finished sleep\val: - inb $0x40, %al - or $0b1000000, %al - cmp $0b1000000, %al - jne sleep\val + + // read back command + mov $0b11100010, %al + outb %al,$0x43 + + inb $0x40, %al + and $0b10000000, %al + + cmp $0b10000000, %al + jne sleep\val ret diff --git a/kernel/gdt.c b/kernel/gdt.c index 0657387..bf8f203 100644 --- a/kernel/gdt.c +++ b/kernel/gdt.c @@ -7,7 +7,8 @@ #define GDT_SIZE 6 //https://wiki.osdev.org/Task_State_Segment -tss_struct sys_tss[SMP_MAX_PROC]; //Define the TSS as a global structure +//Define the TSS as a global structure, boah TODO: move to own page? +tss_struct sys_tss[SMP_MAX_PROC]; void install_tss(uint32_t cpu,uint32_t esp0){ @@ -19,6 +20,7 @@ void install_tss(uint32_t cpu,uint32_t esp0){ // now set the IO bitmap (not necessary, so set above limit) // sys_tss.iomap = ( unsigned short ) sizeof( tss_struct ); } + typedef struct GDT_struct { uint32_t base; @@ -150,6 +152,7 @@ void gdt_init() 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 acf781d..30d8994 100644 --- a/kernel/interrupts.c +++ b/kernel/interrupts.c @@ -59,7 +59,7 @@ uint32_t interrupt_handler(uint32_t esp, uint32_t irq) { // DO NOT WRITE INSIDE INTERRUPTS!! COZ IT ACQUIRES LOCK AND WE WILL DEADLOCK -// klog("int: %d on 0x%x",irq,apicID()); + //klog("int: %d on 0x%x",irq,apicID()); if(irq==0)asm_pit_tick(); // mouse and kb diff --git a/kernel/kernel.c b/kernel/kernel.c index 17bf9b7..e20d2e1 100644 --- a/kernel/kernel.c +++ b/kernel/kernel.c @@ -25,12 +25,13 @@ void kernel_main(uint32_t eax,uint32_t ebx) serial_init(); klog("FOOL-OS ver-%s (%s)",GIT_REVISION,__DATE__); - // while(1); + klog("Global Descriptor Table (GDT) init ..."); + gdt_init(); klog("Interrupt Vector Table (IVT) init ..."); interrupts_init(0x08); - klog("Setting up PIC"); + klog("Remapping & (not yet Disabling) PIC ..."); asm_pic_setup(); klog("Keyboard init ..."); @@ -39,24 +40,27 @@ void kernel_main(uint32_t eax,uint32_t ebx) klog("Mouse init ..."); mouse_init(); - klog("Global Descriptor Table (GDT) init ..."); - gdt_init(); - - klog("Multiboot Structures init ... "); + // gather some info (before we start paging) + klog("Search / Read Multiboot Structures ... "); multiboot_information *info; info=get_multiboot(eax, ebx); + klog("Search / Read ACPI Structures... "); + smp_processors procdata; + bool acpi_found=acpi_find(&procdata); + + klog("Search / Read MP Structures... "); + smp_processors procdata2; + bool mp_found=mp_find(&procdata2); + // + + // memory management klog("Memory init ... "); uint32_t kernel_blocks=mem_init(info); - klog("Symmetrical Multi Processing (SMP) init ... "); - smp_processors procdata; - if(!acpi_find(&procdata)) - if(!mp_find(&procdata))kpanic("No ACPI and no MP found!"); - - // searching for ACPI etc.. in physical mem has to be performed before that. klog("Vritual Memory / Paging init ... "); pdirectory *dir=vmem_init(kernel_blocks,(uint32_t)info->framebuffer_addr,procdata.local_apic_address); + // klog("Ram Filesystem init ... "); fs_mount(info); @@ -81,16 +85,12 @@ void kernel_main(uint32_t eax,uint32_t ebx) uint64_t unixtime=timer_init(); klog("Unix Time = %u seconds)",unixtime); - klog("Setting Interrupt Flag on BSP ..."); + klog("Enable Interrupts & Unlock application processors ... "); asm_smp_unlock(); - x86_sti(); // this will start processing hardware interrupts. - - // TODO : pray that this is reached BEFORE scheduler kicks in!? - - klog("Unlock application processors ... "); + // TODO : bsp sti needs to happen before ap sti? seriously? why? is this guaranteed now? + // TODO: switch to ioapic + x86_sti(); // this will start processing hardware interrupts - while(1){ // now just wait until our scheduler kicks in. -// klog("bsp"); - asm("hlt"); - } + // now just wait until our scheduler kicks in. + while(1)asm("hlt"); } diff --git a/kernel/smp.c b/kernel/smp.c index da91148..b2ce6b0 100644 --- a/kernel/smp.c +++ b/kernel/smp.c @@ -43,6 +43,7 @@ volatile uint8_t proc; uint32_t cpu_counter[SMP_MAX_PROC]; uint32_t local_apic_addr; +uint32_t countdown; void writeAPIC(uint32_t offset, uint32_t value) { @@ -81,6 +82,35 @@ void apicEnable() } +/** select mode : divisor. + * 0 - 1 + * 1 - 2 + * 2 - 4 + * 3 - 8 + * 4 - 16 + * 5 - 32 + * 6 - 64 + * 7 - 128 + */ + +uint32_t probeBusSpeed(uint32_t sel) +{ + uint32_t div[]={1,2,4,8,16,32,64,128}; + uint32_t reg[]={0b1011,0,1,2,3,0b1000,0b1001,0b1010}; + + uint32_t divisor=div[sel]; + + klog("Probing bus speed for 50ms (div=%d)) ...",divisor); + writeAPIC(APIC_TMRDIV, reg[sel]); + writeAPIC(APIC_TMRINITCNT, 0xFFFFFFFF); +// for(int i=0;i<20;i++) + asm_pit_sleep_50ms(); + //writeAPIC(APIC_LVT_TMR, APIC_LVT_INT_MASKED); //?? + uint32_t ticksInS = 0xFFFFFFFF - readAPIC(APIC_TMRCURRCNT); + ticksInS*=20; // adjust to one full second. + klog("%d MHz (%d Hz) bus speed (ticks=%d)",ticksInS/(1000000/divisor),ticksInS*divisor,ticksInS/20); + return ticksInS*divisor; +} void smp_main() { // setup stack @@ -99,7 +129,6 @@ void kernel_ap() int_install(); gdt_init(); - uint32_t countdown=0x0fffffff; // TODO: calc to be constant, depending on bus speed. (use pit for measurement?) writeAPIC(APIC_TMRDIV, 0x3); writeAPIC(APIC_LVT_TMR, 200 | TMR_PERIODIC); writeAPIC(APIC_TMRINITCNT, countdown); @@ -151,9 +180,18 @@ 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; - klog("bsp local apic id: 0x%08X",apicID()); + apicEnable(); // bsp apic seems to be enabled anyway. + + uint32_t speed=probeBusSpeed(4); // get bus speed (divisor: 16) + + // setup apic timer + countdown=speed/16; // tick once a second + writeAPIC(APIC_TMRDIV, 0x3); // divisor 16 + writeAPIC(APIC_LVT_TMR, 200 | TMR_PERIODIC); // on interrupt 200 + writeAPIC(APIC_TMRINITCNT, countdown); + for(int i=0;i<pros->processors;i++) { if(pros->boot==i)continue; @@ -177,19 +215,5 @@ void smp_start_aps(smp_processors *pros) // TODO retry 110 SIPI with 1s timeout } - - apicEnable(); // bsp seems to be enabled anyway. - - writeAPIC(APIC_TMRDIV, 0x3); - writeAPIC(APIC_TMRINITCNT, 0xFFFFFFFF); - //asm_pit_sleep_1ms(); - //writeAPIC(APIC_LVT_TMR, APIC_LVT_INT_MASKED); //?? - uint32_t ticksInS = 0xFFFFFFFF - readAPIC(APIC_TMRCURRCNT); - - klog("%d MHz bus speed",ticksInS/1000); - - uint32_t countdown=0x0fffffff; // TODO: calc to be constant, depending on bus speed. (use pit for measurement?) - writeAPIC(APIC_TMRDIV, 0x3); - writeAPIC(APIC_LVT_TMR, 200 | TMR_PERIODIC); - writeAPIC(APIC_TMRINITCNT, countdown); } + |
