diff options
Diffstat (limited to 'kernel')
| -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 |
4 files changed, 68 insertions, 41 deletions
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); } + |
