From 13ce3249888755d1570ba27a670b14b6f4b6efdb Mon Sep 17 00:00:00 2001 From: Philippe Aubertin <39178965+phaubertin@users.noreply.github.com> Date: Tue, 12 Nov 2024 22:37:51 -0500 Subject: [PATCH] Reorganize and cleanup architecture-specific code (#83) * Organize architecture-specific code into subdirectories. * Split per CPU data access and CPU feature detection into separate files. * Rename functions related to page mapping. * Reorganize architecture-specific definitions in header files. * Ensure object and dependency files don't conflict when assembly and C source files have the same name (e.g. thread.c vs thread.asm). --- .github/workflows/build-i686.yml | 2 +- common.mk | 36 +-- header.mk | 14 +- include/kernel/domain/alloc/slab.h | 2 +- .../kernel/infrastructure/i686/asm/cpuid.h | 64 +++++ .../kernel/infrastructure/i686/asm/cpuinfo.h | 61 +++++ .../i686/{remap.h => asm/eflags.h} | 10 +- include/kernel/infrastructure/i686/asm/msr.h | 50 ++++ include/kernel/infrastructure/i686/cpu.h | 132 --------- include/kernel/infrastructure/i686/cpuinfo.h | 57 ++++ .../i686/{ => drivers}/asm/pic8259.h | 4 +- .../i686/{ => drivers}/asm/uart16550a.h | 4 +- .../i686/{ => drivers}/asm/vga.h | 4 +- .../i686/{ => drivers}/pic8259.h | 6 +- .../i686/{ => drivers}/uart16550a.h | 4 +- .../infrastructure/i686/{ => drivers}/vga.h | 6 +- include/kernel/infrastructure/i686/iodelay.h | 37 +++ .../infrastructure/i686/{ => isa}/abi.h | 5 +- .../kernel/infrastructure/i686/isa/instrs.h | 64 +++++ .../kernel/infrastructure/i686/{ => isa}/io.h | 10 +- .../infrastructure/i686/{x86.h => isa/regs.h} | 48 +--- include/kernel/infrastructure/i686/memory.h | 2 +- .../i686/{cpu_data.h => percpu.h} | 24 +- .../i686/{asm/vm.h => pmap/asm/pmap.h} | 8 +- .../kernel/infrastructure/i686/pmap/init.h | 47 ++++ .../i686/{vm_x86.h => pmap/nopae.h} | 32 +-- .../i686/{vm_pae.h => pmap/pae.h} | 36 +-- .../infrastructure/i686/{vm.h => pmap/pmap.h} | 32 +-- .../i686/{vm_private.h => pmap/private.h} | 28 +- include/kernel/infrastructure/i686/thread.h | 43 +++ include/kernel/infrastructure/i686/types.h | 8 +- include/kernel/machine/cpuinfo.h | 37 +++ include/kernel/machine/{vm.h => pmap.h} | 4 +- include/kernel/machine/{cpu.h => tls.h} | 6 +- include/kernel/utils/{vm.h => pmap.h} | 4 +- kernel/Makefile | 39 +-- kernel/application/syscalls/mclone.c | 2 +- kernel/application/syscalls/mmap.c | 2 +- .../application/syscalls/set_thread_local.c | 2 +- kernel/domain/alloc/page_alloc.c | 2 +- kernel/domain/alloc/slab.c | 2 +- kernel/domain/alloc/vmalloc.c | 2 +- kernel/domain/entities/object.c | 2 +- kernel/domain/entities/process.c | 2 +- kernel/domain/services/ipc.c | 2 +- kernel/infrastructure/elf.c | 4 +- kernel/infrastructure/i686/boot_alloc.c | 2 +- kernel/infrastructure/i686/cpu.c | 252 ------------------ kernel/infrastructure/i686/cpuinfo.c | 185 +++++++++++++ kernel/infrastructure/i686/debug.c | 4 +- .../i686/{ => drivers}/pic8259.c | 5 +- .../i686/{ => drivers}/uart16550a.c | 6 +- .../infrastructure/i686/{ => drivers}/vga.c | 8 +- kernel/infrastructure/i686/halt.c | 4 +- kernel/infrastructure/i686/init.c | 62 +++-- kernel/infrastructure/i686/iodelay.asm | 40 +++ kernel/infrastructure/i686/{ => isa}/abi.asm | 4 - kernel/infrastructure/i686/isa/instrs.asm | 167 ++++++++++++ kernel/infrastructure/i686/{ => isa}/io.asm | 19 +- .../i686/{x86.asm => isa/regs.asm} | 214 +-------------- kernel/infrastructure/i686/memory.c | 6 +- kernel/infrastructure/i686/percpu.c | 101 +++++++ .../i686/{remap.asm => pmap/init.asm} | 39 ++- .../i686/{vm_x86.c => pmap/nopae.c} | 36 +-- .../i686/{vm_pae.c => pmap/pae.c} | 103 +++---- .../infrastructure/i686/{vm.c => pmap/pmap.c} | 150 +++++------ kernel/infrastructure/i686/process.c | 10 +- .../i686/{thread_switch.asm => thread.asm} | 15 +- kernel/infrastructure/i686/thread.c | 25 +- .../{infrastructure => interface}/i686/auxv.c | 0 kernel/interface/i686/bootinfo.c | 2 +- kernel/interface/i686/interrupt.c | 6 +- kernel/interface/i686/ld/image.lds | 8 +- kernel/interface/i686/setup16.asm | 2 +- kernel/interface/i686/setup32.asm | 8 +- kernel/interface/i686/trap.asm | 2 +- kernel/interface/syscalls.c | 2 +- userspace/lib/jinue/Makefile | 2 +- userspace/lib/libc/Makefile | 4 +- 79 files changed, 1413 insertions(+), 1072 deletions(-) create mode 100644 include/kernel/infrastructure/i686/asm/cpuid.h create mode 100644 include/kernel/infrastructure/i686/asm/cpuinfo.h rename include/kernel/infrastructure/i686/{remap.h => asm/eflags.h} (85%) create mode 100644 include/kernel/infrastructure/i686/asm/msr.h delete mode 100644 include/kernel/infrastructure/i686/cpu.h create mode 100644 include/kernel/infrastructure/i686/cpuinfo.h rename include/kernel/infrastructure/i686/{ => drivers}/asm/pic8259.h (95%) rename include/kernel/infrastructure/i686/{ => drivers}/asm/uart16550a.h (93%) rename include/kernel/infrastructure/i686/{ => drivers}/asm/vga.h (95%) rename include/kernel/infrastructure/i686/{ => drivers}/pic8259.h (90%) rename include/kernel/infrastructure/i686/{ => drivers}/uart16550a.h (92%) rename include/kernel/infrastructure/i686/{ => drivers}/vga.h (91%) create mode 100644 include/kernel/infrastructure/i686/iodelay.h rename include/kernel/infrastructure/i686/{ => isa}/abi.h (94%) create mode 100644 include/kernel/infrastructure/i686/isa/instrs.h rename include/kernel/infrastructure/i686/{ => isa}/io.h (94%) rename include/kernel/infrastructure/i686/{x86.h => isa/regs.h} (72%) rename include/kernel/infrastructure/i686/{cpu_data.h => percpu.h} (77%) rename include/kernel/infrastructure/i686/{asm/vm.h => pmap/asm/pmap.h} (90%) create mode 100644 include/kernel/infrastructure/i686/pmap/init.h rename include/kernel/infrastructure/i686/{vm_x86.h => pmap/nopae.h} (63%) rename include/kernel/infrastructure/i686/{vm_pae.h => pmap/pae.h} (66%) rename include/kernel/infrastructure/i686/{vm.h => pmap/pmap.h} (79%) rename include/kernel/infrastructure/i686/{vm_private.h => pmap/private.h} (81%) create mode 100644 include/kernel/infrastructure/i686/thread.h create mode 100644 include/kernel/machine/cpuinfo.h rename include/kernel/machine/{vm.h => pmap.h} (96%) rename include/kernel/machine/{cpu.h => tls.h} (92%) rename include/kernel/utils/{vm.h => pmap.h} (97%) delete mode 100644 kernel/infrastructure/i686/cpu.c create mode 100644 kernel/infrastructure/i686/cpuinfo.c rename kernel/infrastructure/i686/{ => drivers}/pic8259.c (96%) rename kernel/infrastructure/i686/{ => drivers}/uart16550a.c (95%) rename kernel/infrastructure/i686/{ => drivers}/vga.c (96%) create mode 100755 kernel/infrastructure/i686/iodelay.asm rename kernel/infrastructure/i686/{ => isa}/abi.asm (99%) create mode 100644 kernel/infrastructure/i686/isa/instrs.asm rename kernel/infrastructure/i686/{ => isa}/io.asm (91%) rename kernel/infrastructure/i686/{x86.asm => isa/regs.asm} (57%) create mode 100644 kernel/infrastructure/i686/percpu.c rename kernel/infrastructure/i686/{remap.asm => pmap/init.asm} (86%) rename kernel/infrastructure/i686/{vm_x86.c => pmap/nopae.c} (83%) rename kernel/infrastructure/i686/{vm_pae.c => pmap/pae.c} (86%) rename kernel/infrastructure/i686/{vm.c => pmap/pmap.c} (87%) rename kernel/infrastructure/i686/{thread_switch.asm => thread.asm} (92%) rename kernel/{infrastructure => interface}/i686/auxv.c (100%) diff --git a/.github/workflows/build-i686.yml b/.github/workflows/build-i686.yml index 81177323..862faa54 100644 --- a/.github/workflows/build-i686.yml +++ b/.github/workflows/build-i686.yml @@ -21,7 +21,7 @@ jobs: steps: - name: Install dependencies - run: sudo apt-get install -y gcc-multilib grub-common nasm qemu-system-x86 xorriso + run: sudo apt update && sudo apt-get install -y gcc-multilib grub-common nasm qemu-system-x86 xorriso - uses: actions/checkout@v4 with: diff --git a/common.mk b/common.mk index 6649f5f8..a23f906e 100644 --- a/common.mk +++ b/common.mk @@ -50,27 +50,27 @@ FORCE: %.nasm: %.asm @echo "; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *" > $@ - @echo "; * This file is automatically generated by passing the assembly language" >> $@ - @echo "; * file through the C preprocessor. Any change made here will be lost" >> $@ - @echo "; * on the next build." >> $@ - @echo "; *" >> $@ - @echo "; * The file you want to edit instead is $<." >> $@ - @echo "; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *" >> $@ - @echo "" >> $@ - $(CPP) $(DEPFLAGS) $(CPPFLAGS) -x assembler-with-cpp $< >> $@ + @echo "; * This file is automatically generated by passing the assembly language" >> $@ + @echo "; * file through the C preprocessor. Any change made here will be lost" >> $@ + @echo "; * on the next build." >> $@ + @echo "; *" >> $@ + @echo "; * The file you want to edit instead is $<." >> $@ + @echo "; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *" >> $@ + @echo "" >> $@ + $(CPP) $(DEPFLAGS)$(basename $@)-nasm.d $(CPPFLAGS) -x assembler-with-cpp $< >> $@ %.ld: %.lds - @echo "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *" > $@ - @echo " * This file is automatically generated by passing the linker script" >> $@ - @echo " * through the C preprocessor. Any change made here will be lost on the" >> $@ - @echo " * next build." >> $@ - @echo " *" >> $@ - @echo " * The file you want to edit instead is $<." >> $@ - @echo " * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */" >> $@ - @echo "" >> $@ + @echo "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *" > $@ + @echo " * This file is automatically generated by passing the linker script" >> $@ + @echo " * through the C preprocessor. Any change made here will be lost on the" >> $@ + @echo " * next build." >> $@ + @echo " *" >> $@ + @echo " * The file you want to edit instead is $<." >> $@ + @echo " * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */" >> $@ + @echo "" >> $@ $(CPP) $(CPPFLAGS) -x c -P $< >> $@ -%.o: %.nasm +%-nasm.o: %.nasm nasm -f elf $(NASMFLAGS) -o $@ $< %.bin: %.nasm @@ -81,4 +81,4 @@ FORCE: .PRECIOUS: %.nasm -include $(wildcard $(patsubst %,%.d,$(basename $(objects)))) +include $(wildcard $(depfiles)) diff --git a/header.mk b/header.mk index f9e32977..adbd6c7b 100644 --- a/header.mk +++ b/header.mk @@ -75,17 +75,23 @@ libjinue_utils = $(libjinue)/libjinue-utils.a # object files objects.c = $(sources.c:%.c=%.o) -objects.nasm = $(sources.nasm:%.asm=%.o) +objects.nasm = $(sources.nasm:%.asm=%-nasm.o) objects.extra = objects = $(objects.c) $(objects.nasm) $(objects.extra) +# Dependency files +depfiles.c = $(sources.c:%.c=%.d) +depfiles.nasm = $(sources.nasm:%.asm=%-nasm.d) +depfiles.extra = +depfiles = $(depfiles.c) $(depfiles.nasm) $(depfiles.extra) + # built targets targets.phony ?= targets ?= $(target) targets.all = $(targets) $(targets.phony) # files to clean up -unclean.build = $(objects) $(targets) $(objects:%.o=%.d) $(sources.nasm:%.asm=%.nasm) +unclean.build = $(objects) $(targets) $(depfiles) $(sources.nasm:%.asm=%.nasm) unclean.extra = unclean = $(unclean.build) $(unclean.extra) unclean_recursive ?= @@ -134,10 +140,10 @@ NASMFLAGS = $(NASMFLAGS.arch) $(NASMFLAGS.debug) $(NASMFLAGS.others) STRIPFLAGS = --strip-debug # Automatic dependencies generation flags -DEPFLAGS = -MT $@ -MD -MP -MF $*.d +DEPFLAGS = -MT $@ -MD -MP -MF # Add dependencies generation flags when compiling object files from C source code -COMPILE.c = $(CC) $(DEPFLAGS) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c +COMPILE.c = $(CC) $(DEPFLAGS) $(basename $@).d $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c # macro to include common target definitions (all, clean, implicit rules) common = $(jinue_root)/common.mk diff --git a/include/kernel/domain/alloc/slab.h b/include/kernel/domain/alloc/slab.h index 9f0dbf38..463970d2 100644 --- a/include/kernel/domain/alloc/slab.h +++ b/include/kernel/domain/alloc/slab.h @@ -33,7 +33,7 @@ #define JINUE_KERNEL_DOMAIN_SLAB_H #include -#include +#include #include #define SLAB_SIZE PAGE_SIZE diff --git a/include/kernel/infrastructure/i686/asm/cpuid.h b/include/kernel/infrastructure/i686/asm/cpuid.h new file mode 100644 index 00000000..f5963988 --- /dev/null +++ b/include/kernel/infrastructure/i686/asm/cpuid.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2019-2024 Philippe Aubertin. + * All rights reserved. + + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the author nor the names of other contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef JINUE_KERNEL_INFRASTRUCTURE_I686_ASM_CPUID_H +#define JINUE_KERNEL_INFRASTRUCTURE_I686_ASM_CPUID_H + +#define CPUID_FEATURE_FPU (1<<0) + +#define CPUID_FEATURE_PSE (1<<3) + +#define CPUID_FEATURE_PAE (1<<6) + +#define CPUID_FEATURE_APIC (1<<9) + +#define CPUID_FEATURE_SEP (1<<11) + +#define CPUID_FEATURE_PGE (1<<13) + +#define CPUID_FEATURE_CLFLUSH (1<<19) + +#define CPUID_FEATURE_NXE (1<<20) + +#define CPUID_FEATURE_HTT (1<<28) + + +#define CPUID_EXT_FEATURE_SYSCALL (1<<11) + +#define CPUID_VENDOR_AMD_DW0 0x68747541 /* Auth */ +#define CPUID_VENDOR_AMD_DW1 0x69746e65 /* enti */ +#define CPUID_VENDOR_AMD_DW2 0x444d4163 /* cAMD */ + +#define CPUID_VENDOR_INTEL_DW0 0x756e6547 /* Genu */ +#define CPUID_VENDOR_INTEL_DW1 0x49656e69 /* ineI */ +#define CPUID_VENDOR_INTEL_DW2 0x6c65746e /* ntel */ + +#endif diff --git a/include/kernel/infrastructure/i686/asm/cpuinfo.h b/include/kernel/infrastructure/i686/asm/cpuinfo.h new file mode 100644 index 00000000..f2215ebd --- /dev/null +++ b/include/kernel/infrastructure/i686/asm/cpuinfo.h @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2019-2024 Philippe Aubertin. + * All rights reserved. + + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the author nor the names of other contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef JINUE_KERNEL_INFRASTRUCTURE_I686_ASM_CPUINFO_H +#define JINUE_KERNEL_INFRASTRUCTURE_I686_ASM_CPUINFO_H + +/* features */ + +#define CPUINFO_FEATURE_CPUID (1<<0) + +#define CPUINFO_FEATURE_SYSENTER (1<<1) + +#define CPUINFO_FEATURE_SYSCALL (1<<2) + +#define CPUINFO_FEATURE_LOCAL_APIC (1<<3) + +#define CPUINFO_FEATURE_PAE (1<<4) + +#define CPUINFO_FEATURE_PGE (1<<5) + +#define CPUINFO_FEATURE_PSE (1<<6) + +#define CPUINFO_FEATURE_NOEXEC (1<<7) + +/* vendors */ + +#define CPUINFO_VENDOR_GENERIC 0 + +#define CPUINFO_VENDOR_AMD 1 + +#define CPUINFO_VENDOR_INTEL 2 + +#endif diff --git a/include/kernel/infrastructure/i686/remap.h b/include/kernel/infrastructure/i686/asm/eflags.h similarity index 85% rename from include/kernel/infrastructure/i686/remap.h rename to include/kernel/infrastructure/i686/asm/eflags.h index 7e418856..8ece872b 100644 --- a/include/kernel/infrastructure/i686/remap.h +++ b/include/kernel/infrastructure/i686/asm/eflags.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2021 Philippe Aubertin. + * Copyright (C) 2019-2024 Philippe Aubertin. * All rights reserved. * Redistribution and use in source and binary forms, with or without @@ -29,11 +29,9 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef JINUE_KERNEL_INFRASTRUCTURE_I686_REMAP_H -#define JINUE_KERNEL_INFRASTRUCTURE_I686_REMAP_H +#ifndef JINUE_KERNEL_INFRASTRUCTURE_I686_ASM_EFLAGS_H +#define JINUE_KERNEL_INFRASTRUCTURE_I686_ASM_EFLAGS_H -#include - -void move_and_remap_kernel(addr_t end_addr, addr_t pte, uint32_t cr3_value); +#define CPU_EFLAGS_ID (1<<21) #endif diff --git a/include/kernel/infrastructure/i686/asm/msr.h b/include/kernel/infrastructure/i686/asm/msr.h new file mode 100644 index 00000000..89fb6dd3 --- /dev/null +++ b/include/kernel/infrastructure/i686/asm/msr.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2019-2024 Philippe Aubertin. + * All rights reserved. + + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the author nor the names of other contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef JINUE_KERNEL_INFRASTRUCTURE_I686_ASM_MSR_H +#define JINUE_KERNEL_INFRASTRUCTURE_I686_ASM_MSR_H + +#define MSR_IA32_SYSENTER_CS 0x174 + +#define MSR_IA32_SYSENTER_ESP 0x175 + +#define MSR_IA32_SYSENTER_EIP 0x176 + +#define MSR_EFER 0xC0000080 + +#define MSR_STAR 0xC0000081 + + +#define MSR_FLAG_EFER_SCE (1<<0) + +#define MSR_FLAG_EFER_NXE (1<<11) + +#endif diff --git a/include/kernel/infrastructure/i686/cpu.h b/include/kernel/infrastructure/i686/cpu.h deleted file mode 100644 index c3747402..00000000 --- a/include/kernel/infrastructure/i686/cpu.h +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright (C) 2019 Philippe Aubertin. - * All rights reserved. - - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the author nor the names of other contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef JINUE_KERNEL_INFRASTRUCTURE_I686_CPU_H -#define JINUE_KERNEL_INFRASTRUCTURE_I686_CPU_H - -#include - - -#define MSR_IA32_SYSENTER_CS 0x174 - -#define MSR_IA32_SYSENTER_ESP 0x175 - -#define MSR_IA32_SYSENTER_EIP 0x176 - -#define MSR_EFER 0xC0000080 - -#define MSR_STAR 0xC0000081 - - -#define MSR_FLAG_EFER_SCE (1<<0) - -#define MSR_FLAG_EFER_NXE (1<<11) - - -#define CPU_FEATURE_CPUID (1<<0) - -#define CPU_FEATURE_SYSENTER (1<<1) - -#define CPU_FEATURE_SYSCALL (1<<2) - -#define CPU_FEATURE_LOCAL_APIC (1<<3) - -#define CPU_FEATURE_PAE (1<<4) - -#define CPU_FEATURE_PGE (1<<5) - -#define CPU_FEATURE_PSE (1<<6) - -#define CPU_FEATURE_NOEXEC (1<<7) - - -#define CPU_EFLAGS_ID (1<<21) - - -#define CPUID_FEATURE_FPU (1<<0) - -#define CPUID_FEATURE_PSE (1<<3) - -#define CPUID_FEATURE_PAE (1<<6) - -#define CPUID_FEATURE_APIC (1<<9) - -#define CPUID_FEATURE_SEP (1<<11) - -#define CPUID_FEATURE_PGE (1<<13) - -#define CPUID_FEATURE_CLFLUSH (1<<19) - -#define CPUID_FEATURE_NXE (1<<20) - -#define CPUID_FEATURE_HTT (1<<28) - - -#define CPUID_EXT_FEATURE_SYSCALL (1<<11) - - -#define CPU_VENDOR_GENERIC 0 - -#define CPU_VENDOR_AMD 1 - -#define CPU_VENDOR_INTEL 2 - - -#define CPU_VENDOR_AMD_DW0 0x68747541 /* Auth */ -#define CPU_VENDOR_AMD_DW1 0x69746e65 /* enti */ -#define CPU_VENDOR_AMD_DW2 0x444d4163 /* cAMD */ - -#define CPU_VENDOR_INTEL_DW0 0x756e6547 /* Genu */ -#define CPU_VENDOR_INTEL_DW1 0x49656e69 /* ineI */ -#define CPU_VENDOR_INTEL_DW2 0x6c65746e /* ntel */ - -typedef struct { - unsigned int maxphyaddr; - unsigned int dcache_alignment; - uint32_t features; - int vendor; - int family; - int model; - int stepping; -} cpu_info_t; - -extern cpu_info_t cpu_info; - -static inline bool cpu_has_feature(uint32_t mask) { - return (cpu_info.features & mask) == mask; -} - -void cpu_init_data(cpu_data_t *data); - -void cpu_detect_features(void); - - -#endif diff --git a/include/kernel/infrastructure/i686/cpuinfo.h b/include/kernel/infrastructure/i686/cpuinfo.h new file mode 100644 index 00000000..33226eb9 --- /dev/null +++ b/include/kernel/infrastructure/i686/cpuinfo.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2019-2024 Philippe Aubertin. + * All rights reserved. + + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the author nor the names of other contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef JINUE_KERNEL_INFRASTRUCTURE_I686_CPUINFO_H +#define JINUE_KERNEL_INFRASTRUCTURE_I686_CPUINFO_H + +#include +#include +#include + +typedef struct { + unsigned int maxphyaddr; + unsigned int dcache_alignment; + uint32_t features; + int vendor; + int family; + int model; + int stepping; +} cpuinfo_t; + +extern cpuinfo_t cpuinfo; + +void detect_cpu_features(void); + +static inline bool cpu_has_feature(uint32_t mask) { + return (cpuinfo.features & mask) == mask; +} + +#endif diff --git a/include/kernel/infrastructure/i686/asm/pic8259.h b/include/kernel/infrastructure/i686/drivers/asm/pic8259.h similarity index 95% rename from include/kernel/infrastructure/i686/asm/pic8259.h rename to include/kernel/infrastructure/i686/drivers/asm/pic8259.h index 7c30225f..a83488e2 100644 --- a/include/kernel/infrastructure/i686/asm/pic8259.h +++ b/include/kernel/infrastructure/i686/drivers/asm/pic8259.h @@ -29,8 +29,8 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef JINUE_KERNEL_INFRASTRUCTURE_I686_ASM_PIC8259_H -#define JINUE_KERNEL_INFRASTRUCTURE_I686_ASM_PIC8259_H +#ifndef JINUE_KERNEL_INFRASTRUCTURE_I686_DRIVERS_ASM_PIC8259_H +#define JINUE_KERNEL_INFRASTRUCTURE_I686_DRIVERS_ASM_PIC8259_H /** Base I/O port for the main interrupt controller */ #define PIC8259_MAIN_IO_BASE 0x20 diff --git a/include/kernel/infrastructure/i686/asm/uart16550a.h b/include/kernel/infrastructure/i686/drivers/asm/uart16550a.h similarity index 93% rename from include/kernel/infrastructure/i686/asm/uart16550a.h rename to include/kernel/infrastructure/i686/drivers/asm/uart16550a.h index 0ca1e021..e67d1240 100644 --- a/include/kernel/infrastructure/i686/asm/uart16550a.h +++ b/include/kernel/infrastructure/i686/drivers/asm/uart16550a.h @@ -29,8 +29,8 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef JINUE_KERNEL_INFRASTRUCTURE_I686_ASM_UART16550A_H_ -#define JINUE_KERNEL_INFRASTRUCTURE_I686_ASM_UART16550A_H_ +#ifndef JINUE_KERNEL_INFRASTRUCTURE_I686_DRIVERS_ASM_UART16550A_H_ +#define JINUE_KERNEL_INFRASTRUCTURE_I686_DRIVERS_ASM_UART16550A_H_ #define UART165550A_REG_DATA_BUFFER 0 diff --git a/include/kernel/infrastructure/i686/asm/vga.h b/include/kernel/infrastructure/i686/drivers/asm/vga.h similarity index 95% rename from include/kernel/infrastructure/i686/asm/vga.h rename to include/kernel/infrastructure/i686/drivers/asm/vga.h index 9c4c690c..a427dfa9 100644 --- a/include/kernel/infrastructure/i686/asm/vga.h +++ b/include/kernel/infrastructure/i686/drivers/asm/vga.h @@ -29,8 +29,8 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef JINUE_KERNEL_INFRASTRUCTURE_I686_ASM_VGA_H_ -#define JINUE_KERNEL_INFRASTRUCTURE_I686_ASM_VGA_H_ +#ifndef JINUE_KERNEL_INFRASTRUCTURE_I686_DRIVERS_ASM_VGA_H_ +#define JINUE_KERNEL_INFRASTRUCTURE_I686_DRIVERS_ASM_VGA_H_ #define VGA_TEXT_VID_BASE 0xb8000 #define VGA_TEXT_VID_TOP 0xc0000 diff --git a/include/kernel/infrastructure/i686/pic8259.h b/include/kernel/infrastructure/i686/drivers/pic8259.h similarity index 90% rename from include/kernel/infrastructure/i686/pic8259.h rename to include/kernel/infrastructure/i686/drivers/pic8259.h index 2cd63e26..06e61ce3 100644 --- a/include/kernel/infrastructure/i686/pic8259.h +++ b/include/kernel/infrastructure/i686/drivers/pic8259.h @@ -29,10 +29,10 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef JINUE_KERNEL_INFRASTRUCTURE_I686_PIC8259_H -#define JINUE_KERNEL_INFRASTRUCTURE_I686_PIC8259_H +#ifndef JINUE_KERNEL_INFRASTRUCTURE_I686_DRIVERS_PIC8259_H +#define JINUE_KERNEL_INFRASTRUCTURE_I686_DRIVERS_PIC8259_H -#include +#include void pic8259_init(); diff --git a/include/kernel/infrastructure/i686/uart16550a.h b/include/kernel/infrastructure/i686/drivers/uart16550a.h similarity index 92% rename from include/kernel/infrastructure/i686/uart16550a.h rename to include/kernel/infrastructure/i686/drivers/uart16550a.h index f17fb415..71775178 100644 --- a/include/kernel/infrastructure/i686/uart16550a.h +++ b/include/kernel/infrastructure/i686/drivers/uart16550a.h @@ -29,8 +29,8 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef JINUE_KERNEL_INFRASTRUCTURE_I686_UART16550A_H_ -#define JINUE_KERNEL_INFRASTRUCTURE_I686_UART16550A_H_ +#ifndef JINUE_KERNEL_INFRASTRUCTURE_I686_DRIVERS_UART16550A_H_ +#define JINUE_KERNEL_INFRASTRUCTURE_I686_DRIVERS_UART16550A_H_ #include diff --git a/include/kernel/infrastructure/i686/vga.h b/include/kernel/infrastructure/i686/drivers/vga.h similarity index 91% rename from include/kernel/infrastructure/i686/vga.h rename to include/kernel/infrastructure/i686/drivers/vga.h index 38089b0b..4d319b98 100755 --- a/include/kernel/infrastructure/i686/vga.h +++ b/include/kernel/infrastructure/i686/drivers/vga.h @@ -29,10 +29,10 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef JINUE_KERNEL_INFRASTRUCTURE_I686_VGA_H -#define JINUE_KERNEL_INFRASTRUCTURE_I686_VGA_H +#ifndef JINUE_KERNEL_INFRASTRUCTURE_I686_DRIVERS_VGA_H +#define JINUE_KERNEL_INFRASTRUCTURE_I686_DRIVERS_VGA_H -#include +#include #include void vga_init(const config_t *config); diff --git a/include/kernel/infrastructure/i686/iodelay.h b/include/kernel/infrastructure/i686/iodelay.h new file mode 100644 index 00000000..fb4a9fee --- /dev/null +++ b/include/kernel/infrastructure/i686/iodelay.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2019-2024 Philippe Aubertin. + * All rights reserved. + + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the author nor the names of other contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef JINUE_KERNEL_INFRASTRUCTURE_I686_IODELAY_H +#define JINUE_KERNEL_INFRASTRUCTURE_I686_IODELAY_H + +void iodelay(void); + +#endif diff --git a/include/kernel/infrastructure/i686/abi.h b/include/kernel/infrastructure/i686/isa/abi.h similarity index 94% rename from include/kernel/infrastructure/i686/abi.h rename to include/kernel/infrastructure/i686/isa/abi.h index 08bfb67e..00b8d4b1 100755 --- a/include/kernel/infrastructure/i686/abi.h +++ b/include/kernel/infrastructure/i686/isa/abi.h @@ -29,12 +29,11 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef JINUE_KERNEL_INFRASTRUCTURE_I686_ABI_H -#define JINUE_KERNEL_INFRASTRUCTURE_I686_ABI_H +#ifndef JINUE_KERNEL_INFRASTRUCTURE_I686_ISA_ABI_H +#define JINUE_KERNEL_INFRASTRUCTURE_I686_ISA_ABI_H #include - addr_t get_fpointer(void); addr_t get_caller_fpointer(addr_t fptr); diff --git a/include/kernel/infrastructure/i686/isa/instrs.h b/include/kernel/infrastructure/i686/isa/instrs.h new file mode 100644 index 00000000..1ceb5f01 --- /dev/null +++ b/include/kernel/infrastructure/i686/isa/instrs.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2019-2024 Philippe Aubertin. + * All rights reserved. + + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the author nor the names of other contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef JINUE_KERNEL_INFRASTRUCTURE_I686_INSTRS_H +#define JINUE_KERNEL_INFRASTRUCTURE_I686_INSTRS_H + +#include + +typedef struct { + uint32_t eax; + uint32_t ebx; + uint32_t ecx; + uint32_t edx; +} x86_cpuid_regs_t; + +void cli(void); + +void sti(void); + +void hlt(void); + +void invlpg(void *vaddr); + +void lgdt(pseudo_descriptor_t *gdt_info); + +void lidt(pseudo_descriptor_t *idt_info); + +void ltr(seg_selector_t sel); + +uint32_t cpuid(x86_cpuid_regs_t *regs); + +uint64_t rdmsr(uint32_t addr); + +void wrmsr(uint32_t addr, uint64_t val); + +#endif diff --git a/include/kernel/infrastructure/i686/io.h b/include/kernel/infrastructure/i686/isa/io.h similarity index 94% rename from include/kernel/infrastructure/i686/io.h rename to include/kernel/infrastructure/i686/isa/io.h index 4fb0c718..d7bb360a 100755 --- a/include/kernel/infrastructure/i686/io.h +++ b/include/kernel/infrastructure/i686/isa/io.h @@ -29,20 +29,22 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef JINUE_KERNEL_INFRASTRUCTURE_I686_IO_H -#define JINUE_KERNEL_INFRASTRUCTURE_I686_IO_H +#ifndef JINUE_KERNEL_INFRASTRUCTURE_I686_ISA_IO_H +#define JINUE_KERNEL_INFRASTRUCTURE_I686_ISA_IO_H #include uint8_t inb(uint16_t port); + uint16_t inw(uint16_t port); + uint32_t inl(uint16_t port); void outb(uint16_t port, uint8_t value); + void outw(uint16_t port, uint16_t value); -void outl(uint16_t port, uint32_t value); -void iodelay(void); +void outl(uint16_t port, uint32_t value); #endif diff --git a/include/kernel/infrastructure/i686/x86.h b/include/kernel/infrastructure/i686/isa/regs.h similarity index 72% rename from include/kernel/infrastructure/i686/x86.h rename to include/kernel/infrastructure/i686/isa/regs.h index 9ad8bcce..1b5e3681 100644 --- a/include/kernel/infrastructure/i686/x86.h +++ b/include/kernel/infrastructure/i686/isa/regs.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 Philippe Aubertin. + * Copyright (C) 2019-2024 Philippe Aubertin. * All rights reserved. * Redistribution and use in source and binary forms, with or without @@ -29,37 +29,12 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef JINUE_KERNEL_INFRASTRUCTURE_I686_X86_H -#define JINUE_KERNEL_INFRASTRUCTURE_I686_X86_H +#ifndef JINUE_KERNEL_INFRASTRUCTURE_I686_REGS_H +#define JINUE_KERNEL_INFRASTRUCTURE_I686_REGS_H -#include -#include +#include -typedef struct { - uint32_t eax; - uint32_t ebx; - uint32_t ecx; - uint32_t edx; -} x86_cpuid_regs_t; - -typedef uint32_t msr_addr_t; - - -void cli(void); - -void sti(void); - -void hlt(void); - -void invalidate_tlb(void *vaddr); - -void lgdt(pseudo_descriptor_t *gdt_info); - -void lidt(pseudo_descriptor_t *idt_info); - -void ltr(seg_selector_t sel); - -uint32_t cpuid(x86_cpuid_regs_t *regs); +/* control registers */ uint32_t get_esp(void); @@ -77,10 +52,14 @@ void set_cr3(uint32_t val); void set_cr4(uint32_t val); +/* eflags */ + uint32_t get_eflags(void); void set_eflags(uint32_t val); +/* segment registers */ + void set_cs(uint32_t val); void set_ds(uint32_t val); @@ -93,15 +72,6 @@ void set_gs(uint32_t val); void set_ss(uint32_t val); -uint64_t rdmsr(msr_addr_t addr); - -void wrmsr(msr_addr_t addr, uint64_t val); - uint32_t get_gs_ptr(uint32_t *ptr); -uint64_t rdtsc(void); - -void x86_enable_pae(uint32_t cr3_value); - #endif - diff --git a/include/kernel/infrastructure/i686/memory.h b/include/kernel/infrastructure/i686/memory.h index be1e54ee..0a36774c 100644 --- a/include/kernel/infrastructure/i686/memory.h +++ b/include/kernel/infrastructure/i686/memory.h @@ -41,7 +41,7 @@ void check_memory(const bootinfo_t *bootinfo); void memory_initialize_array( boot_alloc_t *boot_alloc, - const bootinfo_t *bootinfo); + const bootinfo_t *bootinfo); void *memory_lookup_page(uint64_t paddr); diff --git a/include/kernel/infrastructure/i686/cpu_data.h b/include/kernel/infrastructure/i686/percpu.h similarity index 77% rename from include/kernel/infrastructure/i686/cpu_data.h rename to include/kernel/infrastructure/i686/percpu.h index 5e28ed51..f5ecc180 100644 --- a/include/kernel/infrastructure/i686/cpu_data.h +++ b/include/kernel/infrastructure/i686/percpu.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 Philippe Aubertin. + * Copyright (C) 2019-2024 Philippe Aubertin. * All rights reserved. * Redistribution and use in source and binary forms, with or without @@ -29,28 +29,28 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef JINUE_KERNEL_INFRASTRUCTURE_I686_CPU_DATA_H -#define JINUE_KERNEL_INFRASTRUCTURE_I686_CPU_DATA_H +#ifndef JINUE_KERNEL_INFRASTRUCTURE_I686_PERCPU_H +#define JINUE_KERNEL_INFRASTRUCTURE_I686_PERCPU_H +#include #include -#include +#define PERCPU_DATA_ALIGNMENT 256 -#define CPU_DATA_ALIGNMENT 256 - - -static inline cpu_data_t *get_cpu_local_data(void) { +static inline percpu_t *get_percpu_data(void) { /* CPU data structure is at address zero within the per-cpu data segment */ - cpu_data_t *const zero = (cpu_data_t *)0; - return (cpu_data_t *)get_gs_ptr( (uint32_t *)&zero->self ); + percpu_t *const zero = (percpu_t *)0; + return (percpu_t *)get_gs_ptr( (uint32_t *)&zero->self ); } static inline tss_t *get_tss(void) { - return &get_cpu_local_data()->tss; + return &get_percpu_data()->tss; } static inline addr_space_t *get_current_addr_space(void) { - return get_cpu_local_data()->current_addr_space; + return get_percpu_data()->current_addr_space; } +void init_percpu_data(percpu_t *data); + #endif diff --git a/include/kernel/infrastructure/i686/asm/vm.h b/include/kernel/infrastructure/i686/pmap/asm/pmap.h similarity index 90% rename from include/kernel/infrastructure/i686/asm/vm.h rename to include/kernel/infrastructure/i686/pmap/asm/pmap.h index 6d7e2079..d558453f 100644 --- a/include/kernel/infrastructure/i686/asm/vm.h +++ b/include/kernel/infrastructure/i686/pmap/asm/pmap.h @@ -29,16 +29,16 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef JINUE_KERNEL_INFRASTRUCTURE_I686_ASM_VM_H -#define JINUE_KERNEL_INFRASTRUCTURE_I686_ASM_VM_H +#ifndef JINUE_KERNEL_INFRASTRUCTURE_I686_PMAP_ASM_PMAP_H +#define JINUE_KERNEL_INFRASTRUCTURE_I686_PMAP_ASM_PMAP_H #include #include /** Number of entries per page table/directory, PAE disabled */ -#define VM_X86_PAGE_TABLE_PTES 1024 +#define NOPAE_PAGE_TABLE_PTES 1024 /** Number of entries per page table/directory, PAE enabled */ -#define VM_PAE_PAGE_TABLE_PTES 512 +#define PAE_PAGE_TABLE_PTES 512 #endif diff --git a/include/kernel/infrastructure/i686/pmap/init.h b/include/kernel/infrastructure/i686/pmap/init.h new file mode 100644 index 00000000..f2d98741 --- /dev/null +++ b/include/kernel/infrastructure/i686/pmap/init.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2019 Philippe Aubertin. + * All rights reserved. + + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the author nor the names of other contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef JINUE_KERNEL_INFRASTRUCTURE_I686_PMAP_INIT_H +#define JINUE_KERNEL_INFRASTRUCTURE_I686_PMAP_INIT_H + +/** This header file contains private definitions shared by pmap.c, pae.c + * and nopae.c in kernel/infrastructure/i686/pmap/. There should be no reason + * to include it anywhere else. */ + +#include +#include + +void move_and_remap_kernel(addr_t end_addr, addr_t pte, uint32_t cr3_value); + +void enable_pae(uint32_t cr3_value); + +#endif + diff --git a/include/kernel/infrastructure/i686/vm_x86.h b/include/kernel/infrastructure/i686/pmap/nopae.h similarity index 63% rename from include/kernel/infrastructure/i686/vm_x86.h rename to include/kernel/infrastructure/i686/pmap/nopae.h index 0b82eb2b..7e0e0a12 100644 --- a/include/kernel/infrastructure/i686/vm_x86.h +++ b/include/kernel/infrastructure/i686/pmap/nopae.h @@ -29,37 +29,37 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef JINUE_KERNEL_INFRASTRUCTURE_I686_VM_X86_H -#define JINUE_KERNEL_INFRASTRUCTURE_I686_VM_X86_H +#ifndef JINUE_KERNEL_INFRASTRUCTURE_I686_PMAP_NOPAE_H +#define JINUE_KERNEL_INFRASTRUCTURE_I686_PMAP_NOPAE_H /** This header file contains declarations for the non-PAE functions defined in - * kernel/infrastructure/i686/vm_x86.c. It is intended to be included by vm.c - * and vm_x86.c. There should be no reason to include it anywhere else. */ + * kernel/infrastructure/i686/pmap/nopae.c. It is intended to be included by + * pmap.c and nopae.c. There should be no reason to include it anywhere else. */ #include -void vm_x86_create_initial_addr_space(addr_space_t *addr_space, pte_t *page_directory); +void nopae_create_initial_addr_space(addr_space_t *addr_space, pte_t *page_directory); -void vm_x86_create_addr_space(addr_space_t *addr_space, pte_t *page_directory); +void nopae_create_addr_space(addr_space_t *addr_space, pte_t *page_directory); -void vm_x86_destroy_addr_space(addr_space_t *addr_space); +void nopae_destroy_addr_space(addr_space_t *addr_space); -unsigned int vm_x86_page_table_offset_of(void *addr); +unsigned int nopae_page_table_offset_of(void *addr); -unsigned int vm_x86_page_directory_offset_of(void *addr); +unsigned int nopae_page_directory_offset_of(void *addr); -pte_t *vm_x86_lookup_page_directory(addr_space_t *addr_space); +pte_t *nopae_lookup_page_directory(addr_space_t *addr_space); -pte_t *vm_x86_get_pte_with_offset(pte_t *pte, unsigned int offset); +pte_t *nopae_get_pte_with_offset(pte_t *pte, unsigned int offset); -void vm_x86_set_pte(pte_t *pte, uint32_t paddr, uint64_t flags); +void nopae_set_pte(pte_t *pte, uint32_t paddr, uint64_t flags); -void vm_x86_set_pte_flags(pte_t *pte, uint64_t flags); +void nopae_set_pte_flags(pte_t *pte, uint64_t flags); -uint32_t vm_x86_get_pte_paddr(const pte_t *pte); +uint32_t nopae_get_pte_paddr(const pte_t *pte); -void vm_x86_clear_pte(pte_t *pte); +void nopae_clear_pte(pte_t *pte); -void vm_x86_copy_pte(pte_t *dest, const pte_t *src); +void nopae_copy_pte(pte_t *dest, const pte_t *src); #endif diff --git a/include/kernel/infrastructure/i686/vm_pae.h b/include/kernel/infrastructure/i686/pmap/pae.h similarity index 66% rename from include/kernel/infrastructure/i686/vm_pae.h rename to include/kernel/infrastructure/i686/pmap/pae.h index ffe4410b..eb9a7d5f 100644 --- a/include/kernel/infrastructure/i686/vm_pae.h +++ b/include/kernel/infrastructure/i686/pmap/pae.h @@ -29,50 +29,50 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef JINUE_KERNEL_INFRASTRUCTURE_I686_VM_PAE_H -#define JINUE_KERNEL_INFRASTRUCTURE_I686_VM_PAE_H +#ifndef JINUE_KERNEL_INFRASTRUCTURE_I686_PMAP_PAE_H +#define JINUE_KERNEL_INFRASTRUCTURE_I686_PMAP_PAE_H /** This header file contains declarations for the PAE functions defined in - * kernel/infrastructure/i686/vm_pae.c. It is intended to be included by vm.c - * and vm_pae.c. There should be no reason to include it anywhere else. */ + * kernel/infrastructure/i686/pmap/pae.c. It is intended to be included by + * pmap.c and pae.c. There should be no reason to include it anywhere else. */ #include #include -void vm_pae_enable(boot_alloc_t *boot_alloc, const bootinfo_t *bootinfo); +void pae_enable(boot_alloc_t *boot_alloc, const bootinfo_t *bootinfo); -void vm_pae_create_initial_addr_space( +void pae_create_initial_addr_space( addr_space_t *address_space, pte_t *page_directories, boot_alloc_t *boot_alloc); -bool vm_pae_create_addr_space(addr_space_t *addr_space, pte_t *first_page_directory); +bool pae_create_addr_space(addr_space_t *addr_space, pte_t *first_page_directory); -void vm_pae_destroy_addr_space(addr_space_t *addr_space); +void pae_destroy_addr_space(addr_space_t *addr_space); -pte_t *vm_pae_lookup_page_directory( +pte_t *pae_lookup_page_directory( addr_space_t *addr_space, void *addr, bool create_as_needed, bool *reload_cr3); -unsigned int vm_pae_page_table_offset_of(void *addr); +unsigned int pae_page_table_offset_of(void *addr); -unsigned int vm_pae_page_directory_offset_of(void *addr); +unsigned int pae_page_directory_offset_of(void *addr); -pte_t *vm_pae_get_pte_with_offset(pte_t *pte, unsigned int offset); +pte_t *pae_get_pte_with_offset(pte_t *pte, unsigned int offset); -void vm_pae_set_pte(pte_t *pte, uint64_t paddr, uint64_t flags); +void pae_set_pte(pte_t *pte, uint64_t paddr, uint64_t flags); -void vm_pae_set_pte_flags(pte_t *pte, uint64_t flags); +void pae_set_pte_flags(pte_t *pte, uint64_t flags); -uint64_t vm_pae_get_pte_paddr(const pte_t *pte); +uint64_t pae_get_pte_paddr(const pte_t *pte); -void vm_pae_clear_pte(pte_t *pte); +void pae_clear_pte(pte_t *pte); -void vm_pae_copy_pte(pte_t *dest, const pte_t *src); +void pae_copy_pte(pte_t *dest, const pte_t *src); -void vm_pae_create_pdpt_cache(void); +void pae_create_pdpt_cache(void); #endif diff --git a/include/kernel/infrastructure/i686/vm.h b/include/kernel/infrastructure/i686/pmap/pmap.h similarity index 79% rename from include/kernel/infrastructure/i686/vm.h rename to include/kernel/infrastructure/i686/pmap/pmap.h index 40f00f3c..09e33507 100644 --- a/include/kernel/infrastructure/i686/vm.h +++ b/include/kernel/infrastructure/i686/pmap/pmap.h @@ -29,18 +29,18 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef JINUE_KERNEL_INFRASTRUCTURE_I686_VM_H -#define JINUE_KERNEL_INFRASTRUCTURE_I686_VM_H +#ifndef JINUE_KERNEL_INFRASTRUCTURE_I686_PMAP_PMAP_H +#define JINUE_KERNEL_INFRASTRUCTURE_I686_PMAP_PMAP_H /** This header file contains the interface exposed to the rest of the kernel's * i686-specific code of the low-level page table management functions defined - * in vm.c and vm_pae.c located in kernel/infrastructure/i686/. */ + * in pmap.c located in kernel/infrastructure/i686/pmap/. */ -#include +#include #include #include #include -#include +#include /** convert physical to virtual address for kernel loaded at 0x100000 (1MB) */ #define PHYS_TO_VIRT_AT_1MB(x) (((uintptr_t)(x)) + BOOT_OFFSET_FROM_1MB) @@ -62,30 +62,30 @@ #define ADDR_4GB UINT64_C(0x100000000) -void vm_set_no_pae(void); +void pmap_set_no_pae(void); -void vm_write_protect_kernel_image(const bootinfo_t *bootinfo); +void pmap_write_protect_kernel_image(const bootinfo_t *bootinfo); -addr_space_t *vm_create_initial_addr_space( +addr_space_t *pmap_create_initial_addr_space( const exec_file_t *kernel, boot_alloc_t *boot_alloc, const bootinfo_t *bootinfo) ; -bool vm_create_addr_space(addr_space_t *addr_space); +bool pmap_create_addr_space(addr_space_t *addr_space); -void vm_destroy_addr_space(addr_space_t *addr_space); +void pmap_destroy_addr_space(addr_space_t *addr_space); -void vm_switch_addr_space(addr_space_t *addr_space); +void pmap_switch_addr_space(addr_space_t *addr_space); -void vm_boot_map(void *addr, uint32_t paddr, int num_entries); +void pmap_boot_map(void *addr, uint32_t paddr, int num_entries); -void vm_map_kernel_page(void *vaddr, kern_paddr_t paddr, int flags); +void pmap_map_kernel_page(void *vaddr, kern_paddr_t paddr, int flags); -void vm_unmap_kernel_page(void *addr); +void pmap_unmap_kernel_page(void *addr); -void vm_unmap_userspace(addr_space_t *addr_space, void *addr); +void pmap_unmap_userspace(addr_space_t *addr_space, void *addr); -bool vm_clone_range( +bool pmap_clone_range( addr_space_t *dest_addr_space, addr_space_t *src_addr_space, addr_t dest_addr, diff --git a/include/kernel/infrastructure/i686/vm_private.h b/include/kernel/infrastructure/i686/pmap/private.h similarity index 81% rename from include/kernel/infrastructure/i686/vm_private.h rename to include/kernel/infrastructure/i686/pmap/private.h index 7e736ca1..1dec358b 100644 --- a/include/kernel/infrastructure/i686/vm_private.h +++ b/include/kernel/infrastructure/i686/pmap/private.h @@ -29,22 +29,22 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef JINUE_KERNEL_INFRASTRUCTURE_I686_VM_PRIVATE_H -#define JINUE_KERNEL_INFRASTRUCTURE_I686_VM_PRIVATE_H +#ifndef JINUE_KERNEL_INFRASTRUCTURE_I686_PMAP_PRIVATE_H +#define JINUE_KERNEL_INFRASTRUCTURE_I686_PMAP_PRIVATE_H +#include +#include +#include #include -#include -#include -#include #include -#include -#include +#include +#include #include #include -/** This header file contains private definitions shared by vm.c, vm_pae.c - * and vm_x86.c in kernel/infrastructure/i686/. There should be no reason to - * include it anywhere else. */ +/** This header file contains private definitions shared by pmap.c, pae.c + * and nopae.c in kernel/infrastructure/i686/pmap/. There should be no reason + * to include it anywhere else. */ /** bit mask for page table or page directory offset */ #define PAGE_TABLE_MASK (PAGE_TABLE_ENTRIES - 1) @@ -61,17 +61,13 @@ extern size_t entries_per_page_table; extern bool pgtable_format_pae; -pte_t *vm_initialize_page_table_linear( +pte_t *initialize_page_table_linear( pte_t *page_table, uint64_t start_paddr, uint64_t flags, int num_entries); -kern_paddr_t vm_clone_page_directory( - kern_paddr_t template_paddr, - unsigned int start_index); - -void vm_destroy_page_directory(void *page_directory, unsigned int last_index); +void destroy_page_directory(void *page_directory, unsigned int last_index); /** * Whether the specified page table/directory entry maps a page present in memory diff --git a/include/kernel/infrastructure/i686/thread.h b/include/kernel/infrastructure/i686/thread.h new file mode 100644 index 00000000..ad4faaaf --- /dev/null +++ b/include/kernel/infrastructure/i686/thread.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2019-2024 Philippe Aubertin. + * All rights reserved. + + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the author nor the names of other contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef JINUE_KERNEL_INFRASTRUCTURE_I686_THREAD_H +#define JINUE_KERNEL_INFRASTRUCTURE_I686_THREAD_H + +#include +#include + +void switch_thread_stack( + machine_thread_t *from_ctx, + machine_thread_t *to_ctx, + bool destroy_from); + +#endif diff --git a/include/kernel/infrastructure/i686/types.h b/include/kernel/infrastructure/i686/types.h index 5dd2ff25..ad8d3134 100644 --- a/include/kernel/infrastructure/i686/types.h +++ b/include/kernel/infrastructure/i686/types.h @@ -110,17 +110,17 @@ typedef struct { uint16_t iomap; } tss_t; -struct cpu_data_t { +struct percpu_t { + struct percpu_t *self; + addr_space_t *current_addr_space; seg_descriptor_t gdt[GDT_LENGTH]; /* The assembly-language system call entry point for the SYSCALL instruction * (fast_amd_entry in trap.asm) makes assumptions regarding the location of * the TSS within this structure. */ tss_t tss; - struct cpu_data_t *self; - addr_space_t *current_addr_space; }; -typedef struct cpu_data_t cpu_data_t; +typedef struct percpu_t percpu_t; typedef struct { uint32_t edi; diff --git a/include/kernel/machine/cpuinfo.h b/include/kernel/machine/cpuinfo.h new file mode 100644 index 00000000..0b5a051d --- /dev/null +++ b/include/kernel/machine/cpuinfo.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2024 Philippe Aubertin. + * All rights reserved. + + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the author nor the names of other contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef JINUE_KERNEL_MACHINE_CPUINFO_H +#define JINUE_KERNEL_MACHINE_CPUINFO_H + +unsigned int machine_get_cpu_dcache_alignment(void); + +#endif diff --git a/include/kernel/machine/vm.h b/include/kernel/machine/pmap.h similarity index 96% rename from include/kernel/machine/vm.h rename to include/kernel/machine/pmap.h index 8de75aee..450079c0 100644 --- a/include/kernel/machine/vm.h +++ b/include/kernel/machine/pmap.h @@ -29,8 +29,8 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef JINUE_KERNEL_MACHINE_VM_H -#define JINUE_KERNEL_MACHINE_VM_H +#ifndef JINUE_KERNEL_MACHINE_PMAP_H +#define JINUE_KERNEL_MACHINE_PMAP_H #include diff --git a/include/kernel/machine/cpu.h b/include/kernel/machine/tls.h similarity index 92% rename from include/kernel/machine/cpu.h rename to include/kernel/machine/tls.h index 095137be..e3197e07 100644 --- a/include/kernel/machine/cpu.h +++ b/include/kernel/machine/tls.h @@ -29,13 +29,11 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef JINUE_KERNEL_MACHINE_CPU_H -#define JINUE_KERNEL_MACHINE_CPU_H +#ifndef JINUE_KERNEL_MACHINE_TLS_H +#define JINUE_KERNEL_MACHINE_TLS_H #include -unsigned int machine_get_cpu_dcache_alignment(void); - void machine_set_tls(const thread_t *thread); #endif diff --git a/include/kernel/utils/vm.h b/include/kernel/utils/pmap.h similarity index 97% rename from include/kernel/utils/vm.h rename to include/kernel/utils/pmap.h index 5a2f7045..bb65cad6 100644 --- a/include/kernel/utils/vm.h +++ b/include/kernel/utils/pmap.h @@ -29,8 +29,8 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef JINUE_KERNEL_UTILS_VM_H -#define JINUE_KERNEL_UTILS_VM_H +#ifndef JINUE_KERNEL_UTILS_PMAP_H +#define JINUE_KERNEL_UTILS_PMAP_H #include diff --git a/kernel/Makefile b/kernel/Makefile index 16bf5184..e6b575f4 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -46,8 +46,8 @@ kernel_elf = interface/i686/kernel stripped = $(kernel_elf)-stripped image = interface/i686/$(notdir $(kernel_img)) kmain = application/kmain.o -setup16 = interface/i686/setup16.o -setup32 = interface/i686/setup32.o +setup16 = interface/i686/setup16-nasm.o +setup32 = interface/i686/setup32-nasm.o target = $(image) unclean.extra = \ @@ -96,34 +96,37 @@ sources.kernel.c = \ domain/services/logging.c \ domain/services/panic.c \ domain/config.c \ - infrastructure/i686/auxv.c \ + infrastructure/i686/drivers/vga.c \ + infrastructure/i686/drivers/pic8259.c \ + infrastructure/i686/drivers/uart16550a.c \ + infrastructure/i686/pmap/nopae.c \ + infrastructure/i686/pmap/pmap.c \ + infrastructure/i686/pmap/pae.c \ infrastructure/i686/boot_alloc.c \ infrastructure/i686/cmdline.c \ infrastructure/i686/config.c \ - infrastructure/i686/cpu.c \ + infrastructure/i686/cpuinfo.c \ infrastructure/i686/debug.c \ infrastructure/i686/halt.c \ infrastructure/i686/init.c \ infrastructure/i686/memory.c \ - infrastructure/i686/pic8259.c \ + infrastructure/i686/percpu.c \ infrastructure/i686/process.c \ infrastructure/i686/thread.c \ - infrastructure/i686/uart16550a.c \ - infrastructure/i686/vga.c \ - infrastructure/i686/vm.c \ - infrastructure/i686/vm_pae.c \ - infrastructure/i686/vm_x86.c \ infrastructure/elf.c \ + interface/i686/auxv.c \ interface/i686/bootinfo.c \ interface/i686/interrupt.c \ interface/syscalls.c sources.kernel.nasm = \ - infrastructure/i686/abi.asm \ - infrastructure/i686/io.asm \ - infrastructure/i686/remap.asm \ - infrastructure/i686/thread_switch.asm \ - infrastructure/i686/x86.asm \ + infrastructure/i686/isa/abi.asm \ + infrastructure/i686/isa/instrs.asm \ + infrastructure/i686/isa/io.asm \ + infrastructure/i686/isa/regs.asm \ + infrastructure/i686/pmap/init.asm \ + infrastructure/i686/iodelay.asm \ + infrastructure/i686/thread.asm \ interface/i686/crt.asm \ interface/i686/trap.asm @@ -134,7 +137,7 @@ sources.setup.nasm = \ sources.c = $(sources.kernel.c) sources.nasm = $(sources.kernel.nasm) $(sources.setup.nasm) -objects.kernel = $(sources.kernel.nasm:%.asm=%.o) $(sources.kernel.c:%.c=%.o) +objects.kernel = $(sources.kernel.nasm:%.asm=%-nasm.o) $(sources.kernel.c:%.c=%.o) include $(common) @@ -152,9 +155,9 @@ $(build_info_h): FORCE $(kmain): $(kmain:%.o=%.c) $(build_info_h) -$(setup16): $(setup16:%.o=%.asm) +$(setup16): $(setup16:%-nasm.o=%.asm) -$(setup32): $(setup32:%.o=%.asm) +$(setup32): $(setup32:%-nasm.o=%.asm) $(kernel_elf): $(objects.kernel) $(kernel_ldscript) libc $(LINK.o) $(KERNEL_LDFLAGS) $(objects.kernel) $(c.lib) $(KERNEL_LDLIBS) -o $@ diff --git a/kernel/application/syscalls/mclone.c b/kernel/application/syscalls/mclone.c index 9608a983..1c56b239 100644 --- a/kernel/application/syscalls/mclone.c +++ b/kernel/application/syscalls/mclone.c @@ -34,7 +34,7 @@ #include #include #include -#include +#include /** * Implementation for the MCLONE system call diff --git a/kernel/application/syscalls/mmap.c b/kernel/application/syscalls/mmap.c index 3b532754..93b8574e 100644 --- a/kernel/application/syscalls/mmap.c +++ b/kernel/application/syscalls/mmap.c @@ -33,7 +33,7 @@ #include #include #include -#include +#include /** * Implementation for the MMAP system call diff --git a/kernel/application/syscalls/set_thread_local.c b/kernel/application/syscalls/set_thread_local.c index e0233666..34517d24 100644 --- a/kernel/application/syscalls/set_thread_local.c +++ b/kernel/application/syscalls/set_thread_local.c @@ -31,8 +31,8 @@ #include #include -#include #include +#include void set_thread_local(void *addr, size_t size) { thread_t *thread = get_current_thread(); diff --git a/kernel/domain/alloc/page_alloc.c b/kernel/domain/alloc/page_alloc.c index bd5018dd..f6580f04 100644 --- a/kernel/domain/alloc/page_alloc.c +++ b/kernel/domain/alloc/page_alloc.c @@ -33,7 +33,7 @@ #include #include #include -#include +#include #include diff --git a/kernel/domain/alloc/slab.c b/kernel/domain/alloc/slab.c index 55dcf727..ebbab5bb 100644 --- a/kernel/domain/alloc/slab.c +++ b/kernel/domain/alloc/slab.c @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/kernel/domain/alloc/vmalloc.c b/kernel/domain/alloc/vmalloc.c index fd143f4e..5691c9fd 100644 --- a/kernel/domain/alloc/vmalloc.c +++ b/kernel/domain/alloc/vmalloc.c @@ -31,7 +31,7 @@ #include #include -#include +#include /** diff --git a/kernel/domain/entities/object.c b/kernel/domain/entities/object.c index db25bbf2..d2e6471c 100644 --- a/kernel/domain/entities/object.c +++ b/kernel/domain/entities/object.c @@ -73,7 +73,7 @@ void destroy_object(object_header_t *object) { } } -/* This function is called by assembly code. See thread_context_switch_stack(). */ +/* This function is called by assembly code. See switch_thread_stack(). */ void sub_ref_to_object(object_header_t *object) { --object->ref_count; diff --git a/kernel/domain/entities/process.c b/kernel/domain/entities/process.c index 1386a719..ba192a95 100644 --- a/kernel/domain/entities/process.c +++ b/kernel/domain/entities/process.c @@ -35,9 +35,9 @@ #include #include #include +#include #include #include -#include #include #include diff --git a/kernel/domain/services/ipc.c b/kernel/domain/services/ipc.c index d101d2b6..2e9621e6 100644 --- a/kernel/domain/services/ipc.c +++ b/kernel/domain/services/ipc.c @@ -36,7 +36,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/kernel/infrastructure/elf.c b/kernel/infrastructure/elf.c index 79be6e1b..20264cc1 100644 --- a/kernel/infrastructure/elf.c +++ b/kernel/infrastructure/elf.c @@ -40,9 +40,9 @@ #include #include #include -#include +#include #include -#include +#include #include #include diff --git a/kernel/infrastructure/i686/boot_alloc.c b/kernel/infrastructure/i686/boot_alloc.c index 03948bf0..48a3642b 100644 --- a/kernel/infrastructure/i686/boot_alloc.c +++ b/kernel/infrastructure/i686/boot_alloc.c @@ -32,8 +32,8 @@ #include #include #include +#include #include -#include #include #include #include diff --git a/kernel/infrastructure/i686/cpu.c b/kernel/infrastructure/i686/cpu.c deleted file mode 100644 index ae6cd6fd..00000000 --- a/kernel/infrastructure/i686/cpu.c +++ /dev/null @@ -1,252 +0,0 @@ -/* - * Copyright (C) 2019 Philippe Aubertin. - * All rights reserved. - - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the author nor the names of other contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include -#include -#include -#include -#include - -cpu_info_t cpu_info; - -static void set_tls_segment(cpu_data_t *data, void *addr, size_t size) { - data->gdt[GDT_USER_TLS_DATA] = SEG_DESCRIPTOR( - addr, - size - 1, - SEG_TYPE_DATA | SEG_FLAG_USER | SEG_FLAG_NORMAL - ); -} - -void machine_set_tls(const thread_t *thread) { - cpu_data_t *data = get_cpu_local_data(); - set_tls_segment(data, thread->local_storage_addr, thread->local_storage_size); -} - -void cpu_init_data(cpu_data_t *data) { - tss_t *tss; - - tss = &data->tss; - - /* initialize with zeroes */ - memset(data, '\0', sizeof(cpu_data_t)); - - data->self = data; - data->current_addr_space = NULL; - - /* initialize GDT */ - data->gdt[GDT_NULL] = SEG_DESCRIPTOR(0, 0, 0); - - data->gdt[GDT_KERNEL_CODE] = - SEG_DESCRIPTOR( 0, 0xfffff, SEG_TYPE_CODE | SEG_FLAG_KERNEL | SEG_FLAG_NORMAL); - - data->gdt[GDT_KERNEL_DATA] = - SEG_DESCRIPTOR( 0, 0xfffff, SEG_TYPE_DATA | SEG_FLAG_KERNEL | SEG_FLAG_NORMAL); - - data->gdt[GDT_USER_CODE] = - SEG_DESCRIPTOR( 0, 0xfffff, SEG_TYPE_CODE | SEG_FLAG_USER | SEG_FLAG_NORMAL); - - data->gdt[GDT_USER_DATA] = - SEG_DESCRIPTOR( 0, 0xfffff, SEG_TYPE_DATA | SEG_FLAG_USER | SEG_FLAG_NORMAL); - - data->gdt[GDT_TSS] = - SEG_DESCRIPTOR( tss, TSS_LIMIT-1, SEG_TYPE_TSS | SEG_FLAG_KERNEL | SEG_FLAG_TSS); - - data->gdt[GDT_PER_CPU_DATA] = - SEG_DESCRIPTOR( data, sizeof(cpu_data_t)-1, SEG_TYPE_DATA | SEG_FLAG_KERNEL | SEG_FLAG_32BIT | SEG_FLAG_IN_BYTES | SEG_FLAG_NOSYSTEM | SEG_FLAG_PRESENT); - - set_tls_segment(data, NULL, 0); - - /* setup kernel stack in TSS */ - tss->ss0 = SEG_SELECTOR(GDT_KERNEL_DATA, RPL_KERNEL); - tss->ss1 = SEG_SELECTOR(GDT_KERNEL_DATA, RPL_KERNEL); - tss->ss2 = SEG_SELECTOR(GDT_KERNEL_DATA, RPL_KERNEL); - - /* kernel stack address is updated by machine_switch_thread() */ - tss->esp0 = NULL; - tss->esp1 = NULL; - tss->esp2 = NULL; - - /* From Intel 64 and IA-32 Architectures Software Developer's Manual Volume - * 3 System Programming Guide chapter 16.5: - * - * " If the I/O bit map base address is greater than or equal to the TSS - * segment limit, there is no I/O permission map, and all I/O instructions - * generate exceptions when the CPL is greater than the current IOPL. " */ - tss->iomap = TSS_LIMIT; -} - -void cpu_detect_features(void) { - uint32_t temp_eflags; - - /* default values */ - cpu_info.maxphyaddr = 32; - cpu_info.dcache_alignment = 32; - cpu_info.features = 0; - cpu_info.vendor = CPU_VENDOR_GENERIC; - cpu_info.family = 0; - cpu_info.model = 0; - cpu_info.stepping = 0; - - /* The CPUID instruction is available if we can change the value of eflags - * bit 21 (ID) */ - temp_eflags = get_eflags(); - temp_eflags ^= CPU_EFLAGS_ID; - set_eflags(temp_eflags); - - if(temp_eflags == get_eflags()) { - cpu_info.features |= CPU_FEATURE_CPUID; - } - - if(cpu_has_feature(CPU_FEATURE_CPUID)) { - x86_cpuid_regs_t regs; - - /* default values */ - uint32_t flags = 0; - uint32_t ext_flags = 0; - - /* function 0: vendor ID string, max value of eax when calling CPUID */ - regs.eax = 0; - - /* call CPUID instruction */ - uint32_t cpuid_max = cpuid(®s); - uint32_t vendor_dw0 = regs.ebx; - uint32_t vendor_dw1 = regs.edx; - uint32_t vendor_dw2 = regs.ecx; - - /* identify vendor */ - if( vendor_dw0 == CPU_VENDOR_AMD_DW0 - && vendor_dw1 == CPU_VENDOR_AMD_DW1 - && vendor_dw2 == CPU_VENDOR_AMD_DW2) { - - cpu_info.vendor = CPU_VENDOR_AMD; - } - else if (vendor_dw0 == CPU_VENDOR_INTEL_DW0 - && vendor_dw1 == CPU_VENDOR_INTEL_DW1 - && vendor_dw2 == CPU_VENDOR_INTEL_DW2) { - - cpu_info.vendor = CPU_VENDOR_INTEL; - } - - /* get processor signature (family/model/stepping) and feature flags */ - if(cpuid_max >= 1) { - /* function 1: processor signature and feature flags */ - regs.eax = 1; - - /* call CPUID instruction */ - uint32_t signature = cpuid(®s); - - /* set processor signature */ - cpu_info.stepping = signature & 0xf; - cpu_info.model = (signature>>4) & 0xf; - cpu_info.family = (signature>>8) & 0xf; - - /* feature flags */ - flags = regs.edx; - - /* cache alignment */ - if(flags & CPUID_FEATURE_CLFLUSH) { - cpu_info.dcache_alignment = ((regs.ebx >> 8) & 0xff) * 8; - } - - /* global pages */ - if(flags & CPUID_FEATURE_PGE) { - cpu_info.features |= CPU_FEATURE_PGE; - } - } - - /* extended function 0: max value of eax when calling CPUID (extended function) */ - regs.eax = 0x80000000; - uint32_t cpuid_ext_max = cpuid(®s); - - /* get extended feature flags */ - if(cpuid_ext_max >= 0x80000001) { - /* extended function 1: extended feature flags */ - regs.eax = 0x80000001; - (void)cpuid(®s); - - /* extended feature flags */ - ext_flags = regs.edx; - } - - /* support for SYSENTER/SYSEXIT instructions */ - if(flags & CPUID_FEATURE_SEP) { - if(cpu_info.vendor == CPU_VENDOR_AMD) { - cpu_info.features |= CPU_FEATURE_SYSENTER; - } - else if(cpu_info.vendor == CPU_VENDOR_INTEL) { - if(cpu_info.family == 6 && cpu_info.model < 3 && cpu_info.stepping < 3) { - /* not supported */ - } - else { - cpu_info.features |= CPU_FEATURE_SYSENTER; - } - } - } - - /* support for SYSCALL/SYSRET instructions */ - if(cpu_info.vendor == CPU_VENDOR_AMD) { - if(ext_flags & CPUID_EXT_FEATURE_SYSCALL) { - cpu_info.features |= CPU_FEATURE_SYSCALL; - } - } - - if(cpu_info.vendor == CPU_VENDOR_AMD || cpu_info.vendor == CPU_VENDOR_INTEL) { - /* support for local APIC */ - if(flags & CPUID_FEATURE_APIC) { - cpu_info.features |= CPU_FEATURE_LOCAL_APIC; - } - - /* large 4MB pages in 32-bit (non-PAE) paging mode */ - if(flags & CPUID_FEATURE_PSE) { - cpu_info.features |= CPU_FEATURE_PSE; - } - - /* support for physical address extension (PAE) */ - if((flags & CPUID_FEATURE_PAE) && (ext_flags & CPUID_FEATURE_NXE)) { - cpu_info.features |= CPU_FEATURE_PAE; - - /* max physical memory size */ - if(cpuid_ext_max >= 0x80000008) { - regs.eax = 0x80000008; - (void)cpuid(®s); - - cpu_info.maxphyaddr = regs.eax & 0xff; - } - } - } - } -} - -unsigned int machine_get_cpu_dcache_alignment(void) { - return cpu_info.dcache_alignment; -} diff --git a/kernel/infrastructure/i686/cpuinfo.c b/kernel/infrastructure/i686/cpuinfo.c new file mode 100644 index 00000000..a9f6b70b --- /dev/null +++ b/kernel/infrastructure/i686/cpuinfo.c @@ -0,0 +1,185 @@ +/* + * Copyright (C) 2019-2024 Philippe Aubertin. + * All rights reserved. + + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the author nor the names of other contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include + +cpuinfo_t cpuinfo; + +void detect_cpu_features(void) { + uint32_t temp_eflags; + + /* default values */ + cpuinfo.maxphyaddr = 32; + cpuinfo.dcache_alignment = 32; + cpuinfo.features = 0; + cpuinfo.vendor = CPUINFO_VENDOR_GENERIC; + cpuinfo.family = 0; + cpuinfo.model = 0; + cpuinfo.stepping = 0; + + /* The CPUID instruction is available if we can change the value of eflags + * bit 21 (ID) */ + temp_eflags = get_eflags(); + temp_eflags ^= CPU_EFLAGS_ID; + set_eflags(temp_eflags); + + if(temp_eflags == get_eflags()) { + cpuinfo.features |= CPUINFO_FEATURE_CPUID; + } + + if(cpu_has_feature(CPUINFO_FEATURE_CPUID)) { + x86_cpuid_regs_t regs; + + /* default values */ + uint32_t flags = 0; + uint32_t ext_flags = 0; + + /* function 0: vendor ID string, max value of eax when calling CPUID */ + regs.eax = 0; + + /* call CPUID instruction */ + uint32_t cpuid_max = cpuid(®s); + uint32_t vendor_dw0 = regs.ebx; + uint32_t vendor_dw1 = regs.edx; + uint32_t vendor_dw2 = regs.ecx; + + /* identify vendor */ + if( vendor_dw0 == CPUID_VENDOR_AMD_DW0 + && vendor_dw1 == CPUID_VENDOR_AMD_DW1 + && vendor_dw2 == CPUID_VENDOR_AMD_DW2) { + + cpuinfo.vendor = CPUINFO_VENDOR_AMD; + } + else if (vendor_dw0 == CPUID_VENDOR_INTEL_DW0 + && vendor_dw1 == CPUID_VENDOR_INTEL_DW1 + && vendor_dw2 == CPUID_VENDOR_INTEL_DW2) { + + cpuinfo.vendor = CPUINFO_VENDOR_INTEL; + } + + /* get processor signature (family/model/stepping) and feature flags */ + if(cpuid_max >= 1) { + /* function 1: processor signature and feature flags */ + regs.eax = 1; + + /* call CPUID instruction */ + uint32_t signature = cpuid(®s); + + /* set processor signature */ + cpuinfo.stepping = signature & 0xf; + cpuinfo.model = (signature>>4) & 0xf; + cpuinfo.family = (signature>>8) & 0xf; + + /* feature flags */ + flags = regs.edx; + + /* cache alignment */ + if(flags & CPUID_FEATURE_CLFLUSH) { + cpuinfo.dcache_alignment = ((regs.ebx >> 8) & 0xff) * 8; + } + + /* global pages */ + if(flags & CPUID_FEATURE_PGE) { + cpuinfo.features |= CPUINFO_FEATURE_PGE; + } + } + + /* extended function 0: max value of eax when calling CPUID (extended function) */ + regs.eax = 0x80000000; + uint32_t cpuid_ext_max = cpuid(®s); + + /* get extended feature flags */ + if(cpuid_ext_max >= 0x80000001) { + /* extended function 1: extended feature flags */ + regs.eax = 0x80000001; + (void)cpuid(®s); + + /* extended feature flags */ + ext_flags = regs.edx; + } + + /* support for SYSENTER/SYSEXIT instructions */ + if(flags & CPUID_FEATURE_SEP) { + if(cpuinfo.vendor == CPUINFO_VENDOR_AMD) { + cpuinfo.features |= CPUINFO_FEATURE_SYSENTER; + } + else if(cpuinfo.vendor == CPUINFO_VENDOR_INTEL) { + if(cpuinfo.family == 6 && cpuinfo.model < 3 && cpuinfo.stepping < 3) { + /* not supported */ + } + else { + cpuinfo.features |= CPUINFO_FEATURE_SYSENTER; + } + } + } + + /* support for SYSCALL/SYSRET instructions */ + if(cpuinfo.vendor == CPUINFO_VENDOR_AMD) { + if(ext_flags & CPUID_EXT_FEATURE_SYSCALL) { + cpuinfo.features |= CPUINFO_FEATURE_SYSCALL; + } + } + + if(cpuinfo.vendor == CPUINFO_VENDOR_AMD || cpuinfo.vendor == CPUINFO_VENDOR_INTEL) { + /* support for local APIC */ + if(flags & CPUID_FEATURE_APIC) { + cpuinfo.features |= CPUINFO_FEATURE_LOCAL_APIC; + } + + /* large 4MB pages in 32-bit (non-PAE) paging mode */ + if(flags & CPUID_FEATURE_PSE) { + cpuinfo.features |= CPUINFO_FEATURE_PSE; + } + + /* support for physical address extension (PAE) */ + if((flags & CPUID_FEATURE_PAE) && (ext_flags & CPUID_FEATURE_NXE)) { + cpuinfo.features |= CPUINFO_FEATURE_PAE; + + /* max physical memory size */ + if(cpuid_ext_max >= 0x80000008) { + regs.eax = 0x80000008; + (void)cpuid(®s); + + cpuinfo.maxphyaddr = regs.eax & 0xff; + } + } + } + } +} + +unsigned int machine_get_cpu_dcache_alignment(void) { + return cpuinfo.dcache_alignment; +} diff --git a/kernel/infrastructure/i686/debug.c b/kernel/infrastructure/i686/debug.c index 9573a219..4ed8b927 100644 --- a/kernel/infrastructure/i686/debug.c +++ b/kernel/infrastructure/i686/debug.c @@ -30,10 +30,10 @@ */ #include -#include -#include #include +#include #include +#include #include #include #include diff --git a/kernel/infrastructure/i686/pic8259.c b/kernel/infrastructure/i686/drivers/pic8259.c similarity index 96% rename from kernel/infrastructure/i686/pic8259.c rename to kernel/infrastructure/i686/drivers/pic8259.c index a120d5e3..fba594ea 100644 --- a/kernel/infrastructure/i686/pic8259.c +++ b/kernel/infrastructure/i686/drivers/pic8259.c @@ -29,8 +29,9 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include -#include +#include +#include +#include #include #include diff --git a/kernel/infrastructure/i686/uart16550a.c b/kernel/infrastructure/i686/drivers/uart16550a.c similarity index 95% rename from kernel/infrastructure/i686/uart16550a.c rename to kernel/infrastructure/i686/drivers/uart16550a.c index c9cfb118..c8618461 100644 --- a/kernel/infrastructure/i686/uart16550a.c +++ b/kernel/infrastructure/i686/drivers/uart16550a.c @@ -30,9 +30,9 @@ */ #include -#include -#include -#include +#include +#include +#include static void printn(int loglevel, const char *message, size_t n); diff --git a/kernel/infrastructure/i686/vga.c b/kernel/infrastructure/i686/drivers/vga.c similarity index 96% rename from kernel/infrastructure/i686/vga.c rename to kernel/infrastructure/i686/drivers/vga.c index 274dc607..793d3d05 100755 --- a/kernel/infrastructure/i686/vga.c +++ b/kernel/infrastructure/i686/drivers/vga.c @@ -31,11 +31,11 @@ #include #include -#include -#include -#include +#include +#include +#include #include -#include +#include typedef unsigned int vga_pos_t; diff --git a/kernel/infrastructure/i686/halt.c b/kernel/infrastructure/i686/halt.c index 26bf9da9..3a985eb8 100644 --- a/kernel/infrastructure/i686/halt.c +++ b/kernel/infrastructure/i686/halt.c @@ -29,8 +29,8 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include -#include +#include +#include #include #include diff --git a/kernel/infrastructure/i686/init.c b/kernel/infrastructure/i686/init.c index 271e807d..9f9fc3b6 100644 --- a/kernel/infrastructure/i686/init.c +++ b/kernel/infrastructure/i686/init.c @@ -34,18 +34,20 @@ #include #include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include -#include -#include +#include #include #include -#include -#include -#include -#include -#include -#include -#include +#include #include #include #include @@ -87,7 +89,7 @@ static void move_kernel_at_16mb(const bootinfo_t *bootinfo) { (addr_t)bootinfo->page_table_klimit, (uint32_t)bootinfo->page_directory); - vm_write_protect_kernel_image(bootinfo); + pmap_write_protect_kernel_image(bootinfo); } static bool maybe_enable_pae( @@ -97,7 +99,7 @@ static bool maybe_enable_pae( bool use_pae; - if(cpu_has_feature(CPU_FEATURE_PAE)) { + if(cpu_has_feature(CPUINFO_FEATURE_PAE)) { use_pae = (config->machine.pae != CONFIG_PAE_DISABLE); } else { @@ -110,11 +112,11 @@ static bool maybe_enable_pae( if(! use_pae) { warning("Warning: Physical Address Extension (PAE) not enabled. NX protection disabled."); - vm_set_no_pae(); + pmap_set_no_pae(); } else { info("Enabling Physical Address Extension (PAE)."); - vm_pae_enable(boot_alloc, bootinfo); + pae_enable(boot_alloc, bootinfo); } return use_pae; @@ -145,7 +147,7 @@ static void init_idt(void) { } } -static void load_selectors(cpu_data_t *cpu_data, boot_alloc_t *boot_alloc) { +static void load_selectors(percpu_t *cpu_data, boot_alloc_t *boot_alloc) { /* Pseudo-descriptor allocation is temporary for the duration of this * function only. Remember heap pointer on entry so we can free the * pseudo-allocator when we are done. */ @@ -191,7 +193,7 @@ static void remap_text_video_memory(boot_alloc_t *boot_alloc) { void *buffer = boot_page_alloc_n(boot_alloc, num_pages); void *mapped = (void *)PHYS_TO_VIRT_AT_16MB(buffer); - vm_boot_map(mapped, VGA_TEXT_VID_BASE, num_pages); + pmap_boot_map(mapped, VGA_TEXT_VID_BASE, num_pages); info("Remapping text video memory at %#p", mapped); @@ -203,7 +205,7 @@ static void remap_text_video_memory(boot_alloc_t *boot_alloc) { } static void enable_global_pages(void) { - if(cpu_has_feature(CPU_FEATURE_PGE)) { + if(cpu_has_feature(CPUINFO_FEATURE_PGE)) { set_cr4(get_cr4() | X86_CR4_PGE); } } @@ -219,7 +221,7 @@ static void initialize_page_allocator(boot_alloc_t *boot_alloc) { } static void select_syscall_implementation(void) { - if(cpu_has_feature(CPU_FEATURE_SYSCALL)) { + if(cpu_has_feature(CPUINFO_FEATURE_SYSCALL)) { uint64_t msrval; syscall_implementation = JINUE_I686_HOWSYSCALL_FAST_AMD; @@ -234,7 +236,7 @@ static void select_syscall_implementation(void) { wrmsr(MSR_STAR, msrval); } - else if(cpu_has_feature(CPU_FEATURE_SYSENTER)) { + else if(cpu_has_feature(CPUINFO_FEATURE_SYSENTER)) { syscall_implementation = JINUE_I686_HOWSYSCALL_FAST_INTEL; wrmsr(MSR_IA32_SYSENTER_CS, SEG_SELECTOR(GDT_KERNEL_CODE, RPL_KERNEL)); @@ -310,7 +312,7 @@ void machine_init(const config_t *config) { const bootinfo_t *bootinfo = get_bootinfo(); - cpu_detect_features(); + detect_cpu_features(); check_data_segment(bootinfo); @@ -338,17 +340,13 @@ void machine_init(const config_t *config) { * * We need to ensure that the Task State Segment (TSS) contained in this * memory block does not cross a page boundary. */ - assert(sizeof(cpu_data_t) < CPU_DATA_ALIGNMENT); - cpu_data_t *cpu_data = boot_heap_alloc(&boot_alloc, cpu_data_t, CPU_DATA_ALIGNMENT); + assert(sizeof(percpu_t) < PERCPU_DATA_ALIGNMENT); + percpu_t *cpu_data = boot_heap_alloc(&boot_alloc, percpu_t, PERCPU_DATA_ALIGNMENT); /* initialize per-CPU data */ - cpu_init_data(cpu_data); + init_percpu_data(cpu_data); - /* Initialize interrupt descriptor table (IDT) - * - * This function modifies the IDT in-place (see trap.asm). This must be - * done before vm_boot_init() because the page protection bits set up by - * vm_boot_init() prevent this. */ + /* Initialize interrupt descriptor table (IDT) */ init_idt(); /* load segment selectors */ @@ -360,18 +358,18 @@ void machine_init(const config_t *config) { exec_file_t kernel; get_kernel_exec_file(&kernel, bootinfo); - addr_space_t *addr_space = vm_create_initial_addr_space(&kernel, &boot_alloc, bootinfo); + addr_space_t *addr_space = pmap_create_initial_addr_space(&kernel, &boot_alloc, bootinfo); memory_initialize_array(&boot_alloc, bootinfo); /* After this, VGA output is not possible until we switch to the - * new address space (see the call to vm_switch_addr_space() below). + * new address space (see the call to pmap_switch_addr_space() below). * Attempting it will cause a kernel panic due to a page fault (and the * panic handler itself attempts to log). */ remap_text_video_memory(&boot_alloc); /* switch to new address space */ - vm_switch_addr_space(addr_space); + pmap_switch_addr_space(addr_space); enable_global_pages(); @@ -387,9 +385,9 @@ void machine_init(const config_t *config) { * because the slab allocator needs to allocate a slab to allocate the new * slab cache on the slab cache cache. * - * This must be done before the first time vm_create_addr_space() is called. */ + * This must be done before the first time pmap_create_addr_space() is called. */ if(pae_enabled) { - vm_pae_create_pdpt_cache(); + pae_create_pdpt_cache(); } /* choose a system call implementation */ diff --git a/kernel/infrastructure/i686/iodelay.asm b/kernel/infrastructure/i686/iodelay.asm new file mode 100755 index 00000000..1074ed48 --- /dev/null +++ b/kernel/infrastructure/i686/iodelay.asm @@ -0,0 +1,40 @@ +; Copyright (C) 2019-2024 Philippe Aubertin. +; All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions +; are met: +; +; 1. Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; +; 2. Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in the +; documentation and/or other materials provided with the distribution. +; +; 3. Neither the name of the author nor the names of other contributors +; may be used to endorse or promote products derived from this software +; without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND +; ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +; DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY +; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + bits 32 + +;------------------------------------------------------------------------ +; FUNCTION: iodelay +; C PROTOTYPE: void iodelay(void) +;------------------------------------------------------------------------ + global iodelay:function (iodelay.end - iodelay) +iodelay: + out 0x80, al + ret +.end: diff --git a/kernel/infrastructure/i686/abi.asm b/kernel/infrastructure/i686/isa/abi.asm similarity index 99% rename from kernel/infrastructure/i686/abi.asm rename to kernel/infrastructure/i686/isa/abi.asm index 647c64a0..acbc12ae 100755 --- a/kernel/infrastructure/i686/abi.asm +++ b/kernel/infrastructure/i686/isa/abi.asm @@ -38,7 +38,6 @@ get_fpointer: mov eax, ebp ret - .end: ; ------------------------------------------------------------------------------ @@ -54,7 +53,6 @@ get_caller_fpointer: pop ebp ; Restore ebp ret - .end: ; ------------------------------------------------------------------------------ @@ -70,7 +68,6 @@ get_ret_addr: pop ebp ; Restore ebp ret - .end: ; ------------------------------------------------------------------------------ @@ -82,5 +79,4 @@ get_program_counter: mov eax, [esp] ret - .end: diff --git a/kernel/infrastructure/i686/isa/instrs.asm b/kernel/infrastructure/i686/isa/instrs.asm new file mode 100644 index 00000000..46253195 --- /dev/null +++ b/kernel/infrastructure/i686/isa/instrs.asm @@ -0,0 +1,167 @@ +; Copyright (C) 2019-2024 Philippe Aubertin. +; All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions +; are met: +; +; 1. Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; +; 2. Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in the +; documentation and/or other materials provided with the distribution. +; +; 3. Neither the name of the author nor the names of other contributors +; may be used to endorse or promote products derived from this software +; without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND +; ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +; DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY +; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + bits 32 + +; ------------------------------------------------------------------------------ +; FUNCTION: cli +; C PROTOTYPE: void cli(void); +; ------------------------------------------------------------------------------ + global cli:function (cli.end - cli) +cli: + cli + ret +.end: + +; ------------------------------------------------------------------------------ +; FUNCTION: sti +; C PROTOTYPE: void sti(void); +; ------------------------------------------------------------------------------ + global sti:function (sti.end - sti) +sti: + sti + ret +.end: + +; ------------------------------------------------------------------------------ +; FUNCTION: hlt +; C PROTOTYPE: void hlt(void); +; ------------------------------------------------------------------------------ + global hlt:function (hlt.end - hlt) +hlt: + hlt + ret +.end: + +; ------------------------------------------------------------------------------ +; FUNCTION: invlpg +; C PROTOTYPE: void invlpg(void *vaddr) +; ------------------------------------------------------------------------------ + global invlpg:function (invlpg.end - invlpg) +invlpg: + mov eax, [esp+4] ; First param: vaddr + invlpg [eax] + ret +.end: + +; ------------------------------------------------------------------------------ +; FUNCTION: lgdt +; C PROTOTYPE: void lgdt(x86_pseudo_descriptor_t *gdt_desc) +; ------------------------------------------------------------------------------ + global lgdt:function (lgdt.end - lgdt) +lgdt: + mov eax, [esp+4] ; First param: gdt_info + add eax, 2 ; gdt_info_t structure contains two bytes of + ; padding for alignment + lgdt [eax] + ret +.end: + +; ------------------------------------------------------------------------------ +; FUNCTION: lidt +; C PROTOTYPE: void lidt(x86_pseudo_descriptor_t *idt_desc) +; ------------------------------------------------------------------------------ + global lidt:function (lidt.end - lidt) +lidt: + mov eax, [esp+4] ; First param: idt_info + add eax, 2 ; idt_info_t structure contains two bytes of + ; padding for alignment + lidt [eax] + ret +.end: + +; ------------------------------------------------------------------------------ +; FUNCTION: ltr +; C PROTOTYPE: void ltr(seg_selector_t sel) +; ------------------------------------------------------------------------------ + global ltr:function (ltr.end - ltr) +ltr: + mov eax, [esp+4] ; First param: sel + ltr ax + ret +.end: + +; ------------------------------------------------------------------------------ +; FUNCTION: cpuid +; C PROTOTYPE: uint32_t cpuid(x86_cpuid_regs_t *regs) +; ------------------------------------------------------------------------------ + global cpuid:function (cpuid.end - cpuid) +cpuid: + ; save registers + push ebx + push edi + + mov edi, [esp+12] ; First param: regs + + mov eax, [edi+ 0] ; regs->eax + mov ebx, [edi+ 4] ; regs->ebx + mov ecx, [edi+ 8] ; regs->ecx + mov edx, [edi+12] ; regs->edx + + cpuid + + mov edi, [esp+12] ; First param: regs + + mov [edi+ 0], eax + mov [edi+ 4], ebx + mov [edi+ 8], ecx + mov [edi+12], edx + + ; restore registers + pop edi + pop ebx + + ret +.end: + +; ------------------------------------------------------------------------------ +; FUNCTION: rdmsr +; C PROTOTYPE: uint64_t rdmsr(uint32_t addr) +; ------------------------------------------------------------------------------ + global rdmsr:function (rdmsr.end - rdmsr) +rdmsr: + mov ecx, [esp+ 4] ; First param: addr + + rdmsr + ret +.end: + +; ------------------------------------------------------------------------------ +; FUNCTION: wrmsr +; C PROTOTYPE: void wrmsr(uint32_t addr, uint64_t val) +; ------------------------------------------------------------------------------ + global wrmsr:function (wrmsr.end - wrmsr) +wrmsr: + mov ecx, [esp+ 4] ; First param: addr + mov eax, [esp+ 8] ; Second param: val (low dword) + mov edx, [esp+12] ; Second param: val (high dword) + + wrmsr + ret +.end: diff --git a/kernel/infrastructure/i686/io.asm b/kernel/infrastructure/i686/isa/io.asm similarity index 91% rename from kernel/infrastructure/i686/io.asm rename to kernel/infrastructure/i686/isa/io.asm index d8e93f1a..e32b2dcf 100755 --- a/kernel/infrastructure/i686/io.asm +++ b/kernel/infrastructure/i686/isa/io.asm @@ -1,4 +1,4 @@ -; Copyright (C) 2019 Philippe Aubertin. +; Copyright (C) 2019-2024 Philippe Aubertin. ; All rights reserved. ; ; Redistribution and use in source and binary forms, with or without @@ -39,7 +39,6 @@ inb: in al, dx movsx eax, al ret - .end: ; ------------------------------------------------------------------------------ @@ -52,7 +51,6 @@ inw: in ax, dx movsx eax, ax ret - .end: ; ------------------------------------------------------------------------------ @@ -64,7 +62,6 @@ inl: mov edx, [esp+4] ; first argument: port in eax, dx ret - .end: ; ------------------------------------------------------------------------------ @@ -77,7 +74,6 @@ outb: mov edx, [esp+4] ; first argument: port out dx, al ret - .end: ; ------------------------------------------------------------------------------ @@ -90,7 +86,6 @@ outw: mov edx, [esp+4] ; first argument: port out dx, ax ret - .end: ; ------------------------------------------------------------------------------ @@ -103,16 +98,4 @@ outl: mov edx, [esp+4] ; first argument: port out dx, eax ret - -.end: - -;------------------------------------------------------------------------ -; FUNCTION: iodelay -; C PROTOTYPE: void iodelay(void) -;------------------------------------------------------------------------ - global iodelay:function (iodelay.end - iodelay) -iodelay: - out 0x80, al - ret - .end: diff --git a/kernel/infrastructure/i686/x86.asm b/kernel/infrastructure/i686/isa/regs.asm similarity index 57% rename from kernel/infrastructure/i686/x86.asm rename to kernel/infrastructure/i686/isa/regs.asm index fc8e5280..6f335fbf 100644 --- a/kernel/infrastructure/i686/x86.asm +++ b/kernel/infrastructure/i686/isa/regs.asm @@ -1,4 +1,4 @@ -; Copyright (C) 2019 Philippe Aubertin. +; Copyright (C) 2019-2024 Philippe Aubertin. ; All rights reserved. ; ; Redistribution and use in source and binary forms, with or without @@ -27,130 +27,8 @@ ; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#include -#include - bits 32 -; ------------------------------------------------------------------------------ -; FUNCTION: cli -; C PROTOTYPE: void cli(void); -; ------------------------------------------------------------------------------ - global cli:function (cli.end - cli) -cli: - cli - ret - -.end: - -; ------------------------------------------------------------------------------ -; FUNCTION: sti -; C PROTOTYPE: void sti(void); -; ------------------------------------------------------------------------------ - global sti:function (sti.end - sti) -sti: - sti - ret - -.end: - -; ------------------------------------------------------------------------------ -; FUNCTION: hlt -; C PROTOTYPE: void hlt(void); -; ------------------------------------------------------------------------------ - global hlt:function (hlt.end - hlt) -hlt: - hlt - ret - -.end: - -; ------------------------------------------------------------------------------ -; FUNCTION: invalidate_tlb -; C PROTOTYPE: void invalidate_tlb(void *vaddr) -; ------------------------------------------------------------------------------ - global invalidate_tlb:function (invalidate_tlb.end - invalidate_tlb) -invalidate_tlb: - mov eax, [esp+4] ; First param: vaddr - invlpg [eax] - ret - -.end: - -; ------------------------------------------------------------------------------ -; FUNCTION: lgdt -; C PROTOTYPE: void lgdt(x86_pseudo_descriptor_t *gdt_desc) -; ------------------------------------------------------------------------------ - global lgdt:function (lgdt.end - lgdt) -lgdt: - mov eax, [esp+4] ; First param: gdt_info - add eax, 2 ; gdt_info_t structure contains two bytes of - ; padding for alignment - lgdt [eax] - ret - -.end: - -; ------------------------------------------------------------------------------ -; FUNCTION: lidt -; C PROTOTYPE: void lidt(x86_pseudo_descriptor_t *idt_desc) -; ------------------------------------------------------------------------------ - global lidt:function (lidt.end - lidt) -lidt: - mov eax, [esp+4] ; First param: idt_info - add eax, 2 ; idt_info_t structure contains two bytes of - ; padding for alignment - lidt [eax] - ret - -.end: - -; ------------------------------------------------------------------------------ -; FUNCTION: ltr -; C PROTOTYPE: void ltr(seg_selector_t sel) -; ------------------------------------------------------------------------------ - global ltr:function (ltr.end - ltr) -ltr: - mov eax, [esp+4] ; First param: sel - ltr ax - ret - -.end: - -; ------------------------------------------------------------------------------ -; FUNCTION: cpuid -; C PROTOTYPE: uint32_t cpuid(x86_regs_t *regs) -; ------------------------------------------------------------------------------ - global cpuid:function (cpuid.end - cpuid) -cpuid: - ; save registers - push ebx - push edi - - mov edi, [esp+12] ; First param: regs - - mov eax, [edi+ 0] ; regs->eax - mov ebx, [edi+ 4] ; regs->ebx - mov ecx, [edi+ 8] ; regs->ecx - mov edx, [edi+12] ; regs->edx - - cpuid - - mov edi, [esp+12] ; First param: regs - - mov [edi+ 0], eax - mov [edi+ 4], ebx - mov [edi+ 8], ecx - mov [edi+12], edx - - ; restore registers - pop edi - pop ebx - - ret - -.end: - ; ------------------------------------------------------------------------------ ; FUNCTION: get_esp ; C PROTOTYPE: uint32_t get_esp(void) @@ -159,7 +37,6 @@ cpuid: get_esp: mov eax, esp ret - .end: ; ------------------------------------------------------------------------------ @@ -170,7 +47,6 @@ get_esp: get_cr0: mov eax, cr0 ret - .end: ; ------------------------------------------------------------------------------ @@ -181,7 +57,6 @@ get_cr0: get_cr2: mov eax, cr2 ret - .end: ; ------------------------------------------------------------------------------ @@ -192,7 +67,6 @@ get_cr2: get_cr3: mov eax, cr3 ret - .end: ; ------------------------------------------------------------------------------ @@ -203,7 +77,6 @@ get_cr3: get_cr4: mov eax, cr4 ret - .end: ; ------------------------------------------------------------------------------ @@ -218,7 +91,6 @@ set_cr0: jmp .do_ret ; jump to flush the instruction queue .do_ret: ret - .end: ; ------------------------------------------------------------------------------ @@ -230,7 +102,6 @@ set_cr3: mov eax, [esp+4] ; First param: val mov cr3, eax ret - .end: ; ------------------------------------------------------------------------------ @@ -242,7 +113,6 @@ set_cr4: mov eax, [esp+4] ; First param: val mov cr4, eax ret - .end: ; ------------------------------------------------------------------------------ @@ -254,7 +124,6 @@ get_eflags: pushfd pop eax ret - .end: ; ------------------------------------------------------------------------------ @@ -267,7 +136,6 @@ set_eflags: push eax popfd ret - .end: ; ------------------------------------------------------------------------------ @@ -293,7 +161,6 @@ set_ds: mov eax, [esp+4] ; First param: val mov ds, eax ret - .end: ; ------------------------------------------------------------------------------ @@ -305,7 +172,6 @@ set_es: mov eax, [esp+4] ; First param: val mov es, eax ret - .end: ; ------------------------------------------------------------------------------ @@ -317,7 +183,6 @@ set_fs: mov eax, [esp+4] ; First param: val mov fs, eax ret - .end: ; ------------------------------------------------------------------------------ @@ -329,7 +194,6 @@ set_gs: mov eax, [esp+4] ; First param: val mov gs, eax ret - .end: ; ------------------------------------------------------------------------------ @@ -341,35 +205,6 @@ set_ss: mov eax, [esp+4] ; First param: val mov ss, eax ret - -.end: - -; ------------------------------------------------------------------------------ -; FUNCTION: rdmsr -; C PROTOTYPE: uint64_t rdmsr(msr_addr_t addr) -; ------------------------------------------------------------------------------ - global rdmsr:function (rdmsr.end - rdmsr) -rdmsr: - mov ecx, [esp+ 4] ; First param: addr - - rdmsr - ret - -.end: - -; ------------------------------------------------------------------------------ -; FUNCTION: wrmsr -; C PROTOTYPE: void wrmsr(msr_addr_t addr, uint64_t val) -; ------------------------------------------------------------------------------ - global wrmsr:function (wrmsr.end - wrmsr) -wrmsr: - mov ecx, [esp+ 4] ; First param: addr - mov eax, [esp+ 8] ; Second param: val (low dword) - mov edx, [esp+12] ; Second param: val (high dword) - - wrmsr - ret - .end: ; ------------------------------------------------------------------------------ @@ -381,51 +216,4 @@ get_gs_ptr: mov ecx, [esp+ 4] ; First param: ptr mov eax, [gs:ecx] ret - -.end: - -; ------------------------------------------------------------------------------ -; FUNCTION: rdtsc -; C PROTOTYPE: uint64_t rdtsc(void) -; ------------------------------------------------------------------------------ - global rdtsc:function (rdtsc.end - rdtsc) -rdtsc: - rdtsc - ret - -.end: - -; ------------------------------------------------------------------------------ -; FUNCTION: x86_enable_pae -; C PROTOTYPE: void x86_enable_pae(uint32_t cr3_value) -; ------------------------------------------------------------------------------ - global x86_enable_pae:function (x86_enable_pae.end - x86_enable_pae) -x86_enable_pae: - mov eax, [esp+ 4] ; First argument: pdpt - - ; Jump to low-address alias - jmp .just_here - BOOT_OFFSET_FROM_16MB -.just_here: - - ; Disable paging. - mov ecx, cr0 - and ecx, ~X86_CR0_PG - mov cr0, ecx - - ; Load CR3 with address of PDPT. - mov cr3, eax - - ; Enable PAE. - mov eax, cr4 - or eax, X86_CR4_PAE - mov cr4, eax - - ; Re-enable paging (PG), prevent kernel from writing to read-only pages (WP). - or ecx, X86_CR0_PG | X86_CR0_WP - mov cr0, ecx - - ; No need to jump back to high alias. The ret instruction will take care - ; of it because this is where the return address is. - ret - .end: diff --git a/kernel/infrastructure/i686/memory.c b/kernel/infrastructure/i686/memory.c index 45c8d643..75ea31da 100644 --- a/kernel/infrastructure/i686/memory.c +++ b/kernel/infrastructure/i686/memory.c @@ -32,9 +32,9 @@ #include #include #include +#include #include #include -#include #include #include #include @@ -70,7 +70,7 @@ static bool memory_ranges_overlap( static bool range_is_in_available_memory( const memory_range_t *range, - const bootinfo_t *bootinfo) { + const bootinfo_t *bootinfo) { bool retval = false; @@ -211,7 +211,7 @@ static uint64_t memory_find_top(const bootinfo_t *bootinfo) { * */ void memory_initialize_array( boot_alloc_t *boot_alloc, - const bootinfo_t *bootinfo) { + const bootinfo_t *bootinfo) { const size_t entries_per_page = PAGE_SIZE / sizeof(uintptr_t); diff --git a/kernel/infrastructure/i686/percpu.c b/kernel/infrastructure/i686/percpu.c new file mode 100644 index 00000000..2965e8bd --- /dev/null +++ b/kernel/infrastructure/i686/percpu.c @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2019-2024 Philippe Aubertin. + * All rights reserved. + + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the author nor the names of other contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include + +static void set_tls_segment(percpu_t *data, void *addr, size_t size) { + data->gdt[GDT_USER_TLS_DATA] = SEG_DESCRIPTOR( + addr, + size - 1, + SEG_TYPE_DATA | SEG_FLAG_USER | SEG_FLAG_NORMAL + ); +} + +void machine_set_tls(const thread_t *thread) { + percpu_t *data = get_percpu_data(); + set_tls_segment(data, thread->local_storage_addr, thread->local_storage_size); +} + +void init_percpu_data(percpu_t *data) { + tss_t *tss; + + tss = &data->tss; + + /* initialize with zeroes */ + memset(data, '\0', sizeof(percpu_t)); + + data->self = data; + data->current_addr_space = NULL; + + /* initialize GDT */ + data->gdt[GDT_NULL] = SEG_DESCRIPTOR(0, 0, 0); + + data->gdt[GDT_KERNEL_CODE] = + SEG_DESCRIPTOR( 0, 0xfffff, SEG_TYPE_CODE | SEG_FLAG_KERNEL | SEG_FLAG_NORMAL); + + data->gdt[GDT_KERNEL_DATA] = + SEG_DESCRIPTOR( 0, 0xfffff, SEG_TYPE_DATA | SEG_FLAG_KERNEL | SEG_FLAG_NORMAL); + + data->gdt[GDT_USER_CODE] = + SEG_DESCRIPTOR( 0, 0xfffff, SEG_TYPE_CODE | SEG_FLAG_USER | SEG_FLAG_NORMAL); + + data->gdt[GDT_USER_DATA] = + SEG_DESCRIPTOR( 0, 0xfffff, SEG_TYPE_DATA | SEG_FLAG_USER | SEG_FLAG_NORMAL); + + data->gdt[GDT_TSS] = + SEG_DESCRIPTOR( tss, TSS_LIMIT-1, SEG_TYPE_TSS | SEG_FLAG_KERNEL | SEG_FLAG_TSS); + + data->gdt[GDT_PER_CPU_DATA] = + SEG_DESCRIPTOR( data, sizeof(percpu_t)-1, SEG_TYPE_DATA | SEG_FLAG_KERNEL | SEG_FLAG_32BIT | SEG_FLAG_IN_BYTES | SEG_FLAG_NOSYSTEM | SEG_FLAG_PRESENT); + + set_tls_segment(data, NULL, 0); + + /* setup kernel stack in TSS */ + tss->ss0 = SEG_SELECTOR(GDT_KERNEL_DATA, RPL_KERNEL); + tss->ss1 = SEG_SELECTOR(GDT_KERNEL_DATA, RPL_KERNEL); + tss->ss2 = SEG_SELECTOR(GDT_KERNEL_DATA, RPL_KERNEL); + + /* kernel stack address is updated by machine_switch_thread() */ + tss->esp0 = NULL; + tss->esp1 = NULL; + tss->esp2 = NULL; + + /* From Intel 64 and IA-32 Architectures Software Developer's Manual Volume + * 3 System Programming Guide chapter 16.5: + * + * " If the I/O bit map base address is greater than or equal to the TSS + * segment limit, there is no I/O permission map, and all I/O instructions + * generate exceptions when the CPL is greater than the current IOPL. " */ + tss->iomap = TSS_LIMIT; +} diff --git a/kernel/infrastructure/i686/remap.asm b/kernel/infrastructure/i686/pmap/init.asm similarity index 86% rename from kernel/infrastructure/i686/remap.asm rename to kernel/infrastructure/i686/pmap/init.asm index 51139579..deb40201 100644 --- a/kernel/infrastructure/i686/remap.asm +++ b/kernel/infrastructure/i686/pmap/init.asm @@ -1,4 +1,4 @@ -; Copyright (C) 2021 Philippe Aubertin. +; Copyright (C) 2019-2024 Philippe Aubertin. ; All rights reserved. ; ; Redistribution and use in source and binary forms, with or without @@ -27,8 +27,9 @@ ; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#include #include -#include +#include bits 32 @@ -144,3 +145,37 @@ move_and_remap_kernel: pop esi ret .end: + +; ------------------------------------------------------------------------------ +; FUNCTION: enable_pae +; C PROTOTYPE: void enable_pae(uint32_t cr3_value) +; ------------------------------------------------------------------------------ + global enable_pae:function (enable_pae.end - enable_pae) +enable_pae: + mov eax, [esp+ 4] ; First argument: pdpt + + ; Jump to low-address alias + jmp .just_here - BOOT_OFFSET_FROM_16MB +.just_here: + + ; Disable paging. + mov ecx, cr0 + and ecx, ~X86_CR0_PG + mov cr0, ecx + + ; Load CR3 with address of PDPT. + mov cr3, eax + + ; Enable PAE. + mov eax, cr4 + or eax, X86_CR4_PAE + mov cr4, eax + + ; Re-enable paging (PG), prevent kernel from writing to read-only pages (WP). + or ecx, X86_CR0_PG | X86_CR0_WP + mov cr0, ecx + + ; No need to jump back to high alias. The ret instruction will take care + ; of it because this is where the return address is. + ret +.end: diff --git a/kernel/infrastructure/i686/vm_x86.c b/kernel/infrastructure/i686/pmap/nopae.c similarity index 83% rename from kernel/infrastructure/i686/vm_x86.c rename to kernel/infrastructure/i686/pmap/nopae.c index bc8ee1d2..6649d5d5 100644 --- a/kernel/infrastructure/i686/vm_x86.c +++ b/kernel/infrastructure/i686/pmap/nopae.c @@ -30,37 +30,37 @@ */ #include +#include #include -#include #include /* This file contains non-Physical Address Extension (PAE) memory management - * code. PAE code is located in vm_pae.c. Virtual memory management code - * independent of PAE is located in vm.c. */ + * code. PAE code is located in pae.c. Virtual memory management code + * independent of PAE is located in pmap.c. */ /** number of entries in a page directory or page table */ -#define PAGE_TABLE_ENTRIES VM_X86_PAGE_TABLE_PTES +#define PAGE_TABLE_ENTRIES NOPAE_PAGE_TABLE_PTES struct pte_t { uint32_t entry; }; -void vm_x86_create_initial_addr_space(addr_space_t *addr_space, pte_t *page_directory) { +void nopae_create_initial_addr_space(addr_space_t *addr_space, pte_t *page_directory) { addr_space->top_level.pd = (pte_t *)PHYS_TO_VIRT_AT_16MB(page_directory); addr_space->cr3 = (uintptr_t)page_directory; } -void vm_x86_create_addr_space(addr_space_t *addr_space, pte_t *page_directory) { +void nopae_create_addr_space(addr_space_t *addr_space, pte_t *page_directory) { addr_space->top_level.pd = page_directory; addr_space->cr3 = machine_lookup_kernel_paddr(page_directory); } -void vm_x86_destroy_addr_space(addr_space_t *addr_space) { - vm_destroy_page_directory( +void nopae_destroy_addr_space(addr_space_t *addr_space) { + destroy_page_directory( addr_space->top_level.pd, /* Free page tables for addresses 0..KLIMIT, be careful not to free * the kernel page tables starting at KLIMIT. */ - vm_x86_page_directory_offset_of((addr_t)KLIMIT)); + nopae_page_directory_offset_of((addr_t)KLIMIT)); } /** @@ -70,7 +70,7 @@ void vm_x86_destroy_addr_space(addr_space_t *addr_space) { * @return entry offset of address within page table * */ -unsigned int vm_x86_page_table_offset_of(void *addr) { +unsigned int nopae_page_table_offset_of(void *addr) { return PAGE_TABLE_OFFSET_OF(addr); } @@ -81,7 +81,7 @@ unsigned int vm_x86_page_table_offset_of(void *addr) { * @return entry offset of address within page directory * */ -unsigned int vm_x86_page_directory_offset_of(void *addr) { +unsigned int nopae_page_directory_offset_of(void *addr) { return PAGE_DIRECTORY_OFFSET_OF(addr); } @@ -94,7 +94,7 @@ unsigned int vm_x86_page_directory_offset_of(void *addr) { * * @param addr_space address space in which the address is looked up. */ -pte_t *vm_x86_lookup_page_directory(addr_space_t *addr_space) { +pte_t *nopae_lookup_page_directory(addr_space_t *addr_space) { return addr_space->top_level.pd; } @@ -106,7 +106,7 @@ pte_t *vm_x86_lookup_page_directory(addr_space_t *addr_space) { * @return PTE at specified offset * */ -pte_t *vm_x86_get_pte_with_offset(pte_t *pte, unsigned int offset) { +pte_t *nopae_get_pte_with_offset(pte_t *pte, unsigned int offset) { return &pte[offset]; } @@ -143,7 +143,7 @@ static uint32_t filter_pte_flags(uint64_t flags) { * @param flags flags * */ -void vm_x86_set_pte(pte_t *pte, uint32_t paddr, uint64_t flags) { +void nopae_set_pte(pte_t *pte, uint32_t paddr, uint64_t flags) { assert((paddr & PAGE_MASK) == 0); pte->entry = paddr | filter_pte_flags(flags); } @@ -159,7 +159,7 @@ void vm_x86_set_pte(pte_t *pte, uint32_t paddr, uint64_t flags) { * @param pte flags flags * */ -void vm_x86_set_pte_flags(pte_t *pte, uint64_t flags) { +void nopae_set_pte_flags(pte_t *pte, uint64_t flags) { pte->entry = (pte->entry & ~PAGE_MASK) | filter_pte_flags(flags); } @@ -170,7 +170,7 @@ void vm_x86_set_pte_flags(pte_t *pte, uint64_t flags) { * @return physical address * */ -uint32_t vm_x86_get_pte_paddr(const pte_t *pte) { +uint32_t nopae_get_pte_paddr(const pte_t *pte) { return pte->entry & ~PAGE_MASK; } @@ -183,7 +183,7 @@ uint32_t vm_x86_get_pte_paddr(const pte_t *pte) { * @param pte page table or page directory entry * */ -void vm_x86_clear_pte(pte_t *pte) { +void nopae_clear_pte(pte_t *pte) { pte->entry = 0; } @@ -194,6 +194,6 @@ void vm_x86_clear_pte(pte_t *pte) { * @param src source page table/directory entry * */ -void vm_x86_copy_pte(pte_t *dest, const pte_t *src) { +void nopae_copy_pte(pte_t *dest, const pte_t *src) { dest->entry = src->entry; } diff --git a/kernel/infrastructure/i686/vm_pae.c b/kernel/infrastructure/i686/pmap/pae.c similarity index 86% rename from kernel/infrastructure/i686/vm_pae.c rename to kernel/infrastructure/i686/pmap/pae.c index b1cbb71d..6169dcd2 100644 --- a/kernel/infrastructure/i686/vm_pae.c +++ b/kernel/infrastructure/i686/pmap/pae.c @@ -33,19 +33,22 @@ #include #include #include +#include +#include +#include +#include +#include #include -#include +#include #include -#include -#include #include #include #include #include /* This file contains Physical Address Extension (PAE) memory management code. - * Non-PAE code is located in vm_x86.c. Virtual memory management code - * independent of PAE is located in vm.c. */ + * Non-PAE code is located in nopae.c. Virtual memory management code + * independent of PAE is located in pmap.c. */ /** number of address bits that encode the PDPT offset */ #define PDPT_BITS 2 @@ -54,7 +57,7 @@ #define PDPT_ENTRIES (1 << PDPT_BITS) /** number of entries in a page directory or page table */ -#define PAGE_TABLE_ENTRIES VM_PAE_PAGE_TABLE_PTES +#define PAGE_TABLE_ENTRIES PAE_PAGE_TABLE_PTES struct pte_t { @@ -81,7 +84,7 @@ static inline unsigned int pdpt_offset_of(void *addr) { static void clear_pdpt(pdpt_t *pdpt) { for(int idx = 0; idx < PDPT_ENTRIES; ++idx) { - vm_pae_clear_pte(&pdpt->pd[idx]); + pae_clear_pte(&pdpt->pd[idx]); } } @@ -92,7 +95,7 @@ static void clear_pdpt(pdpt_t *pdpt) { * * */ static void initialize_boot_mapping_at_1mb(pte_t *page_table_1mb) { - vm_initialize_page_table_linear( + initialize_page_table_linear( page_table_1mb, 0, X86_PTE_READ_WRITE, @@ -113,14 +116,14 @@ static void initialize_boot_mapping_at_16mb( size_t image_pages = image_size / PAGE_SIZE; /* map kernel image read only */ - pte_t *next_pte = vm_initialize_page_table_linear( + pte_t *next_pte = initialize_page_table_linear( page_table_16mb, MEMORY_ADDR_16MB, 0, image_pages); /* map remaining of region read/write */ - vm_initialize_page_table_linear( + initialize_page_table_linear( next_pte, MEMORY_ADDR_16MB + image_size, X86_PTE_READ_WRITE, @@ -144,7 +147,7 @@ static void initialize_boot_mapping_at_klimit( size_t image_pages = image_size / PAGE_SIZE; /* map kernel image read only */ - pte_t *next_pte_after_image = vm_initialize_page_table_linear( + pte_t *next_pte_after_image = initialize_page_table_linear( page_table_klimit, MEMORY_ADDR_16MB, 0, @@ -153,14 +156,14 @@ static void initialize_boot_mapping_at_klimit( /* map kernel data segment */ size_t offset = ((uintptr_t)bootinfo->data_start - KLIMIT) / PAGE_SIZE; - vm_initialize_page_table_linear( - vm_pae_get_pte_with_offset(page_table_klimit, offset), + initialize_page_table_linear( + pae_get_pte_with_offset(page_table_klimit, offset), bootinfo->data_physaddr + MEMORY_ADDR_16MB - MEMORY_ADDR_1MB, X86_PTE_READ_WRITE, bootinfo->data_size / PAGE_SIZE); /* map rest of region read/write */ - vm_initialize_page_table_linear( + initialize_page_table_linear( next_pte_after_image, MEMORY_ADDR_16MB + image_size, X86_PTE_READ_WRITE, @@ -180,15 +183,15 @@ static void initialize_boot_low_page_directory( const pte_t *page_table_1mb, const pte_t *page_table_16mb) { - vm_pae_set_pte( + pae_set_pte( low_page_directory, (uintptr_t)page_table_1mb, X86_PTE_READ_WRITE | X86_PTE_PRESENT); - vm_initialize_page_table_linear( - vm_pae_get_pte_with_offset( + initialize_page_table_linear( + pae_get_pte_with_offset( low_page_directory, - vm_pae_page_directory_offset_of((addr_t)MEMORY_ADDR_16MB)), + pae_page_directory_offset_of((addr_t)MEMORY_ADDR_16MB)), (uintptr_t)page_table_16mb, X86_PTE_READ_WRITE, BOOT_PTES_AT_16MB / PAGE_TABLE_ENTRIES); @@ -205,10 +208,10 @@ static void initialize_boot_page_directory_klimit( pte_t *page_directory_klimit, const pte_t *page_table_klimit) { - vm_pae_set_pte( - vm_pae_get_pte_with_offset( + pae_set_pte( + pae_get_pte_with_offset( page_directory_klimit, - vm_pae_page_directory_offset_of((addr_t)KLIMIT)), + pae_page_directory_offset_of((addr_t)KLIMIT)), (uintptr_t)page_table_klimit, X86_PTE_READ_WRITE | X86_PTE_PRESENT); } @@ -226,12 +229,12 @@ static void initialize_boot_pdpt( const pte_t *low_page_directory, const pte_t *page_directory_klimit) { - vm_pae_set_pte( + pae_set_pte( &pdpt->pd[0], (uintptr_t)low_page_directory, X86_PTE_PRESENT); - vm_pae_set_pte( + pae_set_pte( &pdpt->pd[pdpt_offset_of((addr_t)KLIMIT)], (uintptr_t)page_directory_klimit, X86_PTE_PRESENT); @@ -316,14 +319,14 @@ static pdpt_t *initialize_boot_page_tables( * @param bootinfo boot information structure * * */ -void vm_pae_enable(boot_alloc_t *boot_alloc, const bootinfo_t *bootinfo) { +void pae_enable(boot_alloc_t *boot_alloc, const bootinfo_t *bootinfo) { pgtable_format_pae = true; - entries_per_page_table = VM_PAE_PAGE_TABLE_PTES; - page_frame_number_mask = ((UINT64_C(1) << cpu_info.maxphyaddr) - 1) & (~PAGE_MASK); + entries_per_page_table = PAE_PAGE_TABLE_PTES; + page_frame_number_mask = ((UINT64_C(1) << cpuinfo.maxphyaddr) - 1) & (~PAGE_MASK); pdpt_t *pdpt = initialize_boot_page_tables(boot_alloc, bootinfo); - x86_enable_pae(PTR_TO_PHYS_ADDR_AT_16MB(pdpt)); + enable_pae(PTR_TO_PHYS_ADDR_AT_16MB(pdpt)); /* Enable support for NX/XD bit */ uint64_t msrval = rdmsr(MSR_EFER); @@ -331,7 +334,7 @@ void vm_pae_enable(boot_alloc_t *boot_alloc, const bootinfo_t *bootinfo) { wrmsr(MSR_EFER, msrval); } -void vm_pae_create_initial_addr_space( +void pae_create_initial_addr_space( addr_space_t *address_space, pte_t *page_directories, boot_alloc_t *boot_alloc) { @@ -340,7 +343,7 @@ void vm_pae_create_initial_addr_space( initial_pdpt = boot_heap_alloc(boot_alloc, pdpt_t, 32); int offset = pdpt_offset_of((void *)KLIMIT); - vm_initialize_page_table_linear( + initialize_page_table_linear( &initial_pdpt->pd[offset], (uintptr_t)page_directories, X86_PTE_PRESENT, @@ -350,7 +353,7 @@ void vm_pae_create_initial_addr_space( address_space->cr3 = VIRT_TO_PHYS_AT_16MB(initial_pdpt); } -bool vm_pae_create_addr_space(addr_space_t *addr_space, pte_t *first_page_directory) { +bool pae_create_addr_space(addr_space_t *addr_space, pte_t *first_page_directory) { /* Create a PDPT for the new address space */ pdpt_t *pdpt = slab_cache_alloc(&pdpt_cache); @@ -362,13 +365,13 @@ bool vm_pae_create_addr_space(addr_space_t *addr_space, pte_t *first_page_direct unsigned int klimit_offset = pdpt_offset_of((void *)KLIMIT); - vm_pae_set_pte( + pae_set_pte( &pdpt->pd[klimit_offset], machine_lookup_kernel_paddr(first_page_directory), X86_PTE_PRESENT); for(int idx = klimit_offset + 1; idx < PDPT_ENTRIES; ++idx) { - vm_pae_copy_pte(&pdpt->pd[idx], &initial_pdpt->pd[idx]); + pae_copy_pte(&pdpt->pd[idx], &initial_pdpt->pd[idx]); } /* Lookup the physical address of the page where the PDPT resides. */ @@ -383,15 +386,15 @@ bool vm_pae_create_addr_space(addr_space_t *addr_space, pte_t *first_page_direct return true; } -void vm_pae_destroy_addr_space(addr_space_t *addr_space) { +void pae_destroy_addr_space(addr_space_t *addr_space) { pdpt_t *pdpt = addr_space->top_level.pdpt; for(unsigned int idx = 0; idx < pdpt_offset_of((void *)KLIMIT); ++idx) { pte_t *pdpte = &pdpt->pd[idx]; if(pte_is_present(pdpte)) { - vm_destroy_page_directory( - memory_lookup_page(vm_pae_get_pte_paddr(pdpte)), + destroy_page_directory( + memory_lookup_page(pae_get_pte_paddr(pdpte)), entries_per_page_table); } } @@ -411,15 +414,15 @@ void vm_pae_destroy_addr_space(addr_space_t *addr_space) { * entry for address KLIMIT is at some non-zero offset within this page * directory. In this case, we must free the userspace page tables, but * not the kernel page tables, and then free the page directory. */ - unsigned int klimit_offset = vm_pae_page_directory_offset_of((void *)KLIMIT); + unsigned int klimit_offset = pae_page_directory_offset_of((void *)KLIMIT); if(klimit_offset > 0) { pte_t *pdpte = &pdpt->pd[pdpt_offset_of((void *)KLIMIT)]; assert(pte_is_present(pdpte)); - vm_destroy_page_directory( - memory_lookup_page(vm_pae_get_pte_paddr(pdpte)), + destroy_page_directory( + memory_lookup_page(pae_get_pte_paddr(pdpte)), klimit_offset); } @@ -433,7 +436,7 @@ void vm_pae_destroy_addr_space(addr_space_t *addr_space) { * @param addr address to look up * @param create_as_need Whether a page table is allocated if it does not exist */ -pte_t *vm_pae_lookup_page_directory( +pte_t *pae_lookup_page_directory( addr_space_t *addr_space, void *addr, bool create_as_needed, @@ -449,7 +452,7 @@ pte_t *vm_pae_lookup_page_directory( pte_t *pdpte = &pdpt->pd[pdpt_offset_of(addr)]; if(pte_is_present(pdpte)) { - return memory_lookup_page(vm_pae_get_pte_paddr(pdpte)); + return memory_lookup_page(pae_get_pte_paddr(pdpte)); } if(!create_as_needed) { @@ -461,7 +464,7 @@ pte_t *vm_pae_lookup_page_directory( if(page_directory != NULL) { clear_page(page_directory); - vm_pae_set_pte( + pae_set_pte( pdpte, machine_lookup_kernel_paddr(page_directory), X86_PTE_PRESENT); @@ -482,7 +485,7 @@ pte_t *vm_pae_lookup_page_directory( * @return entry offset of address within page table * */ -unsigned int vm_pae_page_table_offset_of(void *addr) { +unsigned int pae_page_table_offset_of(void *addr) { return PAGE_TABLE_OFFSET_OF(addr); } @@ -493,7 +496,7 @@ unsigned int vm_pae_page_table_offset_of(void *addr) { * @return entry offset of address within page directory * */ -unsigned int vm_pae_page_directory_offset_of(void *addr) { +unsigned int pae_page_directory_offset_of(void *addr) { return PAGE_DIRECTORY_OFFSET_OF(addr); } @@ -505,7 +508,7 @@ unsigned int vm_pae_page_directory_offset_of(void *addr) { * @return PTE at specified offset * */ -pte_t *vm_pae_get_pte_with_offset(pte_t *pte, unsigned int offset) { +pte_t *pae_get_pte_with_offset(pte_t *pte, unsigned int offset) { return &pte[offset]; } @@ -521,7 +524,7 @@ pte_t *vm_pae_get_pte_with_offset(pte_t *pte, unsigned int offset) { * @param flags flags * */ -void vm_pae_set_pte(pte_t *pte, uint64_t paddr, uint64_t flags) { +void pae_set_pte(pte_t *pte, uint64_t paddr, uint64_t flags) { assert((paddr & ~page_frame_number_mask) == 0); pte->entry = paddr | flags; } @@ -537,7 +540,7 @@ void vm_pae_set_pte(pte_t *pte, uint64_t paddr, uint64_t flags) { * @param pte flags flags * */ -void vm_pae_set_pte_flags(pte_t *pte, uint64_t flags) { +void pae_set_pte_flags(pte_t *pte, uint64_t flags) { pte->entry = (pte->entry & page_frame_number_mask) | flags; } @@ -548,7 +551,7 @@ void vm_pae_set_pte_flags(pte_t *pte, uint64_t flags) { * @return physical address * */ -uint64_t vm_pae_get_pte_paddr(const pte_t *pte) { +uint64_t pae_get_pte_paddr(const pte_t *pte) { return (pte->entry & page_frame_number_mask); } @@ -561,7 +564,7 @@ uint64_t vm_pae_get_pte_paddr(const pte_t *pte) { * @param pte page table or page directory entry * */ -void vm_pae_clear_pte(pte_t *pte) { +void pae_clear_pte(pte_t *pte) { pte->entry = 0; } @@ -572,11 +575,11 @@ void vm_pae_clear_pte(pte_t *pte) { * @param src source page table/directory entry * */ -void vm_pae_copy_pte(pte_t *dest, const pte_t *src) { +void pae_copy_pte(pte_t *dest, const pte_t *src) { dest->entry = src->entry; } -void vm_pae_create_pdpt_cache(void) { +void pae_create_pdpt_cache(void) { slab_cache_init( &pdpt_cache, "pae_pdpt", diff --git a/kernel/infrastructure/i686/vm.c b/kernel/infrastructure/i686/pmap/pmap.c similarity index 87% rename from kernel/infrastructure/i686/vm.c rename to kernel/infrastructure/i686/pmap/pmap.c index ac8d9274..783b6a08 100644 --- a/kernel/infrastructure/i686/vm.c +++ b/kernel/infrastructure/i686/pmap/pmap.c @@ -37,16 +37,16 @@ #include #include #include +#include +#include +#include +#include #include -#include #include -#include -#include -#include -#include +#include #include #include -#include +#include #include #include #include @@ -55,8 +55,8 @@ #include /* This file contains memory management code that is independent of whether - * Physical Address Extension (PAE) is enabled or not. The PAE code is in the - * vm_pae.c file. Non-PAE code is in the vm_x86.c file. + * Physical Address Extension (PAE) is enabled or not. The PAE code is in + * pae.c. Non-PAE code is in nopae.c. * * Type "pte_t *" is a pointer on a page table or page directory entry. Such * pointers might point to a 32-bit (non-PAE) entry or a 64-bit (PAE) entry and, @@ -98,10 +98,10 @@ static addr_space_t initial_addr_space; */ static pte_t *get_pte_with_offset(pte_t *pte, unsigned int offset) { if(pgtable_format_pae) { - return vm_pae_get_pte_with_offset(pte, offset); + return pae_get_pte_with_offset(pte, offset); } else { - return vm_x86_get_pte_with_offset(pte, offset); + return nopae_get_pte_with_offset(pte, offset); } } @@ -132,10 +132,10 @@ static inline const pte_t *get_pte_with_offset_const( */ static unsigned int page_table_offset_of(void *addr) { if(pgtable_format_pae) { - return vm_pae_page_table_offset_of(addr); + return pae_page_table_offset_of(addr); } else { - return vm_x86_page_table_offset_of(addr); + return nopae_page_table_offset_of(addr); } } @@ -148,10 +148,10 @@ static unsigned int page_table_offset_of(void *addr) { */ static unsigned int page_directory_offset_of(void *addr) { if(pgtable_format_pae) { - return vm_pae_page_directory_offset_of(addr); + return pae_page_directory_offset_of(addr); } else { - return vm_x86_page_directory_offset_of(addr); + return nopae_page_directory_offset_of(addr); } } @@ -168,10 +168,10 @@ static unsigned int page_directory_offset_of(void *addr) { */ static void set_pte_flags(pte_t *pte, uint64_t flags) { if(pgtable_format_pae) { - vm_pae_set_pte_flags(pte, flags); + pae_set_pte_flags(pte, flags); } else { - vm_x86_set_pte_flags(pte, flags); + nopae_set_pte_flags(pte, flags); } } @@ -184,10 +184,10 @@ static void set_pte_flags(pte_t *pte, uint64_t flags) { */ static void copy_pte(pte_t *dest, const pte_t *src) { if(pgtable_format_pae) { - vm_pae_copy_pte(dest, src); + pae_copy_pte(dest, src); } else { - vm_x86_copy_pte(dest, src); + nopae_copy_pte(dest, src); } } @@ -221,10 +221,10 @@ void copy_ptes(pte_t *dest, const pte_t *src, int n) { */ static void set_pte(pte_t *pte, user_paddr_t paddr, uint64_t flags) { if(pgtable_format_pae) { - vm_pae_set_pte(pte, paddr, flags); + pae_set_pte(pte, paddr, flags); } else { - vm_x86_set_pte(pte, (uint32_t)paddr, flags); + nopae_set_pte(pte, (uint32_t)paddr, flags); } } @@ -239,10 +239,10 @@ static void set_pte(pte_t *pte, user_paddr_t paddr, uint64_t flags) { */ static void clear_pte(pte_t *pte) { if(pgtable_format_pae) { - vm_pae_clear_pte(pte); + pae_clear_pte(pte); } else { - vm_x86_clear_pte(pte); + nopae_clear_pte(pte); } } @@ -271,10 +271,10 @@ void clear_ptes(pte_t *pte, int n) { */ static user_paddr_t get_pte_paddr(const pte_t *pte) { if(pgtable_format_pae) { - return vm_pae_get_pte_paddr(pte); + return pae_get_pte_paddr(pte); } else { - return vm_x86_get_pte_paddr(pte); + return nopae_get_pte_paddr(pte); } } @@ -282,12 +282,12 @@ static user_paddr_t get_pte_paddr(const pte_t *pte) { * Initialize virtual memory management to not use PAE * * During initialization, the kernel either calls this function or calls - * vm_pae_enable() to enable PAE. + * pae_enable() to enable PAE. * */ -void vm_set_no_pae(void) { +void pmap_set_no_pae(void) { pgtable_format_pae = false; - entries_per_page_table = VM_X86_PAGE_TABLE_PTES; + entries_per_page_table = NOPAE_PAGE_TABLE_PTES; } /** @@ -300,7 +300,7 @@ void vm_set_no_pae(void) { * @return first page table entry after affected ones * */ -pte_t *vm_initialize_page_table_linear( +pte_t *initialize_page_table_linear( pte_t *page_table, uint64_t start_paddr, uint64_t flags, @@ -330,7 +330,7 @@ pte_t *vm_initialize_page_table_linear( * @param bootinfo boot information structure * */ -void vm_write_protect_kernel_image(const bootinfo_t *bootinfo) { +void pmap_write_protect_kernel_image(const bootinfo_t *bootinfo) { size_t image_size = (char *)bootinfo->image_top - (char *)bootinfo->image_start; size_t image_pages = image_size / PAGE_SIZE; @@ -352,14 +352,14 @@ static void initialize_initial_page_tables( size_t image_pages = image_size / PAGE_SIZE; /* map kernel image read only, not executable */ - pte_t *next_pte_after_image = vm_initialize_page_table_linear( + pte_t *next_pte_after_image = initialize_page_table_linear( page_tables, MEMORY_ADDR_16MB, X86_PTE_GLOBAL | X86_PTE_NX, image_pages); /* map rest of region read/write */ - vm_initialize_page_table_linear( + initialize_page_table_linear( next_pte_after_image, MEMORY_ADDR_16MB + image_size, X86_PTE_GLOBAL | X86_PTE_READ_WRITE | X86_PTE_NX, @@ -376,7 +376,7 @@ static void initialize_initial_page_tables( size_t code_size = phdr->p_memsz + OFFSET_OF_PTR(phdr->p_vaddr, PAGE_SIZE); size_t code_offset = (code_vaddr - KLIMIT) / PAGE_SIZE; - vm_initialize_page_table_linear( + initialize_page_table_linear( get_pte_with_offset(page_tables, code_offset), code_vaddr + MEMORY_ADDR_16MB - KLIMIT, X86_PTE_GLOBAL, @@ -385,7 +385,7 @@ static void initialize_initial_page_tables( /* map kernel data segment */ size_t data_offset = ((uintptr_t)bootinfo->data_start - KLIMIT) / PAGE_SIZE; - vm_initialize_page_table_linear( + initialize_page_table_linear( get_pte_with_offset(page_tables, data_offset), bootinfo->data_physaddr + MEMORY_ADDR_16MB - MEMORY_ADDR_1MB, X86_PTE_GLOBAL | X86_PTE_READ_WRITE | X86_PTE_NX, @@ -399,14 +399,14 @@ static void initialize_initial_page_directories( int offset = page_directory_offset_of((void *)KLIMIT); - vm_initialize_page_table_linear( + initialize_page_table_linear( get_pte_with_offset(page_directories, offset), (uintptr_t)page_tables, X86_PTE_READ_WRITE, num_page_tables); } -addr_space_t *vm_create_initial_addr_space( +addr_space_t *pmap_create_initial_addr_space( const exec_file_t *kernel, boot_alloc_t *boot_alloc, const bootinfo_t *bootinfo) { @@ -431,13 +431,13 @@ addr_space_t *vm_create_initial_addr_space( kernel_page_tables = (pte_t *)PHYS_TO_VIRT_AT_16MB(page_tables); if(pgtable_format_pae) { - vm_pae_create_initial_addr_space( + pae_create_initial_addr_space( &initial_addr_space, page_directories, boot_alloc); } else { - vm_x86_create_initial_addr_space(&initial_addr_space, page_directories); + nopae_create_initial_addr_space(&initial_addr_space, page_directories); } return &initial_addr_space; @@ -447,14 +447,14 @@ static pte_t *clone_first_kernel_page_directory(void) { pte_t *pd_template; if(pgtable_format_pae) { - pd_template = vm_pae_lookup_page_directory( + pd_template = pae_lookup_page_directory( &initial_addr_space, (void *)KLIMIT, false, NULL); } else { - pd_template = vm_x86_lookup_page_directory(&initial_addr_space); + pd_template = nopae_lookup_page_directory(&initial_addr_space); } assert(pd_template != NULL); @@ -491,7 +491,7 @@ static void free_first_kernel_page_directory(pte_t *page_directory) { } } -bool vm_create_addr_space(addr_space_t *addr_space) { +bool pmap_create_addr_space(addr_space_t *addr_space) { pte_t *page_directory = clone_first_kernel_page_directory(); if(page_directory == NULL) { @@ -499,11 +499,11 @@ bool vm_create_addr_space(addr_space_t *addr_space) { } if(!pgtable_format_pae) { - vm_x86_create_addr_space(addr_space, page_directory); + nopae_create_addr_space(addr_space, page_directory); return true; } - bool retval = vm_pae_create_addr_space(addr_space, page_directory); + bool retval = pae_create_addr_space(addr_space, page_directory); if(!retval) { free_first_kernel_page_directory(page_directory); @@ -512,7 +512,7 @@ bool vm_create_addr_space(addr_space_t *addr_space) { return retval; } -void vm_destroy_page_directory(void *page_directory, unsigned int last_index) { +void destroy_page_directory(void *page_directory, unsigned int last_index) { for(unsigned int idx = 0; idx < last_index; ++idx) { pte_t *pte = get_pte_with_offset(page_directory, idx); @@ -526,7 +526,7 @@ void vm_destroy_page_directory(void *page_directory, unsigned int last_index) { page_free(page_directory); } -void vm_destroy_addr_space(addr_space_t *addr_space) { +void pmap_destroy_addr_space(addr_space_t *addr_space) { /** ASSERTION: address space must not be NULL */ assert(addr_space != NULL); @@ -537,24 +537,24 @@ void vm_destroy_addr_space(addr_space_t *addr_space) { assert( addr_space != get_current_addr_space() ); if(pgtable_format_pae) { - vm_pae_destroy_addr_space(addr_space); + pae_destroy_addr_space(addr_space); } else { - vm_x86_destroy_addr_space(addr_space); + nopae_destroy_addr_space(addr_space); } } -void vm_switch_addr_space(addr_space_t *addr_space) { +void pmap_switch_addr_space(addr_space_t *addr_space) { set_cr3(addr_space->cr3); - cpu_data_t *cpu_data = get_cpu_local_data(); + percpu_t *cpu_data = get_percpu_data(); cpu_data->current_addr_space = addr_space; } -void vm_boot_map(void *addr, uint32_t paddr, int num_entries) { +void pmap_boot_map(void *addr, uint32_t paddr, int num_entries) { int offset = (uintptr_t)((char *)addr - KLIMIT) / PAGE_SIZE; - vm_initialize_page_table_linear( + initialize_page_table_linear( get_pte_with_offset( (pte_t *)PTR_TO_PHYS_ADDR_AT_16MB(kernel_page_tables), offset), @@ -563,7 +563,7 @@ void vm_boot_map(void *addr, uint32_t paddr, int num_entries) { num_entries); } -static pte_t *vm_lookup_page_table( +static pte_t *pmap_lookup_page_table( addr_space_t *addr_space, void *addr, bool create_as_needed, @@ -575,14 +575,14 @@ static pte_t *vm_lookup_page_table( assert(addr_space != NULL); if(pgtable_format_pae) { - page_directory = vm_pae_lookup_page_directory( + page_directory = pae_lookup_page_directory( addr_space, addr, create_as_needed, reload_cr3); } else { - page_directory = vm_x86_lookup_page_directory(addr_space); + page_directory = nopae_lookup_page_directory(addr_space); } if(page_directory == NULL) { @@ -643,7 +643,7 @@ static pte_t *vm_lookup_page_table( * @return pointer to page table entry on success, NULL otherwise * * */ -static pte_t *vm_lookup_page_table_entry( +static pte_t *lookup_page_table_entry( addr_space_t *addr_space, void *addr, bool create_as_needed, @@ -666,7 +666,7 @@ static pte_t *vm_lookup_page_table_entry( page_number_of((uintptr_t)addr - KLIMIT)); } - pte_t *page_table = vm_lookup_page_table( + pte_t *page_table = pmap_lookup_page_table( addr_space, addr, create_as_needed, @@ -713,7 +713,7 @@ static void invalidate_mapping( set_cr3(cr3); } else { - invalidate_tlb(addr); + invlpg(addr); } } } @@ -754,9 +754,9 @@ static uint64_t map_page_access_flags(int prot) { /** * Map a page frame (physical page) to a virtual memory page. * - * This function is intended to be called by vm_map_userspace_page()) and - * vm_map_kernel_page(). Either of these functions should be called elsewhere - * instead of calling this function directly. + * This function is intended to be called by map_userspace_page()) and + * machine_map_kernel_page(). Either of these functions should be called + * elsewhere instead of calling this function directly. * * There is no need to specify an address space for kernel mappings since * kernel mappings are global. @@ -767,11 +767,11 @@ static uint64_t map_page_access_flags(int prot) { * @param addr_space address space in which to map, NULL for kernel mappings * @param vaddr virtual address of mapping * @param paddr address of page frame - * @param flags flags used for mapping (see VM_FLAG_x constants in vm.h) + * @param flags flags used for mapping (see X86_PTE_... constants) * @return true on success, false on page table allocation error * */ -static bool vm_map_page( +static bool map_page( addr_space_t *addr_space, void *vaddr, user_paddr_t paddr, @@ -781,7 +781,7 @@ static bool vm_map_page( assert( page_offset_of(vaddr) == 0 ); bool reload_cr3 = false; - pte_t *pte = vm_lookup_page_table_entry(addr_space, vaddr, true, &reload_cr3); + pte_t *pte = lookup_page_table_entry(addr_space, vaddr, true, &reload_cr3); /* kernel page tables are pre-allocated so this should always succeed for * kernel mappings. */ @@ -812,7 +812,7 @@ static bool vm_map_page( */ void machine_map_kernel_page(void *vaddr, kern_paddr_t paddr, int prot) { assert(is_kernel_pointer(vaddr)); - vm_map_page(NULL, vaddr, paddr, map_page_access_flags(prot) | X86_PTE_GLOBAL); + map_page(NULL, vaddr, paddr, map_page_access_flags(prot) | X86_PTE_GLOBAL); } /** @@ -824,18 +824,18 @@ void machine_map_kernel_page(void *vaddr, kern_paddr_t paddr, int prot) { * @param addr_space address space in which to map * @param vaddr virtual address of mapping * @param paddr address of page frame - * @param flags flags used for the mapping (see VM_FLAG_x constants in vm.h) + * @param prot protections flags * @return true on success, false on page table allocation error * */ -static bool vm_map_userspace_page( +static bool map_userspace_page( addr_space_t *addr_space, void *vaddr, user_paddr_t paddr, int prot) { assert(is_userspace_pointer(vaddr)); - return vm_map_page(addr_space, vaddr, paddr, map_page_access_flags(prot) | X86_PTE_USER); + return map_page(addr_space, vaddr, paddr, map_page_access_flags(prot) | X86_PTE_USER); } /** @@ -865,7 +865,7 @@ bool machine_map_userspace( for(size_t idx = 0; idx < length / PAGE_SIZE; ++idx) { /* TODO We should be able to optimize by not looking up the page table * for each entry. */ - if(!vm_map_userspace_page(addr_space, addr, paddr, prot)) { + if(!map_userspace_page(addr_space, addr, paddr, prot)) { return false; } @@ -888,11 +888,11 @@ bool machine_map_userspace( * @param addr address of page to unmap * */ -static void vm_unmap_page(addr_space_t *addr_space, void *addr) { +static void unmap_page(addr_space_t *addr_space, void *addr) { /** ASSERTION: addr is aligned on a page boundary */ assert( page_offset_of(addr) == 0 ); - pte_t *pte = vm_lookup_page_table_entry(addr_space, addr, false, NULL); + pte_t *pte = lookup_page_table_entry(addr_space, addr, false, NULL); if(pte != NULL) { clear_pte(pte); @@ -913,7 +913,7 @@ static void vm_unmap_page(addr_space_t *addr_space, void *addr) { */ void machine_unmap_kernel_page(void *addr) { assert(is_kernel_pointer(addr)); - vm_unmap_page(NULL, addr); + unmap_page(NULL, addr); } /** @@ -947,15 +947,15 @@ bool machine_clone_userspace_mapping( for(size_t idx = 0; idx < length / PAGE_SIZE; ++idx) { /* TODO We should be able to optimize by not looking up the page table * for each entry, both for source and destination. */ - pte_t *src_pte = vm_lookup_page_table_entry(src_addr_space, src_addr, false, NULL); + pte_t *src_pte = lookup_page_table_entry(src_addr_space, src_addr, false, NULL); if(src_pte == NULL || !pte_is_present(src_pte)) { - vm_unmap_page(dest_addr_space, dest_addr); + unmap_page(dest_addr_space, dest_addr); } else { user_paddr_t paddr = get_pte_paddr(src_pte); - if(!vm_map_userspace_page(dest_addr_space, dest_addr, paddr, prot)) { + if(!map_userspace_page(dest_addr_space, dest_addr, paddr, prot)) { return false; } } @@ -977,7 +977,7 @@ bool machine_clone_userspace_mapping( kern_paddr_t machine_lookup_kernel_paddr(void *addr) { assert( is_kernel_pointer(addr) ); - pte_t *pte = vm_lookup_page_table_entry(NULL, addr, false, NULL); + pte_t *pte = lookup_page_table_entry(NULL, addr, false, NULL); assert(pte != NULL && pte_is_present(pte)); @@ -985,5 +985,5 @@ kern_paddr_t machine_lookup_kernel_paddr(void *addr) { } void machine_switch_to_kernel_addr_space(void) { - vm_switch_addr_space(&initial_addr_space); + pmap_switch_addr_space(&initial_addr_space); } diff --git a/kernel/infrastructure/i686/process.c b/kernel/infrastructure/i686/process.c index c0798b6c..cd9751b2 100644 --- a/kernel/infrastructure/i686/process.c +++ b/kernel/infrastructure/i686/process.c @@ -29,18 +29,18 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include -#include +#include +#include #include void machine_switch_to_process(process_t *process) { - vm_switch_addr_space(&process->addr_space); + pmap_switch_addr_space(&process->addr_space); } bool machine_init_process(process_t *process) { - return vm_create_addr_space(&process->addr_space); + return pmap_create_addr_space(&process->addr_space); } void machine_finalize_process(process_t *process) { - vm_destroy_addr_space(&process->addr_space); + pmap_destroy_addr_space(&process->addr_space); } diff --git a/kernel/infrastructure/i686/thread_switch.asm b/kernel/infrastructure/i686/thread.asm similarity index 92% rename from kernel/infrastructure/i686/thread_switch.asm rename to kernel/infrastructure/i686/thread.asm index ac25780d..16c3419e 100644 --- a/kernel/infrastructure/i686/thread_switch.asm +++ b/kernel/infrastructure/i686/thread.asm @@ -35,14 +35,14 @@ extern sub_ref_to_object ; ------------------------------------------------------------------------------ -; FUNCTION: thread_context_switch_stack -; C PROTOTYPE: void thread_context_switch_stack( -; machine_thread_t *from_ctx, -; machine_thread_t *to_ctx, -; bool destroy_from); +; FUNCTION: switch_thread_stack +; C PROTOTYPE: void switch_thread_stack( +; machine_thread_t *from_ctx, +; machine_thread_t *to_ctx, +; bool destroy_from); ; ------------------------------------------------------------------------------ - global thread_context_switch_stack:function (thread_context_switch_stack.end - thread_context_switch_stack) -thread_context_switch_stack: + global switch_thread_stack:function (switch_thread_stack.end - switch_thread_stack) +switch_thread_stack: ; System V ABI calling convention: these four registers must be preserved ; ; We must store these registers whether we are actually using them here or @@ -113,5 +113,4 @@ thread_context_switch_stack: .skip_destroy: ret - .end: diff --git a/kernel/infrastructure/i686/thread.c b/kernel/infrastructure/i686/thread.c index 74bd69d4..5a5bc5be 100644 --- a/kernel/infrastructure/i686/thread.c +++ b/kernel/infrastructure/i686/thread.c @@ -30,26 +30,23 @@ */ #include +#include #include -#include -#include +#include +#include +#include #include +#include +#include #include #include #include -#include +#include #include #include #include #include - -/* defined in thread_switch.asm */ -void thread_context_switch_stack( - machine_thread_t *from_ctx, - machine_thread_t *to_ctx, - bool destroy_from); - /* For each thread, a page is allocated which contains: * - The thread structure (thread_t), which includes the thread's message * buffer; and @@ -114,7 +111,7 @@ void machine_prepare_thread(thread_t *thread, const thread_params_t *params) { memset(kernel_context, 0, sizeof(kernel_context_t)); - /* This is the address to which thread_context_switch_stack() will return. */ + /* This is the address to which switch_thread_stack() will return. */ kernel_context->eip = (uint32_t)return_from_interrupt; /* set thread stack pointer */ @@ -150,12 +147,12 @@ void machine_switch_thread(thread_t *from, thread_t *to, bool destroy_from) { machine_set_tls(to); /* update kernel stack address for SYSENTER instruction */ - if(cpu_has_feature(CPU_FEATURE_SYSENTER)) { + if(cpu_has_feature(CPUINFO_FEATURE_SYSENTER)) { wrmsr(MSR_IA32_SYSENTER_ESP, (uint64_t)(uintptr_t)kernel_stack_base); } - /* switch thread context stack */ - thread_context_switch_stack(from_ctx, to_ctx, destroy_from); + /* switch thread stack */ + switch_thread_stack(from_ctx, to_ctx, destroy_from); } thread_t *get_current_thread(void) { diff --git a/kernel/infrastructure/i686/auxv.c b/kernel/interface/i686/auxv.c similarity index 100% rename from kernel/infrastructure/i686/auxv.c rename to kernel/interface/i686/auxv.c diff --git a/kernel/interface/i686/bootinfo.c b/kernel/interface/i686/bootinfo.c index a37988cb..a1513a52 100644 --- a/kernel/interface/i686/bootinfo.c +++ b/kernel/interface/i686/bootinfo.c @@ -30,7 +30,7 @@ */ #include -#include +#include #include #include diff --git a/kernel/interface/i686/interrupt.c b/kernel/interface/i686/interrupt.c index ac3a8eb4..09213225 100644 --- a/kernel/interface/i686/interrupt.c +++ b/kernel/interface/i686/interrupt.c @@ -31,9 +31,9 @@ #include #include -#include -#include -#include +#include +#include +#include #include #include #include diff --git a/kernel/interface/i686/ld/image.lds b/kernel/interface/i686/ld/image.lds index f9e26cd0..13e5186a 100755 --- a/kernel/interface/i686/ld/image.lds +++ b/kernel/interface/i686/ld/image.lds @@ -34,8 +34,8 @@ OUTPUT_FORMAT("binary") TARGET("elf32-i386") -INPUT("interface/i686/setup16.o") -INPUT("interface/i686/setup32.o") +INPUT("interface/i686/setup16-nasm.o") +INPUT("interface/i686/setup32-nasm.o") /* Even though the next two input files are ELF binaries, we want to insert them * whole into the kernel image, hence why the TARGET is specified as binary. Both @@ -65,7 +65,7 @@ SECTIONS { * Needed symbols: setup_size_div512 * kernel_size_div16 */ setup16 : { - interface/i686/setup16.o + interface/i686/setup16-nasm.o } /* Everything below this point is loaded consecutively starting at 0x100000 @@ -101,7 +101,7 @@ SECTIONS { * loader_start * loader_size */ setup32 BOOT_SETUP32_ADDR : AT(ADDR(setup16) + SIZEOF(setup16)) { - interface/i686/setup32.o + interface/i686/setup32-nasm.o } /* The next section must start at a specific offset (BOOT_SETUP32_SIZE) from diff --git a/kernel/interface/i686/setup16.asm b/kernel/interface/i686/setup16.asm index 8a88f452..7f8ec2ce 100755 --- a/kernel/interface/i686/setup16.asm +++ b/kernel/interface/i686/setup16.asm @@ -28,8 +28,8 @@ ; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include +#include #include -#include #include #include diff --git a/kernel/interface/i686/setup32.asm b/kernel/interface/i686/setup32.asm index d0d6d673..116c466e 100644 --- a/kernel/interface/i686/setup32.asm +++ b/kernel/interface/i686/setup32.asm @@ -164,8 +164,8 @@ ; === +=======================================+ 0 #include +#include #include -#include #include #include #include @@ -567,7 +567,7 @@ prepare_data_segment: ; Page tables that need to be allocated: ; - One for the first 2MB of memory, which is where the kernel image is ; located, as well as VGA text video memory. - ; - BOOT_PTES_AT_16MB / VM_X86_PAGE_TABLE_PTES for mapping at 0x1000000 + ; - BOOT_PTES_AT_16MB / NOPAE_PAGE_TABLE_PTES for mapping at 0x1000000 ; (i.e. at 16MB) where the kernel image will be moved by the kernel. ; - One for kernel image mapping at KLIMIT ; @@ -588,7 +588,7 @@ allocate_page_tables: ; Page tables for mapping at 0x1000000 (i.e. at 16MB) mov dword [ebp + BOOTINFO_PAGE_TABLE_16MB], edi - add edi, PAGE_SIZE * BOOT_PTES_AT_16MB / VM_X86_PAGE_TABLE_PTES + add edi, PAGE_SIZE * BOOT_PTES_AT_16MB / NOPAE_PAGE_TABLE_PTES ; One page table for mapping at KLIMIT mov dword [ebp + BOOTINFO_PAGE_TABLE_KLIMIT], edi @@ -828,7 +828,7 @@ initialize_page_directory: mov eax, dword [ebp + BOOTINFO_PAGE_TABLE_16MB] or eax, X86_PTE_READ_WRITE lea edi, [edi + 4 * (MEMORY_ADDR_16MB >> 22)] - mov ecx, BOOT_PTES_AT_16MB / VM_X86_PAGE_TABLE_PTES + mov ecx, BOOT_PTES_AT_16MB / NOPAE_PAGE_TABLE_PTES call map_linear ; add entry for the last page table diff --git a/kernel/interface/i686/trap.asm b/kernel/interface/i686/trap.asm index 63851d28..a6a2103d 100644 --- a/kernel/interface/i686/trap.asm +++ b/kernel/interface/i686/trap.asm @@ -263,7 +263,7 @@ fast_amd_entry: mov gs, dx ; load gs with per-cpu data segment selector mov esp, [gs:GDT_LENGTH * 8 + 4] ; load kernel stack pointer from TSS ; Stack pointer is at offset 4 in the TSS, and - ; the TSS follows the GDT (see cpu_data_t). + ; the TSS follows the GDT (see percpu_t). ; For details on the stack layout, see comments in interrupt_entry above and ; the definition of the trapframe_t type. diff --git a/kernel/interface/syscalls.c b/kernel/interface/syscalls.c index eb9715bb..07c2be33 100644 --- a/kernel/interface/syscalls.c +++ b/kernel/interface/syscalls.c @@ -40,7 +40,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/userspace/lib/jinue/Makefile b/userspace/lib/jinue/Makefile index 8df90ff7..53c72433 100644 --- a/userspace/lib/jinue/Makefile +++ b/userspace/lib/jinue/Makefile @@ -37,7 +37,7 @@ target.syscalls = $(notdir $(libjinue_syscalls)) target.utils = $(notdir $(libjinue_utils)) targets = $(target.syscalls) $(target.utils) -objects.syscalls = i686/stubs.o i686/syscalls.o syscalls.o +objects.syscalls = i686/stubs-nasm.o i686/syscalls.o syscalls.o objects.utils = loader.o logging.o include $(common) diff --git a/userspace/lib/libc/Makefile b/userspace/lib/libc/Makefile index c5f6c499..fa9f9a0d 100644 --- a/userspace/lib/libc/Makefile +++ b/userspace/lib/libc/Makefile @@ -57,7 +57,7 @@ targets = $(target.user) $(target.pthread) $(target.kernel) objects.generic = string.o snprintf.o vsnprintf.o objects.user = \ - i686/crt.o \ + i686/crt-nasm.o \ pthread/libc.o \ brk.o \ descriptors.o \ @@ -68,7 +68,7 @@ objects.user = \ mmap.o \ physmem.o objects.pthread = \ - i686/pthread.o \ + i686/pthread-nasm.o \ i686/stack.o \ pthread/attr.o \ pthread/thread.o