Skip to content

Commit

Permalink
Moved EOI from assembly handler to C code handler to uniformly handle…
Browse files Browse the repository at this point in the history
… PIC and LAPIC interrupts. Also, turn on other interrupts on APs.
  • Loading branch information
shoily committed Dec 1, 2020
1 parent ffcaef6 commit c915172
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 66 deletions.
8 changes: 5 additions & 3 deletions apic.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ int lapic_base_register;
int lapic_id;
int ioapic_base_register;
u32 ioapic_gsi_base;
bool ioapic_initialized;

extern int _kernel_pg_dir;

Expand Down Expand Up @@ -48,13 +49,10 @@ extern int lapic_calibration_tick;
extern bool lapic_calibration_mode;
extern bool lapic_timer_enabled;

void lapic_irq_handler_0();

void calibrate_lapic_timer() {

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);

lapic_calibration_mode = true;
lapic_write_register(LAPIC_INITIAL_COUNTER_REG, LAPIC_COUNTER_VALUE);
Expand Down Expand Up @@ -123,3 +121,7 @@ void lapic_switch(bool enable) {

lapic_write_register(LAPIC_SPURIOUS_REG, value);
}

void ioapic_init() {
ioapic_initialized = false;
}
1 change: 1 addition & 0 deletions apic.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,5 +44,6 @@ void lapic_switch(bool enable);
int lapic_read_register(int lapic_register);
void lapic_write_register(int lapic_register, int value);
void lapic_enable_timer();
void ioapic_init();

#endif
57 changes: 0 additions & 57 deletions handlr32.S
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,6 @@
.globl irq_handler_14
.globl irq_handler_15

.globl lapic_irq_handler_0
.globl lapic_irq_handler_1


// macro for defining IRQ handler using PIC
.macro DEFINE_IRQ_HANDLER irqn

Expand All @@ -62,14 +58,6 @@
call common_interrupt_handler
addl $4, %esp

movb $0x20,%al
movb $\irqn, %ah
cmpb $8, %ah
jl 1f
outb %al,$0xa0
1:
outb %al,$0x20

pop %gs
pop %fs
pop %es
Expand Down Expand Up @@ -174,48 +162,3 @@ common_trap_handler:
sti

iret


// macro for defining IRQ handler using Local APIC
.macro DEFINE_IRQ_HANDLER_LAPIC irqn

lapic_irq_handler_\irqn:
pushl $\irqn
pusha
push %ds
push %es
push %fs
push %gs

movl %esp, %ebp

movl $0x28, %eax
movl %eax, %ds
movl %eax, %es
movl %eax, %fs
movl %eax, %gs

push %ebp
call common_interrupt_handler
addl $4, %esp

// send EOI
movl lapic_base_register, %eax
addl $0xb0, %eax
movl $0, (%eax)

pop %gs
pop %fs
pop %es
pop %ds
popa

addl $4, %esp

iret

.endm


DEFINE_IRQ_HANDLER_LAPIC 0
DEFINE_IRQ_HANDLER_LAPIC 1
38 changes: 33 additions & 5 deletions setup32.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ extern int _kernel_stack_0_start;
extern int _kernel_pg_dir;

extern int lapic_present;
extern bool ioapic_initialized;
extern int lapic_base_register;

void common_trap_handler();
void sys_call_handler_128();
Expand All @@ -70,9 +72,6 @@ void irq_handler_13();
void irq_handler_14();
void irq_handler_15();

void lapic_irq_handler_0();
void lapic_irq_handler_1();

#define DEBUG_TRAP 1

__attribute__((regparm(0))) void trap_handler(struct regs_frame *rf) {
Expand All @@ -97,6 +96,33 @@ int timer_counter[MAX_NUM_SMPS];
int seconds[MAX_NUM_SMPS];
#endif

void sendEOI(int intno) {

if (ioapic_initialized || (intno == 0 && lapic_present)) {

__asm__ __volatile__("movl %0,%%eax;"
"addl $0xb0,%%eax;"
"movl $0,(%%eax);"
:
: "m"(lapic_base_register)
: "%eax"
);
} else {

__asm__ __volatile__("movb $0x20,%%al;"
"movb %0,%%ah;"
"cmpb $8,%%ah;"
"jl 1f;"
"outb %%al,$0xa0;"
"1:"
"outb %%al,$0x20;"
:
: "m"(intno)
: "%eax"
);
}
}

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

if (rf->code_nr == 0) {
Expand All @@ -111,7 +137,8 @@ __attribute__((regparm(0))) void common_interrupt_handler(struct regs_frame *rf)
#ifdef DEBUG_TIMER
char s[20];
timer_counter[CUR_CPU]++;
if (timer_counter[CUR_CPU] >= (1000*lapic_calibration_tick)) {
if ((!lapic_present && timer_counter[CUR_CPU] >= PIT_HZ) ||
(lapic_present && timer_counter[CUR_CPU] >= (1000*lapic_calibration_tick))) {
timer_counter[CUR_CPU] = 0;
seconds[CUR_CPU]++;

Expand All @@ -121,6 +148,8 @@ __attribute__((regparm(0))) void common_interrupt_handler(struct regs_frame *rf)
#endif
}
}

sendEOI(rf->code_nr);
}

__attribute__((regparm(0))) void common_sys_call_handler(struct regs_frame *rf) {
Expand Down Expand Up @@ -286,7 +315,6 @@ void setup32() {
init_lapic();

if (!lapic_present) {
lapic_calibration_tick = 1;
init_pic_8259();
init_pit_frequency();
}
Expand Down
5 changes: 4 additions & 1 deletion smp.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ void finish_smp_initialization(int smp_id) {
loadTSS32(smp_id);
loadIDT32();

lapic_write_register(LAPIC_SPURIOUS_REG, lapic_read_register(LAPIC_SPURIOUS_REG)| 0x100);
lapic_write_register(LAPIC_SPURIOUS_REG, lapic_read_register(LAPIC_SPURIOUS_REG)| 0x1ff);
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
lapic_write_register(LAPIC_INITIAL_COUNTER_REG, LAPIC_COUNTER_VALUE);
Expand Down Expand Up @@ -94,6 +94,9 @@ void smp_start() {

INIT_SPIN_LOCK(&spinlock_smp);

if (!lapic_present)
return;

copy_smp_init_to_low_mem();

initialize_kernel_pg_tables();
Expand Down
1 change: 1 addition & 0 deletions start.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ int start_kernel(void) {
init_memory();
bda_read_table();
acpi_init();
ioapic_init();
usermode_load_first_program();
smp_start();
initialize_usermode();
Expand Down

0 comments on commit c915172

Please sign in to comment.