diff --git a/arch/x86_64/acpi/apic.c b/arch/x86_64/acpi/apic.c index 5ec13be..b8627af 100644 --- a/arch/x86_64/acpi/apic.c +++ b/arch/x86_64/acpi/apic.c @@ -89,21 +89,43 @@ kern_status_t local_apic_enable(void) static void configure_legacy_pic(void) { printk("acpi: APIC unavailable, using 8259 PIC"); - pit_init(1000); + pit_start(1000); +} + +static void ioapic_init(void) +{ + +} + +static void init_all_ioapic(void) +{ + ioapic_init(); } kern_status_t apic_init(void) { - if (check_apic() == 0) { + static int bsp_id = -1; + + /* the bootstrap processor will be the first one ro call apic_init(). + it is responsible for initialising the I/O APICs */ + if (bsp_id == -1) { + bsp_id = this_cpu(); + } + + struct acpi_madt *madt = (struct acpi_madt *)acpi_find_sdt(ACPI_SIG_MADT); + + if (check_apic() == 0 || !madt) { configure_legacy_pic(); return KERN_UNSUPPORTED; } - if (local_apic_enable() != KERN_OK) { - configure_legacy_pic(); - return KERN_UNSUPPORTED; + if (this_cpu() == bsp_id) { + init_all_ioapic(); } - disable_8259(); + local_apic_enable(); + disable_8259(); + + pit_start(10); return KERN_OK; } diff --git a/arch/x86_64/config.mk b/arch/x86_64/config.mk index 484fb9a..707302b 100644 --- a/arch/x86_64/config.mk +++ b/arch/x86_64/config.mk @@ -1,10 +1,12 @@ LD := $(SOCKS_ARCH)-elf-gcc CC := $(SOCKS_ARCH)-elf-gcc +CXX := $(SOCKS_ARCH)-elf-g++ ASM := $(SOCKS_ARCH)-elf-gcc OBJCOPY := $(SOCKS_ARCH)-elf-objcopy STRIP := $(SOCKS_ARCH)-elf-strip CFLAGS := -ffreestanding -nostdlib +CXXFLAGS := $(CFLAGS) ASMFLAGS := $(CFLAGS) LDFLAGS := -nostdlib @@ -14,5 +16,6 @@ ARCH_LDFLAGS := -z max-page-size=0x1000 -T arch/x86_64/layout.ld ARCH_DIR := arch/$(SOCKS_ARCH) ARCH_C_FILES := $(wildcard $(ARCH_DIR)/*.c) $(wildcard $(ARCH_DIR)/acpi/*.c) +ARCH_CXX_FILES := $(wildcard $(ARCH_DIR)/*.cpp) $(wildcard $(ARCH_DIR)/acpi/*.cpp) ARCH_ASM_FILES := $(wildcard $(ARCH_DIR)/*.S) $(wildcard $(ARCH_DIR)/acpi/*.S) -ARCH_OBJ := $(addprefix $(BUILD_DIR)/,$(ARCH_C_FILES:.c=.o) $(ARCH_ASM_FILES:.S=.o)) +ARCH_OBJ := $(addprefix $(BUILD_DIR)/,$(ARCH_C_FILES:.c=.o) $(ARCH_CXX_FILES:.cpp=.o) $(ARCH_ASM_FILES:.S=.o)) diff --git a/arch/x86_64/include/arch/irq.h b/arch/x86_64/include/arch/irq.h index 4aa95e5..65bc3d2 100644 --- a/arch/x86_64/include/arch/irq.h +++ b/arch/x86_64/include/arch/irq.h @@ -66,5 +66,6 @@ extern int idt_init(struct idt_ptr *idtp); extern int idt_load(struct idt_ptr *idtp); extern void hook_irq(irq_vector_t vec, irq_hook_t *hook); +extern void unhook_irq(irq_vector_t vec, irq_hook_t *hook); #endif diff --git a/arch/x86_64/include/arch/pit.h b/arch/x86_64/include/arch/pit.h index 4d46017..f5559a6 100644 --- a/arch/x86_64/include/arch/pit.h +++ b/arch/x86_64/include/arch/pit.h @@ -1,6 +1,8 @@ #ifndef ARCH_PIT_H_ #define ARCH_PIT_H_ -extern void pit_init(unsigned int hz); +extern void pit_start(unsigned int hz); +extern void pit_stop(void); +extern void pit_wait(unsigned int ticks); #endif diff --git a/arch/x86_64/irq.c b/arch/x86_64/irq.c index 6ff5123..2fccd86 100644 --- a/arch/x86_64/irq.c +++ b/arch/x86_64/irq.c @@ -263,3 +263,9 @@ void hook_irq(irq_vector_t vec, irq_hook_t *hook) queue_t *hook_queue = &irq_hooks[vec - IRQ0]; queue_push_back(hook_queue, &hook->irq_entry); } + +void unhook_irq(irq_vector_t vec, irq_hook_t *hook) +{ + queue_t *hook_queue = &irq_hooks[vec - IRQ0]; + queue_delete(hook_queue, &hook->irq_entry); +} diff --git a/arch/x86_64/pit.c b/arch/x86_64/pit.c index b2a35dd..b6b248a 100644 --- a/arch/x86_64/pit.c +++ b/arch/x86_64/pit.c @@ -1,9 +1,13 @@ #include +#include #include #include +static unsigned long long tick_counter = 0; + static int pit_callback(void) { + tick_counter++; printk("tick"); return 0; } @@ -12,7 +16,7 @@ static irq_hook_t pit_irq_hook = { .irq_callback = pit_callback }; -void pit_init(unsigned int hz) +void pit_start(unsigned int hz) { unsigned int divisor = 1193180 / hz; @@ -24,6 +28,28 @@ void pit_init(unsigned int hz) outportb(0x40, hi); hook_irq(IRQ0, &pit_irq_hook); - - printk("clock: 8253 PIT initialised at %uHz", hz); +} + +void pit_stop(void) +{ + /* lowest possible frequency */ + unsigned int divisor = 1193180; + + outportb(0x43, 0x36); + uint8_t lo = (uint8_t)(divisor & 0xFF); + uint8_t hi = (uint8_t)((divisor >> 8) & 0xFF); + + outportb(0x40, lo); + outportb(0x40, hi); + + unhook_irq(IRQ0, &pit_irq_hook); +} + +void pit_wait(unsigned int ticks) +{ + unsigned long long end = tick_counter + ticks; + + while (tick_counter < end) { + ml_cpu_pause(); + } }