summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--asm/asm_int.h1
-rw-r--r--asm/asm_int.s2
-rw-r--r--asm/asm_mp.asm16
-rw-r--r--asm/asm_pic.asm1
-rw-r--r--asm/asm_pit.h3
-rw-r--r--asm/asm_pit.s66
-rw-r--r--asm/asm_start.s2
-rw-r--r--driver/timer.c3
-rw-r--r--kernel/gdt.c11
-rw-r--r--kernel/interrupts.c26
-rw-r--r--kernel/kernel.c59
-rw-r--r--kernel/kernel.h2
-rw-r--r--kernel/scheduler.c11
-rw-r--r--kernel/smp.c119
-rw-r--r--kernel/vmem.c59
-rw-r--r--kernel/vmem.h3
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);