diff options
| -rw-r--r-- | driver/timer.c | 2 | ||||
| -rw-r--r-- | kernel/acpi.c | 3 | ||||
| -rw-r--r-- | kernel/apic.c | 169 | ||||
| -rw-r--r-- | kernel/apic.h | 42 | ||||
| -rw-r--r-- | kernel/exceptions.c | 3 | ||||
| -rw-r--r-- | kernel/interrupts.c | 5 | ||||
| -rw-r--r-- | kernel/kernel.c | 14 | ||||
| -rw-r--r-- | kernel/kernel.h | 2 | ||||
| -rw-r--r-- | kernel/smp.c | 211 | ||||
| -rw-r--r-- | kernel/smp.h | 14 | ||||
| -rw-r--r-- | kernel/vmem.c | 3 |
11 files changed, 259 insertions, 209 deletions
diff --git a/driver/timer.c b/driver/timer.c index 34e7637..7e95afe 100644 --- a/driver/timer.c +++ b/driver/timer.c @@ -154,7 +154,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_rate_40ms(); - fixme("pit rate does not work anymore 1/25 seconds??" ); + fixme("pit rate once did not work anymore 1/25 seconds?? but now ok?" ); return epoch_time; } diff --git a/kernel/acpi.c b/kernel/acpi.c index f424312..67f31fb 100644 --- a/kernel/acpi.c +++ b/kernel/acpi.c @@ -57,6 +57,7 @@ static uint8_t *apci_get_next_entry(uint8_t *addr,acpi_information *procdata) if(*addr==0) { klog("Type 0: LocalAPIC (enabled=%d) (id=0x%08X)",addr[4]&1,addr[3]); + // usable if(addr[4]&1) { @@ -74,10 +75,10 @@ static uint8_t *apci_get_next_entry(uint8_t *addr,acpi_information *procdata) { klog("Type 1: IO APIC (id=%d) (addr=0x%08X) (base=%d)",addr[2], *((uint32_t*)&addr[4]),*((uint32_t*)&addr[8])); procdata->io_apic_address=*((uint32_t*)&addr[4]); + fixme("support multiple IO Apics and consider interrupt source overrides during irq config!"); } 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]); diff --git a/kernel/apic.c b/kernel/apic.c new file mode 100644 index 0000000..a670208 --- /dev/null +++ b/kernel/apic.c @@ -0,0 +1,169 @@ +#include "kernel.h" +#include "apic.h" +#include "interrupts.h" +#include "asm_pit.h" + +#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) + +static uint32_t local_apic_addr; +static uint32_t io_apic_addr; +static uint32_t bus_speed; + +static void ioapic_write(uint32_t offset, uint32_t value) +{ + uint32_t *reg=io_apic_addr; + reg[0]=(offset & 0xff); + reg[4]= value; +} + +static uint32_t ioapic_read(uint32_t offset) +{ + uint32_t *reg=io_apic_addr; + reg[0]=(offset & 0xff); + return reg[4]; +} + +static void ioapic_config_entry(uint32_t irq, uint32_t low, uint32_t high) +{ + ioapic_write(0x10+irq*2,low); + ioapic_write(0x11+irq*2,high); +} + +static void apic_write(uint32_t offset, uint32_t value) +{ + uint32_t *reg; + reg=local_apic_addr+offset; + *reg=value; +} + +static uint32_t apic_read(uint32_t offset) +{ + uint32_t *reg; + reg=local_apic_addr+offset; + uint32_t value=*reg; + return value; +} + +uint32_t apic_id() +{ + return apic_read(APIC_APICID)>>24; +} + +void apic_eoi() +{ + apic_write(0xB0,0); +} + +void apic_ipi(uint8_t dest, uint8_t number) +{ + apic_write(APIC_ICRH,dest<<24); // destination apic bits 24-27 + apic_write(APIC_ICRL,number | (1<<14)); // send ipi +} + +void apic_enable() +{ + apic_write(APIC_SPURIOUS,apic_read(APIC_SPURIOUS)|0x100); + apic_write(APIC_SPURIOUS,apic_read(APIC_SPURIOUS)|0xFF); // set spurious to 255 (default anyway) +} + +/** select mode : divisor. + * 0 - 1 + * 1 - 2 + * 2 - 4 + * 3 - 8 + * 4 - 16 + * 5 - 32 + * 6 - 64 + * 7 - 128 + */ + +static uint32_t apic_get_bus_speed(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); + apic_write(APIC_TMRDIV, reg[sel]); + apic_write(APIC_TMRINITCNT, 0xFFFFFFFF); + asm_pit_sleep_50ms(); + //writeAPIC(APIC_LVT_TMR, APIC_LVT_INT_MASKED); //?? + uint32_t ticksInS = 0xFFFFFFFF - apic_read(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; +} + +/** run this before anything else */ +void apic_init(acpi_information *info) +{ + fixme("how to support IPI addressing more than 16cpus?"); + fixme("check via cpuid if apic exist?"); + local_apic_addr=info->local_apic_address; + io_apic_addr=info->io_apic_address; + bus_speed=apic_get_bus_speed(4); // get bus speed (divisor: 16) +} + +/** set ticks per second for timer interrupt*/ +void apic_init_timer(uint32_t ticks_per_second) +{ + uint32_t countdown=bus_speed/16/ticks_per_second; + + apic_write(APIC_TMRDIV, 0x3); // divisor 16 + apic_write(APIC_LVT_TMR, INTERRUPT_APIC_TIMER | TMR_PERIODIC); + apic_write(APIC_TMRINITCNT, countdown); +} + +/** setup io apic */ +void ioapic_config() +{ + fixme("use acpi info to setup IOAPIC"); + // setup IO APIC + // PIT irq 00 -> 02 flags 0 -> 0x90 + // kb irq 01 -> 01 flags ? -> 0x91 + // mouse irq 12 -> 12 flags ? -> 0x92 + ioapic_config_entry(2,0x90,0x0); + ioapic_config_entry(1,0x91,0x0); + ioapic_config_entry(12,0x92,0x0); +} + +/** startup other cpus*/ +void apic_sipi(uint32_t dest,uint32_t addy) +{ + // uint32_t addy=0x7; + fixme("poll flag/timeout"); + apic_write(APIC_ICRH,dest<<24); //select destionation cpu/apic + apic_write(APIC_ICRL,(5<<8)|(1<<14)); //101 INIT IPI + + // TODO: wait 10 milliseconds + + apic_write(APIC_ICRL,(6<<8)|(1<<14)|addy); /// 110 SIPI + + // TODO: poll a flag?(timeout 1ms) + // TODO retry 110 SIPI with 1s timeout +} diff --git a/kernel/apic.h b/kernel/apic.h new file mode 100644 index 0000000..f2252ed --- /dev/null +++ b/kernel/apic.h @@ -0,0 +1,42 @@ +/** + * @file + * Advanced Programmable Interrupt Controller + * ========================================== + * + * The APIC consists of one (or more) IO-APIC and one LAPIC (Local APIC) + * for each core. Currently we only support he most usual setup with a single + * IO-APIC. Call apic_init() once, providing an acpi_information structure, + * before using the other functions. + */ + +#include <stdint.h> +#include "acpi.h" + +/** run this before anything else */ +void apic_init(acpi_information *info); + +/** setup io apic */ +void ioapic_config(); + +/** get local apic id */ +uint32_t apic_id(); + +/** send end-of-interrupt to local apic + * It seems we need this for hardware interrupts and IPIs as well + */ +void apic_eoi(); + +/** send inter processor interrupt to destination and number */ +void apic_ipi(uint8_t dest, uint8_t number); + +/** enable local apic */ +void apic_enable(); + +/** set ticks per second for timer interrupt*/ +void apic_init_timer(uint32_t ticks_per_second); + +/** startup other cpu + * @dest destination apic + * @addy entrypoint (example 0x7->0x7000 etc..) + * */ +void apic_sipi(uint32_t dest,uint32_t addy); diff --git a/kernel/exceptions.c b/kernel/exceptions.c index 3030b9c..0c8f6af 100644 --- a/kernel/exceptions.c +++ b/kernel/exceptions.c @@ -3,6 +3,7 @@ #include "asm_x86.h" #include "smp.h" +#include "apic.h" static void defklog(uint32_t esp) { @@ -36,7 +37,7 @@ void exception_handle(uint32_t esp, uint32_t irq) { uint32_t error_code=0; - klog("EXCEPTION: apicID: 0x%08X",apicID()); + klog("EXCEPTION: apicID: 0x%08X",apic_id()); klog("EXCEPTION: vector nr.: %d",irq); switch(irq){ //this interrupts push also an error_code diff --git a/kernel/interrupts.c b/kernel/interrupts.c index 180658a..9ffd7c6 100644 --- a/kernel/interrupts.c +++ b/kernel/interrupts.c @@ -7,6 +7,7 @@ #include "scheduler.h" #include "asm_x86.h" #include "smp.h" +#include "apic.h" /** The size of our interrupts table */ #define INT_MAX 256 // 0-255 @@ -63,7 +64,7 @@ uint32_t interrupt_handler(uint32_t esp, uint32_t irq) // TODO: mouse // test ipi - apicIPI(2,0x81); // force cpu16 to autoschedule? just test + apic_ipi(2,0x81); // force cpu16 to autoschedule? just test //klog("0x60 in %d",in); } @@ -85,7 +86,7 @@ uint32_t interrupt_handler(uint32_t esp, uint32_t irq) // schedules on APIC timer 0x8C and IPI 0x81 if(irq==INTERRUPT_APIC_TIMER || irq==INTERRUPT_IPI)esp=my_scheduler(esp,-1); // autoschedule - if(irq!=INTERRUPT_SYSCALL)apicEOI(); // ack all except software syscalls + if(irq!=INTERRUPT_SYSCALL)apic_eoi(); // ack all except software syscalls if(irq==255)kpanic("Spurious/Unknown Interrupt!?"); // default and spurious diff --git a/kernel/kernel.c b/kernel/kernel.c index dd8d3f0..4c7227b 100644 --- a/kernel/kernel.c +++ b/kernel/kernel.c @@ -11,6 +11,7 @@ #include "vmem.h" //-- clean below headers --// +#include "apic.h" #include "kernel/scheduler.h" #include "driver/timer.h" @@ -70,6 +71,13 @@ void kernel_main(uint32_t eax,uint32_t ebx) interrupts_install(); fixme("register interrupt callback funcs (instead hardcoded dispatcher)"); + // -- APIC -- // + klog("Advanced Programmable Interrupt Controller (APIC) config ..."); + apic_init(&cfg_acpi); + ioapic_config(); + apic_enable(); + apic_init_timer(3);// freq in HZ + // -- MEMORY MANAGEMENT -- // klog("Memory init ... "); mem_init(cfg_multiboot); @@ -88,6 +96,10 @@ void kernel_main(uint32_t eax,uint32_t ebx) x86_set_page_directory(dir); x86_paging_enable(); + // temporary TODO + uint32_t *cpu_mem=0x8000000; //1024 pages from here on are mapped per cpu for testing! TODO: dynamic! + *cpu_mem=apic_id(); + // -- RAM IMAGE -- // klog("Ram Filesystem init ... "); fs_mount(cfg_multiboot); @@ -120,6 +132,8 @@ void kernel_main(uint32_t eax,uint32_t ebx) klog("Unlock application processors ... "); asm_smp_unlock(); + PutFont('X', 100,200, 0x00ffff,0xff00ff); // TODO temporary! + klog("Enable Interrupts ... "); x86_sti(); // this will start processing hardware interrupts diff --git a/kernel/kernel.h b/kernel/kernel.h index c7406e7..d175965 100644 --- a/kernel/kernel.h +++ b/kernel/kernel.h @@ -31,7 +31,7 @@ #ifndef FOOLOS_LOG_OFF #define kpanic(...) {log(FOOLOS_LOG_COLOR,__FILE__,0," \033[41;37m [KERNEL PANIC] \033[37;40m " __VA_ARGS__ ); while(1);} #define klog(...) log(FOOLOS_LOG_COLOR,__FILE__ ":" S2(__LINE__), 10, __VA_ARGS__) -#define fixme(...) log(FOOLOS_LOG_COLOR,__FILE__ ":" S2(__LINE__), 10, "\033[44;37m [FIXME] \033[37;40m " __VA_ARGS__) +#define fixme(...) log(FOOLOS_LOG_COLOR,__FILE__ ":" S2(__LINE__) "[FIXME]:" , 10, __VA_ARGS__) #endif #ifdef FOOLOS_LOG_OFF diff --git a/kernel/smp.c b/kernel/smp.c index 3787ac1..084f730 100644 --- a/kernel/smp.c +++ b/kernel/smp.c @@ -11,132 +11,12 @@ #include "asm_x86.h" #include "asm_pit.h" #include "asm_smp.h" +#include "apic.h" -#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) - -// -uint32_t c1,c2,c3; -volatile uint8_t proc; -uint32_t cpu_counter[SMP_MAX_PROC]; - -uint32_t local_apic_addr; -uint32_t io_apic_addr; - -uint32_t countdown; - -void writeIOAPIC(uint32_t offset, uint32_t value) -{ - uint32_t *reg=io_apic_addr; - reg[0]=(offset & 0xff); - reg[4]= value; -} - -uint32_t readIOAPIC(uint32_t offset) -{ - uint32_t *reg=io_apic_addr; - reg[0]=(offset & 0xff); - return reg[4]; -} - -void irqIOAPIC(uint32_t irq, uint32_t low, uint32_t high) -{ - writeIOAPIC(0x10+irq*2,low); - writeIOAPIC(0x11+irq*2,high); -} - -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; -} - -uint32_t apicID() -{ - return readAPIC(APIC_APICID)>>24; -} - -void apicEOI() -{ - writeAPIC(0xB0,0); -} - -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); -} - -/** 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 + // setup stack and jump to kernel_ap(); uint32_t ebp=kballoc(1); asm volatile("mov %0, %%ebp"::"r"(ebp)); asm volatile("mov %ebp, %esp"); @@ -145,102 +25,45 @@ void smp_main() void kernel_ap() { - klog("smp local apic id: 0x%08X",apicID()); - apicEnable(); + apic_enable(); + klog("Install Interrupt Vector Table (IVT) on CPU with lapic_id=0x%x ...",apic_id()); interrupts_install(); + + klog("Install Global Descriptor Table (GDT) on CPU with lapic_id=0x%x ...",apic_id()); gdt_init(); + klog("Setup Paging on CPU with lapic_id=0x%x ...",apic_id()); struct pdirectory_struct *dir=vmem_kernel_dir(); x86_set_page_directory(dir); x86_paging_enable(); - - uint32_t *cpu_mem=0x8000000; //1024 pages from here on are mapped per cpu for testing! TODO: dynamic! - *cpu_mem=apicID(); - writeAPIC(APIC_TMRDIV, 0x3); - writeAPIC(APIC_LVT_TMR,INTERRUPT_APIC_TIMER | TMR_PERIODIC); - writeAPIC(APIC_TMRINITCNT, countdown); + uint32_t *cpu_mem=0x8000000; //1024 pages from here on are mapped per cpu for testing! TODO: dynamic! + *cpu_mem=apic_id(); + klog("%x",*cpu_mem); + + klog("Setup the LAPIC Timer on CPU with lapic_id=0x%x ...",apic_id()); + apic_init_timer(1);// freq 1HZ + klog("Enable Interrupts on CPU with lapic_id=0x%x ...",apic_id()); x86_sti(); asm_smp_unlock(); while(1)asm("hlt"); - -// switch_to_user_mode(); - /* - - while(1); - - uint32_t ebp=pmmngr_alloc_block()+4095; - - asm volatile("mov %0, %%ebp"::"r"(ebp)); - asm volatile("mov %ebp, %esp"); - asm volatile("jmp kernel_ap"); - - proc=c1=c2=c3=0; - for(int i=0;i<SMP_MAX_PROC;i++)cpu_counter[i]=0; - */ } // this will start all our application processors! void smp_start_aps(acpi_information *pros) { - - fixme("how to support IPI addressing more than 16cpus?"); - fixme("check via cpuid if apic exist?"); - local_apic_addr=pros->local_apic_address; - io_apic_addr=pros->io_apic_address; - - uint32_t *cpu_mem=0x8000000; //1024 pages from here on are mapped per cpu for testing! TODO: dynamic! - *cpu_mem=apicID(); - - klog("bsp local apic id: 0x%08X",*cpu_mem); - - apicEnable(); // bsp apic seems to be enabled anyway. - - uint32_t speed=probeBusSpeed(4); // get bus speed (divisor: 16) - - // setup apic timer - countdown=speed/16/10; // tick 10 times a second - countdown*=10; - writeAPIC(APIC_TMRDIV, 0x3); // divisor 16 - writeAPIC(APIC_LVT_TMR, INTERRUPT_APIC_TIMER | TMR_PERIODIC); // on interrupt 200 - writeAPIC(APIC_TMRINITCNT, countdown); - - // setup IO APIC - // PIT irq 00 -> 02 flags 0 -> 0x90 - // kb irq 01 -> 01 flags ? -> 0x91 - // mouse irq 12 -> 12 flags ? -> 0x92 - - fixme("use acpi info to setup IOAPIC"); - irqIOAPIC(2,0x90,0x0); - irqIOAPIC(1,0x91,0x0); - irqIOAPIC(12,0x92,0x0); - for(int i=0;i<pros->processors;i++) { - if(pros->boot==i)continue; + if(pros->boot==i)continue; // skib bsp uint8_t dest=pros->local_apic_id[i]; - klog("starting cpu %d (dest: %d) ",i,dest); - - uint32_t *reg; - - reg=local_apic_addr+APIC_ICRH; - *reg=dest<<24; // destination apic. - - reg=local_apic_addr+APIC_ICRL; - *reg=(5<<8)|(1<<14); // 101 INIT IPI - - // TODO: wait 10 milliseconds - // https://wiki.osdev.org/Symmetric_Multiprocessing + klog("starting cpu %d (destination apic id: 0x%x) ",i,dest); + apic_sipi(dest,0x7); // start on 0x7000 - *reg=(6<<8)|(1<<14)|0x7; // 110 SIPI - // TODO: poll a flag?(timeout 1ms) - // TODO retry 110 SIPI with 1s timeout - } } diff --git a/kernel/smp.h b/kernel/smp.h index 7e4c66a..94f0d3e 100644 --- a/kernel/smp.h +++ b/kernel/smp.h @@ -1,21 +1,19 @@ +/** + * @file // 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 +// https://wiki.osdev.org/Symmetric_Multiprocessing // + */ + #ifndef SMP_H #define SMP_H -#include "kernel.h" #include "acpi.h" -#include <stdbool.h> -#include <stdint.h> - -void apicEOI(); -uint32_t apicID(); -void apicIPI(uint8_t dest, uint8_t number); -void smp_start_aps(acpi_information *pros); +void smp_start_aps(acpi_information *); #endif diff --git a/kernel/vmem.c b/kernel/vmem.c index 04f0354..c18b0a2 100644 --- a/kernel/vmem.c +++ b/kernel/vmem.c @@ -347,11 +347,12 @@ pdirectory* vmem_kernel_dir() fixme("remove user flags where appropriate"); fixme("do not waste soo many pages/page tables!"); fixme("align properly!! / merge page tables if required!"); + fixme("Is ioapic/lapic really on one page?"); pdirectory* dir = vmem_clean_dir(); vmem_add_identity(dir,0,1024*8);//first 32 megs if(fb_addr>0x100000)vmem_add_identity(dir,fb_addr,1024*4);//16megs (?) TODO: dynamic vmem_add_identity(dir,apic_addr,1024*2); - vmem_add_identity(dir,io_apic_addr,1024*2); + //vmem_add_identity(dir,io_apic_addr,1024*2); // we do not nee this (ioapic never accessed after paging enabled) vmem_add_alloc(dir,0x8000000,1024*4); return dir; } |
