diff options
| author | Miguel <m.i@gmx.at> | 2018-09-08 17:08:55 +0200 |
|---|---|---|
| committer | Miguel <m.i@gmx.at> | 2018-09-08 17:08:55 +0200 |
| commit | 9fde748acea83d775e367a64858414b674f05b13 (patch) | |
| tree | 0927b570c07c9ee469817a560b965c094c5d8145 | |
| parent | aa4b4c6c1918a51318709761873d1c5e248a831d (diff) | |
struggling with pic and lapic and smp...
| -rw-r--r-- | asm/asm_int.h | 1 | ||||
| -rw-r--r-- | asm/asm_int.s | 2 | ||||
| -rw-r--r-- | asm/asm_mp.asm | 16 | ||||
| -rw-r--r-- | asm/asm_pic.asm | 1 | ||||
| -rw-r--r-- | asm/asm_pit.h | 3 | ||||
| -rw-r--r-- | asm/asm_pit.s | 66 | ||||
| -rw-r--r-- | asm/asm_start.s | 2 | ||||
| -rw-r--r-- | driver/timer.c | 3 | ||||
| -rw-r--r-- | kernel/gdt.c | 11 | ||||
| -rw-r--r-- | kernel/interrupts.c | 26 | ||||
| -rw-r--r-- | kernel/kernel.c | 59 | ||||
| -rw-r--r-- | kernel/kernel.h | 2 | ||||
| -rw-r--r-- | kernel/scheduler.c | 11 | ||||
| -rw-r--r-- | kernel/smp.c | 119 | ||||
| -rw-r--r-- | kernel/vmem.c | 59 | ||||
| -rw-r--r-- | kernel/vmem.h | 3 |
16 files changed, 261 insertions, 123 deletions
diff --git a/asm/asm_int.h b/asm/asm_int.h index 25ab885..465b08b 100644 --- a/asm/asm_int.h +++ b/asm/asm_int.h @@ -18,6 +18,7 @@ void int15(); void int128(); // syscalls void int129(); // scheduler void int200(); // apic timer +void int170(); // smp scheduler void int255(); // unhandled void exc0(); diff --git a/asm/asm_int.s b/asm/asm_int.s index f7107de..70993b4 100644 --- a/asm/asm_int.s +++ b/asm/asm_int.s @@ -19,6 +19,7 @@ .global int128 .global int129 .global int200 +.global int170 .global int255 .global exc0 @@ -159,6 +160,7 @@ int129: intx ack0 $129 interrupt_handler int255: intx ack0 $255 interrupt_handler int200: intx ack0 $200 interrupt_handler +int170: intx ack0 $170 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 5e5259e..165dc97 100644 --- a/asm/asm_mp.asm +++ b/asm/asm_mp.asm @@ -1,7 +1,8 @@ global smp_start -global LLOCK extern smp_main global gdt_descriptor +global asm_smp_unlock + ; master boot record for application processors smp_start: @@ -20,7 +21,12 @@ smp_start: [bits 32] -LLOCK: dd 0 +LLOCK: dd 1 + +asm_smp_unlock: + mov eax, 0x0 + mov [LLOCK], eax + ret init_pm: @@ -31,7 +37,7 @@ init_pm: mov fs, ax mov gs, ax - mov ebp, 0x7000 + mov ebp, 0x7000 ;temporary stack mov esp, ebp call boot_32_pm ;continue booting in 32-bit protected mode @@ -46,11 +52,11 @@ boot_32_pm: mov ebp, 0x7000 mov esp, ebp - call smp_main + and esp,-16 ; padding to align stack on 16byte boundary before CALL + call smp_main jmp $ ; should never be reached - gdt_start: gdt_null: ;null descriptor (2 x 4 bytes) diff --git a/asm/asm_pic.asm b/asm/asm_pic.asm index 901f854..2514be7 100644 --- a/asm/asm_pic.asm +++ b/asm/asm_pic.asm @@ -74,7 +74,6 @@ in al, 0x21 ; read in the primary PIC Interrupt Mask Register (IMR) and al, 0x00 ; 0xEF => 11101111b. This sets the IRQ4 bit (Bit 5) in AL out 0x21, al ; write the value back into IMR - 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 diff --git a/asm/asm_pit.h b/asm/asm_pit.h index d020de1..58067bf 100644 --- a/asm/asm_pit.h +++ b/asm/asm_pit.h @@ -15,9 +15,6 @@ #include <stdint.h> -/** Init PIT - 25 times a second*/ -void asm_pit_init(); - /** install this interrupt handler to your Interrupt Vector Table */ void asm_pit_tick(); diff --git a/asm/asm_pit.s b/asm/asm_pit.s index 8e16d0b..8be29cb 100644 --- a/asm/asm_pit.s +++ b/asm/asm_pit.s @@ -1,7 +1,16 @@ -.global asm_pit_init .global asm_pit_tick .global asm_pit_get_ticks +.global asm_pit_sleep_50ms +.global asm_pit_sleep_40ms +.global asm_pit_sleep_10ms +.global asm_pit_sleep_1ms + +.global asm_pit_rate_50ms +.global asm_pit_rate_40ms +.global asm_pit_rate_10ms +.global asm_pit_rate_1ms + ticks: .int 0 @@ -22,19 +31,62 @@ asm_pit_tick: ret -asm_pit_init: +.macro asm_pit_rate val - // configure ticking 25 times a second - // 1193180 / 25 = 47727.2 - mov $47727, %dx - mov $0b00110100, %al + mov $0b00110100, %al // chan 0 / mode 2 outb %al,$0x43 - mov %dx,%ax + // LSB first + mov \val, %dx + out %al, $0x40 + xchg %ah,%al + out %al, $0x40 + + ret + +.endm + +.macro asm_pit_sleep val + mov $0x00110000, %al // chan 0 / mode 0 + outb %al,$0x43 + + // LSB first + mov \val, %ax 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 + sleep\val: + inb $0x40, %al + or $0b1000000, %al + cmp $0b1000000, %al + jne sleep\val ret + +.endm + +/* decrements at 1.193182Mhz +0xE90B // 50ms - 20 Hz +0xBA6F // 40ms - 25 Hz +0x2E9C // 10ms - 100 Hz +0x04A9 // 1ms - 1000 Hz +*/ + +asm_pit_sleep_50ms: asm_pit_sleep $0xE90B +asm_pit_sleep_40ms: asm_pit_sleep $0xBA6F +asm_pit_sleep_10ms: asm_pit_sleep $0x2E9C +asm_pit_sleep_1ms: asm_pit_sleep $0x04A9 + +asm_pit_rate_50ms: asm_pit_rate $0xE90B +asm_pit_rate_40ms: asm_pit_rate $0xBA6F +asm_pit_rate_10ms: asm_pit_rate $0x2E9C +asm_pit_rate_1ms: asm_pit_rate $0x04A9 diff --git a/asm/asm_start.s b/asm/asm_start.s index e961ef6..8f0cf1e 100644 --- a/asm/asm_start.s +++ b/asm/asm_start.s @@ -20,7 +20,7 @@ .section .smp .code16 _start_smp: -call smp_start # TODO: align later before going C +call smp_start # Declare a header as in the Multiboot Standard. We put this into a special # section so we can force the header to be in the start of the final program. diff --git a/driver/timer.c b/driver/timer.c index 3a8c31c..d30a299 100644 --- a/driver/timer.c +++ b/driver/timer.c @@ -1,4 +1,3 @@ - #include "timer.h" #include "asm_x86.h" @@ -152,7 +151,7 @@ uint64_t timer_init() { uint64_t epoch_time=get_rtc_time(); task_system_clock_start=epoch_time*25; // since pit ticks 25times a second - asm_pit_init(); + asm_pit_rate_40ms(); return epoch_time; } diff --git a/kernel/gdt.c b/kernel/gdt.c index c91524a..0657387 100644 --- a/kernel/gdt.c +++ b/kernel/gdt.c @@ -9,12 +9,12 @@ //https://wiki.osdev.org/Task_State_Segment tss_struct sys_tss[SMP_MAX_PROC]; //Define the TSS as a global structure -void install_tss(uint32_t esp0){ +void install_tss(uint32_t cpu,uint32_t esp0){ // now fill each value // set values necessary - sys_tss[0].ss0 = 0x10; //kernel data - sys_tss[0].esp0 = esp0; + sys_tss[cpu].ss0 = 0x10; //kernel data + sys_tss[cpu].esp0 = esp0; // now set the IO bitmap (not necessary, so set above limit) // sys_tss.iomap = ( unsigned short ) sizeof( tss_struct ); @@ -135,7 +135,7 @@ void gdt_init() myGDT[4].type=0xF2; //TSS 0x28 - myGDT[5].base=&sys_tss[last_cpu++]; //tss start + myGDT[5].base=&sys_tss[last_cpu]; //tss start myGDT[5].limit=sizeof(tss_struct); //tss end myGDT[5].type=0x89; @@ -144,7 +144,8 @@ void gdt_init() encodeGdtEntry(&gdt_struct[8*i],myGDT[i]); // update tss entry - install_tss(0); + install_tss(last_cpu,0); + last_cpu++; setup_gdt(gdt_struct); diff --git a/kernel/interrupts.c b/kernel/interrupts.c index f93de9e..acf781d 100644 --- a/kernel/interrupts.c +++ b/kernel/interrupts.c @@ -57,12 +57,19 @@ void int_install() 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()); if(irq==0)asm_pit_tick(); // mouse and kb if(irq==1 || irq==12 ){ uint32_t in=x86_inb(0x60); - if(irq=1)keyboard_handle(in); // do this in separate thread! + if(irq==1)keyboard_handle(in); // do this in separate thread! + // TODO: mouse + + // test ipi + apicIPI(2,170); // klog("0x60 in %d",in); } @@ -83,11 +90,14 @@ 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==200){ // apic timer + apicEOI(); } if(irq==255)kpanic("Unhandled Interrupt!"); + if(irq==170){ +// if(apicID()!=0)apicIPI(0,170); + apicEOI(); + } return esp; } @@ -130,6 +140,7 @@ void exception_handle(uint32_t esp, uint32_t irq) { uint32_t error_code=0; + klog("EXCEPTION: apicID: 0x%08X",apicID()); klog("EXCEPTION: vector nr.: %d",irq); switch(irq){ //this interrupts push also an error_code @@ -198,10 +209,6 @@ void exception_handle(uint32_t esp, uint32_t irq) // set default handler for all interrupts for a start void interrupts_init(uint16_t sel) { - // Setup PIC - klog("setting up PIC",&idt,&idtd); - asm_pic_setup(); - klog("initializing. IDT: 0x%08x, IDTD: 0x%08X",&idt,&idtd); // Default interrupt handling @@ -250,6 +257,9 @@ void interrupts_init(uint16_t sel) // Wake Scheduler int_install_ir(0x81, 0b11101110, 0x08,&int129); + // Wake SMP Scheduler + int_install_ir(0xAA, 0b11101110, 0x08,&int170); + // APIC Timer int_install_ir(200, 0b11101110, 0x08,&int200); diff --git a/kernel/kernel.c b/kernel/kernel.c index 30949f8..17bf9b7 100644 --- a/kernel/kernel.c +++ b/kernel/kernel.c @@ -25,9 +25,13 @@ void kernel_main(uint32_t eax,uint32_t ebx) serial_init(); klog("FOOL-OS ver-%s (%s)",GIT_REVISION,__DATE__); - klog("Programmable Interval Timer (PIT) init ..."); - uint64_t unixtime=timer_init(); - klog("Unix Time = %u seconds)",unixtime); + // while(1); + + klog("Interrupt Vector Table (IVT) init ..."); + interrupts_init(0x08); + + klog("Setting up PIC"); + asm_pic_setup(); klog("Keyboard init ..."); keyboard_init(0); @@ -44,30 +48,19 @@ void kernel_main(uint32_t eax,uint32_t ebx) klog("Memory init ... "); uint32_t kernel_blocks=mem_init(info); - - klog("Ram Filesystem init ... "); - fs_mount(info); - - 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!"); + if(!acpi_find(&procdata)) + if(!mp_find(&procdata))kpanic("No ACPI and no MP found!"); - // Start the other Processors (before paging because apic addr etc..?) - //TODO: remap apic !!! Check commented out sleep ()!!! - klog("Symmetric Multi Processing (SMP) start ... "); - smp_log_procdata(&procdata); - smp_start_aps(&procdata); - + // 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); - - klog("Peripheral Component Interconnet (PCI) init ... "); - pci_init(); + pdirectory *dir=vmem_init(kernel_blocks,(uint32_t)info->framebuffer_addr,procdata.local_apic_address); + klog("Ram Filesystem init ... "); + fs_mount(info); + klog("Video Electronics Standards Association (VESA) init ... "); // TODO check if text or fb? uint32_t addr=kballoc(1); fs_content("/binfont.bin",addr,0x100); // copy font (0x100 bytes) to memory. @@ -78,6 +71,26 @@ void kernel_main(uint32_t eax,uint32_t ebx) uint32_t sstdout = syscall_open("term",0,0); // stdout 1 uint32_t sstderr = syscall_open("stderr",0,0); // stderr 2 - klog("Enable Interrupts & Start Scheduling ..."); + klog("Scheduler init ..."); scheduler_init(dir); + + klog("Symmetric Multi Processing (SMP) start ... "); + smp_start_aps(&procdata); + + klog("Programmable Interval Timer (PIT) init ..."); + uint64_t unixtime=timer_init(); + klog("Unix Time = %u seconds)",unixtime); + + klog("Setting Interrupt Flag on BSP ..."); + 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 ... "); + + while(1){ // now just wait until our scheduler kicks in. +// klog("bsp"); + asm("hlt"); + } } diff --git a/kernel/kernel.h b/kernel/kernel.h index e1a33d2..c2befbd 100644 --- a/kernel/kernel.h +++ b/kernel/kernel.h @@ -30,6 +30,4 @@ #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__) -//#define klog(...) __asm__("nop") - #endif diff --git a/kernel/scheduler.c b/kernel/scheduler.c index 1cbd658..72165f9 100644 --- a/kernel/scheduler.c +++ b/kernel/scheduler.c @@ -159,11 +159,12 @@ volatile uint32_t my_scheduler(uint32_t oldesp,uint32_t force_pid) if(!first) task_list[current_task].esp=oldesp; first=false; // + if(force_pid>-1) { int pid=force_pid; current_task=pid; - install_tss(task_list[pid].esp0); + install_tss(0,task_list[pid].esp0); x86_set_page_directory(task_list[pid].vmem); return task_list[pid].esp; @@ -178,7 +179,7 @@ volatile uint32_t my_scheduler(uint32_t oldesp,uint32_t force_pid) //if(current_task!=pid)klog("switch from %d to %d", current_task, pid); current_task=pid; - install_tss(task_list[pid].esp0); + install_tss(0,task_list[pid].esp0); x86_set_page_directory(task_list[pid].vmem); return task_list[pid].esp; @@ -270,12 +271,6 @@ volatile void scheduler_init(void *dir) task_pusha(task_list[2].esp); // task_pusha(task_list[1].esp); task_pusha(task_list[0].esp); - - // finally enable interrrupts so the scheduler is called (by timer) - x86_sti(); - - // loop until scheduler kicks in and reschedules us... - while(1); } volatile int task_get_current_pid() diff --git a/kernel/smp.c b/kernel/smp.c index 3709ed5..da91148 100644 --- a/kernel/smp.c +++ b/kernel/smp.c @@ -11,11 +11,6 @@ #include "spinlock.h" #include "asm_x86.h" -#define FOOLOS_APIC_SPUR_INT 0x00f0 -#define FOOLOS_APIC_INT_COMMAND_LOW 0x0300 -#define FOOLOS_APIC_INT_COMMAND_HIGH 0x0310 -#define FOOLOS_APIC_ID 0x020 - #define APIC_APICID 0x20 #define APIC_APICVER 0x30 #define APIC_TASKPRIOR 0x80 @@ -48,16 +43,6 @@ volatile uint8_t proc; uint32_t cpu_counter[SMP_MAX_PROC]; uint32_t local_apic_addr; -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) { @@ -74,33 +59,59 @@ uint32_t readAPIC(uint32_t offset) return value; } -void kernel_ap() +uint32_t apicID() { + return readAPIC(APIC_APICID); +} - uint32_t *reg; - reg=local_apic_addr+FOOLOS_APIC_ID; - klog("smp local apic id: 0x%08X",(*reg)); +void apicEOI() +{ + writeAPIC(0xB0,0); +} - reg=local_apic_addr+FOOLOS_APIC_SPUR_INT; - klog("svr value: 0x%08X",(*reg)); - *reg|=0x100; // enable APIC +void apicIPI(uint8_t dest, uint8_t number) +{ + writeAPIC(APIC_ICRH,dest<<24); // destination apic bits 24-27 + writeAPIC(APIC_ICRL,number | (1<<14)); // send ipi +} + +void apicEnable() +{ + writeAPIC(APIC_SPURIOUS,readAPIC(APIC_SPURIOUS)|0x100); + +} + +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 kernel_ap() +{ + klog("smp local apic id: 0x%08X",apicID()); + apicEnable(); int_install(); gdt_init(); - - uint32_t countdown=0x0fffffff; + + 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); - x86_sti(); - LLOCK=0; // release lock, so next ap can continue... + + asm_smp_unlock(); while(1) { asm("hlt"); - klog("tack: 0x%08X: 0x%08X",readAPIC(FOOLOS_APIC_ID), readAPIC(APIC_TMRCURRCNT)); + klog("tack: 0x%08X: 0x%08X",readAPIC(APIC_APICID), readAPIC(APIC_TMRCURRCNT)); } // switch_to_user_mode(); @@ -135,30 +146,13 @@ void kernel_ap_old() } } -void smp_log_procdata(smp_processors *procdata) -{ - klog("---- smp -----"); - for(int i=0;i<procdata->processors;i++) - { - klog("cpu %d, apic_id: 0x%X, bps: %s, 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) { - - // TODO: check if local APIC is present via CPUID (P6 (i686) and above) + // 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 -// uint32_t *reg=local_apic_addr+FOOLOS_APIC_SPUR_INT; -// *reg=0xffffffff; // all bits 1 and interrupt 255 (is this not set anyway?) -// *reg=0; - - uint32_t *reg=local_apic_addr+FOOLOS_APIC_ID; - klog("bsp local apic id: 0x%08X",(*reg)); + klog("bsp local apic id: 0x%08X",apicID()); for(int i=0;i<pros->processors;i++) { @@ -167,18 +161,35 @@ void smp_start_aps(smp_processors *pros) uint8_t dest=pros->local_apic_id[i]; klog("starting cpu %d (dest: %d) ",i,dest); - reg=local_apic_addr+FOOLOS_APIC_INT_COMMAND_HIGH; + uint32_t *reg; + + reg=local_apic_addr+APIC_ICRH; *reg=dest<<24; // destination apic. - reg=local_apic_addr+FOOLOS_APIC_INT_COMMAND_LOW; - *reg=(5<<8)|(1<<14); // 101 INIT + reg=local_apic_addr+APIC_ICRL; + *reg=(5<<8)|(1<<14); // 101 INIT IPI - // do we really neet this? - // TODO!! - // todo: use some real sleep (not implemented yet :( ) - //sleep(30); + // TODO: wait 10 milliseconds + // https://wiki.osdev.org/Symmetric_Multiprocessing - // start proc 0x7 = at addr 0x7000; *reg=(6<<8)|(1<<14)|0x7; // 110 SIPI + // TODO: poll a flag?(timeout 1ms) + // 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); } diff --git a/kernel/vmem.c b/kernel/vmem.c index 1652a9e..6d34a08 100644 --- a/kernel/vmem.c +++ b/kernel/vmem.c @@ -7,6 +7,7 @@ static uint32_t kernel_pages; uint32_t fb_addr; +uint32_t apic_addr; // TODO : why is the frame not 0xfffff?? enum PAGE_PTE_FLAGS @@ -222,7 +223,7 @@ void vmem_free_dir(pdirectory *dir) // programm pages procreates new programmspace // // TODO: FIX -// KERNEL SPACE `kernel_pages` first PAGES +// KERNEL SPACE `kernel_pages` first 8 PAGES = 32megs // FRAMEBUFER WE GET ON INIT // PROGRAMM SPACE HARDCODED TO 0x8000000+2 pages and 0x8c00000+1 pages // @@ -244,6 +245,8 @@ pdirectory* vmem_new_space_dir(pdirectory *copy_dir,bool stack_only) uint32_t phys_addr=0; uint32_t virt_addr=0; + kernel_pages=8; + // first pages are identity mapped for(int j=0;j<kernel_pages;j++) { @@ -346,6 +349,57 @@ pdirectory* vmem_new_space_dir(pdirectory *copy_dir,bool stack_only) virt_addr+=1024*4096; } + // 2 pages for apic ( in case on boundary??) + phys_addr=apic_addr; + virt_addr=apic_addr; + + for(int j=0;j<2;j++) + { + + // this is the table for our page directory. It maps 1024*4096 bytes + ptable* table; + + // create new tables on init + if(copy_dir==NULL) + { + // alloc space for our new table + table = (ptable*) kballoc(1); + if (!table)kpanic("unable to alloc table"); + + //! idenitity mapping + for (int i=0, frame=phys_addr, virt=virt_addr; i<1024; i++, frame+=4096, virt+=4096) + { + //! create a new page + pt_entry page=0; + pt_entry_add_attrib (&page, I86_PTE_PRESENT); + pt_entry_add_attrib (&page, I86_PTE_WRITABLE); + pt_entry_add_attrib (&page, I86_PTE_USER); + pt_entry_set_frame (&page, frame); + + //! ...and add it to the page table + table->m_entries [PAGE_TABLE_INDEX (virt) ] = page; + } + + pd_entry* entry = &dir->m_entries [PAGE_DIRECTORY_INDEX (virt_addr) ]; + *entry=0; + pd_entry_add_attrib (entry, I86_PDE_PRESENT); + pd_entry_add_attrib (entry, I86_PDE_WRITABLE); + pt_entry_add_attrib (entry, I86_PTE_USER); + pd_entry_set_frame (entry, (physical_addr)table); + + } + + // otherwise simply take existing stuff from pdir 0 + else + { + dir->m_entries[PAGE_DIRECTORY_INDEX(virt_addr)]= + copy_dir->m_entries[PAGE_DIRECTORY_INDEX(virt_addr)]; + + } + + phys_addr+=1024*4096; + virt_addr+=1024*4096; + } // programm space virt_addr=0x8000000; for(int j=0;j<2;j++) @@ -478,9 +532,10 @@ pdirectory* vmem_new_space_dir(pdirectory *copy_dir,bool stack_only) return dir; } -pdirectory* vmem_init(uint32_t kernel_blocks, uint32_t frameb_addr) +pdirectory* vmem_init(uint32_t kernel_blocks, uint32_t frameb_addr, uint32_t apic_ad) { fb_addr=frameb_addr; + apic_addr=apic_ad; kernel_pages=kernel_blocks/1024+1; return vmem_new_space_dir(NULL,false); } diff --git a/kernel/vmem.h b/kernel/vmem.h index bfd758e..3a2a8e6 100644 --- a/kernel/vmem.h +++ b/kernel/vmem.h @@ -47,7 +47,6 @@ * */ - //! i86 architecture defines 1024 entries per table--do not change #define PAGES_PER_TABLE 1024 #define PAGES_PER_DIR 1024 @@ -81,4 +80,4 @@ typedef struct pdirectory_struct { pd_entry m_entries[PAGES_PER_DIR]; }pdirectory; -pdirectory* vmem_init(uint32_t kernel_blocks,uint32_t fb_addr); +pdirectory* vmem_init(uint32_t kernel_blocks,uint32_t fb_addr,uint32_t apic_addr); |
