diff --git a/.github/configs/x86_64-ci.config b/.github/configs/x86_64-ci.config deleted file mode 100644 index a270d8a1..00000000 --- a/.github/configs/x86_64-ci.config +++ /dev/null @@ -1,8 +0,0 @@ -CONFIG_ARCH_X86_64=y -CONFIG_VERBOSE_INIT_LEVELS=y -CONFIG_DEBUG_MM=y -CONFIG_PARAVIRT=y -CONFIG_KVM_GUEST=y -CONFIG_BHYVE_GUEST=y -CONFIG_EMULATOR_GUEST=y -CONFIG_FLANTERM_CONSOLE=y diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 3b43a558..3418745c 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -31,6 +31,20 @@ jobs: mypy *.py mypy scripts/ + lint-kernel: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + with: + submodules: true + + - name: Build the platform toolchain + run: "${{ github.workspace }}/build.py --toolchain clang --toolchain-only" + + - name: Check the coding conventions + run: "${{ github.workspace }}/build.py --toolchain clang --lint" + build: runs-on: ${{ matrix.os }} @@ -40,6 +54,7 @@ jobs: os: [ubuntu-latest, macos-latest] arch: [x86_64] toolchain: [gcc, clang] + preset: [debug-lite, release] exclude: # FIXME: the GCC build somehow ends up being corrupted with # libexec/cc1 containing garbage data. @@ -78,11 +93,20 @@ jobs: key: ${{ steps.toolchain-cache.outputs.cache-primary-key }} - name: Build the kernel - run: "${{ github.workspace }}/build.py --config ${{ github.workspace }}/.github/configs/${{ matrix.arch }}-ci.config --toolchain ${{ matrix.toolchain }} --no-tune-native" + run: "${{ github.workspace }}/build.py --arch ${{ matrix.arch }} --config ${{ matrix.preset }} --toolchain ${{ matrix.toolchain }} --no-tune-native" + + unit-tests: + runs-on: ${{ matrix.os }} + + strategy: + fail-fast: true + matrix: + os: [ubuntu-latest, macos-latest] + + steps: + - uses: actions/checkout@v3 + with: + submodules: true - name: Run the userspace unit tests run: "${{ github.workspace }}/build.py --unit-tests" - - - if: ${{ matrix.toolchain == 'clang' && matrix.os == 'ubuntu-latest' }} - name: Check the coding conventions - run: "${{ github.workspace }}/build.py --config ${{ github.workspace }}/.github/configs/${{ matrix.arch }}-ci.config --toolchain ${{ matrix.toolchain }} --no-build --lint" diff --git a/build.py b/build.py index 73cc1c4e..4e7891ed 100755 --- a/build.py +++ b/build.py @@ -20,6 +20,7 @@ sys.modules["kconfiglib"] = kc import scripts.build_utils.wsl_wrap as ww + import scripts.config_layers as cl import scripts.build_utils.package_manager as pm import scripts.build_utils.toolchain_builder as tb import scripts.build_utils.toolchain_args as ta @@ -73,16 +74,6 @@ # How long --run-for waits for the first output before giving up QEMU_SILENT_BOOT_SECONDS = 30 -ARCH_TO_CONFIG_KEY = { - "x86_64": "ARCH_X86_64", - "aarch64": "ARCH_AARCH64", -} - -TOOLCHAIN_TO_CONFIG_KEY = { - "clang": "TOOLCHAIN_CLANG", - "gcc": "TOOLCHAIN_GCC", -} - @contextmanager def enter_work_dir(path: str) -> Iterator[None]: @@ -180,28 +171,36 @@ def cmake_native_build_args(build_dir: str) -> List[str]: return ["--", "-Oline"] -def cmake_build( +def cmake_configure( args: argparse.Namespace, build_dir: str, extra_args: List[str] = [], - reconfigure_cb: Optional[Callable[[], None]] = None + reconfigure_cb: Optional[Callable[[], None]] = None, + refresh: bool = False ) -> None: cmake_cache = os.path.join(build_dir, "CMakeCache.txt") - rerun_cmake = args.reconfigure or not os.path.isfile(cmake_cache) + has_cache = os.path.isfile(cmake_cache) - if rerun_cmake: - if reconfigure_cb is not None: - reconfigure_cb() - os.makedirs(build_dir, exist_ok=True) + if has_cache and refresh and not args.reconfigure: + subprocess.run(["cmake", "."], check=True, cwd=build_dir) + return - generator_args = [] - if not os.path.isfile(cmake_cache) and shutil.which("ninja"): - generator_args = ["-G", "Ninja"] - - subprocess.run(["cmake", "..", *generator_args, *extra_args], - check=True, cwd=build_dir) - else: + if has_cache and not args.reconfigure: print("Not rerunning cmake since build directory already exists " "(--reconfigure)") + return + + if reconfigure_cb is not None: + reconfigure_cb() + os.makedirs(build_dir, exist_ok=True) + + generator_args = [] + if not has_cache and shutil.which("ninja"): + generator_args = ["-G", "Ninja"] + subprocess.run(["cmake", "..", *generator_args, *extra_args], + check=True, cwd=build_dir) + + +def cmake_run_build(build_dir: str) -> None: subprocess.run( ["cmake", "--build", ".", "-j", str(os.cpu_count()), *cmake_native_build_args(build_dir)], @@ -209,21 +208,49 @@ def cmake_build( ) -def build_ultra( - args: argparse.Namespace, build_dir: str +def cmake_build(args: argparse.Namespace, build_dir: str) -> None: + cmake_configure(args, build_dir) + cmake_run_build(build_dir) + + +def configure_ultra( + args: argparse.Namespace, build_dir: str, refresh: bool = False ) -> None: def rebuild_toolchain() -> None: # Only rerun toolchain builder if reconfigure is not artificial if not args.reconfigure: build_toolchain(args) - cmake_build( + cmake_configure( args, build_dir, [f"-DCONFIG_FILE={args.config}"], - rebuild_toolchain + rebuild_toolchain, refresh ) -def make_hyper_config(arch: str) -> str: +def build_ultra( + args: argparse.Namespace, build_dir: str +) -> None: + configure_ultra(args, build_dir) + cmake_run_build(build_dir) + + +QEMU_HYPER_OPTIONS = """ +cmdline = "log-level=debug earlycon=e9,colored" + +# Hardcode a resolution that's good enough for local testing, +# we don't need a huge QEMU window. +video-mode: + width = 1024 + height = 768 +""" + +IMAGE_TARGETS = { + "qemu": QEMU_HYPER_OPTIONS, + "baremetal": "", +} + + +def make_hyper_config(arch: str, target: str) -> str: return \ f""" default-entry = ultra-{arch} @@ -239,15 +266,7 @@ def make_hyper_config(arch: str) -> str: page-table: levels = 5 constraint = maximum - -cmdline = "log-level=debug earlycon=e9,colored" - -# Hardcode a resolution that's good enough for local testing, -# we don't need a huge QEMU window. -video-mode: - width = 1024 - height = 768 - +{IMAGE_TARGETS[target]} [ultra-aarch64] protocol = ultra higher-half-exclusive = true @@ -269,7 +288,7 @@ def get_kernel_path(execution_node: str, build_dir: str) -> str: def make_hyper_image( - br_type: str, fs_type: str, arch: str, build_dir: str, + br_type: str, fs_type: str, arch: str, target: str, build_dir: str, hyper_installer: Optional[str], hyper_iso_br: Optional[str], hyper_uefi_binaries: List[str], image_path: str, force_regenerate: bool ) -> Optional[ultr.DiskImage]: @@ -290,7 +309,7 @@ def make_hyper_image( return ultr.DiskImage( image_root_path, br_type, fs_type, - hyper_config=make_hyper_config(arch), + hyper_config=make_hyper_config(arch, target), hyper_uefi_binary_paths=hyper_uefi_binaries, hyper_iso_br_path=hyper_iso_br, hyper_installer_path=hyper_installer, @@ -454,6 +473,7 @@ def run_lint(args: argparse.Namespace, build_dir: str) -> int: if args.toolchain != "clang": sys.exit("--lint only works with --toolchain clang") + configure_ultra(args, build_dir, refresh=True) return lint.run(build_dir) @@ -465,44 +485,6 @@ def run_unit_tests(args: argparse.Namespace, this_os: str) -> int: return subprocess.run([binary]).returncode -def root_kconfig() -> kc.Kconfig: - with enter_work_dir(pg.project_root()): - kconfig = kc.Kconfig(pg.project_root_relative("Kconfig")) - - return kconfig - - -def make_config_from_preset( - preset: str, out_path: str, toolchain: str, arch: str -) -> str: - kconfig = root_kconfig() - kconfig.load_config(preset) - - preset_arch = kconfig.syms["ARCH_STRING"].str_value - if arch != "auto" and arch != preset_arch: - sys.exit(f"--arch {arch} conflicts with {preset}, " - f"which is for {preset_arch}") - - toolchain_sym = kconfig.syms[TOOLCHAIN_TO_CONFIG_KEY[toolchain]] - preset_toolchain = toolchain_sym.choice.user_selection - - if preset_toolchain is not None and preset_toolchain is not toolchain_sym: - print(f"Ignoring {preset_toolchain.name} from {preset}, " - f"building with --toolchain {toolchain}") - - toolchain_sym.set_value("y") - kconfig.write_config(out_path) - - return preset_arch - - -def make_default_config(out_path: str, toolchain: str, arch: str) -> None: - kconfig = root_kconfig() - kconfig.syms[TOOLCHAIN_TO_CONFIG_KEY[toolchain]].set_value("y") - kconfig.syms[ARCH_TO_CONFIG_KEY[arch]].set_value("y") - kconfig.write_config(out_path) - - def main() -> None: ww.relaunch_in_wsl_if_windows() pg.set_project_root(os.path.dirname(os.path.abspath(__file__))) @@ -512,13 +494,15 @@ def main() -> None: ) build = parser.add_argument_group("Build") - build.add_argument("--arch", default="auto", - choices=["auto", "x86_64", "aarch64"], - help="CPU architecture to build the kernel for " - "(auto implies x86_64 or the config setting if " - "--config is specified)") + build.add_argument("--arch", default="x86_64", + choices=["x86_64", "aarch64"], + help="CPU architecture to build the kernel for") build.add_argument("--config", - help="Configuration file to use for this build") + help="Preset from configs/ or a config file to build " + f"(default: {cl.DEFAULT_PRESET})") + build.add_argument("--reset-config", action="store_true", + help="Recreate the build directory's config from " + "--config, discarding the changes made to it") build.add_argument("--menuconfig", action="store_true", help="Run menuconfig to edit the current config file") build.add_argument("--guiconfig", action="store_true", @@ -536,8 +520,11 @@ def main() -> None: help="Build the toolchain and exit") image = parser.add_argument_group("Image") - image.add_argument("--make-image", action="store_true", - help="Produce a bootable image after building") + image.add_argument("--make-image", nargs="?", const="qemu", + choices=IMAGE_TARGETS.keys(), metavar="TARGET", + help="Produce a bootable image after building, " + "for QEMU or for real hardware with " + "'baremetal' (default: qemu)") image.add_argument("--image-type", choices=["iso", "raw"], default="iso", help="Image type to produce (with --make-image)") image.add_argument("--hyper-installer", type=str, @@ -586,7 +573,7 @@ def main() -> None: tests.add_argument("--unit-tests", action="store_true", help="Run the userspace test suite") tests.add_argument("--lint", action="store_true", - help="Check the coding conventions after building," + help="Check the coding conventions without building," " needs the clang toolchain") args = parser.parse_args() @@ -603,35 +590,24 @@ def main() -> None: if rc is not None: sys.exit(rc) - if args.config: - if not os.path.isfile(args.config): - raise RuntimeError(f"Invalid --config path: {args.config}") - - preset_name = os.path.splitext(os.path.basename(args.config))[0] - if preset_name.startswith("."): - preset_name = "user-config" + config_layers = cl.build_layers(args.config, args.arch) + config_file = config_layers[-1] + default_preset = cl.preset_path(cl.DEFAULT_PRESET) + build_dir_name = f"build-{args.toolchain}-{args.arch}" - build_dir = pg.project_root_relative( - f"build-{args.toolchain}-{preset_name}" - ) - os.makedirs(build_dir, exist_ok=True) + if os.path.abspath(config_file) != os.path.abspath(default_preset): + config_name = os.path.splitext(os.path.basename(config_file))[0] + if config_name.startswith("."): + config_name = "user-config" - config = os.path.join(build_dir, ".config") - args.arch = make_config_from_preset(args.config, config, - args.toolchain, args.arch) - args.config = config - else: - if args.arch == "auto": - args.arch = "x86_64" + build_dir_name += f"-{config_name}" - build_dir = pg.project_root_relative( - f"build-{args.toolchain}-{args.arch}" - ) - os.makedirs(build_dir, exist_ok=True) + build_dir = pg.project_root_relative(build_dir_name) + os.makedirs(build_dir, exist_ok=True) - args.config = os.path.join(build_dir, ".config") - if not os.path.isfile(args.config): - make_default_config(args.config, args.toolchain, args.arch) + args.config = os.path.join(build_dir, ".config") + cl.prepare_config(args.config, config_layers, args.toolchain, + args.arch, args.reset_config) if args.menuconfig or args.guiconfig: os.environ["KCONFIG_CONFIG"] = args.config @@ -642,19 +618,19 @@ def main() -> None: module = mc if args.menuconfig else gc with enter_work_dir(pg.project_root()): - module.menuconfig(root_kconfig()) + module.menuconfig(cl.root_kconfig()) sys.exit(0) if args.toolchain_only: build_toolchain(args) sys.exit(0) - if not args.no_build: - build_ultra(args, build_dir) - if args.lint: sys.exit(run_lint(args, build_dir)) + if not args.no_build: + build_ultra(args, build_dir) + rc = bmc.run_from_args(args, args.arch, get_kernel_path(args.arch, build_dir), build_dir) if rc is not None: @@ -667,6 +643,11 @@ def main() -> None: if args.run_for is not None and is_debug: sys.exit("--run-for cannot be combined with a debug run") + image_target = args.make_image or "qemu" + if should_run and image_target != "qemu": + sys.exit(f"--make-image {image_target} cannot be combined " + "with a QEMU run") + if should_run or args.make_image: hyper_installer = args.hyper_installer hyper_iso_br = args.hyper_iso_loader @@ -674,10 +655,15 @@ def main() -> None: if args.image_type == "iso": fs_type = "ISO9660" - image_name = "image.iso" + image_ext = "iso" else: fs_type = "FAT32" - image_name = "image.raw" + image_ext = "raw" + + image_name = "image" + if image_target != "qemu": + image_name += f"-{image_target}" + image_name += f".{image_ext}" if not hyper_installer: hyper_installer = hyper_get_installer() @@ -696,9 +682,9 @@ def main() -> None: image_path = os.path.join(build_dir, image_name) make_hyper_image( - "MBR", fs_type, args.arch, build_dir, + "MBR", fs_type, args.arch, image_target, build_dir, hyper_installer, hyper_iso_br, hyper_uefi_binary_paths, - image_path, args.make_image + image_path, args.make_image is not None ) if should_run: diff --git a/configs/arch/x86_64/base.config b/configs/arch/x86_64/base.config new file mode 100644 index 00000000..7d38e833 --- /dev/null +++ b/configs/arch/x86_64/base.config @@ -0,0 +1,2 @@ +CONFIG_PARAVIRT=y +CONFIG_FLANTERM_CONSOLE=y diff --git a/configs/debug-lite.config b/configs/debug-lite.config new file mode 100644 index 00000000..3559c0fa --- /dev/null +++ b/configs/debug-lite.config @@ -0,0 +1,2 @@ +CONFIG_DEBUG_MM=y +CONFIG_UBSAN=y diff --git a/configs/release.config b/configs/release.config new file mode 100644 index 00000000..2cedb6f1 --- /dev/null +++ b/configs/release.config @@ -0,0 +1,2 @@ +CONFIG_LTO=y +CONFIG_OPTIMIZATION_LEVEL=3 diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index 1ff2318a..4fe9de85 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -1,3 +1,4 @@ +include(CheckCCompilerFlag) include(symbols.cmake) include(free_after_init.cmake) include(build_stamp.cmake) @@ -33,24 +34,44 @@ set( ${ULTRA_KERNEL_BASE} ) -if (CONFIG_ARCH_UNKNOWN_BIT_WIDTH) - message( +if (CONFIG_ARCH_64BIT AND CONFIG_ARCH_32BIT) + message( + FATAL_ERROR + "Please fix your architecture's Kconfig to specify only one bitness" + ) +elseif (NOT CONFIG_ARCH_WIDTH) + message( FATAL_ERROR - "Please fix your achitecture's Kconfig to specify bitness" + "Please fix your architecture's Kconfig to specify bitness" ) endif () -if (CONFIG_ARCH_LITTLE_ENDIAN) +if (CONFIG_ARCH_LITTLE_ENDIAN AND CONFIG_ARCH_BIG_ENDIAN) + message( + FATAL_ERROR + "Please fix your architecture's Kconfig to specify only one " + "endianness" + ) +elseif (CONFIG_ARCH_LITTLE_ENDIAN) ultra_compile_definitions(ULTRA_ARCH_LITTLE_ENDIAN) elseif (CONFIG_ARCH_BIG_ENDIAN) ultra_compile_definitions(ULTRA_ARCH_BIG_ENDIAN) else () message( FATAL_ERROR - "Please fix your achitecture's Kconfig to specify endianness" + "Please fix your architecture's Kconfig to specify endianness" ) endif () +if (NOT CONFIG_PAGE_SHIFT) + message( + FATAL_ERROR + "Please fix your architecture's Kconfig to select a page size" + ) +endif () + +math(EXPR ULTRA_PAGE_SIZE "1 << ${CONFIG_PAGE_SHIFT}") + ultra_compile_definitions( ULTRA_ARCH_WIDTH=${CONFIG_ARCH_WIDTH} ULTRA_ARCH_PHYS_ADDR_WIDTH=${CONFIG_ARCH_PHYS_ADDR_WIDTH} @@ -115,8 +136,14 @@ ultra_compile_options( -Wimplicit-fallthrough -fomit-frame-pointer -Wdate-time + -Wundef ) +check_c_compiler_flag(-Wformat-signedness HAVE_FORMAT_SIGNEDNESS) +if (HAVE_FORMAT_SIGNEDNESS) + ultra_compile_options(-Wformat-signedness) +endif () + if (CONFIG_LTO) ultra_compile_options(${ULTRA_TOOLCHAIN_LTO_FLAGS}) endif () diff --git a/kernel/arch/Kconfig b/kernel/arch/Kconfig index 870f819c..0a5a6b8a 100644 --- a/kernel/arch/Kconfig +++ b/kernel/arch/Kconfig @@ -5,10 +5,6 @@ config ARCH_LITTLE_ENDIAN config ARCH_BIG_ENDIAN bool -config ARCH_UNKNOWN_ENDIAN - bool - default y if !ARCH_LITTLE_ENDIAN && !ARCH_BIG_ENDIAN - # Arch bitness settings config ARCH_64BIT bool @@ -16,10 +12,6 @@ config ARCH_64BIT config ARCH_32BIT bool -config ARCH_UNKNOWN_BIT_WIDTH - bool - default y if !ARCH_64BIT && !ARCH_32BIT - config ARCH_WIDTH int default 8 if ARCH_64BIT @@ -36,6 +28,31 @@ config ARCH_PHYS_ADDR_WIDTH config ARCH_HAS_UBSAN bool +config ARCH_HAS_PAGE_SIZE_4K + bool + +choice + prompt "Page size" + + config PAGE_SIZE_4K + bool "4KiB" + depends on ARCH_HAS_PAGE_SIZE_4K +endchoice + +config PAGE_SHIFT + int + default 12 if PAGE_SIZE_4K + +# Declared here so the symbol always exists as an int. An arch with +# a different cache line size gives it a default of its own. +config ARCH_CACHE_LINE_SHIFT + int + +config CACHE_LINE_SHIFT + int + default ARCH_CACHE_LINE_SHIFT if ARCH_CACHE_LINE_SHIFT > 0 + default 6 + if ARCH_X86_64 rsource "x86_64/Kconfig" endif diff --git a/kernel/arch/aarch64/CMakeLists.txt b/kernel/arch/aarch64/CMakeLists.txt index bfeb4828..cbac1241 100644 --- a/kernel/arch/aarch64/CMakeLists.txt +++ b/kernel/arch/aarch64/CMakeLists.txt @@ -28,5 +28,5 @@ add_ultra_ld_template( ultra_link_options( -T${ULTRA_LD_SCRIPT} - -z max-page-size=4096 + -z max-page-size=${ULTRA_PAGE_SIZE} ) diff --git a/kernel/arch/aarch64/Kconfig b/kernel/arch/aarch64/Kconfig index 16f49cbf..11e32e02 100644 --- a/kernel/arch/aarch64/Kconfig +++ b/kernel/arch/aarch64/Kconfig @@ -15,3 +15,4 @@ config ARCH_AARCH64_BASE # Big endian mode is not supported select ARCH_LITTLE_ENDIAN select ARCH_64BIT + select ARCH_HAS_PAGE_SIZE_4K diff --git a/kernel/arch/aarch64/include/arch/constants.h b/kernel/arch/aarch64/include/arch/constants.h deleted file mode 100644 index e66a0b9c..00000000 --- a/kernel/arch/aarch64/include/arch/constants.h +++ /dev/null @@ -1,6 +0,0 @@ -#pragma once - -#define PAGE_SIZE 4096 -#define PAGE_SHIFT 12 - -#define CACHE_LINE_SIZE 64 diff --git a/kernel/arch/x86_64/CMakeLists.txt b/kernel/arch/x86_64/CMakeLists.txt index a8d5de0c..88060f93 100644 --- a/kernel/arch/x86_64/CMakeLists.txt +++ b/kernel/arch/x86_64/CMakeLists.txt @@ -1,7 +1,6 @@ -include(CheckCompilerFlag) +ultra_sources_no_lto(string.c) ultra_sources( - string.c apic.c vector_alloc.c lapic_domain.c @@ -28,12 +27,12 @@ ultra_sources( ) ultra_include_directories(include) -check_compiler_flag( - C -mpreferred-stack-boundary=4 +check_c_compiler_flag( + -mpreferred-stack-boundary=4 HAVE_PREFERRED_STACK_BOUNDARY ) -check_compiler_flag( - C -mstack-alignment=16 +check_c_compiler_flag( + -mstack-alignment=16 HAVE_STACK_ALIGNMENT ) @@ -71,7 +70,7 @@ add_ultra_ld_template( ultra_link_options( -T${ULTRA_LD_SCRIPT} - -Wl,-z,max-page-size=4096 + -Wl,-z,max-page-size=${ULTRA_PAGE_SIZE} ) add_subdirectory(hypervisor) diff --git a/kernel/arch/x86_64/Kconfig b/kernel/arch/x86_64/Kconfig index 721018ea..5079f6e1 100644 --- a/kernel/arch/x86_64/Kconfig +++ b/kernel/arch/x86_64/Kconfig @@ -14,6 +14,7 @@ config ARCH_X86_64_BASE bool select ARCH_LITTLE_ENDIAN select ARCH_64BIT + select ARCH_HAS_PAGE_SIZE_4K select ARCH_HAS_UBSAN select SMBIOS select ACPI diff --git a/kernel/arch/x86_64/cpu.c b/kernel/arch/x86_64/cpu.c index 0e8c35bb..10f75562 100644 --- a/kernel/arch/x86_64/cpu.c +++ b/kernel/arch/x86_64/cpu.c @@ -177,7 +177,7 @@ void INIT_CODE cpu_info_setup(struct x86_cpu_info *info) } if (info != &g_cpu_info) { - int i; + u32 i; /* * AND our features into the BSP feature table so that it contains the diff --git a/kernel/arch/x86_64/earlycon.c b/kernel/arch/x86_64/earlycon.c index bc25070f..3c71ebe5 100644 --- a/kernel/arch/x86_64/earlycon.c +++ b/kernel/arch/x86_64/earlycon.c @@ -31,7 +31,7 @@ static struct console s_e9_console = { .write = e9_write, }; -enum ns16550_reg { +enum ns16550_reg : u32 { NS16550_REG_THR = 0, NS16550_REG_IER = 1, NS16550_REG_FCR = 2, @@ -165,7 +165,7 @@ static error_t INIT_CODE e9_console_init(bool colored) return ret; } -enum ns16550_source_kind { +enum ns16550_source_kind : u32 { NS16550_SOURCE_NONE, NS16550_SOURCE_IO, NS16550_SOURCE_PCI, @@ -403,7 +403,7 @@ static error_t INIT_CODE ns16550_console_init( return EOK; } -enum earlycon_mode { +enum earlycon_mode : u32 { EARLYCON_MODE_NONE, EARLYCON_MODE_E9, EARLYCON_MODE_NS16550, diff --git a/kernel/arch/x86_64/entry.c b/kernel/arch/x86_64/entry.c index 5392ea60..8c3fc8f5 100644 --- a/kernel/arch/x86_64/entry.c +++ b/kernel/arch/x86_64/entry.c @@ -41,7 +41,7 @@ static error_t INIT_CODE x86_early_init(void) cr0_setup(); pr_info( - "Running on %s (%d:%d:%d)\n", + "Running on %s (%u:%u:%u)\n", g_cpu_info.name_string, g_cpu_info.family, g_cpu_info.model, g_cpu_info.stepping ); diff --git a/kernel/arch/x86_64/exceptions.c b/kernel/arch/x86_64/exceptions.c index d28700aa..fa061b88 100644 --- a/kernel/arch/x86_64/exceptions.c +++ b/kernel/arch/x86_64/exceptions.c @@ -79,13 +79,13 @@ EXCEPTION_HANDLER(X86_EXCEPTION_UD) EXCEPTION_HANDLER(X86_EXCEPTION_PF) { - phys_addr_t addr; + virt_addr_t addr; if (handle_abortable_instruction(regs)) return; asm volatile("mov %%cr2, %0" : "=r"(addr)); - panic("Page fault at 0x%016llX", addr); + panic("Page fault at 0x%016zX", addr); } bool arch_handle_abortable_instruction( diff --git a/kernel/arch/x86_64/include/arch/constants.h b/kernel/arch/x86_64/include/arch/constants.h deleted file mode 100644 index a601e5c3..00000000 --- a/kernel/arch/x86_64/include/arch/constants.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#ifndef __ASSEMBLER__ -#include - -extern u8 g_max_phys_bits; -#define MAX_PHYS_BITS g_max_phys_bits -#endif - -#define PAGE_SIZE 4096 -#define PAGE_SHIFT 12 - -#define CACHE_LINE_SIZE 64 diff --git a/kernel/arch/x86_64/include/arch/memory.h b/kernel/arch/x86_64/include/arch/memory.h index 38dc239e..1813ec6b 100644 --- a/kernel/arch/x86_64/include/arch/memory.h +++ b/kernel/arch/x86_64/include/arch/memory.h @@ -9,3 +9,6 @@ extern virt_addr_t g_memory_map_base, g_memory_map_end; extern virt_addr_t g_valloc_base, g_valloc_end; #define VALLOC_BASE g_valloc_base #define VALLOC_END g_valloc_end + +extern u8 g_max_phys_bits; +#define MAX_PHYS_BITS g_max_phys_bits diff --git a/kernel/arch/x86_64/include/arch/page_table.h b/kernel/arch/x86_64/include/arch/page_table.h index e0790ad8..4002f2fd 100644 --- a/kernel/arch/x86_64/include/arch/page_table.h +++ b/kernel/arch/x86_64/include/arch/page_table.h @@ -3,7 +3,7 @@ #include #include -#include +#include #include #include diff --git a/kernel/arch/x86_64/include/arch/private/apic.h b/kernel/arch/x86_64/include/arch/private/apic.h index a71bbf31..5c84096d 100644 --- a/kernel/arch/x86_64/include/arch/private/apic.h +++ b/kernel/arch/x86_64/include/arch/private/apic.h @@ -3,7 +3,7 @@ #include #include -enum apic_reg { +enum apic_reg : u32 { APIC_REG_ID = 0x20, APIC_REG_VERSION = 0x30, APIC_REG_TPR = 0x80, @@ -60,7 +60,7 @@ enum apic_reg { #define APIC_ID_NONE 0xFFFF'FFFF -enum apic_mode { +enum apic_mode : u32 { APIC_MODE_NONE = 0, APIC_MODE_X, APIC_MODE_X2, diff --git a/kernel/arch/x86_64/include/arch/private/cpu.h b/kernel/arch/x86_64/include/arch/private/cpu.h index 113071b6..8d5a6f33 100644 --- a/kernel/arch/x86_64/include/arch/private/cpu.h +++ b/kernel/arch/x86_64/include/arch/private/cpu.h @@ -6,7 +6,7 @@ #include -enum x86_feature_dword { +enum x86_feature_dword : u32 { X86_FEATURE_DWORD_1_C = 0, X86_FEATURE_DWORD_1_D, X86_FEATURE_DWORD_7_B, @@ -29,7 +29,7 @@ enum x86_feature_dword { #define X86_FEATURE_DWORD_BIT(name, bit) \ ((X86_FEATURE_DWORD_##name * sizeof(u32) * BITS_PER_BYTE) + (bit)) -enum x86_feature { +enum x86_feature : u32 { X86_FEATURE_SSE3 = X86_FEATURE_DWORD_BIT(1_C, 0), X86_FEATURE_PCLMULQDQ = X86_FEATURE_DWORD_BIT(1_C, 1), X86_FEATURE_DTES64 = X86_FEATURE_DWORD_BIT(1_C, 2), diff --git a/kernel/arch/x86_64/ioapic.c b/kernel/arch/x86_64/ioapic.c index a62e5957..65cb19cd 100644 --- a/kernel/arch/x86_64/ioapic.c +++ b/kernel/arch/x86_64/ioapic.c @@ -4,12 +4,12 @@ #include #include #include -#include #include #include #include +#include #include #include #include @@ -28,7 +28,7 @@ #define IOAPIC_IOWIN 0x10 #define IOAPIC_EOIR 0x40 -enum ioapic_reg { +enum ioapic_reg : u32 { IOAPIC_REG_ID = 0x00, #define IOAPIC_ID MAKE_BIT_MASK(31, 24) @@ -143,7 +143,7 @@ static INIT_CODE void irq_resolve_activation( break; default: pr_warn( - "invalid polarity value %d for irq %d, assuming active high\n", + "invalid polarity value %u for irq %u, assuming active high\n", *in_out_polarity, irq ); FALLTHROUGH; @@ -167,7 +167,7 @@ static INIT_CODE void irq_resolve_activation( break; default: pr_warn( - "invalid triggering value %d for irq %d, assuming edge\n", + "invalid triggering value %u for irq %u, assuming edge\n", *in_out_triggering, irq ); FALLTHROUGH; @@ -300,10 +300,10 @@ static INIT_CODE bool ioapic_check_collisions( out_collision: pr_warn( - "unable to register IOAPIC[%u] (0x%llX, GSI[%u->%u]): " - "%s collides with existing IOAPIC[%u] (0x%llX, GSI[%u->%u])\n", - ioapic->id, ioapic->base, ioapic->gsi_base, ioapic->gsi_last, which, - other->id, other->base, other->gsi_base, other->gsi_last + "unable to register IOAPIC[%u] (%8pPA, GSI[%u->%u]): " + "%s collides with existing IOAPIC[%u] (%8pPA, GSI[%u->%u])\n", + ioapic->id, &ioapic->base, ioapic->gsi_base, ioapic->gsi_last, which, + other->id, &other->base, other->gsi_base, other->gsi_last ); return true; } @@ -787,8 +787,8 @@ void INIT_CODE ioapic_register(u8 id, phys_addr_t base, u32 gsi_base) spin_lock_init(&new_ioapic->lock); s_num_ioapics++; pr_info( - "registered IOAPIC[%u] (0x%llX, GSI[%u->%u])\n", - new_ioapic->id, new_ioapic->base, + "registered IOAPIC[%u] (%8pPA, GSI[%u->%u])\n", + new_ioapic->id, &new_ioapic->base, new_ioapic->gsi_base, new_ioapic->gsi_last ); return; @@ -797,7 +797,7 @@ void INIT_CODE ioapic_register(u8 id, phys_addr_t base, u32 gsi_base) io_window_unmap(&new_ioapic->iow); out_no_reg: pr_warn( - "unable to register IOAPIC[%u] (0x%llX, GSI base %u): %s\n", - id, base, gsi_base, why + "unable to register IOAPIC[%u] (%8pPA, GSI base %u): %s\n", + id, &base, gsi_base, why ); } diff --git a/kernel/arch/x86_64/smp.c b/kernel/arch/x86_64/smp.c index da34651d..89f039e7 100644 --- a/kernel/arch/x86_64/smp.c +++ b/kernel/arch/x86_64/smp.c @@ -176,7 +176,7 @@ static INIT_CODE error_t register_cpu(u32 apic_id) if (g_num_present_cpus >= ULTRA_MAX_CPUS) { pr_warn( - "Skipping CPU 0x%08X, configured MAX_CPUS is 0x%08X\n", + "Skipping CPU 0x%08X, configured MAX_CPUS is %d\n", apic_id, ULTRA_MAX_CPUS ); @@ -272,7 +272,7 @@ static INIT_CODE uacpi_iteration_decision detect_isos( if (unlikely(iso->bus != 0)) { pr_warn( - "ignoring MADT IRQ %d override for a non-ISA bus %d\n", + "ignoring MADT IRQ %u override for a non-ISA bus %u\n", iso->source, iso->bus ); return UACPI_ITERATION_DECISION_CONTINUE; @@ -280,7 +280,7 @@ static INIT_CODE uacpi_iteration_decision detect_isos( if (unlikely(iso->source >= NUM_ISA_IRQS)) { pr_warn( - "MADT IRQ %d override outside of ISA range, ignored\n", + "MADT IRQ %u override outside of ISA range, ignored\n", iso->source ); return UACPI_ITERATION_DECISION_CONTINUE; diff --git a/kernel/arch/x86_64/x2apic.c b/kernel/arch/x86_64/x2apic.c index 82103c76..2278640a 100644 --- a/kernel/arch/x86_64/x2apic.c +++ b/kernel/arch/x86_64/x2apic.c @@ -2,7 +2,6 @@ #include #include -#include #include diff --git a/kernel/arch/x86_64/xapic.c b/kernel/arch/x86_64/xapic.c index b726a455..3aacb912 100644 --- a/kernel/arch/x86_64/xapic.c +++ b/kernel/arch/x86_64/xapic.c @@ -2,7 +2,6 @@ #include #include -#include #include #include @@ -13,6 +12,7 @@ #include #include +#include #include static u64 s_xapic_phys_base; diff --git a/kernel/common/CMakeLists.txt b/kernel/common/CMakeLists.txt index 195dfc61..d1ac8a34 100644 --- a/kernel/common/CMakeLists.txt +++ b/kernel/common/CMakeLists.txt @@ -4,7 +4,8 @@ ultra_sources( ctype.c error.c format.c - string.c string_container.c rb_tree.c ) + +ultra_sources_no_lto(string.c) diff --git a/kernel/common/format.c b/kernel/common/format.c index 22d78824..35975bf5 100644 --- a/kernel/common/format.c +++ b/kernel/common/format.c @@ -201,6 +201,22 @@ static void write_symbol( } } +static void write_phys_addr( + struct fmt_buf_state *fb_state, struct fmt_spec *fm, phys_addr_t addr +) +{ + if (fm->min_width == 0) + fm->min_width = sizeof(phys_addr_t) * 2; + + fm->base = 16; + fm->uppercase = true; + fm->pad_char = '0'; + fm->left_justify = false; + + write_cstr(fb_state, "0x"); + write_integer(fb_state, fm, addr); +} + static void consume_digits(struct string *fmt, struct string *out_digits) { out_digits->text = fmt->text; @@ -215,7 +231,7 @@ static void consume_digits(struct string *fmt, struct string *out_digits) } } -enum parse_number_mode { +enum parse_number_mode : u32 { PARSE_NUMBER_MODE_MAYBE, PARSE_NUMBER_MODE_MUST, }; @@ -434,6 +450,11 @@ static MAYBE_NERR(int) do_vsnprintf( continue; } + if (consume(&fmt, STR("PA"))) { + write_phys_addr(fb_state, &fm, *va_arg(vlist, phys_addr_t*)); + continue; + } + if (consume(&fmt, STR("PCI"))) { char text[16]; struct pci_address *addr; diff --git a/kernel/common/string.c b/kernel/common/string.c index a95907d4..d28fb49c 100644 --- a/kernel/common/string.c +++ b/kernel/common/string.c @@ -130,4 +130,20 @@ int strcmp(const char *s1, const char *s2) } #endif +#ifndef ARCH_HAS_CUSTOM_STRNCMP +#undef strncmp +int strncmp(const char *s1, const char *s2, size_t count) +{ + while (count--) { + if (*s1 != *s2 || *s1 == '\0') + return (int)(unsigned char)*s1 - (int)(unsigned char)*s2; + + ++s1; + ++s2; + } + + return 0; +} +#endif + #pragma GCC diagnostic pop diff --git a/kernel/drivers/acpi/acpi.c b/kernel/drivers/acpi/acpi.c index 2cd1a52d..36967847 100644 --- a/kernel/drivers/acpi/acpi.c +++ b/kernel/drivers/acpi/acpi.c @@ -1,8 +1,7 @@ #include #include -#include - +#include #include #include diff --git a/kernel/drivers/acpi/uacpi b/kernel/drivers/acpi/uacpi index e05715b2..fd92d3f3 160000 --- a/kernel/drivers/acpi/uacpi +++ b/kernel/drivers/acpi/uacpi @@ -1 +1 @@ -Subproject commit e05715b2e6a3ae913aecdb86f4fd2dba30304e45 +Subproject commit fd92d3f3bdd614afda47d08ff5fc373c6d1e4c27 diff --git a/kernel/drivers/acpi/uacpi_glue.c b/kernel/drivers/acpi/uacpi_glue.c index b2d37a29..02a25c09 100644 --- a/kernel/drivers/acpi/uacpi_glue.c +++ b/kernel/drivers/acpi/uacpi_glue.c @@ -18,7 +18,13 @@ uacpi_status uacpi_kernel_get_rsdp(uacpi_phys_addr *out_rsdp_address) void *uacpi_kernel_map(uacpi_phys_addr addr, uacpi_size len) { - return io_window_map_cached(addr, len); + void *virt; + + virt = io_window_map_cached(addr, len); + if (unlikely(virt == nullptr)) + return UACPI_MAP_FAILED; + + return virt; } void uacpi_kernel_unmap(void *addr, uacpi_size len) diff --git a/kernel/drivers/smbios.c b/kernel/drivers/smbios.c index 4eb50cdb..682e90f3 100644 --- a/kernel/drivers/smbios.c +++ b/kernel/drivers/smbios.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -76,7 +77,7 @@ static INIT_CODE void smbios3_setup(void *base) if (unlikely(entry->size < sizeof(struct smbios3_entrypoint) || entry->size > 0xFF)) { - pr_err("invalid entrypoint size %d\n", entry->size); + pr_err("invalid entrypoint size %u\n", entry->size); return; } @@ -117,7 +118,7 @@ static INIT_CODE void smbios2_setup(void *base) if (unlikely(entry->size < sizeof(struct smbios2_entrypoint) || entry->size > 0xFF)) { - pr_err("invalid entrypoint size %d\n", entry->size); + pr_err("invalid entrypoint size %u\n", entry->size); return; } @@ -415,7 +416,7 @@ static error_t INIT_CODE smbios_setup(void) if (!smbios_available()) return ENXIO; - pr_info("version %d.%d.%d\n", s_ctx.major, s_ctx.minor, s_ctx.docrev); + pr_info("version %u.%u.%u\n", s_ctx.major, s_ctx.minor, s_ctx.docrev); ret = smbios_for_each(smbios_parse, nullptr); if (is_error(ret)) { @@ -466,7 +467,7 @@ error_t smbios_for_each(smbios_callback cb, void *user) hdr = cursor; if (unlikely(hdr->size > bytes_left || hdr->size < sizeof(*hdr))) { pr_err( - "invalid entry[%d]: size %d (with %u bytes left)\n", + "invalid entry[%d]: size %u (with %u bytes left)\n", item_idx, hdr->size, bytes_left ); break; @@ -527,7 +528,7 @@ error_t smbios_for_each(smbios_callback cb, void *user) if (bytes_left) { pr_debug( - "table size truncated %d -> %d\n", + "table size truncated %u -> %u\n", s_ctx.size, s_ctx.size - bytes_left ); s_ctx.size -= bytes_left; diff --git a/kernel/drivers/time/acpi_pm.c b/kernel/drivers/time/acpi_pm.c index f02f5822..a5e3f5a9 100644 --- a/kernel/drivers/time/acpi_pm.c +++ b/kernel/drivers/time/acpi_pm.c @@ -47,7 +47,7 @@ static error_t pm_timer_init(void) if (fadt->hdr.revision >= 3) { if (fadt->x_pm_tmr_blk.address_space_id != ACPI_AS_ID_SYS_IO) { pr_warn( - "timer not in SystemIO: %d\n", + "timer not in SystemIO: %u\n", fadt->x_pm_tmr_blk.address_space_id ); return ENOSYS; @@ -61,7 +61,7 @@ static error_t pm_timer_init(void) if (!port) return EOK; - pr_info("at 0x%04X, %d-bit counter\n", port, bitness); + pr_info("at 0x%04X, %u-bit counter\n", port, bitness); ret = io_window_map_pio(port, 4, &s_pm_io); if (is_error(ret)) { diff --git a/kernel/drivers/time/hpet.c b/kernel/drivers/time/hpet.c index 63485cb9..66bd08d5 100644 --- a/kernel/drivers/time/hpet.c +++ b/kernel/drivers/time/hpet.c @@ -11,7 +11,7 @@ #include -enum hpet_reg { +enum hpet_reg : u32 { HPET_REG_CAPID = 0x00, #define REV_ID MAKE_BIT_MASK(7, 0) #define NUM_TIM_CAP MAKE_BIT_MASK(12, 8) @@ -82,7 +82,7 @@ static error_t hpet_init(void) uacpi_table_unref(&tbl); if (gas.address_space_id != ACPI_AS_ID_SYS_MEM) { - pr_warn("timer not in SystemMemory: %d\n", gas.address_space_id); + pr_warn("timer not in SystemMemory: %u\n", gas.address_space_id); return ENOSYS; } address = gas.address; @@ -107,7 +107,7 @@ static error_t hpet_init(void) return ENXIO; } - pr_info("at 0x%llX, %d-bit counter\n", address, bitness); + pr_info("at %8pPA, %u-bit counter\n", &address, bitness); config = hpet_read(HPET_REG_CONFIG); config |= ENABLE_CNF; diff --git a/kernel/entry.c b/kernel/entry.c index b597bc09..a0c7608f 100644 --- a/kernel/entry.c +++ b/kernel/entry.c @@ -120,7 +120,7 @@ static error_t INIT_CODE boot_info_init(void) ); pr_info( - "direct map set at 0x%016zX (%d pt levels)\n", + "direct map set at 0x%016zX (%u pt levels)\n", g_direct_map_base, pi->page_table_depth ); diff --git a/kernel/include/arch_constants.h b/kernel/include/arch_constants.h new file mode 100644 index 00000000..793bdcf0 --- /dev/null +++ b/kernel/include/arch_constants.h @@ -0,0 +1,10 @@ +#pragma once + +#include +#include + +#define PAGE_SHIFT CONFIG_PAGE_SHIFT +#define PAGE_SIZE (LITERAL_OF_TYPE(reg_t, 1) << PAGE_SHIFT) + +#define CACHE_LINE_SHIFT CONFIG_CACHE_LINE_SHIFT +#define CACHE_LINE_SIZE (LITERAL_OF_TYPE(reg_t, 1) << CACHE_LINE_SHIFT) diff --git a/kernel/include/common/align.h b/kernel/include/common/align.h index 5cfc3c81..e96f54ca 100644 --- a/kernel/include/common/align.h +++ b/kernel/include/common/align.h @@ -1,7 +1,7 @@ #pragma once #include -#include +#include #if HAS_BUILTIN(__builtin_align_up) #define ALIGN_UP(x, val) __builtin_align_up(x, val) diff --git a/kernel/include/common/atomic.h b/kernel/include/common/atomic.h index 074fe8a7..ec82d8e6 100644 --- a/kernel/include/common/atomic.h +++ b/kernel/include/common/atomic.h @@ -1,6 +1,8 @@ #pragma once -enum memory_order { +#include + +enum memory_order : u32 { MO_RELAXED = __ATOMIC_RELAXED, MO_CONSUME = __ATOMIC_CONSUME, MO_ACQ_REL = __ATOMIC_ACQ_REL, diff --git a/kernel/include/common/ctype.h b/kernel/include/common/ctype.h index 852577f2..969012c9 100644 --- a/kernel/include/common/ctype.h +++ b/kernel/include/common/ctype.h @@ -4,7 +4,7 @@ #include -enum char_type { +enum char_type : u32 { CHAR_TYPE_CONTROL = 1 << 0, CHAR_TYPE_SPACE = 1 << 1, CHAR_TYPE_BLANK = 1 << 2, diff --git a/kernel/include/common/string.h b/kernel/include/common/string.h index 555425b5..8555c440 100644 --- a/kernel/include/common/string.h +++ b/kernel/include/common/string.h @@ -10,6 +10,7 @@ #define strlen __builtin_strlen #define strstr __builtin_strstr #define strcmp __builtin_strcmp +#define strncmp __builtin_strncmp static ALWAYS_INLINE void *memzero(void *dest, size_t count) { diff --git a/kernel/include/common/types.h b/kernel/include/common/types.h index 6580f4ed..a232399a 100644 --- a/kernel/include/common/types.h +++ b/kernel/include/common/types.h @@ -1,12 +1,21 @@ #pragma once +#include + +/* + * Typed constants for headers shared with assembly and linker scripts. + * LITERAL_OF_TYPE() only takes a number but also works in #if, + * CONST_OF_TYPE() takes any expression. + */ +#ifdef __ASSEMBLER__ +#define LITERAL_OF_TYPE(type, x) x +#define CONST_OF_TYPE(type, x) x +#else #include #include #include #include -#include - // signed types typedef int8_t i8; typedef int16_t i16; @@ -28,11 +37,27 @@ typedef reg_t irq_state_t; #if ULTRA_ARCH_PHYS_ADDR_WIDTH == 4 typedef u32 phys_addr_t; -#else +#define LITERAL_SUFFIX_phys_addr_t LITERAL_SUFFIX_u32 +#elif ULTRA_ARCH_PHYS_ADDR_WIDTH == 8 typedef u64 phys_addr_t; +#define LITERAL_SUFFIX_phys_addr_t LITERAL_SUFFIX_u64 +#else +#error Unsupported ULTRA_ARCH_PHYS_ADDR_WIDTH #endif typedef ptr_t virt_addr_t; +typedef size_t pfn_t; + +#define LITERAL_SUFFIX_i32 +#define LITERAL_SUFFIX_i64 ll +#define LITERAL_SUFFIX_u32 u +#define LITERAL_SUFFIX_u64 ull +#define LITERAL_SUFFIX_ptr_t ul +#define LITERAL_SUFFIX_reg_t ul +#define LITERAL_SUFFIX_virt_addr_t LITERAL_SUFFIX_ptr_t + +#define LITERAL_OF_TYPE(type, x) CONCAT(x, LITERAL_SUFFIX_##type) +#define CONST_OF_TYPE(type, x) ((type)(x)) #if !defined(ULTRA_TEST) || defined(_MSC_VER) #if UINTPTR_MAX == 0xFFFFFFFF @@ -55,3 +80,16 @@ BUILD_BUG_ON(sizeof(u32) != 4); BUILD_BUG_ON(sizeof(u64) != 8); BUILD_BUG_ON(sizeof(bool) != 1); + +// __builtin_types_compatible_p() does not exist in C++ +#ifndef __cplusplus +BUILD_BUG_ON(!ARE_SAME_TYPE(LITERAL_OF_TYPE(i32, 1), i32)); +BUILD_BUG_ON(!ARE_SAME_TYPE(LITERAL_OF_TYPE(i64, 1), i64)); +BUILD_BUG_ON(!ARE_SAME_TYPE(LITERAL_OF_TYPE(u32, 1), u32)); +BUILD_BUG_ON(!ARE_SAME_TYPE(LITERAL_OF_TYPE(u64, 1), u64)); +BUILD_BUG_ON(!ARE_SAME_TYPE(LITERAL_OF_TYPE(ptr_t, 1), ptr_t)); +BUILD_BUG_ON(!ARE_SAME_TYPE(LITERAL_OF_TYPE(reg_t, 1), reg_t)); +BUILD_BUG_ON(!ARE_SAME_TYPE(LITERAL_OF_TYPE(virt_addr_t, 1), virt_addr_t)); +BUILD_BUG_ON(!ARE_SAME_TYPE(LITERAL_OF_TYPE(phys_addr_t, 1), phys_addr_t)); +#endif +#endif diff --git a/kernel/include/irq.h b/kernel/include/irq.h index b0273c67..76f1876a 100644 --- a/kernel/include/irq.h +++ b/kernel/include/irq.h @@ -68,7 +68,7 @@ struct irq_spec { enum irq_trigger trigger; }; -enum irq_result { +enum irq_result : u32 { IRQ_RESULT_UNHANDLED, IRQ_RESULT_HANDLED, }; diff --git a/kernel/include/linker_common.ld.h b/kernel/include/linker_common.ld.h index 649d5e5b..f20c2ac6 100644 --- a/kernel/include/linker_common.ld.h +++ b/kernel/include/linker_common.ld.h @@ -2,7 +2,7 @@ #include -#include +#include #include #define PHDR_READ (1 << 2) diff --git a/kernel/include/log.h b/kernel/include/log.h index b3fe204f..5239b115 100644 --- a/kernel/include/log.h +++ b/kernel/include/log.h @@ -2,6 +2,7 @@ #include #include +#include #include @@ -21,7 +22,7 @@ #define SYSLOG_DEBUG 7 #define LOG_LEVEL_CONTINUED 8 -enum log_level { +enum log_level : u32 { LOG_LEVEL_EMERG = SYSLOG_EMERG, LOG_LEVEL_ALERT = SYSLOG_ALERT, LOG_LEVEL_CRIT = SYSLOG_CRIT, @@ -61,7 +62,7 @@ enum log_level { // For a level only known at runtime #define LOG_LEVEL_FMT LOG_LEVEL_PREFIX "%c" -#define LOG_LEVEL_ARG(lvl) ('0' + (lvl)) +#define LOG_LEVEL_ARG(lvl) ((char)('0' + (lvl))) void vprint(const char *msg, va_list vlist); diff --git a/kernel/include/memory/alloc_behavior.h b/kernel/include/memory/alloc_behavior.h index 228b6a55..fdb8302f 100644 --- a/kernel/include/memory/alloc_behavior.h +++ b/kernel/include/memory/alloc_behavior.h @@ -1,6 +1,8 @@ #pragma once -enum alloc_behavior { +#include + +enum alloc_behavior : u32 { /* * Generic kernel allocation, may sleep, use IO, reclaim, * retry, or otherwise do things that may cause unpredictable diff --git a/kernel/include/memory/buddy.h b/kernel/include/memory/buddy.h index 4a05e3ee..1f3b4b2d 100644 --- a/kernel/include/memory/buddy.h +++ b/kernel/include/memory/buddy.h @@ -5,7 +5,7 @@ #include #include -#include +#include #include #include diff --git a/kernel/include/memory/io.h b/kernel/include/memory/io.h index ffde1329..8c010624 100644 --- a/kernel/include/memory/io.h +++ b/kernel/include/memory/io.h @@ -4,7 +4,7 @@ #include #include -#include +#include #include #define MAX_PHYS_ADDR BIT_OF_TYPE(phys_addr_t, MAX_PHYS_BITS) diff --git a/kernel/include/memory/page.h b/kernel/include/memory/page.h index bebb2a26..5a744748 100644 --- a/kernel/include/memory/page.h +++ b/kernel/include/memory/page.h @@ -39,7 +39,7 @@ #include #include -#include +#include #include /* @@ -269,27 +269,34 @@ static inline ptr_t page_to_block_ptr(const struct page *page) extern struct page *g_memory_map; -#define PHYS_ADDR_TO_PFN(phys_addr) ((phys_addr) >> PAGE_SHIFT) -#define PFN_TO_PHYS_ADDR(pfn) ((phys_addr_t)(pfn) << PAGE_SHIFT) +static inline pfn_t phys_to_pfn(phys_addr_t addr) +{ + return addr >> PAGE_SHIFT; +} + +static inline phys_addr_t pfn_to_phys(pfn_t pfn) +{ + return (phys_addr_t)pfn << PAGE_SHIFT; +} -static inline struct page *pfn_to_page(phys_addr_t pfn) +static inline struct page *pfn_to_page(pfn_t pfn) { return &g_memory_map[pfn]; } -static inline phys_addr_t page_to_pfn(const struct page *page) +static inline pfn_t page_to_pfn(const struct page *page) { - return (phys_addr_t)(page - g_memory_map); + return (pfn_t)(page - g_memory_map); } static inline struct page *phys_to_page(phys_addr_t addr) { - return pfn_to_page(PHYS_ADDR_TO_PFN(addr)); + return pfn_to_page(phys_to_pfn(addr)); } static inline phys_addr_t page_to_phys(const struct page *page) { - return PFN_TO_PHYS_ADDR(page_to_pfn(page)); + return pfn_to_phys(page_to_pfn(page)); } static inline void *page_to_virt(const struct page *page) diff --git a/kernel/include/memory/vm_flags.h b/kernel/include/memory/vm_flags.h index 475eae1e..0792abc6 100644 --- a/kernel/include/memory/vm_flags.h +++ b/kernel/include/memory/vm_flags.h @@ -1,6 +1,8 @@ #pragma once -enum vm_prot { +#include + +enum vm_prot : u32 { VM_PROT_NONE = 0, VM_PROT_READ = 1 << 0, VM_PROT_WRITE = 1 << 1, diff --git a/kernel/include/param.h b/kernel/include/param.h index a14ed167..94788fde 100644 --- a/kernel/include/param.h +++ b/kernel/include/param.h @@ -9,7 +9,7 @@ #include #include -enum param_flags { +enum param_flags : u32 { /* * The value may be changed on a running system, the setter is invoked * with is_runtime set to true for such writes. Writing is always a diff --git a/kernel/include/pci/config_space.h b/kernel/include/pci/config_space.h index 42dcfb3d..78f07f8b 100644 --- a/kernel/include/pci/config_space.h +++ b/kernel/include/pci/config_space.h @@ -8,7 +8,7 @@ #define PCI_CONFIG_SPACE_SIZE 256 #define PCIE_CONFIG_SPACE_SIZE 4096 -enum pci_config_reg { +enum pci_config_reg : u32 { PCI_CONFIG_VENDOR_ID = 0x00, #define PCI_VENDOR_ID_NONE 0xFFFF diff --git a/kernel/include/private/log_ring.h b/kernel/include/private/log_ring.h index f6d09d95..1a6417f6 100644 --- a/kernel/include/private/log_ring.h +++ b/kernel/include/private/log_ring.h @@ -74,7 +74,7 @@ struct log_ring { struct log_data_ring data_ring; }; -enum descriptor_state { +enum descriptor_state : i32 { DESCRIPTOR_STATE_RESERVED = 0b00, DESCRIPTOR_STATE_FREE = 0b01, DESCRIPTOR_STATE_COMMITTED = 0b10, diff --git a/kernel/include/smbios_structures.h b/kernel/include/smbios_structures.h index 0354b5f9..bbcc611d 100644 --- a/kernel/include/smbios_structures.h +++ b/kernel/include/smbios_structures.h @@ -44,7 +44,7 @@ struct PACKED smbios3_entrypoint { EXPECT_SIZEOF(struct smbios3_entrypoint, 0x18); // smbios_structure_hdr->type -enum smbios_structure_type { +enum smbios_structure_type : u32 { SMBIOS_STRUCTURE_TYPE_BIOS_INFORMATION = 0, SMBIOS_STRUCTURE_TYPE_SYSTEM_INFORMATION = 1, SMBIOS_STRUCTURE_TYPE_BOARD_INFORMATION = 2, diff --git a/kernel/init_level.c b/kernel/init_level.c index 91ccd491..2218f509 100644 --- a/kernel/init_level.c +++ b/kernel/init_level.c @@ -47,7 +47,7 @@ static const struct init_calls INIT_RODATA s_init_calls[] = { static enum init_level s_init_level = INIT_LEVEL_NONE; static bool s_in_progress = false; -enum init_call_type { +enum init_call_type : u32 { INIT_CALL_TYPE_AT, INIT_CALL_TYPE_PRE, INIT_CALL_TYPE_POST, diff --git a/kernel/log.c b/kernel/log.c index 023175a1..89ac1c17 100644 --- a/kernel/log.c +++ b/kernel/log.c @@ -14,11 +14,10 @@ #include #include #include +#include #include