Skip to content

Commit

Permalink
Initial SMP support. Intializes AP and it halts in realmode. Fixed ou…
Browse files Browse the repository at this point in the history
…tputting last character in a line. Aligned user mode stack in 8 bytes boundary. Fixed protected mode address loading in boot loader.
  • Loading branch information
shoily committed Aug 15, 2020
1 parent 0d401f8 commit c59183e
Show file tree
Hide file tree
Showing 11 changed files with 161 additions and 58 deletions.
2 changes: 1 addition & 1 deletion apic.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ void init_lapic() {
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);
write_lapic_register(LAPIC_SPURIOUS_REG, read_lapic_register(LAPIC_SPURIOUS_REG)| 0x100);
}

void lapic_switch(bool enable) {
Expand Down
28 changes: 15 additions & 13 deletions apic.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,23 @@
#define LAPIC_PPR 0xa0
#define LAPIC_EOI_REG 0xb0
#define LAPIC_SPURIOUS_REG 0xf0
#define ISR_0_31 0x100
#define TMR_0_31 0x180
#define IRR_0_31 0x200
#define ERROR_STATUS_REG 0x280
#define ICR_1 0x300
#define ICR_2 0x310
#define LVT_TIMER_REG 0x320
#define LVT_LINT_0_REG 0x350
#define LVT_LINT_1_REG 0x360
#define LVT_ERROR_REG 0x370
#define INITIAL_COUNTER_REG 0x380
#define CURRENT_COUNTER_REG 0x390
#define DIVIDE_CONFIGURATION_REG 0x3e0
#define LAPIC_ISR_0_31 0x100
#define LAPIC_TMR_0_31 0x180
#define LAPIC_IRR_0_31 0x200
#define LAPIC_ERROR_STATUS_REG 0x280
#define LAPIC_ICR_1 0x300
#define LAPIC_ICR_2 0x310
#define LAPIC_LVT_TIMER_REG 0x320
#define LAPIC_LVT_LINT_0_REG 0x350
#define LAPIC_LVT_LINT_1_REG 0x360
#define LAPIC_LVT_ERROR_REG 0x370
#define LAPIC_INITIAL_COUNTER_REG 0x380
#define LAPIC_CURRENT_COUNTER_REG 0x390
#define LAPIC_DIVIDE_CONFIGURATION_REG 0x3e0

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

#endif
3 changes: 1 addition & 2 deletions bootldr.S
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
.equ E820_MAP_ADDR, 0x1008
.equ PROTECTED_MODE_STACK, 0xf000
.equ KERNEL_SECTORS, ((KERNEL_SIZE + 0x200 -1) / 0x200)
.equ PIT_FREQUENCY, 1000

// machine boots in 16bit real mode
.code16
Expand Down Expand Up @@ -206,7 +205,7 @@ protectedmodeaddress:
movl %eax, %gs

// initialize protected mode stack
movl PROTECTED_MODE_STACK, %eax
movl $PROTECTED_MODE_STACK, %eax
movl %eax, %esp
movl %eax, %ebp

Expand Down
5 changes: 3 additions & 2 deletions handlr32.S
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,6 @@
push %es
push %fs
push %gs

movl %esp, %ebp

movl $0x28, %eax
movl %eax, %ds
Expand All @@ -59,6 +57,7 @@

sti

movl %esp, %ebp
push %ebp
call common_interrupt_handler
addl $4, %esp
Expand Down Expand Up @@ -146,6 +145,7 @@


common_trap_handler:
cli
pusha

push %ds
Expand All @@ -171,6 +171,7 @@ common_trap_handler:
pop %ds

popa
sti

iret

Expand Down
3 changes: 3 additions & 0 deletions kernel32.ld
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ SECTIONS
. = ALIGN(4096);
.um : AT(ADDR(.um) - 0x80000000) {*(.um);}
um_size = SIZEOF(um);
. = ALIGN(4096);
.mp_init : AT(ADDR(.mp_init) - 0x80000000) {*(.mp_init);}
mp_init_size = SIZEOF(mp_init);
.kernel_data ALIGN(4096) : AT(ADDR(.kernel_data) - 0x80000000) {*(.kernel_data); }
. = ALIGN(4096);
_kernel_pg_dir = .;
Expand Down
31 changes: 31 additions & 0 deletions mpinit.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*****************************************************************************/
/* File: mp_init.S */
/* */
/* Description: Startup code for AP. */
/* */
/* Author: Shoily O Rahman <[email protected]> */
/* */
/* Date: Aug 9, 2020 */
/* */
/*****************************************************************************/

.equ AP_COUNT_PHYS_ADDR, 0xfff8
.code16

.globl init_ap

.section "mp_init", "ax"

init_ap:

cli
xorw %ax, %ax
movw %ax, %ss
movw %ax, %ds
movw %ax, %es
movw %ax, %fs
movw %ax, %gs

incw AP_COUNT_PHYS_ADDR

hlt
50 changes: 16 additions & 34 deletions setup32.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "system.h"
#include "setup32.h"
#include "apic.h"
#include "smp.h"

// GDT data
struct gdt_entry __attribute__((aligned(8))) gdt[LAST_SEG/8];
Expand Down Expand Up @@ -68,41 +69,22 @@ void irq_handler_13();
void irq_handler_14();
void irq_handler_15();

void lapic_irq_handler_0();
void lapic_irq_handler_1();


__attribute__((regparm(0))) void trap_handler(struct regs_frame *rf) {

char str[20];

print_vga("Trap handler", true);

itoa(rf->gs, str, 16);
print_vga(str, true);

itoa(rf->fs, str, 16);
print_vga(str, true);

itoa(rf->es, str, 16);
print_vga(str, true);

itoa(rf->ds, str, 16);
print_vga(str, true);

itoa(rf->code_nr, str, 16);
print_vga(str, true);

itoa(rf->cs, str, 16);
print_vga(str, true);

itoa(rf->eip, str, 16);
print_vga(str, true);

itoa(rf->ss, str, 16);
print_vga(str, true);

itoa(rf->esp, str, 16);
print_vga(str, true);
print_msg("gs", rf->gs, 16, false);
print_msg("fs", rf->fs, 16, false);
print_msg("es", rf->es, 16, false);
print_msg("ds", rf->ds, 16, false);
print_msg("code_nr", rf->code_nr, 16, false);
print_msg("cs", rf->cs, 16, false);
print_msg("eip", rf->eip, 16, false);
print_msg("ss", rf->ss, 16, false);
print_msg("esp", rf->esp, 16, false);

__asm__ __volatile__("1: hlt; jmp 1b;" : : : );
}
Expand Down Expand Up @@ -253,16 +235,16 @@ void setup32() {
setupGDT32();
setupLDT32();

if (!lapic_present) {
init_pic_8259();
init_pit_frequency();
}

init_lapic();

init_pic_8259();
init_pit_frequency();

setupIDT32();
setupTSS32();

smp_start();

STI;

print_vga("Setup GDT,IDT, LDT and TSS done", true);
Expand Down
67 changes: 67 additions & 0 deletions smp.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*****************************************************************************/
/* File: smp.c */
/* */
/* Description: Source file SMP related code. */
/* */
/* Author: Shoily O Rahman <[email protected]> */
/* */
/* Date: Aug 9, 2020 */
/* */
/*****************************************************************************/

#include "util.h"
#include "system.h"
#include "apic.h"

#define AP_INIT_PHYS_TEXT 0xf000
#define AP_COUNT_PHYS_ADDR 0xfff8

extern int mp_init_size;
extern int init_ap;

void copy_smp_init_to_low_mem() {

char *s = (char*)&init_ap;
char *d = (char*)(AP_INIT_PHYS_TEXT+KERNEL_VIRT_ADDR);

for(int i=0;i<(int)&mp_init_size;i++) {
*d++ = *s++;
}
}

void smp_start() {

int status;

copy_smp_init_to_low_mem();

// initialize AP processor count with 0
// it will be increased by AP startup code
*(int*)(AP_COUNT_PHYS_ADDR+KERNEL_VIRT_ADDR) = 0;

MFENCE;

// send INIT IPI to APs
write_lapic_register(LAPIC_ICR_1, 0x000c4500);
write_lapic_register(LAPIC_ICR_2, 0);
for(int i=0;i<10;i++) {
status = read_lapic_register(LAPIC_ICR_1) & 0x1000;
if (!status)
break;
pit_wait(0xffff);
}

// send Startup IPI to APs
write_lapic_register(LAPIC_ICR_1, 0x000c4600 | (AP_INIT_PHYS_TEXT >> 12));
write_lapic_register(LAPIC_ICR_2, 0);
for(int i=0;i<30;i++) {
status = read_lapic_register(LAPIC_ICR_1) & 0x1000;
if (!status)
break;
pit_wait(0xffff);
}

pit_wait(0xffff);

print_msg("Number of APs", *(int*)(AP_COUNT_PHYS_ADDR+KERNEL_VIRT_ADDR), 10, true);
}
17 changes: 17 additions & 0 deletions smp.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*****************************************************************************/
/* File: smp.h */
/* */
/* Description: Header file SMP related code. */
/* */
/* Author: Shoily O Rahman <[email protected]> */
/* */
/* Date: Aug 9, 2020 */
/* */
/*****************************************************************************/

#ifndef SMP_H
#define SMP_H

void smp_start();

#endif
7 changes: 6 additions & 1 deletion system.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@
/* */
/*****************************************************************************/

//
// Reserved memory aside from E820
//
//

#include "system.h"
#include "util.h"

Expand All @@ -33,7 +38,7 @@ void print_vga(char *c, bool newline) {
c++;
vga_buffer_index += 2;
p++;
if (vga_buffer_index > 160) {
if (vga_buffer_index == 160) {
vga_buffer_line++;
vga_buffer_index = 0;
}
Expand Down
6 changes: 1 addition & 5 deletions usermode.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ char __attribute__((aligned(4096))) um_pg_table[4096];
char __attribute__((aligned(4096))) user_mode_program[4096];

#define USER_MODE_STACK_SIZE 8192
char user_mode_stack[USER_MODE_STACK_SIZE];
char __attribute__((aligned(8))) user_mode_stack[USER_MODE_STACK_SIZE];

extern int um, um_size;
extern int _kernel_pg_dir;
Expand All @@ -45,8 +45,6 @@ void load_usermode_function(char *usermodefunction) {
for(i=(int)&um;i<(int)&um+(int)&um_size;i++) {
*d++ = *s++;
}

print_vga("User mode progam copied", true);
}

void switch_to_um() {
Expand Down Expand Up @@ -89,6 +87,4 @@ void initialize_usermode() {
MFENCE;

switch_to_um();

print_vga("Test", true);
}

0 comments on commit c59183e

Please sign in to comment.