From 38d9a9586d55e684401b4095b42c4268d06ab3ce Mon Sep 17 00:00:00 2001 From: fef Date: Sat, 30 Oct 2021 03:34:04 +0200 Subject: [PATCH] smp: add base for SMP awareness --- arch/x86/boot/setup32.S | 5 +++- arch/x86/include/arch/sched.h | 35 +++++++++++------------- arch/x86/include/arch/smp.h | 50 +++++++++++++++++++++++++++++++++++ arch/x86/include/i386/sched.h | 41 ++++++++++++++++++++++++++++ cmake/config.cmake | 4 +++ include/gay/config.h.in | 6 +++++ 6 files changed, 121 insertions(+), 20 deletions(-) create mode 100644 arch/x86/include/arch/smp.h create mode 100644 arch/x86/include/i386/sched.h diff --git a/arch/x86/boot/setup32.S b/arch/x86/boot/setup32.S index bd578e0..0663137 100644 --- a/arch/x86/boot/setup32.S +++ b/arch/x86/boot/setup32.S @@ -3,6 +3,7 @@ #include #include +#include #include #include @@ -173,6 +174,7 @@ ASM_ENTRY(_setup_highmem) /* set up the initial stack frame */ mov $stack_top, %ebp mov %ebp, %esp + pushl $0 /* cpu number, see smp_cpuid() in arch/smp.h */ /* reset EFLAGS */ pushl $0 @@ -199,8 +201,9 @@ ASM_ENTRY(_setup_highmem) ASM_END(_setup_highmem) .section .bootstrap_stack, "aw", @nobits + .align KERN_STACK_SIZE stack_bottom: - .skip 16384 /* 16 KiB for the stack should be plenty for now */ + .skip KERN_STACK_SIZE stack_top: /* diff --git a/arch/x86/include/arch/sched.h b/arch/x86/include/arch/sched.h index c62d204..0148888 100644 --- a/arch/x86/include/arch/sched.h +++ b/arch/x86/include/arch/sched.h @@ -1,29 +1,24 @@ /* See the end of this file for copyright and license terms. */ #pragma once +#define _ARCH_SCHED_H_ + +#include + +#define KERN_STACK_PAGES 2 +#define KERN_STACK_SHIFT (PAGE_SHIFT + KERN_STACK_PAGES - 1) +#define KERN_STACK_SIZE (1 << KERN_STACK_SHIFT) + +#ifndef _ASM_SOURCE #include #include -/** - * @brief In-kernel context save for the x86. - * This precise structure layout is hardcoded in assembly, so don't forget to - * update `arch/x86/sys/switch.S` if you need to change it for whatever reason. - */ -struct x86_context { - /** - * The register itself is %esp, which points to the %eip that was pushed - * by the function calling `arch_switch_to()` as per the x86 SysV ABI - */ - union { - register_t esp; - register_t *eip; - }; - register_t esi; - register_t edi; - register_t ebx; - register_t ebp; -} __packed; +#ifdef __x86_64__ +#include +#else +#include +#endif /** * @brief Arch dependent Task Control Block (x86 version). @@ -41,6 +36,8 @@ typedef struct x86_context tcb_t; */ extern void arch_switch_to(tcb_t *new, tcb_t *old); +#endif /* not _ASM_SOURCE */ + /* * This file is part of GayBSD. * Copyright (c) 2021 fef . diff --git a/arch/x86/include/arch/smp.h b/arch/x86/include/arch/smp.h new file mode 100644 index 0000000..7040c0a --- /dev/null +++ b/arch/x86/include/arch/smp.h @@ -0,0 +1,50 @@ +/* See the end of this file for copyright and license terms. */ + +#pragma once + +#include +#include + +#include +#include +#include + +static inline int smp_cpuid(void) +{ +#if CFG_SMP + /* + * The x86 has a dedicated CPUID instruction that can be used to query + * pretty much anything except literally the cpu id. Therefore, we make + * use of the fact that kernel stacks are always aligned to their size. + * The cpu number is the topmost item on the stack; for cpu 0 this gets + * pushed in the assembly routine in startup{32,64}.S and for all others + * ... there is no implementation yet. + */ + u_register_t sp; + +#ifdef __x86_64__ + __asm__ volatile("movq %%rsp, %0" : "=r"(sp)); +#else + __asm__ volatile("movl %%esp, %0" : "=r"(sp)); +#endif + + sp &= ~(KERN_STACK_SIZE - 1); + return ((int *)sp)[KERN_STACK_SIZE / sizeof(int) - 1]; +#else /* !CFG_SMP */ + return 0; +#endif /* !CFG_SMP */ +} + +/* + * This file is part of GayBSD. + * Copyright (c) 2021 fef . + * + * GayBSD is nonviolent software: you may only use, redistribute, and/or + * modify it under the terms of the Cooperative Nonviolent Public License + * (CNPL) as found in the LICENSE file in the source code root directory + * or at ; either version 7 + * of the license, or (at your option) any later version. + * + * GayBSD comes with ABSOLUTELY NO WARRANTY, to the extent + * permitted by applicable law. See the CNPL for details. + */ diff --git a/arch/x86/include/i386/sched.h b/arch/x86/include/i386/sched.h new file mode 100644 index 0000000..1c95dea --- /dev/null +++ b/arch/x86/include/i386/sched.h @@ -0,0 +1,41 @@ +/* See the end of this file for copyright and license terms. */ + +#pragma once + +#ifndef _ARCH_SCHED_H_ +#error "This file is not meant to be included directly, use " +#endif + +/** + * @brief In-kernel context save for the x86. + * This precise structure layout is hardcoded in assembly, so don't forget to + * update `arch/x86/sys/switch.S` if you need to change it for whatever reason. + */ +struct x86_context { + /** + * The register itself is %esp, which points to the %eip that was pushed + * by the function calling `arch_switch_to()` as per the x86 SysV ABI + */ + union { + register_t esp; + register_t *eip; + }; + register_t esi; + register_t edi; + register_t ebx; + register_t ebp; +} __packed; + +/* + * This file is part of GayBSD. + * Copyright (c) 2021 fef . + * + * GayBSD is nonviolent software: you may only use, redistribute, and/or + * modify it under the terms of the Cooperative Nonviolent Public License + * (CNPL) as found in the LICENSE file in the source code root directory + * or at ; either version 7 + * of the license, or (at your option) any later version. + * + * GayBSD comes with ABSOLUTELY NO WARRANTY, to the extent + * permitted by applicable law. See the CNPL for details. + */ diff --git a/cmake/config.cmake b/cmake/config.cmake index 5bbcc95..0fc1af3 100644 --- a/cmake/config.cmake +++ b/cmake/config.cmake @@ -14,6 +14,10 @@ option(CFG_POISON_PAGES "Poison pages after allocate and free" ON) option(CFG_POISON_HEAP "Poison heap memory after kmalloc() and kfree()" ON) +option(CFG_SMP "Enable Symmetric Multiprocessing" ON) + +set(CFG_MAX_CPU "64" CACHE STRING "Maximum number of logical processors") + option(CFG_DEBUG_IRQ "Debug IRQs" ${DEBUG}) option(CFG_DEBUG_CLIST "Sanitize clist operations" ${DEBUG}) diff --git a/include/gay/config.h.in b/include/gay/config.h.in index 4efd91b..c75b4b9 100644 --- a/include/gay/config.h.in +++ b/include/gay/config.h.in @@ -31,6 +31,12 @@ /** @brief Poison heap areas after `kmalloc()` and `kfree()` */ #cmakedefine01 CFG_POISON_HEAP +/** @brief Enable Symmetric Multiprocessing */ +#cmakedefine01 CFG_SMP + +/** @brief Maximum number of logical processors */ +#define CFG_MAX_CPU @CFG_MAX_CPU@ + /** @brief Debug IRQs */ #cmakedefine01 CFG_DEBUG_IRQ