diff --git a/arch/amd64/hw/timer.c b/arch/amd64/hw/timer.c index ee45a97..b3c348a 100644 --- a/arch/amd64/hw/timer.c +++ b/arch/amd64/hw/timer.c @@ -72,14 +72,14 @@ static uint32_t timer_tick(void *arg) { break; } -#if defined(DEBUG_COUNTERS) +//#if defined(DEBUG_COUNTERS) static uint64_t last_debug_cycle = 0; uint64_t delta = (system_time - last_debug_cycle) / 1000000ULL; if (delta >= 1000) { sched_debug_cycle(delta); last_debug_cycle = system_time; } -#endif +//#endif struct list_head *iter, *b_iter; uintptr_t irq; diff --git a/config.h.in b/config.h.in index 8a79997..903ff2a 100644 --- a/config.h.in +++ b/config.h.in @@ -1,7 +1,7 @@ #pragma once #define AMD64_KERNEL_STACK 65536 -#define AMD64_MAX_SMP 1 +//#define AMD64_MAX_SMP 4 //#define SLAB_TRACE_ALLOC 1 #undef SLAB_TRACE_ALLOC diff --git a/etc/Kernel.makefile b/etc/Kernel.makefile index cb9777b..6861d05 100644 --- a/etc/Kernel.makefile +++ b/etc/Kernel.makefile @@ -51,6 +51,10 @@ KERNEL_OBJ=$(O)/arch/amd64/boot/yboot.o \ $(O)/arch/amd64/syscall_s.o \ $(O)/arch/amd64/syscall.o \ $(O)/arch/amd64/binfmt_elf.o \ + $(O)/arch/amd64/smp/smp.o \ + $(O)/arch/amd64/smp/ap_code.o \ + $(O)/arch/amd64/smp/ipi.o \ + $(O)/arch/amd64/smp/irq_ipi_s.o \ $(O)/sys/debug.o \ $(O)/sys/ubsan.o \ $(O)/sys/panic.o \ @@ -127,6 +131,7 @@ DIRS+=$(O)/arch/amd64/hw \ $(O)/drivers/usb \ $(O)/drivers/ata \ $(O)/drivers/pci \ + $(O)/arch/amd64/smp \ $(O)/fs \ $(O)/fs/ext2 \ $(O)/sys/block \ @@ -144,6 +149,8 @@ include etc/KernelOptions.makefile KERNEL_GIT_VERSION=$(shell git describe --always --tags) KERNEL_CFLAGS=-Iinclude \ -Iinclude/arch/amd64/acpica \ + -DAMD64_SMP=4 \ + -DAMD64_MAX_SMP=4 \ -Iboot \ -fshort-wchar \ -I$(O)/include \ @@ -163,7 +170,8 @@ KERNEL_CFLAGS=-Iinclude \ -Wall \ -Wextra \ -Wno-unused \ - -O0 \ + -O2 \ + -funroll-loops \ -ggdb \ -Werror $(KERNEL_DEF) KERNEL_LDFLAGS=-nostdlib \ @@ -202,3 +210,17 @@ $(O)/sys/font/default8x16.psfu.o: etc/default8x16.psfu arch/amd64/incbin.S -DINCBIN_START="_psf_start" \ -DINCBIN_END="_psf_end" \ -o $@ arch/amd64/incbin.S + +$(O)/arch/amd64/smp/ap_code.o: $(O)/arch/amd64/hw/ap_code.bin arch/amd64/incbin.S + @echo " RES $@" + @$(CC) \ + -c \ + -D__ASM__ \ + -DINCBIN_FILE='"$(O)/arch/amd64/hw/ap_code.bin"' \ + -DINCBIN_START="amd64_ap_code_start" \ + -DINCBIN_END="amd64_ap_code_end" \ + -o $@ arch/amd64/incbin.S + +$(O)/arch/amd64/hw/ap_code.bin: arch/amd64/hw/ap_code.nasm + @echo "NASM $@" + @nasm -fbin -o $@ $< diff --git a/fs/sysfs.c b/fs/sysfs.c index 4f7616b..d154881 100644 --- a/fs/sysfs.c +++ b/fs/sysfs.c @@ -372,6 +372,8 @@ void sysfs_populate(void) { sysfs_add_config_endpoint(dir, "modules", SYSFS_MODE_DEFAULT, 512, NULL, mod_list, NULL); sysfs_add_config_endpoint(dir, "debug_serial", SYSFS_MODE_DEFAULT, 32, "serial", debug_config_get, debug_config_set); sysfs_add_config_endpoint(dir, "debug_display", SYSFS_MODE_DEFAULT, 32, "display", debug_config_get, debug_config_set); + extern size_t sched_ncpus; + sysfs_add_config_endpoint(dir, "smp", SYSFS_MODE_DEFAULT, 16, &sched_ncpus, sysfs_config_int64_getter, NULL); sysfs_add_config_endpoint(NULL, "mem", SYSFS_MODE_DEFAULT, 512, NULL, system_mem_getter, NULL); diff --git a/sys/panic.c b/sys/panic.c index c5625b4..9908bc1 100644 --- a/sys/panic.c +++ b/sys/panic.c @@ -13,7 +13,7 @@ void panicf(const char *fmt, ...) { asm volatile ("cli"); va_list args; - kfatal("--- Panic ---\n"); + kfatal("--- Panic (cpu%d) ---\n", get_cpu()->processor_id); if (sched_ready) { debugs(DEBUG_FATAL, "\033[41m"); @@ -35,7 +35,6 @@ void panicf(const char *fmt, ...) { #if defined(AMD64_SMP) // Send PANIC IPIs to all other CPUs size_t cpu = get_cpu()->processor_id; - kfatal("cpu%u initiates panic sequence\n", cpu); for (size_t i = 0; i < smp_ncpus; ++i) { if (i != cpu) { amd64_ipi_send(i, IPI_VECTOR_PANIC); diff --git a/sys/sched.c b/sys/sched.c index 20532fa..9a3d401 100644 --- a/sys/sched.c +++ b/sys/sched.c @@ -25,6 +25,7 @@ static struct thread threads_idle[AMD64_MAX_SMP] = {0}; static size_t queue_sizes[AMD64_MAX_SMP] = {0}; int sched_ncpus = 1; int sched_ready = 0; +static int clk = 0; static spin_t sched_lock = 0; @@ -90,7 +91,11 @@ void sched_queue(struct thread *thr) { } } spin_release_irqrestore(&sched_lock, &irq); - sched_queue_to(thr, min_queue_index); + if (min_queue_size == 0) { + sched_queue_to(thr, (clk++) % sched_ncpus); + } else { + sched_queue_to(thr, min_queue_index); + } #else sched_queue_to(thr, 0); #endif @@ -156,6 +161,26 @@ void sched_unqueue(struct thread *thr, enum thread_state new_state) { } } +void sched_debug_cycle(uint64_t ms) { + uintptr_t irq; + spin_lock_irqsave(&sched_lock, &irq); + + for (int cpu = 0; cpu < sched_ncpus; ++cpu) { + debugf(DEBUG_DEFAULT, "cpu%d: ", cpu); + + for (struct thread *thr = queue_heads[cpu]; thr; thr = thr->sched_next) { + debugf(DEBUG_DEFAULT, "#%d (%s):<%p> ", thr->proc->pid, thr->proc->name, thr); + if (thr->sched_next == queue_heads[cpu]) { + break; + } + } + + debugc(DEBUG_DEFAULT, '\n'); + } + + spin_release_irqrestore(&sched_lock, &irq); +} + //#if defined(DEBUG_COUNTERS) //static void sched_debug_tree(int level, struct thread *thr, int depth) { // for (int i = 0; i < depth; ++i) {