Skip to content

Commit

Permalink
Added per cpu specific page directory support. GDT, LDT, IDT are comm…
Browse files Browse the repository at this point in the history
…on among processors but TSS is per cpu specific to fascilitate switching from user mode to kernel mode. Initialized LAPIC timer for application processors. Usermode stacks are made per cpu specific too (currently, it supports one task per cpu).
  • Loading branch information
shoily committed Oct 28, 2020
1 parent 2883539 commit 7104fbb
Show file tree
Hide file tree
Showing 19 changed files with 239 additions and 134 deletions.
38 changes: 17 additions & 21 deletions apic.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,12 @@ void read_msr(int msr, int *eax, int *edx) {
: );
}

int read_lapic_register(int lapic_register) {
int lapic_read_register(int lapic_register) {

return *((int*)(lapic_base_register+lapic_register));
}

void write_lapic_register(int lapic_register, int value) {
void lapic_write_register(int lapic_register, int value) {

*((int*)(lapic_base_register+lapic_register)) = value;
}
Expand All @@ -51,28 +51,24 @@ void lapic_irq_handler_0();

void calibrate_lapic_timer() {

CLI;
write_lapic_register(LAPIC_LVT_TIMER_REG, 32 | 0x20000); // Periodic timer on vector 32.
write_lapic_register(LAPIC_DIVIDE_CONFIGURATION_REG, 0xa); // Divide by 128
set_idt(32, lapic_irq_handler_0);
lapic_write_register(LAPIC_LVT_TIMER_REG, LAPIC_IDT_VECTOR | 0x20000); // Periodic timer on vector 32.
lapic_write_register(LAPIC_DIVIDE_CONFIGURATION_REG, LAPIC_DIVIDE_CONFIG_VALUE); // Divide by 128
set_idt(LAPIC_IDT_VECTOR, lapic_irq_handler_0);

STI;
lapic_calibration_mode = true;
write_lapic_register(LAPIC_INITIAL_COUNTER_REG, 1024);
lapic_write_register(LAPIC_INITIAL_COUNTER_REG, LAPIC_COUNTER_VALUE);
pit_wait_ms(1);
write_lapic_register(LAPIC_INITIAL_COUNTER_REG, 0);
CLI;
lapic_write_register(LAPIC_INITIAL_COUNTER_REG, 0);
lapic_calibration_mode = false;
CLI;
print_msg("lapic_calibration_tick", lapic_calibration_tick, 10, true);

//STI;
lapic_timer_enabled = true;
write_lapic_register(LAPIC_INITIAL_COUNTER_REG, 1024);
lapic_timer_enabled = true;
STI;
lapic_write_register(LAPIC_INITIAL_COUNTER_REG, LAPIC_COUNTER_VALUE);
}

void init_lapic() {

int eax, edx;
int eax, edx;
pte_t *pgtable[1];

__asm__ __volatile__("movl $1, %%eax;"
Expand Down Expand Up @@ -102,12 +98,12 @@ void init_lapic() {

print_msg("Local APIC address", eax, 16, false);

lapic_id = read_lapic_register(LAPIC_ID_REG) >> 24;
lapic_id = lapic_read_register(LAPIC_ID_REG) >> 24;

print_msg("Local APIC id", lapic_id, 16, true);

// enable receiving interrupt
write_lapic_register(LAPIC_SPURIOUS_REG, read_lapic_register(LAPIC_SPURIOUS_REG)| 0x100);
lapic_write_register(LAPIC_SPURIOUS_REG, lapic_read_register(LAPIC_SPURIOUS_REG)| 0x100);

calibrate_lapic_timer();
}
Expand All @@ -116,13 +112,13 @@ void lapic_switch(bool enable) {

int value;

value = read_lapic_register(LAPIC_SPURIOUS_REG);
value = lapic_read_register(LAPIC_SPURIOUS_REG);
if (enable)
value |= 0x1ff;
else
value &= ~0x1ff;

print_msg("lapic_switch", value, 16, true);
//print_msg("lapic_switch", value, 16, true);

write_lapic_register(LAPIC_SPURIOUS_REG, value);
lapic_write_register(LAPIC_SPURIOUS_REG, value);
}
9 changes: 7 additions & 2 deletions apic.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,14 @@
#define LAPIC_CURRENT_COUNTER_REG 0x390
#define LAPIC_DIVIDE_CONFIGURATION_REG 0x3e0

#define LAPIC_IDT_VECTOR 32
#define LAPIC_DIVIDE_CONFIG_VALUE 10
#define LAPIC_COUNTER_VALUE 1024

void init_lapic();
void lapic_switch(bool enable);
int read_lapic_register(int lapic_register);
void write_lapic_register(int lapic_register, int value);
int lapic_read_register(int lapic_register);
void lapic_write_register(int lapic_register, int value);
void lapic_enable_timer();

#endif
1 change: 0 additions & 1 deletion boot32.S
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
.text

.include "krnlconst.S"
.equ KERNEL_PGDIR_ENTRY, (KERNEL_VIRT_ADDR >> 20)

.globl _start
_start:
Expand Down
2 changes: 1 addition & 1 deletion bootldr.S
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ a20_line:
// memory buffer location of disk address packet
movw dap, %si
xorw %ax, %ax
movw %ax, 4(%si)
movw %ax, 4(%si)

movw $KERNEL_SECTORS, %ax

Expand Down
7 changes: 5 additions & 2 deletions kernel32.ld
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,12 @@ SECTIONS
.mp_init : {*(.mp_init); }
. = ALIGN(4096);
_kernel_pg_dir = .;
_kernel_pg_table_0 = _kernel_pg_dir + 0x1000;
_kernel_stack_0 = _kernel_pg_table_0 + 0x1000;
_kernel_pg_dir_end = _kernel_pg_dir + (0x1000 * 32);
_kernel_pg_table_0 = _kernel_pg_dir_end;
_kernel_pg_table_0_end = _kernel_pg_table_0 + 0x1000;
_kernel_stack_0 = _kernel_pg_table_0_end + 0x1000;
_kernel_stack_0_start = _kernel_stack_0 + 0x2000;
_kernel_private_data = _kernel_stack_0_start + (0x2000 * 32);
_kernel_heap_start = (_kernel_private_data + 0x1000) & ~(0xfff);
_end_kernel = .;
}
4 changes: 4 additions & 0 deletions krnlconst.hdr
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,7 @@ AP_COUNT_PHYS_ADDR 0xfff8
AP_KERNEL_PG_DIR 0xfffc
AP_FINISH_CODE 0x10000
KERNEL_VIRT_ADDR 0x80000000
KERNEL_PGDIR_ENTRY (KERNEL_VIRT_ADDR>>20)
KERNEL_STACK_SIZE 0x2000
FOUR_MB (1024*1024*4)
PAGE_SIZE 4096
4 changes: 2 additions & 2 deletions lock.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

#include "lock.h"

void spinlock_lock(spin_lock *lock) {
void spinlock_lock(spinlock *lock) {

__asm__ __volatile__("movl $1, %%eax;"
"1:;"
Expand All @@ -23,7 +23,7 @@ void spinlock_lock(spin_lock *lock) {
: "%eax", "%ebx", "cc", "memory" );
}

void spinlock_unlock(spin_lock *lock) {
void spinlock_unlock(spinlock *lock) {

__asm__ __volatile__("movl $0, %0;"
: "=m" (lock->val)
Expand Down
10 changes: 5 additions & 5 deletions lock.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@
#ifndef _LOCK_H
#define _LOCK_H

typedef struct _spin_lock {
typedef struct _spinlock {
int val;
} spin_lock;
} spinlock;

#define INIT_SPIN_LOCK(spinlock) memset(spinlock, sizeof(spin_lock), 0)
#define INIT_SPIN_LOCK(lock) memset(lock, sizeof(spinlock), 0)

void spinlock_lock(spin_lock *lock);
void spinlock_unlock(spin_lock *lock);
void spinlock_lock(spinlock *lock);
void spinlock_unlock(spinlock *lock);

#endif
40 changes: 20 additions & 20 deletions mpinit.S
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,6 @@ _start:
orl $1, %eax
movl %eax, %cr0

cli

// jump to protected mode
ljmpl *protectmodecodesegaddr

Expand All @@ -52,20 +50,6 @@ protectedmodeaddress:
movl %eax, %fs
movl %eax, %gs

// turning on paging
movl AP_KERNEL_PG_DIR, %eax
movl %eax, %cr3
movl %cr0, %eax
orl $0x80000000, %eax
movl %eax, %cr0

ljmpl *highcodesegaddr

.code32
.section ".high", "ax"

highaddress:

// get LAPIC id
movl AP_LAPIC_BASE_REGISTER, %ebx
addl $0x20, %ebx
Expand All @@ -74,7 +58,7 @@ highaddress:
movl %eax, %ecx

// calculate start of kernel mode stack for this processor
movl $0x2000, %ebx
movl $KERNEL_STACK_SIZE, %ebx
mull %ebx
movl AP_FIRST_STACK, %ebx
addl %ebx, %eax
Expand All @@ -83,11 +67,27 @@ highaddress:
movl %eax, %esp
movl %esp, %ebp

pushl %ecx
// turning on paging
movl %ecx, %eax
movl $PAGE_SIZE, %ebx
mull %ebx
movl AP_KERNEL_PG_DIR, %ebx
addl %ebx, %eax
movl %eax, %cr3

// increment AP count
lock incw AP_COUNT_PHYS_ADDR+KERNEL_VIRT_ADDR
movl %cr0, %eax
orl $0x80000000, %eax
movl %eax, %cr0

ljmpl *highcodesegaddr

.code32
.section ".high", "ax"

highaddress:

// push lapic id in the stack
pushl %ecx
movl AP_FINISH_CODE+KERNEL_VIRT_ADDR, %eax

// call finish_mp_initialization
Expand Down
2 changes: 0 additions & 2 deletions page32.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@
typedef int pte_t;
typedef int pgd_t;

#define PAGE_SIZE 4096

#define PGD_PRESENT 1
#define PGD_WRITE 2
#define PGD_USER 4
Expand Down
Loading

0 comments on commit 7104fbb

Please sign in to comment.