diff --git a/.gitignore b/.gitignore index 146337c..d88c9c7 100644 --- a/.gitignore +++ b/.gitignore @@ -11,7 +11,14 @@ toolchain/local/ toolchain/build/ toolchain/src/ toolchain/sysroot/ +toolchain/sysroot-*/ programs/bin/ +# Non-x86 userspace builds (programs/mk/arch.mk) +programs/bin-*/ +programs/obj-*/ +programs/src/*/obj-*/ +programs/lib/*/obj-*/ +programs/lib/*/build-*/ programs/obj/ programs/src/*/obj/ programs/libs/*/obj/ diff --git a/GNUmakefile b/GNUmakefile index f2c0906..afb66b8 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -10,12 +10,15 @@ QEMUFLAGS := -smp 4 -m 2G -d int -D qemu.log -no-reboot override IMAGE_NAME := montauk-$(ARCH) -# Userspace exists only for x86_64 so far: other architectures get a -# ramdisk holding just the boot files. +# KERNEL_ONLY=1 builds a ramdisk holding just the boot files (no +# userspace), for bringing up a kernel on a new architecture. +KERNEL_ONLY ?= 0 + +# programs/ builds x86_64 into bin/, other architectures into bin-/. ifeq ($(ARCH),x86_64) - KERNEL_ONLY ?= 0 + PROGRAMS_BIN := programs/bin else - KERNEL_ONLY ?= 1 + PROGRAMS_BIN := programs/bin-$(ARCH) endif override EFI_LOADER_x86_64 := BOOTX64.EFI @@ -23,6 +26,13 @@ override EFI_LOADER_aarch64 := BOOTAA64.EFI override EFI_LOADER_riscv64 := BOOTRISCV64.EFI override EFI_LOADER_loongarch64 := BOOTLOONGARCH64.EFI +# The host strip handles x86_64 images; other targets use their toolchain's. +ifeq ($(ARCH),x86_64) + STRIP := strip +else + STRIP := toolchain/local/bin/$(ARCH)-montauk-strip +endif + # AArch64 UEFI firmware for QEMU (Debian/Ubuntu: qemu-efi-aarch64). AARCH64_EFI_FIRMWARE ?= /usr/share/qemu-efi-aarch64/QEMU_EFI.fd @@ -227,12 +237,12 @@ ramdisk: limine/limine kernel rm -rf .kernel-only-root else ramdisk: limine/limine kernel programs - mkdir -p programs/bin/boot/limine - cp -v limine/$(EFI_LOADER_$(ARCH)) programs/bin/boot/limine/ - cp -v limine.conf programs/bin/boot/limine/ - cp -v kernel/bin-$(ARCH)/kernel programs/bin/boot/ - rm -f programs/bin/boot/ramdisk.tar - ./scripts/mkramdisk.sh programs/bin ramdisk.tar + mkdir -p $(PROGRAMS_BIN)/boot/limine + cp -v limine/$(EFI_LOADER_$(ARCH)) $(PROGRAMS_BIN)/boot/limine/ + cp -v limine.conf $(PROGRAMS_BIN)/boot/limine/ + cp -v kernel/bin-$(ARCH)/kernel $(PROGRAMS_BIN)/boot/ + rm -f $(PROGRAMS_BIN)/boot/ramdisk.tar + ./scripts/mkramdisk.sh $(PROGRAMS_BIN) ramdisk.tar endif $(IMAGE_NAME).iso: limine/limine kernel ramdisk @@ -292,8 +302,8 @@ release: limine/limine kernel ramdisk rm -rf iso_root .release-tmp mkdir -p iso_root/boot cp kernel/bin-$(ARCH)/kernel iso_root/boot/ - strip iso_root/boot/kernel - cp -r programs/bin .release-tmp + $(STRIP) iso_root/boot/kernel + cp -r $(PROGRAMS_BIN) .release-tmp # A release ISO ships only in-tree apps, so drop any out-of-tree port bundles # that happen to be staged in programs/bin/apps (each carries a .port marker). # Pass RELEASE_WITH_PORTS=1 to deliberately cut a ports-included image. @@ -317,11 +327,11 @@ ifeq ($(RELEASE_WITHOUT_SDK),1) .release-tmp/sdk/libexec .release-tmp/sdk/x86_64-montauk endif rm -f $(addprefix .release-tmp/os/,$(RELEASE_EXCLUDE_PROGRAMS)) - find .release-tmp -name '*.elf' -exec strip {} + + find .release-tmp -name '*.elf' -exec $(STRIP) {} + # The ramdisk carries its own copy of the kernel at 0:/boot/kernel -- that is # the image the Installer lays down on the target disk -- and it is not named # *.elf, so the find above misses it. Unstripped it is ~6 MB against ~0.7 MB. - strip .release-tmp/boot/kernel + $(STRIP) .release-tmp/boot/kernel ./scripts/mkramdisk.sh .release-tmp iso_root/boot/ramdisk.tar rm -rf .release-tmp mkdir -p iso_root/boot/limine diff --git a/docs/porting.md b/docs/porting.md index b24eea2..5e53c83 100644 --- a/docs/porting.md +++ b/docs/porting.md @@ -105,29 +105,64 @@ dispatch table (`ArchIrqDispatch`), panic-frame printing, and: between them (device space on ARM). MAIR: 0 Normal WB, 1 Normal NC (`MapWC`), 2 Device-nGnRE (`MapMMIO`). +- GICv2 (`Interrupts.cpp`, from the MADT): IRQ slots map onto INTIDs -- + `IRQ_TIMER` onto the generic timer's PPI, the MSI slots (24-45) onto the + SPIs of a GICv2m MSI frame (`ComposeMsi`), the IPI slots onto SGIs 0/1. + Interrupts are completed (EOI) before the handler runs, as on x86; a + level-triggered source drops its line first in an ack hook. +- Generic timer tick (`Timer.cpp`): the EL1 virtual timer at + `CNTFRQ_EL0`, its PPI from the GTDT, re-armed from the ack hook. +- PSCI `SYSTEM_RESET` / `SYSTEM_OFF` (`Arch::Reboot` / `Arch::PowerOff`) + through the conduit the FADT's ARM_BOOT_ARCH names. Hardware-reduced + ACPI has no PM1 block, so `AcpiShutdown` leaves power-off to the port. +- `Arch::SyncInstructionCache` after the ELF loader writes code: ARM + instruction fetch does not snoop data writes (QEMU hides this; real + cores do not). EL0 may maintain caches itself (`SCTLR_EL1.UCI`). + Not yet written (each is marked `TODO(aarch64)`): -- GIC driver: SPI routing, SGIs for IPIs, MSIs via ITS/GICv2m - (`ComposeMsi` returns false, so drivers fall back to INTx/polling). IRQs - reach `ArchIrqException`, which only logs them. -- Generic timer tick (`Arch::Timer::InitializeBsp` returns false). Boot - currently stops in the first driver that waits on `GetMilliseconds()` - (xHCI port power-up). -- Secondary CPU start-up, PSCI reset and suspend. +- Secondary CPU start-up (`Smp::BootAPs`). +- PCI INTx: the PC interrupt lines (slots 1-23) have no ARM meaning, so + `RouteLegacyIrq` refuses them. Routing a PCI pin needs its `_PRT` + entry and a GSI-based routing call; until then PCI drivers use MSI + (GICv2m) or polling. + +The generic kernel is compiled `-fsigned-char` for AArch64: it was written +for x86's signed plain `char`. Building it needs `clang` and `ld.lld`; without a system `ld.lld` the kernel makefile uses the one rustup ships (`~/.rustup/toolchains/*/lib/rustlib/*/bin/gcc-ld/ld.lld`), and `KERNEL_LD=` -overrides both. `make run ARCH=aarch64` boots a kernel-only image (userspace -is x86_64-only so far) on QEMU `virt` with a GICv2 and Cortex-A72 cores, the +overrides both. `make run ARCH=aarch64` boots the full image (desktop, apps, +USB keyboard and mouse) on QEMU `virt` with a GICv2 and Cortex-A72 cores, the Raspberry Pi 4/400's configuration; it needs `qemu-system-aarch64` and -`qemu-efi-aarch64`. +`qemu-efi-aarch64`, and the userspace compiler +(`./toolchain/build-montauk-toolchain.sh aarch64`). `KERNEL_ONLY=1` builds an +image without userspace. The kernel console is mirrored to the serial port the ACPI SPCR table names (PL011, SBSA UART, 16550 or the BCM2835 mini UART; `Drivers/Serial/Uart.cpp`), including the log written before the port was found. On QEMU that is `-serial stdio`. +## Userspace + +The programs are architecture-neutral C/C++ built by `-montauk-gcc` +(see `toolchain/README.md`). `programs/mk/arch.mk` holds everything +architecture-specific in the build: the toolchain prefix, FP/SIMD flag sets +(`ARCH_FP_FLAGS` for GUI apps, `ARCH_NOFP_FLAGS` for system programs) and the +output layout. x86_64 keeps `bin/`, `obj/` and libraries next to their +sources; other architectures build beside them into `bin-/`, +`obj-/` and `lib//build-/`, so both can be built from one +tree. The few architecture-specific sources are the raw system-call +wrappers (`#if defined(__x86_64__)` / `__aarch64__` blocks in +`montauk/syscall.h`, `libc/montauk.h`, `lib/libc/libc.c` and +`lib/libc/crt/crt1.c`), `lib/libc/arch/setjmp-.S` and the scanout +store fence in `gui/framebuffer.hpp`. + +Not built for AArch64: tcc (it generates x86 code), the on-OS SDK and the +Rust programs (their `x86_64-unknown-montauk` target). + ## Adding another architecture 1. Create `kernel/src/Arch//` with the six inline headers listed above diff --git a/kernel/GNUmakefile b/kernel/GNUmakefile index e3564c5..18f1502 100644 --- a/kernel/GNUmakefile +++ b/kernel/GNUmakefile @@ -153,8 +153,10 @@ ifeq ($(ARCH),aarch64) override CXX += \ -target aarch64-unknown-none endif + # Plain char is signed on x86; the generic kernel is written for that. override SHARED_FLAGS += \ - -mgeneral-regs-only + -mgeneral-regs-only \ + -fsigned-char override LDFLAGS += \ -Wl,-m,aarch64elf endif diff --git a/kernel/src/ACPI/AcpiShutdown.cpp b/kernel/src/ACPI/AcpiShutdown.cpp index d3990f5..b62f1dd 100644 --- a/kernel/src/ACPI/AcpiShutdown.cpp +++ b/kernel/src/ACPI/AcpiShutdown.cpp @@ -38,8 +38,24 @@ namespace Hal { return; } - // Map and parse the DSDT to find \_S5_ auto* dsdt = (void*)Memory::HHDM(fadt.DsdtAddress); + + AML::InitializeInterpreter(dsdt, xsdt); + + if (AML::GetInterpreter().IsInitialized()) { + AcpiDevices::DeviceList devices{}; + AcpiDevices::EnumerateAll(devices); + } + + AcpiSleep::Initialize(xsdt); + + // Hardware-reduced ACPI (ARM) has no PM1 registers: the + // architecture powers off instead (Arch::PowerOff). + if ((fadt.Flags & FADT::FlagHardwareReduced) || fadt.PM1aControlBlock == 0) { + KernelLogStream(INFO, "ACPI") << "No PM1 control block - ACPI S5 shutdown unavailable"; + return; + } + AML::S5Object s5 = AML::FindS5(dsdt); if (!s5.Valid) { @@ -55,23 +71,6 @@ namespace Hal { KernelLogStream(OK, "ACPI") << "ACPI shutdown initialized (PM1a=" << base::hex << (uint64_t)g_pm1aControlBlock << " SLP_TYPa=" << (uint64_t)g_slpTypA << ")"; - - // Initialize the full AML interpreter with the DSDT. - // This loads the entire DSDT namespace, enabling device enumeration, - // method evaluation, and field I/O for the rest of the kernel. - AML::InitializeInterpreter(dsdt, xsdt); - - // Enumerate ACPI devices now that the namespace is loaded - if (AML::GetInterpreter().IsInitialized()) { - AcpiDevices::DeviceList devices{}; - AcpiDevices::EnumerateAll(devices); - } - - // Initialize S3 suspend support (reads FACS and \_S3_ from namespace) - AcpiSleep::Initialize(xsdt); - - // Note: ACPI event handling (SCI, power button) is initialized - // from Main.cpp after the APIC subsystem is ready. } bool IsAvailable() { diff --git a/kernel/src/ACPI/FADT.cpp b/kernel/src/ACPI/FADT.cpp index 97dd57e..59ae9fe 100644 --- a/kernel/src/ACPI/FADT.cpp +++ b/kernel/src/ACPI/FADT.cpp @@ -107,6 +107,8 @@ namespace Hal { result.AcpiEnable = fadt->AcpiEnable; result.AcpiDisable = fadt->AcpiDisable; result.Flags = fadt->Flags; + result.ArmBootArchFlags = fadt->Header.Length >= offsetof(Table, ArmBootArchFlags) + 2 + ? fadt->ArmBootArchFlags : 0; result.Valid = true; KernelLogStream(INFO, "FADT") << "DSDT at " << base::hex << result.DsdtAddress; diff --git a/kernel/src/ACPI/FADT.hpp b/kernel/src/ACPI/FADT.hpp index d7d6692..1977f3a 100644 --- a/kernel/src/ACPI/FADT.hpp +++ b/kernel/src/ACPI/FADT.hpp @@ -69,6 +69,13 @@ namespace Hal { uint8_t X_GPE1Block[12]; } __attribute__((packed)); + // FADT Flags + constexpr uint32_t FlagHardwareReduced = 1u << 20; + + // ARM_BOOT_ARCH flags (ACPI 5.1+) + constexpr uint16_t ArmBootPsciCompliant = 1u << 0; + constexpr uint16_t ArmBootPsciUseHvc = 1u << 1; + struct ParsedFADT { uint64_t DsdtAddress; uint64_t FacsAddress; @@ -91,6 +98,7 @@ namespace Hal { uint8_t AcpiEnable; uint8_t AcpiDisable; uint32_t Flags; + uint16_t ArmBootArchFlags; // 0 when the table predates the field bool Valid; }; diff --git a/kernel/src/Api/BuildNo.hpp b/kernel/src/Api/BuildNo.hpp index 0a5fc31..084f2b1 100644 --- a/kernel/src/Api/BuildNo.hpp +++ b/kernel/src/Api/BuildNo.hpp @@ -12,4 +12,4 @@ #pragma once -#define MONTAUK_BUILD_NUMBER 29 +#define MONTAUK_BUILD_NUMBER 37 diff --git a/kernel/src/Api/Power.hpp b/kernel/src/Api/Power.hpp index d170117..b31cfd0 100644 --- a/kernel/src/Api/Power.hpp +++ b/kernel/src/Api/Power.hpp @@ -73,6 +73,9 @@ namespace montauk::abi { Hal::AcpiShutdown::Shutdown(); } + /* Hardware-reduced platforms (PSCI on ARM) */ + Arch::PowerOff(); + /* Fallback: EFI ResetSystem */ if (Efi::g_ResetSystem) { Memory::VMM::ActivateKernelAddressSpace(); diff --git a/kernel/src/Arch/Cpu.hpp b/kernel/src/Arch/Cpu.hpp index 55b83be..0556960 100644 --- a/kernel/src/Arch/Cpu.hpp +++ b/kernel/src/Arch/Cpu.hpp @@ -79,6 +79,11 @@ namespace Arch { // Write back and invalidate all CPU caches (before power state changes). inline void WritebackInvalidateCaches(); + // Make instructions just written to [address, address+size) (any + // mapping of them) visible to instruction fetch on every CPU. A no-op + // where instruction fetch snoops data writes (x86). + inline void SyncInstructionCache(const void* address, uint64_t size); + // Invalidate this CPU's translation for one virtual page. inline void FlushTlbPage(uint64_t virtualAddress); diff --git a/kernel/src/Arch/Platform.hpp b/kernel/src/Arch/Platform.hpp index 2a421fd..d9fc818 100644 --- a/kernel/src/Arch/Platform.hpp +++ b/kernel/src/Arch/Platform.hpp @@ -51,4 +51,8 @@ namespace Arch { // ResetSystem). Never returns. [[noreturn]] void Reboot(); + // Switch the machine off where ACPI S5 does not apply (hardware-reduced + // ACPI: ARM's PSCI SYSTEM_OFF). Returns if the platform cannot. + void PowerOff(); + } diff --git a/kernel/src/Arch/aarch64/Cpu.hpp b/kernel/src/Arch/aarch64/Cpu.hpp index da0475c..cceef3f 100644 --- a/kernel/src/Arch/aarch64/Cpu.hpp +++ b/kernel/src/Arch/aarch64/Cpu.hpp @@ -93,6 +93,21 @@ namespace Arch { } // The TLBI operand is VA[55:12] in bits [43:0]; the bits above are RES0. + // Clean the data cache to the point of unification, then invalidate + // the whole instruction cache: invalidating by address would only + // reach the alias it names on an aliasing (VIPT) instruction cache. + inline void SyncInstructionCache(const void* address, uint64_t size) { + uint64_t ctr; + asm volatile("mrs %0, ctr_el0" : "=r"(ctr)); + uint64_t line = 4ULL << ((ctr >> 16) & 0xF); // DminLine + uint64_t start = (uint64_t)address & ~(line - 1); + uint64_t end = (uint64_t)address + size; + for (uint64_t p = start; p < end; p += line) { + asm volatile("dc cvau, %0" :: "r"(p) : "memory"); + } + asm volatile("dsb ish\n\tic ialluis\n\tdsb ish\n\tisb" ::: "memory"); + } + inline void FlushTlbPage(uint64_t virtualAddress) { asm volatile("dsb ishst\n\ttlbi vaae1is, %0\n\tdsb ish\n\tisb" :: "r"((virtualAddress >> 12) & ((1ULL << 44) - 1)) : "memory"); diff --git a/kernel/src/Arch/aarch64/Gic.hpp b/kernel/src/Arch/aarch64/Gic.hpp new file mode 100644 index 0000000..51457ac --- /dev/null +++ b/kernel/src/Arch/aarch64/Gic.hpp @@ -0,0 +1,40 @@ +/* + * Gic.hpp + * aarch64 GICv2 interrupt controller (private to the port) + * Copyright (c) 2026 Daniel Hammer +*/ + +#pragma once +#include +#include + +namespace Arch::Gic { + + // Bring up the distributor and the calling CPU's interface from the + // ACPI MADT. Returns false when no usable GIC is described. + bool Initialize(Hal::ACPI::CommonSDTHeader* xsdt); + + bool IsInitialized(); + + // The XSDT Initialize was given (for the other ACPI tables the port reads). + Hal::ACPI::CommonSDTHeader* CurrentXsdt(); + + // Per-CPU part of Initialize, for secondary CPUs. + void InitializeCpuInterface(); + + // Map a private peripheral interrupt (16-31) onto an IRQ slot and enable + // it on the calling CPU. + void RoutePpi(uint32_t intid, uint8_t irq, bool edgeTriggered); + + // Called for an IRQ slot after the interrupt is acknowledged and before + // it is completed (EOI): level-triggered sources deassert here. + using AckHook = void (*)(); + void SetAckHook(uint8_t irq, AckHook hook); + + // The calling CPU's target bit, as the distributor sees it. + uint8_t CurrentTargetMask(); + + // Find an ACPI table in the XSDT by signature. + Hal::ACPI::CommonSDTHeader* FindTable(Hal::ACPI::CommonSDTHeader* xsdt, const char* signature); + +} diff --git a/kernel/src/Arch/aarch64/Interrupts.cpp b/kernel/src/Arch/aarch64/Interrupts.cpp index 256fcda..e0f52c4 100644 --- a/kernel/src/Arch/aarch64/Interrupts.cpp +++ b/kernel/src/Arch/aarch64/Interrupts.cpp @@ -1,63 +1,400 @@ /* * Interrupts.cpp - * aarch64 IRQ slot dispatch (implements Arch/Interrupts.hpp) + * aarch64 GICv2 driver and IRQ slot dispatch (implements Arch/Interrupts.hpp) * Copyright (c) 2026 Daniel Hammer */ #include +#include +#include +#include +#include #include #include -// IRQ slots are delivered by the interrupt controller driver (GICv2/v3, -// not written yet), which maps INTIDs onto slots and calls ArchIrqDispatch -// from the IRQ exception vector after acknowledging the interrupt. +// IRQ slots map onto GIC interrupt IDs (INTIDs): +// IRQ_TIMER the generic timer's PPI (Timer.cpp routes it) +// 24-45 (MSI slots) SPIs of the GICv2m MSI frame, one per slot +// IRQ_TLB_SHOOTDOWN, +// IRQ_RESCHEDULE SGIs 0 and 1 +// The PC platform lines (1-23) have no ARM equivalent; RouteLegacyIrq +// refuses them and drivers fall back to MSI or polling. + +using namespace Kt; namespace Arch { + // Distributor registers + static constexpr uint32_t GICD_CTLR = 0x000; + static constexpr uint32_t GICD_TYPER = 0x004; + static constexpr uint32_t GICD_ISENABLER = 0x100; + static constexpr uint32_t GICD_ICENABLER = 0x180; + static constexpr uint32_t GICD_ICPENDR = 0x280; + static constexpr uint32_t GICD_ICACTIVER = 0x380; + static constexpr uint32_t GICD_IPRIORITYR = 0x400; + static constexpr uint32_t GICD_ITARGETSR = 0x800; + static constexpr uint32_t GICD_ICFGR = 0xC00; + static constexpr uint32_t GICD_SGIR = 0xF00; + + // CPU interface registers + static constexpr uint32_t GICC_CTLR = 0x00; + static constexpr uint32_t GICC_PMR = 0x04; + static constexpr uint32_t GICC_BPR = 0x08; + static constexpr uint32_t GICC_IAR = 0x0C; + static constexpr uint32_t GICC_EOIR = 0x10; + + // GICv2m MSI frame registers + static constexpr uint32_t V2M_MSI_TYPER = 0x008; + static constexpr uint32_t V2M_MSI_SETSPI_NS = 0x040; + + static constexpr uint32_t SpuriousIntid = 1020; + static constexpr uint32_t MaxIntids = 1020; + static constexpr uint8_t DefaultPriority = 0xA0; + static constexpr uint8_t NoSlot = 0xFF; + + static constexpr uint8_t FirstMsiSlot = 24; + static constexpr uint8_t LastMsiSlot = 45; + + // MADT interrupt-controller structures (ACPI 6.x) + static constexpr uint8_t MadtGicc = 0x0B; + static constexpr uint8_t MadtGicd = 0x0C; + static constexpr uint8_t MadtGicMsiFrame = 0x0D; + + struct MadtEntry { + uint8_t Type; + uint8_t Length; + } __attribute__((packed)); + + struct MadtGiccEntry { + MadtEntry Header; + uint16_t Reserved; + uint32_t CpuInterfaceNumber; + uint32_t AcpiProcessorUid; + uint32_t Flags; + uint32_t ParkingProtocolVersion; + uint32_t PerformanceInterruptGsiv; + uint64_t ParkedAddress; + uint64_t PhysicalBaseAddress; // GICC + uint64_t Gicv; + uint64_t Gich; + uint32_t VgicMaintenanceInterrupt; + uint64_t GicrBaseAddress; + uint64_t Mpidr; + } __attribute__((packed)); + + struct MadtGicdEntry { + MadtEntry Header; + uint16_t Reserved; + uint32_t GicId; + uint64_t PhysicalBaseAddress; + uint32_t SystemVectorBase; + uint8_t GicVersion; + } __attribute__((packed)); + + struct MadtMsiFrameEntry { + MadtEntry Header; + uint16_t Reserved; + uint32_t FrameId; + uint64_t PhysicalBaseAddress; + uint32_t Flags; // bit 0: SpiCount/SpiBase override TYPER + uint16_t SpiCount; + uint16_t SpiBase; + } __attribute__((packed)); + + static constexpr uint32_t MadtHeaderSize = 44; // SDT header + LAPIC address + flags + static IrqHandler g_irqHandlers[IRQ_COUNT] = {}; + static Gic::AckHook g_ackHooks[IRQ_COUNT] = {}; + static uint8_t g_intidToSlot[MaxIntids]; + static uint32_t g_slotToIntid[IRQ_COUNT]; + + static volatile uint8_t* g_gicd = nullptr; + static volatile uint8_t* g_gicc = nullptr; + static uint32_t g_intidCount = 0; + + static Hal::ACPI::CommonSDTHeader* g_xsdt = nullptr; + + static uint64_t g_msiFramePhys = 0; + static uint32_t g_msiSpiBase = 0; + static uint32_t g_msiSpiCount = 0; + + static inline uint32_t GicdRead(uint32_t reg) { + return *(volatile uint32_t*)(g_gicd + reg); + } + + static inline void GicdWrite(uint32_t reg, uint32_t value) { + *(volatile uint32_t*)(g_gicd + reg) = value; + } + + static inline void GicdWrite8(uint32_t reg, uint8_t value) { + *(volatile uint8_t*)(g_gicd + reg) = value; + } + + static inline uint8_t GicdRead8(uint32_t reg) { + return *(volatile uint8_t*)(g_gicd + reg); + } + + static inline uint32_t GiccRead(uint32_t reg) { + return *(volatile uint32_t*)(g_gicc + reg); + } + + static inline void GiccWrite(uint32_t reg, uint32_t value) { + *(volatile uint32_t*)(g_gicc + reg) = value; + } + + static volatile uint8_t* MapRegisters(uint64_t phys, uint64_t size) { + for (uint64_t offset = 0; offset < size; offset += 0x1000) { + Memory::VMM::g_paging->MapMMIO(phys + offset, Memory::HHDM(phys + offset)); + } + return (volatile uint8_t*)Memory::HHDM(phys); + } + + static void SetConfig(uint32_t intid, bool edgeTriggered) { + uint32_t reg = GICD_ICFGR + (intid / 16) * 4; + uint32_t shift = (intid % 16) * 2 + 1; + uint32_t value = GicdRead(reg); + if (edgeTriggered) value |= 1u << shift; + else value &= ~(1u << shift); + GicdWrite(reg, value); + } + + static void EnableIntid(uint32_t intid) { + GicdWrite(GICD_ISENABLER + (intid / 32) * 4, 1u << (intid % 32)); + } + + static void Bind(uint32_t intid, uint8_t irq) { + if (intid >= MaxIntids || irq >= IRQ_COUNT) return; + g_intidToSlot[intid] = irq; + g_slotToIntid[irq] = intid; + } + + // Route a shared peripheral interrupt to the boot CPU and unmask it. + static void RouteSpi(uint32_t intid, uint8_t irq, bool edgeTriggered) { + if (intid < 32 || intid >= g_intidCount) return; + Bind(intid, irq); + GicdWrite8(GICD_IPRIORITYR + intid, DefaultPriority); + GicdWrite8(GICD_ITARGETSR + intid, Smp::GetCpuData(0)->arch.gicTargetMask); + SetConfig(intid, edgeTriggered); + EnableIntid(intid); + } + + namespace Gic { + + Hal::ACPI::CommonSDTHeader* FindTable(Hal::ACPI::CommonSDTHeader* xsdt, const char* signature) { + if (xsdt == nullptr) return nullptr; + uint32_t count = (xsdt->Length - sizeof(Hal::ACPI::CommonSDTHeader)) / 8; + auto* entries = (uint64_t*)((uint64_t)xsdt + sizeof(Hal::ACPI::CommonSDTHeader)); + for (uint32_t i = 0; i < count; i++) { + auto* header = (Hal::ACPI::CommonSDTHeader*)Memory::HHDM(entries[i]); + if (header->Signature[0] == signature[0] && header->Signature[1] == signature[1] + && header->Signature[2] == signature[2] && header->Signature[3] == signature[3]) { + return header; + } + } + return nullptr; + } + + // ITARGETSR0-7 are banked: each byte reads back the reading CPU's + // own interface bit. + uint8_t CurrentTargetMask() { + uint32_t value = GicdRead(GICD_ITARGETSR); + return (uint8_t)(value | value >> 8 | value >> 16 | value >> 24); + } + + void InitializeCpuInterface() { + // SGIs and PPIs are banked per CPU: disable the PPIs until a + // driver routes one, keep the SGIs (IPIs) enabled. + GicdWrite(GICD_ICENABLER, 0xFFFF0000u); + GicdWrite(GICD_ISENABLER, 0x0000FFFFu); + GicdWrite(GICD_ICPENDR, 0xFFFFFFFFu); + for (uint32_t intid = 0; intid < 32; intid++) { + GicdWrite8(GICD_IPRIORITYR + intid, DefaultPriority); + } + + GiccWrite(GICC_PMR, 0xF0); + GiccWrite(GICC_BPR, 0); + GiccWrite(GICC_CTLR, 1); + + auto* cpu = Smp::GetCurrentCpuData(); + cpu->arch.gicTargetMask = CurrentTargetMask(); + } + + void RoutePpi(uint32_t intid, uint8_t irq, bool edgeTriggered) { + if (intid < 16 || intid >= 32) return; + Bind(intid, irq); + SetConfig(intid, edgeTriggered); + EnableIntid(intid); + } + + void SetAckHook(uint8_t irq, AckHook hook) { + if (irq < IRQ_COUNT) g_ackHooks[irq] = hook; + } + + bool IsInitialized() { + return g_gicc != nullptr; + } + + Hal::ACPI::CommonSDTHeader* CurrentXsdt() { + return g_xsdt; + } + + bool Initialize(Hal::ACPI::CommonSDTHeader* xsdt) { + g_xsdt = xsdt; + auto* madt = FindTable(xsdt, "APIC"); + if (madt == nullptr) { + KernelLogStream(ERROR, "GIC") << "No MADT"; + return false; + } + + uint64_t gicdPhys = 0, giccPhys = 0; + uint8_t version = 0; + auto* cursor = (uint8_t*)madt + MadtHeaderSize; + auto* end = (uint8_t*)madt + madt->Length; + while (cursor + sizeof(MadtEntry) <= end) { + auto* entry = (MadtEntry*)cursor; + if (entry->Length < sizeof(MadtEntry)) break; + + if (entry->Type == MadtGicd) { + auto* gicd = (MadtGicdEntry*)entry; + gicdPhys = gicd->PhysicalBaseAddress; + version = gicd->GicVersion; + } else if (entry->Type == MadtGicc && giccPhys == 0) { + giccPhys = ((MadtGiccEntry*)entry)->PhysicalBaseAddress; + } else if (entry->Type == MadtGicMsiFrame && g_msiFramePhys == 0) { + auto* frame = (MadtMsiFrameEntry*)entry; + g_msiFramePhys = frame->PhysicalBaseAddress; + if (frame->Flags & 1) { + g_msiSpiBase = frame->SpiBase; + g_msiSpiCount = frame->SpiCount; + } + } + cursor += entry->Length; + } + + // Version 0 means "infer from the hardware"; 1 and 2 share a + // programming model. + if (gicdPhys == 0 || giccPhys == 0 || version > 2) { + KernelLogStream(ERROR, "GIC") << "No GICv2 in the MADT (version " + << base::dec << (uint64_t)version << ")"; + return false; + } + + for (uint32_t i = 0; i < MaxIntids; i++) g_intidToSlot[i] = NoSlot; + for (int i = 0; i < IRQ_COUNT; i++) g_slotToIntid[i] = SpuriousIntid; + Bind(0, IRQ_TLB_SHOOTDOWN); + Bind(1, IRQ_RESCHEDULE); + + g_gicd = MapRegisters(gicdPhys, 0x1000); + g_gicc = MapRegisters(giccPhys, 0x2000); + + g_intidCount = ((GicdRead(GICD_TYPER) & 0x1F) + 1) * 32; + if (g_intidCount > MaxIntids) g_intidCount = MaxIntids; + + // Distributor: everything masked, idle, level-triggered and + // aimed at no CPU until RouteSpi claims it. + GicdWrite(GICD_CTLR, 0); + for (uint32_t intid = 32; intid < g_intidCount; intid += 32) { + GicdWrite(GICD_ICENABLER + (intid / 32) * 4, 0xFFFFFFFFu); + GicdWrite(GICD_ICPENDR + (intid / 32) * 4, 0xFFFFFFFFu); + GicdWrite(GICD_ICACTIVER + (intid / 32) * 4, 0xFFFFFFFFu); + } + for (uint32_t intid = 32; intid < g_intidCount; intid++) { + GicdWrite8(GICD_IPRIORITYR + intid, DefaultPriority); + GicdWrite8(GICD_ITARGETSR + intid, 0); + } + for (uint32_t intid = 32; intid < g_intidCount; intid += 16) { + GicdWrite(GICD_ICFGR + (intid / 16) * 4, 0); + } + GicdWrite(GICD_CTLR, 1); + + InitializeCpuInterface(); + + if (g_msiFramePhys != 0) { + volatile uint8_t* frame = MapRegisters(g_msiFramePhys, 0x1000); + if (g_msiSpiCount == 0) { + uint32_t typer = *(volatile uint32_t*)(frame + V2M_MSI_TYPER); + g_msiSpiBase = (typer >> 16) & 0x3FF; + g_msiSpiCount = typer & 0x3FF; + } + } + + KernelLogStream(OK, "GIC") << "GICv2: distributor 0x" << base::hex << gicdPhys + << ", CPU interface 0x" << giccPhys << ", " << base::dec + << (uint64_t)g_intidCount << " interrupt IDs"; + if (g_msiSpiCount != 0) { + KernelLogStream(OK, "GIC") << "GICv2m MSI frame 0x" << base::hex << g_msiFramePhys + << ": SPIs " << base::dec << (uint64_t)g_msiSpiBase << "-" + << (uint64_t)(g_msiSpiBase + g_msiSpiCount - 1); + } + return true; + } + + } void RegisterIrqHandler(uint8_t irq, IrqHandler handler) { if (irq >= IRQ_COUNT) return; g_irqHandlers[irq] = handler; - Kt::KernelLogStream(Kt::DEBUG, "IRQ") << "Registered handler for IRQ " + KernelLogStream(DEBUG, "IRQ") << "Registered handler for IRQ " << base::dec << (uint64_t)irq; } - // TODO(aarch64): GIC SPI routing (ACPI MADT GICD / interrupt overrides). + // TODO(aarch64): PCI INTx needs the pin's _PRT GSI and a GSI-based + // routing call (RouteSpi with level/polarity); drivers poll until then. void RouteLegacyIrq(uint8_t irq) { - Kt::KernelLogStream(Kt::WARNING, "IRQ") << "aarch64: cannot route IRQ " - << base::dec << (uint64_t)irq << " (no GIC driver)"; + KernelLogStream(WARNING, "IRQ") << "aarch64: no PC interrupt line " + << base::dec << (uint64_t)irq << " to route"; } void EnableLegacyIrq(uint8_t irq) { RouteLegacyIrq(irq); } - // TODO(aarch64): GICv3 ITS / GICv2m doorbell. - bool ComposeMsi(uint8_t, MsiMessage&) { - return false; + bool ComposeMsi(uint8_t irq, MsiMessage& out) { + if (g_gicd == nullptr || irq < FirstMsiSlot || irq > LastMsiSlot) return false; + uint32_t index = irq - FirstMsiSlot; + if (index >= g_msiSpiCount) return false; + + uint32_t spi = g_msiSpiBase + index; + if (g_slotToIntid[irq] != spi) { + RouteSpi(spi, irq, true); + } + out = MsiMessage{ g_msiFramePhys + V2M_MSI_SETSPI_NS, spi }; + return true; } - // TODO(aarch64): GIC software-generated interrupts. - bool SendIpi(int, uint8_t) { - return false; + bool SendIpi(int cpuIndex, uint8_t irq) { + if (g_gicd == nullptr) return false; + auto* cpu = Smp::GetCpuData(cpuIndex); + if (cpu == nullptr || cpu->arch.gicTargetMask == 0) return false; + uint32_t sgi = g_slotToIntid[irq]; + if (sgi >= 16) return false; + + // Make the IPI's memory effects visible before it is raised. + asm volatile("dsb ishst" ::: "memory"); + GicdWrite(GICD_SGIR, ((uint32_t)cpu->arch.gicTargetMask << 16) | sgi); + return true; } } -// IRQ exception vector (Vectors.S). -// TODO(aarch64): acknowledge through the GIC CPU interface, translate the -// INTID to a slot and call ArchIrqDispatch. -extern "C" void ArchIrqException(void*, bool) { - static bool reported = false; - if (!reported) { - reported = true; - Kt::KernelLogStream(Kt::WARNING, "IRQ") << "aarch64: IRQ taken with no interrupt controller driver"; - } -} +// IRQ exception vector (Vectors.S). As on x86, the interrupt is completed +// BEFORE the handler runs: the handler may context-switch away and not +// come back here for a long time, and an un-EOId interrupt would hold this +// CPU's running priority up (no further ticks). Level-triggered sources +// get the chance to drop their line first through an ack hook. +extern "C" void ArchIrqException(void*, bool fromUser) { + using namespace Arch; + uint32_t iar = GiccRead(GICC_IAR); + uint32_t intid = iar & 0x3FF; + if (intid >= SpuriousIntid) return; -extern "C" void ArchIrqDispatch(uint64_t irq, bool fromUser) { - if (irq < Arch::IRQ_COUNT && Arch::g_irqHandlers[irq] != nullptr) { - Arch::g_irqHandlers[irq]((uint8_t)irq, fromUser); + uint8_t irq = g_intidToSlot[intid]; + if (irq != NoSlot && g_ackHooks[irq] != nullptr) { + g_ackHooks[irq](); + } + GiccWrite(GICC_EOIR, iar); + + if (irq != NoSlot && g_irqHandlers[irq] != nullptr) { + g_irqHandlers[irq](irq, fromUser); } } diff --git a/kernel/src/Arch/aarch64/PerCpu.hpp b/kernel/src/Arch/aarch64/PerCpu.hpp index 8514e10..393298a 100644 --- a/kernel/src/Arch/aarch64/PerCpu.hpp +++ b/kernel/src/Arch/aarch64/PerCpu.hpp @@ -17,6 +17,8 @@ namespace Arch { struct CpuState { uint64_t mpidr; // MPIDR_EL1 affinity of this CPU + uint8_t gicTargetMask; // GICv2 CPU-interface bit (SGI/SPI targets) + uint64_t timerPeriod; // tick period in counter ticks, 0 = stopped }; // TPIDR_EL1 holds the CpuData pointer (zeroed in EarlyInitialize until diff --git a/kernel/src/Arch/aarch64/Platform.cpp b/kernel/src/Arch/aarch64/Platform.cpp index d56cb14..f9cf83c 100644 --- a/kernel/src/Arch/aarch64/Platform.cpp +++ b/kernel/src/Arch/aarch64/Platform.cpp @@ -7,6 +7,8 @@ #include #include #include +#include +#include #include #include @@ -18,6 +20,42 @@ namespace Arch { // SCTLR_EL1.WXN: writable memory is execute-never static constexpr uint64_t SctlrWxn = 1ULL << 19; + // SCTLR_EL1.UCT/UCI: EL0 may read CTR_EL0 and clean/invalidate caches + // by address (what __builtin___clear_cache needs for generated code). + static constexpr uint64_t SctlrUct = 1ULL << 15; + static constexpr uint64_t SctlrUci = 1ULL << 26; + + // PSCI 0.2+ function IDs (SMC32 calling convention) + static constexpr uint64_t PsciSystemOff = 0x84000008; + static constexpr uint64_t PsciSystemReset = 0x84000009; + + // How the firmware takes PSCI calls, from the FADT's ARM_BOOT_ARCH. + enum class PsciConduit { None, Smc, Hvc }; + static PsciConduit g_psci = PsciConduit::None; + + static uint64_t PsciCall(uint64_t function) { + register uint64_t x0 asm("x0") = function; + register uint64_t x1 asm("x1") = 0; + register uint64_t x2 asm("x2") = 0; + register uint64_t x3 asm("x3") = 0; + if (g_psci == PsciConduit::Hvc) { + asm volatile("hvc #0" : "+r"(x0), "+r"(x1), "+r"(x2), "+r"(x3) :: "memory"); + } else if (g_psci == PsciConduit::Smc) { + asm volatile("smc #0" : "+r"(x0), "+r"(x1), "+r"(x2), "+r"(x3) :: "memory"); + } + return x0; + } + + static void InitializePsci(Hal::ACPI::CommonSDTHeader* xsdt) { + Hal::FADT::ParsedFADT fadt{}; + if (!Hal::FADT::Parse(xsdt, fadt) || !fadt.Valid) return; + if (!(fadt.ArmBootArchFlags & Hal::FADT::ArmBootPsciCompliant)) { + KernelLogStream(WARNING, "PSCI") << "Firmware is not PSCI compliant: no reset or power-off"; + return; + } + g_psci = (fadt.ArmBootArchFlags & Hal::FADT::ArmBootPsciUseHvc) ? PsciConduit::Hvc : PsciConduit::Smc; + KernelLogStream(OK, "PSCI") << "PSCI through " << (g_psci == PsciConduit::Hvc ? "HVC" : "SMC"); + } void EarlyInitialize() { // No per-CPU data yet: Smp::TryGetCurrentCpuData must see null. @@ -32,10 +70,11 @@ namespace Arch { asm volatile("msr vbar_el1, %0\n\tisb" :: "r"(ArchExceptionVectors) : "memory"); // Kernel mappings are RWX (Paging.cpp), so writable must not - // imply execute-never. + // imply execute-never; user code may maintain its own caches. uint64_t sctlr; asm volatile("mrs %0, sctlr_el1" : "=r"(sctlr)); sctlr &= ~SctlrWxn; + sctlr |= SctlrUct | SctlrUci; asm volatile("msr sctlr_el1, %0\n\tisb" :: "r"(sctlr)); // CPACR_EL1.FPEN = 0b11: FP/SIMD usable at EL0 and EL1 (the kernel @@ -57,10 +96,12 @@ namespace Arch { void InitializeMemoryAttributes() { } - // TODO(aarch64): GIC distributor/redistributor from the ACPI MADT. - void InitializeInterrupts(Hal::ACPI::CommonSDTHeader*) { + void InitializeInterrupts(Hal::ACPI::CommonSDTHeader* xsdt) { Smp::InitBsp(); - KernelLogStream(WARNING, "Arch") << "aarch64: no interrupt controller driver"; + if (!Gic::Initialize(xsdt)) { + KernelLogStream(ERROR, "Arch") << "aarch64: no interrupt controller, running without IRQs"; + } + InitializePsci(xsdt); } void InitializePlatformDevices() { @@ -73,12 +114,22 @@ namespace Arch { void LateInitialize() { } - void ListPlatformDevices(PlatformDeviceSink, void*) { + void ListPlatformDevices(PlatformDeviceSink sink, void* context) { + if (Gic::IsInitialized()) { + sink(context, 1, "GICv2", "ARM Generic Interrupt Controller"); + sink(context, 2, "Generic Timer", "ARM architected timer (EL1 virtual)"); + } } - // TODO(aarch64): PSCI SYSTEM_RESET through the conduit the FADT names. void Reboot() { + PsciCall(PsciSystemReset); HaltForever(); } + void PowerOff() { + if (g_psci != PsciConduit::None) { + PsciCall(PsciSystemOff); + } + } + } diff --git a/kernel/src/Arch/aarch64/Timer.cpp b/kernel/src/Arch/aarch64/Timer.cpp index 7f1d767..19367b5 100644 --- a/kernel/src/Arch/aarch64/Timer.cpp +++ b/kernel/src/Arch/aarch64/Timer.cpp @@ -1,24 +1,115 @@ /* * Timer.cpp - * aarch64 tick timer (implements Arch/Timer.hpp) + * aarch64 tick timer: the EL1 virtual generic timer (implements Arch/Timer.hpp) * Copyright (c) 2026 Daniel Hammer */ #include +#include +#include +#include +#include +#include +#include +#include -// TODO(aarch64): drive the EL1 virtual timer (CNTV_TVAL/CNTV_CTL) from -// CNTFRQ_EL0, re-arming on each tick, once the GIC delivers its PPI. +// The generic timer counts at CNTFRQ_EL0 on every CPU, so it needs no +// calibration. Each CPU's virtual timer raises a PPI (the GTDT names it, +// normally INTID 27); the tick is re-armed from the interrupt's ack hook, +// which also drops the level-triggered line before the EOI. + +using namespace Kt; namespace Arch::Timer { - bool InitializeBsp(uint32_t) { - return false; + // CNTV_CTL_EL0 + static constexpr uint64_t CtlEnable = 1ULL << 0; + static constexpr uint64_t CtlMask = 1ULL << 1; + + // GTDT timer flags + static constexpr uint32_t GtdtEdgeTriggered = 1u << 0; + + static constexpr uint32_t DefaultVirtualTimerIntid = 27; + + struct Gtdt { + Hal::ACPI::CommonSDTHeader Header; + uint64_t CntControlBase; + uint32_t Reserved; + uint32_t SecureEl1Gsiv; + uint32_t SecureEl1Flags; + uint32_t NonSecureEl1Gsiv; + uint32_t NonSecureEl1Flags; + uint32_t VirtualTimerGsiv; + uint32_t VirtualTimerFlags; + } __attribute__((packed)); + + static uint64_t g_ticksPerMs = 0; + static uint32_t g_intid = DefaultVirtualTimerIntid; + static bool g_edgeTriggered = false; + + static inline void WriteCtl(uint64_t value) { + asm volatile("msr cntv_ctl_el0, %0\n\tisb" :: "r"(value) : "memory"); } - void StartPeriodic(uint32_t) { + static inline uint64_t ReadCval() { + uint64_t value; + asm volatile("mrs %0, cntv_cval_el0" : "=r"(value)); + return value; + } + + static inline void WriteCval(uint64_t value) { + asm volatile("msr cntv_cval_el0, %0\n\tisb" :: "r"(value) : "memory"); + } + + // Advance the deadline by one period from the previous one (no drift), + // skipping ticks the CPU missed rather than replaying them. + static void Rearm() { + uint64_t period = Smp::GetCurrentCpuData()->arch.timerPeriod; + if (period == 0) { + WriteCtl(CtlMask); + return; + } + uint64_t now = ReadTimestamp(); + uint64_t next = ReadCval() + period; + if ((int64_t)(next - now) <= 0) next = now + period; + WriteCval(next); + } + + static void ReadGtdt() { + auto* gtdt = (Gtdt*)Gic::FindTable(Gic::CurrentXsdt(), "GTDT"); + if (gtdt == nullptr || gtdt->Header.Length < sizeof(Gtdt)) return; + if (gtdt->VirtualTimerGsiv >= 16 && gtdt->VirtualTimerGsiv < 32) { + g_intid = gtdt->VirtualTimerGsiv; + g_edgeTriggered = (gtdt->VirtualTimerFlags & GtdtEdgeTriggered) != 0; + } + } + + bool InitializeBsp(uint32_t periodMs) { + uint64_t frequency; + asm volatile("mrs %0, cntfrq_el0" : "=r"(frequency)); + if (frequency < 1000 || !Gic::IsInitialized()) return false; + g_ticksPerMs = frequency / 1000; + + ReadGtdt(); + Gic::SetAckHook(IRQ_TIMER, Rearm); + Gic::RoutePpi(g_intid, IRQ_TIMER, g_edgeTriggered); + StartPeriodic(periodMs); + + KernelLogStream(OK, "Timer") << "Generic timer: " << base::dec << frequency + << " Hz counter, virtual timer INTID " << (uint64_t)g_intid; + return true; + } + + void StartPeriodic(uint32_t periodMs) { + uint64_t period = g_ticksPerMs * periodMs; + Smp::GetCurrentCpuData()->arch.timerPeriod = period; + WriteCval(ReadTimestamp() + period); + WriteCtl(CtlEnable); } void Stop() { + Smp::GetCurrentCpuData()->arch.timerPeriod = 0; + WriteCtl(CtlMask); } } diff --git a/kernel/src/Arch/x86_64/Cpu.hpp b/kernel/src/Arch/x86_64/Cpu.hpp index e8cbbf4..5ac1480 100644 --- a/kernel/src/Arch/x86_64/Cpu.hpp +++ b/kernel/src/Arch/x86_64/Cpu.hpp @@ -79,6 +79,9 @@ namespace Arch { asm volatile("wbinvd" ::: "memory"); } + inline void SyncInstructionCache(const void*, uint64_t) { + } + inline void FlushTlbPage(uint64_t virtualAddress) { asm volatile("invlpg (%0)" :: "r"(virtualAddress) : "memory"); } diff --git a/kernel/src/Arch/x86_64/Platform.cpp b/kernel/src/Arch/x86_64/Platform.cpp index f0dbaf3..67bb360 100644 --- a/kernel/src/Arch/x86_64/Platform.cpp +++ b/kernel/src/Arch/x86_64/Platform.cpp @@ -77,4 +77,8 @@ namespace Arch { __builtin_unreachable(); } + // x86 powers off through ACPI S5 (AcpiShutdown). + void PowerOff() { + } + } diff --git a/kernel/src/Drivers/USB/Xhci.cpp b/kernel/src/Drivers/USB/Xhci.cpp index 1885520..3a0bcee 100644 --- a/kernel/src/Drivers/USB/Xhci.cpp +++ b/kernel/src/Drivers/USB/Xhci.cpp @@ -220,6 +220,13 @@ namespace Drivers::USB::Xhci { *(volatile uint32_t*)(g_opBase + reg) = value; } + // PollEvents() acknowledges the Port Status Change event, clearing PRC, + // so a controller that resets instantly (QEMU) can complete the reset + // between two reads of PRC. A port that left reset enabled is done too. + static bool PortResetComplete(uint32_t portsc) { + return (portsc & PORTSC_PRC) || ((portsc & PORTSC_PED) && !(portsc & PORTSC_PR)); + } + static uint32_t ReadOp(uint32_t reg) { return *(volatile uint32_t*)(g_opBase + reg); } @@ -474,6 +481,16 @@ namespace Drivers::USB::Xhci { BudgetExhausted, }; + // Without MSI nothing interrupts: the deferred-work check (timer and + // idle loop) looks at the event ring itself instead. This is the only + // mode on platforms whose PCIe has no MSI controller (Raspberry Pi 4). + static bool g_pollMode = false; + + static bool EventRingHasWork() { + const volatile TRB& evt = g_evtRing[g_evtRingDequeue]; + return ((evt.Control & TRB_CYCLE_BIT) != 0) == g_evtRingCCS; + } + static PollResult PollEventsBounded(uint32_t maxEvents) { // PollEvents runs from synchronous poll loops (ControlTransfer, // SendCommand, firmware download) and idle bottom halves on different @@ -1396,6 +1413,9 @@ namespace Drivers::USB::Xhci { } bool HasDeferredWork() { + if (g_initialized && g_pollMode && EventRingHasWork()) { + g_irqDrainPending.store(true, std::memory_order_release); + } return g_initialized && (g_irqDrainPending.load(std::memory_order_acquire) || g_deferredWorkPending.load(std::memory_order_acquire) || @@ -1537,7 +1557,7 @@ namespace Drivers::USB::Xhci { for (uint32_t i = 0; i < 100000; i++) { PollEvents(); uint32_t ps = ReadOp(OP_PORTSC_BASE + port * OP_PORTSC_STRIDE); - if (ps & PORTSC_PRC) { + if (PortResetComplete(ps)) { resetDone = true; break; } @@ -1732,6 +1752,7 @@ namespace Drivers::USB::Xhci { // MSI setup if (!SetupMsi(dev.Bus, dev.Device, dev.Function)) { KernelLogStream(WARNING, "xHCI") << "MSI not available, using poll mode"; + g_pollMode = true; } // Enable interrupter 0 @@ -1772,7 +1793,7 @@ namespace Drivers::USB::Xhci { for (uint32_t i = 0; i < 100000; i++) { PollEvents(); uint32_t ps = ReadOp(OP_PORTSC_BASE + port * OP_PORTSC_STRIDE); - if (ps & PORTSC_PRC) { resetDone = true; break; } + if (PortResetComplete(ps)) { resetDone = true; break; } for (int j = 0; j < 100; j++) Arch::CompilerBarrier(); } @@ -2045,6 +2066,7 @@ namespace Drivers::USB::Xhci { // ----------------------------------------------------------------- if (!SetupMsi(foundDev->Bus, foundDev->Device, foundDev->Function)) { KernelLogStream(WARNING, "xHCI") << "MSI not available, using poll mode"; + g_pollMode = true; } // ----------------------------------------------------------------- diff --git a/kernel/src/Efi/UEFI.hpp b/kernel/src/Efi/UEFI.hpp index f51d802..b15f6d6 100644 --- a/kernel/src/Efi/UEFI.hpp +++ b/kernel/src/Efi/UEFI.hpp @@ -276,6 +276,13 @@ namespace Efi { inline EFI_RESET_SYSTEM g_ResetSystem = nullptr; inline void Init(SystemTable* ST, const montauk::boot::EfiInfo& efi) { + /* The system table and the runtime regions are firmware-reserved + memory, which the HHDM does not cover on every architecture: + map them (identity and HHDM) before the first access. */ + if (Memory::VMM::g_paging) { + Memory::VMM::g_paging->MapEfiRuntime(efi); + } + Kt::KernelLogStream(Kt::OK, "UEFI") << "ST Minor Revision: " << ST->Header.Revision.MinorRevision; Kt::KernelLogStream(Kt::OK, "UEFI") << "ST Major Revision: " << ST->Header.Revision.MajorRevision; @@ -284,12 +291,6 @@ namespace Efi { if (ST->RuntimeServices != nullptr) { Kt::KernelLogStream(Kt::OK, "UEFI") << "EFI Runtime Service API is available."; - /* Identity-map EFI runtime service regions so firmware code - can reference its own data at physical addresses */ - if (Memory::VMM::g_paging) { - Memory::VMM::g_paging->MapEfiRuntime(efi); - } - EFI_TIME Time; EFI_TIME_CAPABILITIES TimeCapabilities; diff --git a/kernel/src/Sched/ElfLoader.cpp b/kernel/src/Sched/ElfLoader.cpp index 6faf8e5..ed441a3 100644 --- a/kernel/src/Sched/ElfLoader.cpp +++ b/kernel/src/Sched/ElfLoader.cpp @@ -528,6 +528,7 @@ namespace Sched { Fs::Vfs::CloseBackendFile(file); return 0; } + Arch::SyncInstructionCache(page, 0x1000); } } @@ -718,6 +719,7 @@ namespace Sched { uint8_t* dst = (uint8_t*)Memory::HHDM(physAddr) + pageDataOffset; uint8_t* src = fileData + srcOffset; memcpy(dst, src, copySize); + Arch::SyncInstructionCache(dst, copySize); } } } diff --git a/kernel/src/Sched/Scheduler.cpp b/kernel/src/Sched/Scheduler.cpp index 300e899..a726b5a 100644 --- a/kernel/src/Sched/Scheduler.cpp +++ b/kernel/src/Sched/Scheduler.cpp @@ -442,6 +442,7 @@ namespace Sched { // User code that calls SYS_EXIT(0) Arch::WriteExitStub((uint8_t*)stubPage); + Arch::SyncInstructionCache(stubPage, 0x1000); } // Returning from the entry function lands in the exit stub. diff --git a/programs/GNUmakefile b/programs/GNUmakefile index 9237c36..bdba443 100644 --- a/programs/GNUmakefile +++ b/programs/GNUmakefile @@ -2,20 +2,19 @@ MAKEFLAGS += -rR .SUFFIXES: -# Target architecture. -ARCH := x86_64 +# Target architecture (ARCH=x86_64 or aarch64) and the cross compiler +# from toolchain/local/. +include mk/arch.mk -# Auto-detect cross compiler from toolchain/local/. -TOOLCHAIN_PREFIX := $(shell cd .. && pwd)/toolchain/local/bin/x86_64-montauk- ifeq ($(wildcard $(TOOLCHAIN_PREFIX)gcc),) - CXX = $(error x86_64-montauk toolchain not found. Run ./toolchain/build-montauk-toolchain.sh first) - CC = $(error x86_64-montauk toolchain not found. Run ./toolchain/build-montauk-toolchain.sh first) + CXX = $(error $(TOOLCHAIN_MISSING)) + CC = $(error $(TOOLCHAIN_MISSING)) else CXX := $(TOOLCHAIN_PREFIX)g++ CC := $(TOOLCHAIN_PREFIX)gcc endif -# Compiler flags. The x86_64-montauk toolchain supplies the target ABI +# Compiler flags. The -montauk toolchain supplies the target ABI # (static ET_EXEC, 4 KiB pages, no red zone) and header paths; system # programs additionally avoid FP/SIMD and their own runtime (-nostdlib). override CXXFLAGS := \ @@ -30,10 +29,7 @@ override CXXFLAGS := \ -fno-exceptions \ -ffunction-sections \ -fdata-sections \ - -mno-80387 \ - -mno-mmx \ - -mno-sse \ - -mno-sse2 \ + $(ARCH_NOFP_FLAGS) \ -I include # Linker flags: freestanding static ELF. @@ -43,7 +39,7 @@ override LDFLAGS := \ -T link.ld # Output directory. -BINDIR := bin +BINDIR := bin$(ARCH_SUFFIX) # Discover all programs (each subdirectory under src/ is a program). PROGRAMS := $(notdir $(wildcard src/*)) @@ -98,18 +94,34 @@ WPDST := $(patsubst $(WPDIR)/%,$(BINDIR)/os/wallpapers/%,$(WPSRC)) .PHONY: all clean 2048 files settings fetch wiki wikipedia weather imageviewer fontpreview spreadsheet wordprocessor pdfviewer disks devexplorer installer audio music video bluetooth network display capabilities keyboard sshserver sshd terminal syslog procmgr powermgr calculator charmap login desktop shell paint tcc lua screenshot texteditor mandelbrot printers timezone printd printctl dialogs icons fonts configs osdata bearssl libc tls libjpeg libjpegwrite install-apps libloader crashpad rtlsdr sdr check-syscalls gen-syscalls rust -all: bearssl libc libjpeg libjpegwrite tls libloader rtlsdr sdr devkit $(TARGETS) files settings fetch wiki wikipedia weather imageviewer fontpreview spreadsheet wordprocessor pdfviewer disks devexplorer installer audio music video bluetooth network display capabilities sshserver terminal syslog procmgr powermgr calculator charmap 2048 paint tcc lua screenshot texteditor mandelbrot printers timezone printd printctl dialogs login desktop shell sshd icons fonts install-apps crashpad rust $(MANDST) $(WWWDST) $(CA_CERTS) $(CONFIGDST) $(OSDATADST) $(FWDST) $(LICDST) $(WPDST) +# The on-OS SDK, tcc (an x86 code generator) and the Rust programs exist +# for x86_64 only. +ifneq ($(ARCH),x86_64) + ARCH_SKIP := devkit tcc rust +endif + +ALL_TARGETS := bearssl libc libjpeg libjpegwrite tls libloader rtlsdr sdr devkit $(TARGETS) files settings fetch wiki wikipedia weather imageviewer fontpreview spreadsheet wordprocessor pdfviewer disks devexplorer installer audio music video bluetooth network display capabilities sshserver terminal syslog procmgr powermgr calculator charmap 2048 paint tcc lua screenshot texteditor mandelbrot printers timezone printd printctl dialogs login desktop shell sshd icons fonts install-apps crashpad rust $(MANDST) $(WWWDST) $(CA_CERTS) $(CONFIGDST) $(OSDATADST) $(FWDST) $(LICDST) $(WPDST) + +all: $(filter-out $(ARCH_SKIP),$(ALL_TARGETS)) # Build BearSSL static library (cross-compiled for freestanding x86_64). -BEARSSL_INCLUDES := -isystem $(shell cd .. && pwd)/kernel/freestnd-c-hdrs/x86_64/include -isystem $(abspath include/libc) +BEARSSL_INCLUDES := -isystem $(shell cd .. && pwd)/kernel/freestnd-c-hdrs/$(ARCH)/include -isystem $(abspath include/libc) +ifeq ($(ARCH),x86_64) + BEARSSL_ARCH_FLAGS := -m64 -march=x86-64 -mno-80387 -mno-mmx -mno-red-zone -mcmodel=small +else + BEARSSL_ARCH_FLAGS := $(ARCH_CFLAGS) +endif +BEARSSL_LIB := lib/bearssl/build$(ARCH_SUFFIX)/libbearssl.a -lib/bearssl/build/libbearssl.a: +$(BEARSSL_LIB): $(MAKE) -C lib/bearssl CONF=MontaukOS \ BEARSSL_CC="$(CC)" \ BEARSSL_AR="$(TOOLCHAIN_PREFIX)ar" \ + BUILD=build$(ARCH_SUFFIX) \ + BEARSSL_ARCH_FLAGS="$(BEARSSL_ARCH_FLAGS)" \ BEARSSL_INCLUDES="$(BEARSSL_INCLUDES)" -bearssl: lib/bearssl/build/libbearssl.a +bearssl: $(BEARSSL_LIB) # Build shared libc static library. # @@ -120,11 +132,12 @@ bearssl: lib/bearssl/build/libbearssl.a # under -j and silently leaves programs linked against a stale libc. # Grouped target (&:, GNU make 4.3+): one sub-make produces all of them. LIBC_DIR := lib/libc -LIBC_LIB := $(LIBC_DIR)/liblibc.a +LIBC_LIB := $(LIBC_DIR)/$(ARCH_OUT)liblibc.a LIBC_SRCS := $(wildcard $(LIBC_DIR)/*.c $(LIBC_DIR)/*.h $(LIBC_DIR)/*.S \ $(LIBC_DIR)/crt/*.c) $(LIBC_DIR)/Makefile -LIBC_OUTPUTS := $(LIBC_LIB) $(LIBC_DIR)/liblibc-full.a \ - $(LIBC_DIR)/crt1.o $(LIBC_DIR)/crti.o $(LIBC_DIR)/crtn.o +LIBC_OUTPUTS := $(LIBC_LIB) $(LIBC_DIR)/$(ARCH_OUT)liblibc-full.a \ + $(LIBC_DIR)/$(ARCH_OUT)crt1.o $(LIBC_DIR)/$(ARCH_OUT)crti.o \ + $(LIBC_DIR)/$(ARCH_OUT)crtn.o $(LIBC_OUTPUTS) &: $(LIBC_SRCS) $(MAKE) -C $(LIBC_DIR) @@ -282,7 +295,7 @@ login: bearssl libc $(MAKE) -C src/login # Build shell via its own Makefile (multi-file build). -shell: +shell: libc $(MAKE) -C src/shell # Build desktop via its own Makefile (depends on libc, libjpeg, bearssl for user.h, dialogs, and registry config files). @@ -291,11 +304,11 @@ desktop: libc libjpeg bearssl libloader dialogs configs # Copy SVG icons for the desktop into bin/os/icons/. icons: - ../scripts/copy_icons.sh + PROGRAMS_BIN=$(BINDIR) ../scripts/copy_icons.sh # Copy TTF fonts for the desktop into bin/os/fonts/. fonts: - ../scripts/copy_fonts.sh + PROGRAMS_BIN=$(BINDIR) ../scripts/copy_fonts.sh # Copy default system config files into bin/config/. configs: $(CONFIGDST) @@ -400,7 +413,7 @@ crashpad: libc # Install app bundles (manifests, icons, data files) into bin/apps//. install-apps: 2048 files settings paint spreadsheet wordprocessor weather wikipedia imageviewer fontpreview pdfviewer disks devexplorer installer audio music video bluetooth network display capabilities keyboard sshserver terminal syslog procmgr powermgr calculator charmap screenshot texteditor mandelbrot printers timezone crashpad - ../scripts/install_apps.sh + PROGRAMS_BIN=$(BINDIR) ../scripts/install_apps.sh # Copy man pages into bin/os/man/ so mkramdisk.sh picks them up. $(BINDIR)/os/man/%: $(MANDIR)/% @@ -446,14 +459,16 @@ $(BINDIR)/os/wallpapers/%: $(WPDIR)/% # (montauk/capabilities.h, Api/Syscall.hpp, ...) rebuilds every program that # uses it. A missing depfile matches the empty rule below, which forces a # rebuild; that is how programs built before this tracking existed catch up. -$(BINDIR)/os/%.elf: src/%/main.cpp link.ld GNUmakefile $(LIBC_LIB) obj/%/main.elf.d - mkdir -p $(BINDIR)/os obj/$* - $(CXX) $(CXXFLAGS) -MMD -MP -MT $@ -MF obj/$*/main.elf.d -c src/$*/main.cpp -o obj/$*/main.o - $(CXX) $(CXXFLAGS) $(LDFLAGS) obj/$*/main.o $(LIBC_LIB) -o $@ +OBJ := obj$(ARCH_SUFFIX) -obj/%/main.elf.d: ; -.PRECIOUS: obj/%/main.elf.d --include $(wildcard obj/*/main.elf.d) +$(BINDIR)/os/%.elf: src/%/main.cpp link.ld GNUmakefile $(LIBC_LIB) $(OBJ)/%/main.elf.d + mkdir -p $(BINDIR)/os $(OBJ)/$* + $(CXX) $(CXXFLAGS) -MMD -MP -MT $@ -MF $(OBJ)/$*/main.elf.d -c src/$*/main.cpp -o $(OBJ)/$*/main.o + $(CXX) $(CXXFLAGS) $(LDFLAGS) $(OBJ)/$*/main.o $(LIBC_LIB) -o $@ + +$(OBJ)/%/main.elf.d: ; +.PRECIOUS: $(OBJ)/%/main.elf.d +-include $(wildcard $(OBJ)/*/main.elf.d) # ============================================================================ # Native development kit (Montauk SDK): binutils built for MontaukOS @@ -524,7 +539,7 @@ else endif clean: - rm -rf $(BINDIR) obj $(RUST_DIR)/target + rm -rf $(BINDIR) $(OBJ) $(RUST_DIR)/target $(MAKE) -C lib/bearssl clean $(MAKE) -C lib/libc clean $(MAKE) -C lib/libjpeg clean diff --git a/programs/include/gui/framebuffer.hpp b/programs/include/gui/framebuffer.hpp index afb94ec..31f6b53 100644 --- a/programs/include/gui/framebuffer.hpp +++ b/programs/include/gui/framebuffer.hpp @@ -13,6 +13,18 @@ namespace gui { +// Drain write-combining stores to the scanout buffer before it is flipped +// or composited by someone else. +inline void wc_store_fence() { +#if defined(__x86_64__) + asm volatile("sfence" ::: "memory"); +#elif defined(__aarch64__) + asm volatile("dsb st" ::: "memory"); +#else +#error "unsupported architecture" +#endif +} + class Framebuffer { uint32_t* hw_fb; uint32_t* hw_fb2; // second scanout buffer (page flip), nullptr if unsupported @@ -322,12 +334,12 @@ public: montauk::memcpy(mirror, src, row_bytes); } } - if (hw_mirror) asm volatile("sfence" ::: "memory"); + if (hw_mirror) wc_store_fence(); if (hw_fb2) { // Wait for the latch (vsync): the buffer we just left becomes // safe to draw into only once the new one is actually scanning. - asm volatile("sfence" ::: "memory"); + wc_store_fence(); int64_t presented = montauk::fb_flip(hw_next, 1); if (presented == hw_next) { hw_next ^= 1; @@ -359,7 +371,7 @@ public: montauk::memcpy(mirror, src, row_bytes); } } - asm volatile("sfence" ::: "memory"); + wc_store_fence(); } } } diff --git a/programs/include/libc/montauk.h b/programs/include/libc/montauk.h index 44456a2..93a7a76 100644 --- a/programs/include/libc/montauk.h +++ b/programs/include/libc/montauk.h @@ -419,6 +419,8 @@ typedef struct { Raw syscall wrappers ==================================================================== */ +#if defined(__x86_64__) + static inline long _mtk_syscall0(long nr) { long ret; __asm__ volatile("syscall" : "=a"(ret) : "a"(nr) @@ -491,6 +493,66 @@ static inline long _mtk_syscall5(long nr, long a1, long a2, long a3, long a4, lo return ret; } +#elif defined(__aarch64__) + +// AArch64: number in x8, arguments in x0-x5, `svc #0`; the kernel +// preserves every register except x0, which carries the result. +static inline long _mtk_syscall0(long nr) { + register long x8 __asm__("x8") = nr; + register long x0 __asm__("x0"); + __asm__ volatile("svc #0" : "=r"(x0) : "r"(x8) : "memory"); + return x0; +} + +static inline long _mtk_syscall1(long nr, long a1) { + register long x8 __asm__("x8") = nr; + register long x0 __asm__("x0") = a1; + __asm__ volatile("svc #0" : "+r"(x0) : "r"(x8) : "memory"); + return x0; +} + +static inline long _mtk_syscall2(long nr, long a1, long a2) { + register long x8 __asm__("x8") = nr; + register long x0 __asm__("x0") = a1; + register long x1 __asm__("x1") = a2; + __asm__ volatile("svc #0" : "+r"(x0) : "r"(x8), "r"(x1) : "memory"); + return x0; +} + +static inline long _mtk_syscall3(long nr, long a1, long a2, long a3) { + register long x8 __asm__("x8") = nr; + register long x0 __asm__("x0") = a1; + register long x1 __asm__("x1") = a2; + register long x2 __asm__("x2") = a3; + __asm__ volatile("svc #0" : "+r"(x0) : "r"(x8), "r"(x1), "r"(x2) : "memory"); + return x0; +} + +static inline long _mtk_syscall4(long nr, long a1, long a2, long a3, long a4) { + register long x8 __asm__("x8") = nr; + register long x0 __asm__("x0") = a1; + register long x1 __asm__("x1") = a2; + register long x2 __asm__("x2") = a3; + register long x3 __asm__("x3") = a4; + __asm__ volatile("svc #0" : "+r"(x0) : "r"(x8), "r"(x1), "r"(x2), "r"(x3) : "memory"); + return x0; +} + +static inline long _mtk_syscall5(long nr, long a1, long a2, long a3, long a4, long a5) { + register long x8 __asm__("x8") = nr; + register long x0 __asm__("x0") = a1; + register long x1 __asm__("x1") = a2; + register long x2 __asm__("x2") = a3; + register long x3 __asm__("x3") = a4; + register long x4 __asm__("x4") = a5; + __asm__ volatile("svc #0" : "+r"(x0) : "r"(x8), "r"(x1), "r"(x2), "r"(x3), "r"(x4) : "memory"); + return x0; +} + +#else +#error "unsupported architecture" +#endif + /* ==================================================================== Process management ==================================================================== */ diff --git a/programs/include/libc/setjmp.h b/programs/include/libc/setjmp.h index 9933b25..2da46f2 100644 --- a/programs/include/libc/setjmp.h +++ b/programs/include/libc/setjmp.h @@ -7,7 +7,11 @@ extern "C" { #endif -typedef unsigned long jmp_buf[8]; +#if defined(__aarch64__) +typedef unsigned long jmp_buf[21]; /* x19-x30, sp, d8-d15 */ +#else +typedef unsigned long jmp_buf[8]; /* rbx, rbp, r12-r15, rsp, rip */ +#endif int setjmp(jmp_buf env); void longjmp(jmp_buf env, int val) __attribute__((noreturn)); diff --git a/programs/include/montauk/syscall.h b/programs/include/montauk/syscall.h index 0411a8a..917c350 100644 --- a/programs/include/montauk/syscall.h +++ b/programs/include/montauk/syscall.h @@ -1,6 +1,6 @@ /* * syscall.h - * MontaukOS program-side syscall wrappers using SYSCALL instruction + * MontaukOS program-side syscall wrappers (x86_64 SYSCALL, AArch64 SVC) * Copyright (c) 2025 Daniel Hammer */ @@ -13,6 +13,8 @@ namespace montauk { // ---- Raw SYSCALL wrappers ---- +#if defined(__x86_64__) + // The SYSCALL handler does not restore RDI, RSI, RDX, R10, R8, R9 // (they are skipped on the return path). We move arguments into the // correct registers inside the asm block and list ALL argument @@ -108,6 +110,79 @@ namespace montauk { return ret; } +#elif defined(__aarch64__) + + // AArch64: number in x8, arguments in x0-x5, `svc #0`; the kernel + // preserves every register except x0, which carries the result. + + inline int64_t syscall0(uint64_t nr) { + register uint64_t x8 asm("x8") = nr; + register uint64_t x0 asm("x0"); + asm volatile("svc #0" : "=r"(x0) : "r"(x8) : "memory"); + return (int64_t)x0; + } + + inline int64_t syscall1(uint64_t nr, uint64_t a1) { + register uint64_t x8 asm("x8") = nr; + register uint64_t x0 asm("x0") = a1; + asm volatile("svc #0" : "+r"(x0) : "r"(x8) : "memory"); + return (int64_t)x0; + } + + inline int64_t syscall2(uint64_t nr, uint64_t a1, uint64_t a2) { + register uint64_t x8 asm("x8") = nr; + register uint64_t x0 asm("x0") = a1; + register uint64_t x1 asm("x1") = a2; + asm volatile("svc #0" : "+r"(x0) : "r"(x8), "r"(x1) : "memory"); + return (int64_t)x0; + } + + inline int64_t syscall3(uint64_t nr, uint64_t a1, uint64_t a2, uint64_t a3) { + register uint64_t x8 asm("x8") = nr; + register uint64_t x0 asm("x0") = a1; + register uint64_t x1 asm("x1") = a2; + register uint64_t x2 asm("x2") = a3; + asm volatile("svc #0" : "+r"(x0) : "r"(x8), "r"(x1), "r"(x2) : "memory"); + return (int64_t)x0; + } + + inline int64_t syscall4(uint64_t nr, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4) { + register uint64_t x8 asm("x8") = nr; + register uint64_t x0 asm("x0") = a1; + register uint64_t x1 asm("x1") = a2; + register uint64_t x2 asm("x2") = a3; + register uint64_t x3 asm("x3") = a4; + asm volatile("svc #0" : "+r"(x0) : "r"(x8), "r"(x1), "r"(x2), "r"(x3) : "memory"); + return (int64_t)x0; + } + + inline int64_t syscall5(uint64_t nr, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5) { + register uint64_t x8 asm("x8") = nr; + register uint64_t x0 asm("x0") = a1; + register uint64_t x1 asm("x1") = a2; + register uint64_t x2 asm("x2") = a3; + register uint64_t x3 asm("x3") = a4; + register uint64_t x4 asm("x4") = a5; + asm volatile("svc #0" : "+r"(x0) : "r"(x8), "r"(x1), "r"(x2), "r"(x3), "r"(x4) : "memory"); + return (int64_t)x0; + } + + inline int64_t syscall6(uint64_t nr, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5, uint64_t a6) { + register uint64_t x8 asm("x8") = nr; + register uint64_t x0 asm("x0") = a1; + register uint64_t x1 asm("x1") = a2; + register uint64_t x2 asm("x2") = a3; + register uint64_t x3 asm("x3") = a4; + register uint64_t x4 asm("x4") = a5; + register uint64_t x5 asm("x5") = a6; + asm volatile("svc #0" : "+r"(x0) : "r"(x8), "r"(x1), "r"(x2), "r"(x3), "r"(x4), "r"(x5) : "memory"); + return (int64_t)x0; + } + +#else +#error "unsupported architecture" +#endif + // ---- Typed wrappers ---- // Process diff --git a/programs/lib/libc/Makefile b/programs/lib/libc/Makefile index 2f3b0fd..17966b3 100644 --- a/programs/lib/libc/Makefile +++ b/programs/lib/libc/Makefile @@ -6,7 +6,7 @@ MAKEFLAGS += -rR # ---- Toolchain ---- -TOOLCHAIN_PREFIX := $(shell cd ../../.. && pwd)/toolchain/local/bin/x86_64-montauk- +include ../../mk/arch.mk ifneq ($(wildcard $(TOOLCHAIN_PREFIX)gcc),) CC := $(TOOLCHAIN_PREFIX)gcc AR := $(TOOLCHAIN_PREFIX)ar @@ -20,7 +20,7 @@ endif # ---- Paths ---- LIBC_INC := ../../include/libc -OBJDIR := obj +OBJDIR := obj$(ARCH_SUFFIX) CRTDIR := crt ASM_OBJS := $(OBJDIR)/setjmp.o @@ -38,12 +38,8 @@ CFLAGS := \ -fno-PIC \ -ffunction-sections \ -fdata-sections \ - -m64 \ - -march=x86-64 \ - -msse \ - -msse2 \ - -mno-red-zone \ - -mcmodel=small \ + $(ARCH_CFLAGS) \ + $(ARCH_FP_FLAGS) \ -isystem $(LIBC_INC) \ -isystem $(shell $(CC) -print-file-name=include) @@ -55,18 +51,16 @@ CRT_CFLAGS := \ -fno-stack-protector \ -fno-stack-check \ -fno-PIC \ - -m64 \ - -march=x86-64 \ - -mno-red-zone \ + $(ARCH_CFLAGS) \ -fno-tree-loop-distribute-patterns \ -isystem $(LIBC_INC) \ -isystem $(shell $(CC) -print-file-name=include) # ---- Target ---- -TARGET := liblibc.a -SDK_TARGET := liblibc-full.a -CRT_OBJS := crt1.o crti.o crtn.o +TARGET := $(ARCH_OUT)liblibc.a +SDK_TARGET := $(ARCH_OUT)liblibc-full.a +CRT_OBJS := $(ARCH_OUT)crt1.o $(ARCH_OUT)crti.o $(ARCH_OUT)crtn.o .PHONY: all clean @@ -77,6 +71,7 @@ all: $(TARGET) $(SDK_TARGET) $(CRT_OBJS) # a float leave the decimal-conversion and pow/exp/log code behind. Programs # that do need %e/%f/%g must link with -Wl,-u,_pf_putfloat to force it in. $(TARGET): $(OBJDIR)/libc.o $(OBJDIR)/printf_float.o $(ASM_OBJS) + @mkdir -p $(dir $@) $(AR) rcs $@ $^ $(OBJDIR)/libc.o: libc.c printf_internal.h Makefile @@ -87,7 +82,7 @@ $(OBJDIR)/printf_float.o: printf_float.c printf_internal.h Makefile @mkdir -p $(OBJDIR) $(CC) $(CFLAGS) -c $< -o $@ -$(OBJDIR)/setjmp.o: setjmp.S Makefile +$(OBJDIR)/setjmp.o: arch/setjmp-$(ARCH).S Makefile @mkdir -p $(OBJDIR) $(CC) $(CFLAGS) -c $< -o $@ @@ -97,18 +92,22 @@ $(OBJDIR)/setjmp.o: setjmp.S Makefile # compiled ON MontaukOS. Function-level --gc-sections still applies to the # rest; only the float path is pinned. Image size is not a concern here. $(SDK_TARGET): $(OBJDIR)/libc-merged.o $(ASM_OBJS) + @mkdir -p $(dir $@) $(AR) rcs $@ $^ $(OBJDIR)/libc-merged.o: $(OBJDIR)/libc.o $(OBJDIR)/printf_float.o $(LD) -r -o $@ $(OBJDIR)/libc.o $(OBJDIR)/printf_float.o -crt1.o: $(CRTDIR)/crt1.c Makefile +$(ARCH_OUT)crt1.o: $(CRTDIR)/crt1.c Makefile + @mkdir -p $(dir $@) $(CC) $(CRT_CFLAGS) -c $< -o $@ -crti.o: $(CRTDIR)/crti.c Makefile +$(ARCH_OUT)crti.o: $(CRTDIR)/crti.c Makefile + @mkdir -p $(dir $@) $(CC) $(CRT_CFLAGS) -c $< -o $@ -crtn.o: $(CRTDIR)/crtn.c Makefile +$(ARCH_OUT)crtn.o: $(CRTDIR)/crtn.c Makefile + @mkdir -p $(dir $@) $(CC) $(CRT_CFLAGS) -c $< -o $@ clean: diff --git a/programs/lib/libc/arch/setjmp-aarch64.S b/programs/lib/libc/arch/setjmp-aarch64.S new file mode 100644 index 0000000..a5c779b --- /dev/null +++ b/programs/lib/libc/arch/setjmp-aarch64.S @@ -0,0 +1,49 @@ +/* + * setjmp-aarch64.S + * setjmp/longjmp for AArch64 MontaukOS userspace + * Copyright (c) 2026 Daniel Hammer +*/ + +/* jmp_buf: x19-x28, x29 (fp), x30 (lr), sp, d8-d15 -- everything AAPCS64 + requires a callee to preserve. */ + +.text + +.global setjmp +.type setjmp, %function +setjmp: + stp x19, x20, [x0, #0] + stp x21, x22, [x0, #16] + stp x23, x24, [x0, #32] + stp x25, x26, [x0, #48] + stp x27, x28, [x0, #64] + stp x29, x30, [x0, #80] + mov x2, sp + str x2, [x0, #96] + stp d8, d9, [x0, #104] + stp d10, d11, [x0, #120] + stp d12, d13, [x0, #136] + stp d14, d15, [x0, #152] + mov w0, #0 + ret +.size setjmp, . - setjmp + +.global longjmp +.type longjmp, %function +longjmp: + ldp x19, x20, [x0, #0] + ldp x21, x22, [x0, #16] + ldp x23, x24, [x0, #32] + ldp x25, x26, [x0, #48] + ldp x27, x28, [x0, #64] + ldp x29, x30, [x0, #80] + ldr x2, [x0, #96] + mov sp, x2 + ldp d8, d9, [x0, #104] + ldp d10, d11, [x0, #120] + ldp d12, d13, [x0, #136] + ldp d14, d15, [x0, #152] + cmp w1, #0 + csinc w0, w1, wzr, ne + ret +.size longjmp, . - longjmp diff --git a/programs/lib/libc/setjmp.S b/programs/lib/libc/arch/setjmp-x86_64.S similarity index 100% rename from programs/lib/libc/setjmp.S rename to programs/lib/libc/arch/setjmp-x86_64.S diff --git a/programs/lib/libc/crt/crt1.c b/programs/lib/libc/crt/crt1.c index f23743b..88ea88d 100644 --- a/programs/lib/libc/crt/crt1.c +++ b/programs/lib/libc/crt/crt1.c @@ -8,6 +8,8 @@ * calls main(), then exits with main()'s return code. */ +#if defined(__x86_64__) + static inline long _sys1(long nr, long a1) { long ret; __asm__ volatile( @@ -31,6 +33,27 @@ static inline long _sys2(long nr, long a1, long a2) { return ret; } +#elif defined(__aarch64__) + +static inline long _sys1(long nr, long a1) { + register long x8 __asm__("x8") = nr; + register long x0 __asm__("x0") = a1; + __asm__ volatile("svc #0" : "+r"(x0) : "r"(x8) : "memory"); + return x0; +} + +static inline long _sys2(long nr, long a1, long a2) { + register long x8 __asm__("x8") = nr; + register long x0 __asm__("x0") = a1; + register long x1 __asm__("x1") = a2; + __asm__ volatile("svc #0" : "+r"(x0) : "r"(x8), "r"(x1) : "memory"); + return x0; +} + +#else +#error "unsupported architecture" +#endif + #define SYS_EXIT 0 #define SYS_GETARGS 25 #define SYS_GETEXECPATH 151 diff --git a/programs/lib/libc/libc.c b/programs/lib/libc/libc.c index c7137b9..2166fa5 100644 --- a/programs/lib/libc/libc.c +++ b/programs/lib/libc/libc.c @@ -32,6 +32,8 @@ Raw syscall wrappers (C versions matching kernel ABI) ======================================================================== */ +#if defined(__x86_64__) + static inline long _mtk_syscall0(long nr) { long ret; __asm__ volatile("syscall" : "=a"(ret) : "a"(nr) @@ -89,6 +91,55 @@ static inline long _mtk_syscall4(long nr, long a1, long a2, long a3, long a4) { return ret; } +#elif defined(__aarch64__) + +// AArch64: number in x8, arguments in x0-x5, `svc #0`; the kernel +// preserves every register except x0, which carries the result. +static inline long _mtk_syscall0(long nr) { + register long x8 __asm__("x8") = nr; + register long x0 __asm__("x0"); + __asm__ volatile("svc #0" : "=r"(x0) : "r"(x8) : "memory"); + return x0; +} + +static inline long _mtk_syscall1(long nr, long a1) { + register long x8 __asm__("x8") = nr; + register long x0 __asm__("x0") = a1; + __asm__ volatile("svc #0" : "+r"(x0) : "r"(x8) : "memory"); + return x0; +} + +static inline long _mtk_syscall2(long nr, long a1, long a2) { + register long x8 __asm__("x8") = nr; + register long x0 __asm__("x0") = a1; + register long x1 __asm__("x1") = a2; + __asm__ volatile("svc #0" : "+r"(x0) : "r"(x8), "r"(x1) : "memory"); + return x0; +} + +static inline long _mtk_syscall3(long nr, long a1, long a2, long a3) { + register long x8 __asm__("x8") = nr; + register long x0 __asm__("x0") = a1; + register long x1 __asm__("x1") = a2; + register long x2 __asm__("x2") = a3; + __asm__ volatile("svc #0" : "+r"(x0) : "r"(x8), "r"(x1), "r"(x2) : "memory"); + return x0; +} + +static inline long _mtk_syscall4(long nr, long a1, long a2, long a3, long a4) { + register long x8 __asm__("x8") = nr; + register long x0 __asm__("x0") = a1; + register long x1 __asm__("x1") = a2; + register long x2 __asm__("x2") = a3; + register long x3 __asm__("x3") = a4; + __asm__ volatile("svc #0" : "+r"(x0) : "r"(x8), "r"(x1), "r"(x2), "r"(x3) : "memory"); + return x0; +} + +#else +#error "unsupported architecture" +#endif + /* Syscall numbers */ #define SYS_EXIT 0 #define SYS_YIELD 1 diff --git a/programs/lib/libjpeg/Makefile b/programs/lib/libjpeg/Makefile index 7c499f0..a92b869 100644 --- a/programs/lib/libjpeg/Makefile +++ b/programs/lib/libjpeg/Makefile @@ -6,7 +6,7 @@ MAKEFLAGS += -rR # ---- Toolchain ---- -TOOLCHAIN_PREFIX := $(shell cd ../../.. && pwd)/toolchain/local/bin/x86_64-montauk- +include ../../mk/arch.mk ifneq ($(wildcard $(TOOLCHAIN_PREFIX)gcc),) CC := $(TOOLCHAIN_PREFIX)gcc AR := $(TOOLCHAIN_PREFIX)ar @@ -19,8 +19,7 @@ endif LIBC_INC := ../../include/libc PROG_INC := ../../include -OBJDIR := obj - +OBJDIR := obj$(ARCH_SUFFIX) # ---- Compiler flags ---- CFLAGS := \ @@ -36,25 +35,22 @@ CFLAGS := \ -fno-PIC \ -ffunction-sections \ -fdata-sections \ - -m64 \ - -march=x86-64 \ - -msse \ - -msse2 \ - -mno-red-zone \ - -mcmodel=small \ + $(ARCH_CFLAGS) \ + $(ARCH_FP_FLAGS) \ -I $(PROG_INC) \ -isystem $(LIBC_INC) \ -isystem $(shell $(CC) -print-file-name=include) # ---- Target ---- -TARGET := libjpeg.a +TARGET := $(ARCH_OUT)libjpeg.a .PHONY: all clean all: $(TARGET) $(TARGET): $(OBJDIR)/stb_image_impl.o + @mkdir -p $(dir $@) $(AR) rcs $@ $^ $(OBJDIR)/stb_image_impl.o: stb_image_impl.c Makefile diff --git a/programs/lib/libjpeg/libjpeg.a b/programs/lib/libjpeg/libjpeg.a index df67214..4ac9d42 100644 Binary files a/programs/lib/libjpeg/libjpeg.a and b/programs/lib/libjpeg/libjpeg.a differ diff --git a/programs/lib/libjpeg/obj/stb_image_impl.o b/programs/lib/libjpeg/obj/stb_image_impl.o index a57bd24..54aaebf 100644 Binary files a/programs/lib/libjpeg/obj/stb_image_impl.o and b/programs/lib/libjpeg/obj/stb_image_impl.o differ diff --git a/programs/lib/libjpegwrite/Makefile b/programs/lib/libjpegwrite/Makefile index a2b1a7b..2471fef 100644 --- a/programs/lib/libjpegwrite/Makefile +++ b/programs/lib/libjpegwrite/Makefile @@ -6,7 +6,7 @@ MAKEFLAGS += -rR # ---- Toolchain ---- -TOOLCHAIN_PREFIX := $(shell cd ../../.. && pwd)/toolchain/local/bin/x86_64-montauk- +include ../../mk/arch.mk ifneq ($(wildcard $(TOOLCHAIN_PREFIX)gcc),) CC := $(TOOLCHAIN_PREFIX)gcc AR := $(TOOLCHAIN_PREFIX)ar @@ -19,8 +19,7 @@ endif LIBC_INC := ../../include/libc PROG_INC := ../../include -OBJDIR := obj - +OBJDIR := obj$(ARCH_SUFFIX) # ---- Compiler flags ---- CFLAGS := \ @@ -37,25 +36,22 @@ CFLAGS := \ -ffunction-sections \ -fdata-sections \ -fno-tree-loop-distribute-patterns \ - -m64 \ - -march=x86-64 \ - -msse \ - -msse2 \ - -mno-red-zone \ - -mcmodel=small \ + $(ARCH_CFLAGS) \ + $(ARCH_FP_FLAGS) \ -I $(PROG_INC) \ -isystem $(LIBC_INC) \ -isystem $(shell $(CC) -print-file-name=include) # ---- Target ---- -TARGET := libjpegwrite.a +TARGET := $(ARCH_OUT)libjpegwrite.a .PHONY: all clean all: $(TARGET) $(TARGET): $(OBJDIR)/stb_image_write_impl.o + @mkdir -p $(dir $@) $(AR) rcs $@ $^ $(OBJDIR)/stb_image_write_impl.o: stb_image_write_impl.c Makefile diff --git a/programs/lib/libjpegwrite/libjpegwrite.a b/programs/lib/libjpegwrite/libjpegwrite.a index 5cba234..d57a384 100644 Binary files a/programs/lib/libjpegwrite/libjpegwrite.a and b/programs/lib/libjpegwrite/libjpegwrite.a differ diff --git a/programs/lib/libjpegwrite/obj/stb_image_write_impl.o b/programs/lib/libjpegwrite/obj/stb_image_write_impl.o index d52704d..2f815bf 100644 Binary files a/programs/lib/libjpegwrite/obj/stb_image_write_impl.o and b/programs/lib/libjpegwrite/obj/stb_image_write_impl.o differ diff --git a/programs/lib/tls/Makefile b/programs/lib/tls/Makefile index 4a1bc5b..9375f76 100644 --- a/programs/lib/tls/Makefile +++ b/programs/lib/tls/Makefile @@ -6,7 +6,7 @@ MAKEFLAGS += -rR # ---- Toolchain ---- -TOOLCHAIN_PREFIX := $(shell cd ../../.. && pwd)/toolchain/local/bin/x86_64-montauk- +include ../../mk/arch.mk ifneq ($(wildcard $(TOOLCHAIN_PREFIX)gcc),) CXX := $(TOOLCHAIN_PREFIX)g++ AR := $(TOOLCHAIN_PREFIX)ar @@ -20,8 +20,7 @@ endif BEARSSL := ../bearssl LIBC_INC := ../../include/libc PROG_INC := ../../include -OBJDIR := obj - +OBJDIR := obj$(ARCH_SUFFIX) # ---- Compiler flags ---- CXXFLAGS := \ @@ -39,29 +38,24 @@ CXXFLAGS := \ -fno-exceptions \ -ffunction-sections \ -fdata-sections \ - -m64 \ - -march=x86-64 \ - -mno-80387 \ - -mno-mmx \ - -mno-sse \ - -mno-sse2 \ - -mno-red-zone \ - -mcmodel=small \ + $(ARCH_CFLAGS) \ + $(ARCH_NOFP_FLAGS) \ -I $(PROG_INC) \ -isystem $(LIBC_INC) \ -I $(BEARSSL)/inc \ - -isystem ../../../kernel/freestnd-c-hdrs/x86_64/include \ - -isystem ../../../kernel/freestnd-cxx-hdrs/x86_64/include + -isystem ../../../kernel/freestnd-c-hdrs/$(ARCH)/include \ + -isystem ../../../kernel/freestnd-cxx-hdrs/$(ARCH)/include # ---- Target ---- -TARGET := libtls.a +TARGET := $(ARCH_OUT)libtls.a .PHONY: all clean all: $(TARGET) $(TARGET): $(OBJDIR)/tls.o + @mkdir -p $(dir $@) $(AR) rcs $@ $^ $(OBJDIR)/tls.o: tls.cpp Makefile diff --git a/programs/lib/tls/libtls.a b/programs/lib/tls/libtls.a index adbb377..b9f9e88 100644 Binary files a/programs/lib/tls/libtls.a and b/programs/lib/tls/libtls.a differ diff --git a/programs/lib/tls/obj/tls.o b/programs/lib/tls/obj/tls.o index 5eccf5d..c1198fa 100644 Binary files a/programs/lib/tls/obj/tls.o and b/programs/lib/tls/obj/tls.o differ diff --git a/programs/link.ld b/programs/link.ld index 6612f42..4478f0e 100644 --- a/programs/link.ld +++ b/programs/link.ld @@ -3,11 +3,10 @@ * Linker script for MontaukOS userspace programs * Copyright (c) 2025 Daniel Hammer * - * Programs are loaded at a standard user-space address. + * Programs are loaded at a standard user-space address. The output + * format is the toolchain's default (x86_64-montauk or aarch64-montauk). */ -OUTPUT_FORMAT(elf64-x86-64) - ENTRY(_start) SECTIONS diff --git a/programs/mk/arch.mk b/programs/mk/arch.mk new file mode 100644 index 0000000..400f57f --- /dev/null +++ b/programs/mk/arch.mk @@ -0,0 +1,43 @@ +# arch.mk - Target architecture settings shared by every userspace Makefile +# Copyright (c) 2026 Daniel Hammer +# +# Included by programs/GNUmakefile and the per-program/per-library +# Makefiles. Pass ARCH=aarch64 (the top-level build does) to build for ARM. +# +# x86_64 keeps the historical layout: objects in obj/, programs in bin/, +# libraries next to their sources. Other architectures build side by side: +# obj-/, bin-/ and lib//build-/. + +ARCH ?= x86_64 + +ifeq ($(filter $(ARCH),x86_64 aarch64),) + $(error Unsupported ARCH '$(ARCH)' for userspace) +endif + +MONTAUK_ROOT := $(abspath $(dir $(lastword $(MAKEFILE_LIST)))/../..) + +ifeq ($(ARCH),x86_64) + ARCH_SUFFIX := + ARCH_OUT := +else + ARCH_SUFFIX := -$(ARCH) + ARCH_OUT := build-$(ARCH)/ +endif + +TOOLCHAIN_PREFIX := $(MONTAUK_ROOT)/toolchain/local/bin/$(ARCH)-montauk- +TOOLCHAIN_MISSING := $(ARCH)-montauk toolchain not found. Run ./toolchain/build-montauk-toolchain.sh $(ARCH) first + +# ARCH_FP_FLAGS: programs that use floating point / SIMD (GUI apps) +# ARCH_NOFP_FLAGS: system programs that must not touch FP/SIMD registers +# ARCH_CFLAGS: code-model flags the libraries pass explicitly +ifeq ($(ARCH),x86_64) + ARCH_FP_FLAGS := -msse -msse2 + ARCH_NOFP_FLAGS := -mno-80387 -mno-mmx -mno-sse -mno-sse2 + ARCH_CFLAGS := -m64 -march=x86-64 -mno-red-zone -mcmodel=small + ARCH_LD_EMULATION := elf_x86_64 +else + ARCH_FP_FLAGS := + ARCH_NOFP_FLAGS := -mgeneral-regs-only + ARCH_CFLAGS := -mcmodel=small + ARCH_LD_EMULATION := aarch64elf +endif diff --git a/programs/src/2048/Makefile b/programs/src/2048/Makefile index b4d35dc..41be959 100644 --- a/programs/src/2048/Makefile +++ b/programs/src/2048/Makefile @@ -4,17 +4,17 @@ MAKEFLAGS += -rR .SUFFIXES: -TOOLCHAIN_PREFIX := $(shell cd ../../.. && pwd)/toolchain/local/bin/x86_64-montauk- +include ../../mk/arch.mk ifeq ($(wildcard $(TOOLCHAIN_PREFIX)gcc),) - CXX = $(error x86_64-montauk toolchain not found. Run ./toolchain/build-montauk-toolchain.sh first) + CXX = $(error $(TOOLCHAIN_MISSING)) else CXX := $(TOOLCHAIN_PREFIX)g++ endif PROG_INC := ../../include LINK_LD := ../../link.ld -BINDIR := ../../bin -OBJDIR := obj +BINDIR := ../../bin$(ARCH_SUFFIX) +OBJDIR := obj$(ARCH_SUFFIX) LIBDIR := ../../lib CXXFLAGS := \ @@ -31,8 +31,7 @@ CXXFLAGS := \ -fno-exceptions \ -ffunction-sections \ -fdata-sections \ - -msse \ - -msse2 \ + $(ARCH_FP_FLAGS) \ -MMD -MP \ -I $(PROG_INC) \ -isystem $(PROG_INC)/libc @@ -46,8 +45,8 @@ SRCS := main.cpp stb_truetype_impl.cpp OBJS := $(addprefix $(OBJDIR)/,$(SRCS:.cpp=.o)) TARGET := $(BINDIR)/apps/2048/2048.elf -LOADER_LIB := $(LIBDIR)/libloader/liblibloader.a -LIBC_LIB := $(LIBDIR)/libc/liblibc.a +LOADER_LIB := $(LIBDIR)/libloader/$(ARCH_OUT)liblibloader.a +LIBC_LIB := $(LIBDIR)/libc/$(ARCH_OUT)liblibc.a .PHONY: all clean diff --git a/programs/src/audio/Makefile b/programs/src/audio/Makefile index 429c286..3eb7ac5 100644 --- a/programs/src/audio/Makefile +++ b/programs/src/audio/Makefile @@ -6,9 +6,9 @@ MAKEFLAGS += -rR # ---- Toolchain ---- -TOOLCHAIN_PREFIX := $(shell cd ../../.. && pwd)/toolchain/local/bin/x86_64-montauk- +include ../../mk/arch.mk ifeq ($(wildcard $(TOOLCHAIN_PREFIX)gcc),) - CXX = $(error x86_64-montauk toolchain not found. Run ./toolchain/build-montauk-toolchain.sh first) + CXX = $(error $(TOOLCHAIN_MISSING)) else CXX := $(TOOLCHAIN_PREFIX)g++ endif @@ -17,8 +17,8 @@ endif PROG_INC := ../../include LINK_LD := ../../link.ld -BINDIR := ../../bin -OBJDIR := obj +BINDIR := ../../bin$(ARCH_SUFFIX) +OBJDIR := obj$(ARCH_SUFFIX) LIBDIR := ../../lib # ---- Compiler flags ---- @@ -37,8 +37,7 @@ CXXFLAGS := \ -fno-exceptions \ -ffunction-sections \ -fdata-sections \ - -msse \ - -msse2 \ + $(ARCH_FP_FLAGS) \ -I $(PROG_INC) \ -isystem $(PROG_INC)/libc @@ -62,9 +61,9 @@ TARGET := $(BINDIR)/apps/audio/audio.elf all: $(TARGET) -$(TARGET): $(OBJS) $(LINK_LD) Makefile $(LIBDIR)/libc/liblibc.a +$(TARGET): $(OBJS) $(LINK_LD) Makefile $(LIBDIR)/libc/$(ARCH_OUT)liblibc.a mkdir -p $(BINDIR)/apps/audio - $(CXX) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(LIBDIR)/libc/liblibc.a -o $@ + $(CXX) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(LIBDIR)/libc/$(ARCH_OUT)liblibc.a -o $@ $(OBJDIR)/%.o: %.cpp Makefile mkdir -p $(OBJDIR) diff --git a/programs/src/bluetooth/Makefile b/programs/src/bluetooth/Makefile index e1c1533..5dedb74 100644 --- a/programs/src/bluetooth/Makefile +++ b/programs/src/bluetooth/Makefile @@ -6,9 +6,9 @@ MAKEFLAGS += -rR # ---- Toolchain ---- -TOOLCHAIN_PREFIX := $(shell cd ../../.. && pwd)/toolchain/local/bin/x86_64-montauk- +include ../../mk/arch.mk ifeq ($(wildcard $(TOOLCHAIN_PREFIX)gcc),) - CXX = $(error x86_64-montauk toolchain not found. Run ./toolchain/build-montauk-toolchain.sh first) + CXX = $(error $(TOOLCHAIN_MISSING)) else CXX := $(TOOLCHAIN_PREFIX)g++ endif @@ -17,8 +17,8 @@ endif PROG_INC := ../../include LINK_LD := ../../link.ld -BINDIR := ../../bin -OBJDIR := obj +BINDIR := ../../bin$(ARCH_SUFFIX) +OBJDIR := obj$(ARCH_SUFFIX) LIBDIR := ../../lib # ---- Compiler flags ---- @@ -37,8 +37,7 @@ CXXFLAGS := \ -fno-exceptions \ -ffunction-sections \ -fdata-sections \ - -msse \ - -msse2 \ + $(ARCH_FP_FLAGS) \ -I $(PROG_INC) \ -isystem $(PROG_INC)/libc @@ -62,9 +61,9 @@ TARGET := $(BINDIR)/apps/bluetooth/bluetooth.elf all: $(TARGET) -$(TARGET): $(OBJS) $(LINK_LD) Makefile $(LIBDIR)/libc/liblibc.a +$(TARGET): $(OBJS) $(LINK_LD) Makefile $(LIBDIR)/libc/$(ARCH_OUT)liblibc.a mkdir -p $(BINDIR)/apps/bluetooth - $(CXX) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(LIBDIR)/libc/liblibc.a -o $@ + $(CXX) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(LIBDIR)/libc/$(ARCH_OUT)liblibc.a -o $@ $(OBJDIR)/%.o: %.cpp Makefile mkdir -p $(OBJDIR) diff --git a/programs/src/calculator/Makefile b/programs/src/calculator/Makefile index b6d94e2..5ee46a2 100644 --- a/programs/src/calculator/Makefile +++ b/programs/src/calculator/Makefile @@ -6,9 +6,9 @@ MAKEFLAGS += -rR # ---- Toolchain ---- -TOOLCHAIN_PREFIX := $(shell cd ../../.. && pwd)/toolchain/local/bin/x86_64-montauk- +include ../../mk/arch.mk ifeq ($(wildcard $(TOOLCHAIN_PREFIX)gcc),) - CXX = $(error x86_64-montauk toolchain not found. Run ./toolchain/build-montauk-toolchain.sh first) + CXX = $(error $(TOOLCHAIN_MISSING)) else CXX := $(TOOLCHAIN_PREFIX)g++ endif @@ -17,8 +17,8 @@ endif PROG_INC := ../../include LINK_LD := ../../link.ld -BINDIR := ../../bin -OBJDIR := obj +BINDIR := ../../bin$(ARCH_SUFFIX) +OBJDIR := obj$(ARCH_SUFFIX) LIBDIR := ../../lib # ---- Compiler flags ---- @@ -37,8 +37,7 @@ CXXFLAGS := \ -fno-exceptions \ -ffunction-sections \ -fdata-sections \ - -msse \ - -msse2 \ + $(ARCH_FP_FLAGS) \ -I $(PROG_INC) \ -isystem $(PROG_INC)/libc @@ -62,9 +61,9 @@ TARGET := $(BINDIR)/apps/calculator/calculator.elf all: $(TARGET) -$(TARGET): $(OBJS) $(LINK_LD) Makefile $(LIBDIR)/libc/liblibc.a +$(TARGET): $(OBJS) $(LINK_LD) Makefile $(LIBDIR)/libc/$(ARCH_OUT)liblibc.a mkdir -p $(BINDIR)/apps/calculator - $(CXX) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(LIBDIR)/libc/liblibc.a -o $@ + $(CXX) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(LIBDIR)/libc/$(ARCH_OUT)liblibc.a -o $@ $(OBJDIR)/%.o: %.cpp Makefile mkdir -p $(OBJDIR) diff --git a/programs/src/capabilities/Makefile b/programs/src/capabilities/Makefile index f2ab451..65d2d71 100644 --- a/programs/src/capabilities/Makefile +++ b/programs/src/capabilities/Makefile @@ -4,17 +4,17 @@ MAKEFLAGS += -rR .SUFFIXES: -TOOLCHAIN_PREFIX := $(shell cd ../../.. && pwd)/toolchain/local/bin/x86_64-montauk- +include ../../mk/arch.mk ifeq ($(wildcard $(TOOLCHAIN_PREFIX)gcc),) - CXX = $(error x86_64-montauk toolchain not found. Run ./toolchain/build-montauk-toolchain.sh first) + CXX = $(error $(TOOLCHAIN_MISSING)) else CXX := $(TOOLCHAIN_PREFIX)g++ endif PROG_INC := ../../include LINK_LD := ../../link.ld -BINDIR := ../../bin -OBJDIR := obj +BINDIR := ../../bin$(ARCH_SUFFIX) +OBJDIR := obj$(ARCH_SUFFIX) LIBDIR := ../../lib CXXFLAGS := \ @@ -31,8 +31,7 @@ CXXFLAGS := \ -fno-exceptions \ -ffunction-sections \ -fdata-sections \ - -msse \ - -msse2 \ + $(ARCH_FP_FLAGS) \ -MMD -MP \ -I $(PROG_INC) \ -isystem $(PROG_INC)/libc @@ -46,7 +45,7 @@ SRCS := main.cpp stb_truetype_impl.cpp OBJS := $(addprefix $(OBJDIR)/,$(SRCS:.cpp=.o)) TARGET := $(BINDIR)/apps/capabilities/capabilities.elf -LIBS := $(LIBDIR)/libc/liblibc.a +LIBS := $(LIBDIR)/libc/$(ARCH_OUT)liblibc.a .PHONY: all clean diff --git a/programs/src/charmap/Makefile b/programs/src/charmap/Makefile index 0d52d54..7c4d425 100644 --- a/programs/src/charmap/Makefile +++ b/programs/src/charmap/Makefile @@ -6,9 +6,9 @@ MAKEFLAGS += -rR # ---- Toolchain ---- -TOOLCHAIN_PREFIX := $(shell cd ../../.. && pwd)/toolchain/local/bin/x86_64-montauk- +include ../../mk/arch.mk ifeq ($(wildcard $(TOOLCHAIN_PREFIX)gcc),) - CXX = $(error x86_64-montauk toolchain not found. Run ./toolchain/build-montauk-toolchain.sh first) + CXX = $(error $(TOOLCHAIN_MISSING)) else CXX := $(TOOLCHAIN_PREFIX)g++ endif @@ -17,8 +17,8 @@ endif PROG_INC := ../../include LINK_LD := ../../link.ld -BINDIR := ../../bin -OBJDIR := obj +BINDIR := ../../bin$(ARCH_SUFFIX) +OBJDIR := obj$(ARCH_SUFFIX) LIBDIR := ../../lib # ---- Compiler flags ---- @@ -37,8 +37,7 @@ CXXFLAGS := \ -fno-exceptions \ -ffunction-sections \ -fdata-sections \ - -msse \ - -msse2 \ + $(ARCH_FP_FLAGS) \ -I $(PROG_INC) \ -isystem $(PROG_INC)/libc @@ -62,9 +61,9 @@ TARGET := $(BINDIR)/apps/charmap/charmap.elf all: $(TARGET) -$(TARGET): $(OBJS) $(LINK_LD) Makefile $(LIBDIR)/libc/liblibc.a +$(TARGET): $(OBJS) $(LINK_LD) Makefile $(LIBDIR)/libc/$(ARCH_OUT)liblibc.a mkdir -p $(BINDIR)/apps/charmap - $(CXX) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(LIBDIR)/libc/liblibc.a -o $@ + $(CXX) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(LIBDIR)/libc/$(ARCH_OUT)liblibc.a -o $@ $(OBJDIR)/%.o: %.cpp Makefile mkdir -p $(OBJDIR) diff --git a/programs/src/crashpad/Makefile b/programs/src/crashpad/Makefile index 4039ad8..43fe0c2 100644 --- a/programs/src/crashpad/Makefile +++ b/programs/src/crashpad/Makefile @@ -4,17 +4,17 @@ MAKEFLAGS += -rR .SUFFIXES: -TOOLCHAIN_PREFIX := $(shell cd ../../.. && pwd)/toolchain/local/bin/x86_64-montauk- +include ../../mk/arch.mk ifeq ($(wildcard $(TOOLCHAIN_PREFIX)gcc),) - CXX = $(error x86_64-montauk toolchain not found. Run ./toolchain/build-montauk-toolchain.sh first) + CXX = $(error $(TOOLCHAIN_MISSING)) else CXX := $(TOOLCHAIN_PREFIX)g++ endif PROG_INC := ../../include LINK_LD := ../../link.ld -BINDIR := ../../bin -OBJDIR := obj +BINDIR := ../../bin$(ARCH_SUFFIX) +OBJDIR := obj$(ARCH_SUFFIX) LIBDIR := ../../lib CXXFLAGS := \ @@ -31,8 +31,7 @@ CXXFLAGS := \ -fno-exceptions \ -ffunction-sections \ -fdata-sections \ - -msse \ - -msse2 \ + $(ARCH_FP_FLAGS) \ -MMD -MP \ -I $(PROG_INC) \ -isystem $(PROG_INC)/libc \ @@ -47,7 +46,7 @@ SRCS := main.cpp stb_truetype_impl.cpp font_data.cpp OBJS := $(addprefix $(OBJDIR)/,$(SRCS:.cpp=.o)) TARGET := $(BINDIR)/apps/crashpad/crashpad.elf -LIBS := $(LIBDIR)/libc/liblibc.a +LIBS := $(LIBDIR)/libc/$(ARCH_OUT)liblibc.a .PHONY: all clean diff --git a/programs/src/desktop/Makefile b/programs/src/desktop/Makefile index e314a08..1d46073 100644 --- a/programs/src/desktop/Makefile +++ b/programs/src/desktop/Makefile @@ -6,9 +6,9 @@ MAKEFLAGS += -rR # ---- Toolchain ---- -TOOLCHAIN_PREFIX := $(shell cd ../../.. && pwd)/toolchain/local/bin/x86_64-montauk- +include ../../mk/arch.mk ifeq ($(wildcard $(TOOLCHAIN_PREFIX)gcc),) - CXX = $(error x86_64-montauk toolchain not found. Run ./toolchain/build-montauk-toolchain.sh first) + CXX = $(error $(TOOLCHAIN_MISSING)) else CXX := $(TOOLCHAIN_PREFIX)g++ endif @@ -19,11 +19,10 @@ PROG_INC := ../../include JPEG_LIB := ../../lib/libjpeg LIBC_LIB := ../../lib/libc BEARSSL := ../../lib/bearssl -LOADER_LIB := ../../lib/libloader/liblibloader.a +LOADER_LIB := ../../lib/libloader/$(ARCH_OUT)liblibloader.a LINK_LD := ../../link.ld -BINDIR := ../../bin -OBJDIR := obj - +BINDIR := ../../bin$(ARCH_SUFFIX) +OBJDIR := obj$(ARCH_SUFFIX) # ---- C++ compiler flags ---- CXXFLAGS := \ @@ -40,8 +39,7 @@ CXXFLAGS := \ -fno-exceptions \ -ffunction-sections \ -fdata-sections \ - -msse \ - -msse2 \ + $(ARCH_FP_FLAGS) \ -MMD -MP \ -I $(PROG_INC) \ -isystem $(PROG_INC)/libc \ @@ -71,7 +69,7 @@ all: $(TARGET) # ---- Libraries ---- -LIBS := $(LOADER_LIB) $(JPEG_LIB)/libjpeg.a $(BEARSSL)/libbearssl.a $(LIBC_LIB)/liblibc.a +LIBS := $(LOADER_LIB) $(JPEG_LIB)/$(ARCH_OUT)libjpeg.a $(BEARSSL)/build$(ARCH_SUFFIX)/libbearssl.a $(LIBC_LIB)/$(ARCH_OUT)liblibc.a $(TARGET): $(OBJS) $(LIBS) $(LINK_LD) Makefile mkdir -p $(BINDIR)/os diff --git a/programs/src/devexplorer/Makefile b/programs/src/devexplorer/Makefile index 640e09d..6e5fdcc 100644 --- a/programs/src/devexplorer/Makefile +++ b/programs/src/devexplorer/Makefile @@ -6,9 +6,9 @@ MAKEFLAGS += -rR # ---- Toolchain ---- -TOOLCHAIN_PREFIX := $(shell cd ../../.. && pwd)/toolchain/local/bin/x86_64-montauk- +include ../../mk/arch.mk ifeq ($(wildcard $(TOOLCHAIN_PREFIX)gcc),) - CXX = $(error x86_64-montauk toolchain not found. Run ./toolchain/build-montauk-toolchain.sh first) + CXX = $(error $(TOOLCHAIN_MISSING)) else CXX := $(TOOLCHAIN_PREFIX)g++ endif @@ -17,8 +17,8 @@ endif PROG_INC := ../../include LINK_LD := ../../link.ld -BINDIR := ../../bin -OBJDIR := obj +BINDIR := ../../bin$(ARCH_SUFFIX) +OBJDIR := obj$(ARCH_SUFFIX) LIBDIR := ../../lib # ---- Compiler flags ---- @@ -37,8 +37,7 @@ CXXFLAGS := \ -fno-exceptions \ -ffunction-sections \ -fdata-sections \ - -msse \ - -msse2 \ + $(ARCH_FP_FLAGS) \ -I $(PROG_INC) \ -isystem $(PROG_INC)/libc \ -I ../../lib/bearssl/inc @@ -63,9 +62,9 @@ TARGET := $(BINDIR)/apps/devexplorer/devexplorer.elf all: $(TARGET) -$(TARGET): $(OBJS) $(LINK_LD) Makefile $(LIBDIR)/libc/liblibc.a +$(TARGET): $(OBJS) $(LINK_LD) Makefile $(LIBDIR)/libc/$(ARCH_OUT)liblibc.a mkdir -p $(BINDIR)/apps/devexplorer - $(CXX) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(LIBDIR)/libc/liblibc.a -o $@ + $(CXX) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(LIBDIR)/libc/$(ARCH_OUT)liblibc.a -o $@ $(OBJDIR)/%.o: %.cpp Makefile mkdir -p $(OBJDIR) diff --git a/programs/src/dialogs/Makefile b/programs/src/dialogs/Makefile index e0769a4..3ba9254 100644 --- a/programs/src/dialogs/Makefile +++ b/programs/src/dialogs/Makefile @@ -4,12 +4,12 @@ MAKEFLAGS += -rR .SUFFIXES: -TOOLCHAIN_PREFIX := $(shell cd ../../.. && pwd)/toolchain/local/bin/x86_64-montauk- +include ../../mk/arch.mk ifeq ($(wildcard $(TOOLCHAIN_PREFIX)gcc),) - CC = $(error x86_64-montauk toolchain not found. Run ./toolchain/build-montauk-toolchain.sh first) - CXX = $(error x86_64-montauk toolchain not found. Run ./toolchain/build-montauk-toolchain.sh first) - LD = $(error x86_64-montauk toolchain not found. Run ./toolchain/build-montauk-toolchain.sh first) - STRIP = $(error x86_64-montauk toolchain not found. Run ./toolchain/build-montauk-toolchain.sh first) + CC = $(error $(TOOLCHAIN_MISSING)) + CXX = $(error $(TOOLCHAIN_MISSING)) + LD = $(error $(TOOLCHAIN_MISSING)) + STRIP = $(error $(TOOLCHAIN_MISSING)) else CC := $(TOOLCHAIN_PREFIX)gcc CXX := $(TOOLCHAIN_PREFIX)g++ @@ -18,9 +18,9 @@ else endif PROG_INC := ../../include -LIBOUTDIR := ../../bin/os -OBJDIR := obj -LEGACY_APPDIR := ../../bin/apps/dialogs +LIBOUTDIR := ../../bin$(ARCH_SUFFIX)/os +OBJDIR := obj$(ARCH_SUFFIX) +LEGACY_APPDIR := ../../bin$(ARCH_SUFFIX)/apps/dialogs LIBC_SRC := ../../lib/libc/libc.c GCC_INCLUDE := $(shell $(CC) -print-file-name=include) @@ -40,8 +40,7 @@ CXXFLAGS := \ -fno-exceptions \ -ffunction-sections \ -fdata-sections \ - -msse \ - -msse2 \ + $(ARCH_FP_FLAGS) \ -MMD -MP \ -DGUI_DIALOGS_LIBRARY_BUILD \ -I $(PROG_INC) \ @@ -55,7 +54,7 @@ LDFLAGS := \ --hash-style=sysv \ -u dialogs_run_request \ -u dialogs_message_box \ - -m elf_x86_64 + -m $(ARCH_LD_EMULATION) LIBC_CFLAGS := \ -std=gnu11 \ @@ -69,8 +68,7 @@ LIBC_CFLAGS := \ -fvisibility=hidden \ -ffunction-sections \ -fdata-sections \ - -msse \ - -msse2 \ + $(ARCH_FP_FLAGS) \ -isystem $(PROG_INC)/libc \ -isystem $(GCC_INCLUDE) diff --git a/programs/src/disks/Makefile b/programs/src/disks/Makefile index bd01ba0..56ed015 100644 --- a/programs/src/disks/Makefile +++ b/programs/src/disks/Makefile @@ -6,9 +6,9 @@ MAKEFLAGS += -rR # ---- Toolchain ---- -TOOLCHAIN_PREFIX := $(shell cd ../../.. && pwd)/toolchain/local/bin/x86_64-montauk- +include ../../mk/arch.mk ifeq ($(wildcard $(TOOLCHAIN_PREFIX)gcc),) - CXX = $(error x86_64-montauk toolchain not found. Run ./toolchain/build-montauk-toolchain.sh first) + CXX = $(error $(TOOLCHAIN_MISSING)) else CXX := $(TOOLCHAIN_PREFIX)g++ endif @@ -17,8 +17,8 @@ endif PROG_INC := ../../include LINK_LD := ../../link.ld -BINDIR := ../../bin -OBJDIR := obj +BINDIR := ../../bin$(ARCH_SUFFIX) +OBJDIR := obj$(ARCH_SUFFIX) LIBDIR := ../../lib # ---- Compiler flags ---- @@ -37,8 +37,7 @@ CXXFLAGS := \ -fno-exceptions \ -ffunction-sections \ -fdata-sections \ - -msse \ - -msse2 \ + $(ARCH_FP_FLAGS) \ -I $(PROG_INC) \ -isystem $(PROG_INC)/libc @@ -62,9 +61,9 @@ TARGET := $(BINDIR)/apps/disks/disks.elf all: $(TARGET) -$(TARGET): $(OBJS) $(LINK_LD) Makefile $(LIBDIR)/libc/liblibc.a +$(TARGET): $(OBJS) $(LINK_LD) Makefile $(LIBDIR)/libc/$(ARCH_OUT)liblibc.a mkdir -p $(BINDIR)/apps/disks - $(CXX) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(LIBDIR)/libc/liblibc.a -o $@ + $(CXX) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(LIBDIR)/libc/$(ARCH_OUT)liblibc.a -o $@ $(OBJDIR)/%.o: %.cpp Makefile mkdir -p $(OBJDIR) diff --git a/programs/src/display/Makefile b/programs/src/display/Makefile index f2ecd83..c326e71 100644 --- a/programs/src/display/Makefile +++ b/programs/src/display/Makefile @@ -4,17 +4,17 @@ MAKEFLAGS += -rR .SUFFIXES: -TOOLCHAIN_PREFIX := $(shell cd ../../.. && pwd)/toolchain/local/bin/x86_64-montauk- +include ../../mk/arch.mk ifeq ($(wildcard $(TOOLCHAIN_PREFIX)gcc),) - CXX = $(error x86_64-montauk toolchain not found. Run ./toolchain/build-montauk-toolchain.sh first) + CXX = $(error $(TOOLCHAIN_MISSING)) else CXX := $(TOOLCHAIN_PREFIX)g++ endif PROG_INC := ../../include LINK_LD := ../../link.ld -BINDIR := ../../bin -OBJDIR := obj +BINDIR := ../../bin$(ARCH_SUFFIX) +OBJDIR := obj$(ARCH_SUFFIX) LIBDIR := ../../lib CXXFLAGS := \ @@ -31,8 +31,7 @@ CXXFLAGS := \ -fno-exceptions \ -ffunction-sections \ -fdata-sections \ - -msse \ - -msse2 \ + $(ARCH_FP_FLAGS) \ -MMD -MP \ -I $(PROG_INC) \ -isystem $(PROG_INC)/libc @@ -46,7 +45,7 @@ SRCS := main.cpp stb_truetype_impl.cpp OBJS := $(addprefix $(OBJDIR)/,$(SRCS:.cpp=.o)) TARGET := $(BINDIR)/apps/display/display.elf -LIBS := $(LIBDIR)/libc/liblibc.a +LIBS := $(LIBDIR)/libc/$(ARCH_OUT)liblibc.a .PHONY: all clean diff --git a/programs/src/fetch/Makefile b/programs/src/fetch/Makefile index 7fc9a6c..06bc4b4 100644 --- a/programs/src/fetch/Makefile +++ b/programs/src/fetch/Makefile @@ -6,9 +6,9 @@ MAKEFLAGS += -rR # ---- Toolchain ---- -TOOLCHAIN_PREFIX := $(shell cd ../../.. && pwd)/toolchain/local/bin/x86_64-montauk- +include ../../mk/arch.mk ifeq ($(wildcard $(TOOLCHAIN_PREFIX)gcc),) - CXX = $(error x86_64-montauk toolchain not found. Run ./toolchain/build-montauk-toolchain.sh first) + CXX = $(error $(TOOLCHAIN_MISSING)) else CXX := $(TOOLCHAIN_PREFIX)g++ endif @@ -21,9 +21,8 @@ LIBC_LIB := ../../lib/libc LIBC_INC := ../../include/libc PROG_INC := ../../include LINK_LD := ../../link.ld -BINDIR := ../../bin -OBJDIR := obj - +BINDIR := ../../bin$(ARCH_SUFFIX) +OBJDIR := obj$(ARCH_SUFFIX) # ---- Compiler flags ---- CXXFLAGS := \ @@ -39,10 +38,7 @@ CXXFLAGS := \ -fno-exceptions \ -ffunction-sections \ -fdata-sections \ - -mno-80387 \ - -mno-mmx \ - -mno-sse \ - -mno-sse2 \ + $(ARCH_NOFP_FLAGS) \ -I $(PROG_INC) \ -isystem $(LIBC_INC) \ -I $(BEARSSL)/inc @@ -56,7 +52,7 @@ LDFLAGS := \ # ---- Libraries ---- -LIBS := $(TLS_LIB)/libtls.a $(BEARSSL)/libbearssl.a $(LIBC_LIB)/liblibc.a +LIBS := $(TLS_LIB)/$(ARCH_OUT)libtls.a $(BEARSSL)/build$(ARCH_SUFFIX)/libbearssl.a $(LIBC_LIB)/$(ARCH_OUT)liblibc.a # ---- Target ---- diff --git a/programs/src/files/Makefile b/programs/src/files/Makefile index f7799f3..8267468 100644 --- a/programs/src/files/Makefile +++ b/programs/src/files/Makefile @@ -6,9 +6,9 @@ MAKEFLAGS += -rR # ---- Toolchain ---- -TOOLCHAIN_PREFIX := $(shell cd ../../.. && pwd)/toolchain/local/bin/x86_64-montauk- +include ../../mk/arch.mk ifeq ($(wildcard $(TOOLCHAIN_PREFIX)gcc),) - CXX = $(error x86_64-montauk toolchain not found. Run ./toolchain/build-montauk-toolchain.sh first) + CXX = $(error $(TOOLCHAIN_MISSING)) else CXX := $(TOOLCHAIN_PREFIX)g++ endif @@ -17,8 +17,8 @@ endif PROG_INC := ../../include LINK_LD := ../../link.ld -BINDIR := ../../bin -OBJDIR := obj +BINDIR := ../../bin$(ARCH_SUFFIX) +OBJDIR := obj$(ARCH_SUFFIX) LIBDIR := ../../lib BEARSSL := ../../lib/bearssl JPEG_LIB := ../../lib/libjpeg @@ -39,8 +39,7 @@ CXXFLAGS := \ -fno-exceptions \ -ffunction-sections \ -fdata-sections \ - -msse \ - -msse2 \ + $(ARCH_FP_FLAGS) \ -I $(PROG_INC) \ -isystem $(PROG_INC)/libc \ -I $(BEARSSL)/inc @@ -65,7 +64,7 @@ TARGET := $(BINDIR)/apps/files/files.elf all: $(TARGET) -LIBS := $(JPEG_LIB)/libjpeg.a $(BEARSSL)/libbearssl.a $(LIBDIR)/libc/liblibc.a +LIBS := $(JPEG_LIB)/$(ARCH_OUT)libjpeg.a $(BEARSSL)/build$(ARCH_SUFFIX)/libbearssl.a $(LIBDIR)/libc/$(ARCH_OUT)liblibc.a $(TARGET): $(OBJS) $(LINK_LD) Makefile $(LIBS) mkdir -p $(BINDIR)/apps/files diff --git a/programs/src/fontpreview/Makefile b/programs/src/fontpreview/Makefile index 000ae53..90d816a 100644 --- a/programs/src/fontpreview/Makefile +++ b/programs/src/fontpreview/Makefile @@ -6,9 +6,9 @@ MAKEFLAGS += -rR # ---- Toolchain ---- -TOOLCHAIN_PREFIX := $(shell cd ../../.. && pwd)/toolchain/local/bin/x86_64-montauk- +include ../../mk/arch.mk ifeq ($(wildcard $(TOOLCHAIN_PREFIX)gcc),) - CXX = $(error x86_64-montauk toolchain not found. Run ./toolchain/build-montauk-toolchain.sh first) + CXX = $(error $(TOOLCHAIN_MISSING)) else CXX := $(TOOLCHAIN_PREFIX)g++ endif @@ -18,9 +18,8 @@ endif LIBC_LIB := ../../lib/libc PROG_INC := ../../include LINK_LD := ../../link.ld -BINDIR := ../../bin -OBJDIR := obj - +BINDIR := ../../bin$(ARCH_SUFFIX) +OBJDIR := obj$(ARCH_SUFFIX) # ---- Compiler flags ---- CXXFLAGS := \ @@ -37,8 +36,7 @@ CXXFLAGS := \ -fno-exceptions \ -ffunction-sections \ -fdata-sections \ - -msse \ - -msse2 \ + $(ARCH_FP_FLAGS) \ -I $(PROG_INC) # ---- Linker flags ---- @@ -50,7 +48,7 @@ LDFLAGS := \ # ---- Libraries ---- -LIBS := $(LIBC_LIB)/liblibc.a +LIBS := $(LIBC_LIB)/$(ARCH_OUT)liblibc.a # ---- Source files ---- diff --git a/programs/src/imageviewer/Makefile b/programs/src/imageviewer/Makefile index 7288716..4d6f17f 100644 --- a/programs/src/imageviewer/Makefile +++ b/programs/src/imageviewer/Makefile @@ -6,9 +6,9 @@ MAKEFLAGS += -rR # ---- Toolchain ---- -TOOLCHAIN_PREFIX := $(shell cd ../../.. && pwd)/toolchain/local/bin/x86_64-montauk- +include ../../mk/arch.mk ifeq ($(wildcard $(TOOLCHAIN_PREFIX)gcc),) - CXX = $(error x86_64-montauk toolchain not found. Run ./toolchain/build-montauk-toolchain.sh first) + CXX = $(error $(TOOLCHAIN_MISSING)) else CXX := $(TOOLCHAIN_PREFIX)g++ endif @@ -20,9 +20,8 @@ LIBC_LIB := ../../lib/libc LIBC_INC := ../../include/libc PROG_INC := ../../include LINK_LD := ../../link.ld -BINDIR := ../../bin -OBJDIR := obj - +BINDIR := ../../bin$(ARCH_SUFFIX) +OBJDIR := obj$(ARCH_SUFFIX) # ---- Compiler flags ---- CXXFLAGS := \ @@ -39,8 +38,7 @@ CXXFLAGS := \ -fno-exceptions \ -ffunction-sections \ -fdata-sections \ - -msse \ - -msse2 \ + $(ARCH_FP_FLAGS) \ -I $(PROG_INC) \ -isystem $(LIBC_INC) @@ -53,7 +51,7 @@ LDFLAGS := \ # ---- Libraries ---- -LIBS := $(JPEG_LIB)/libjpeg.a $(LIBC_LIB)/liblibc.a +LIBS := $(JPEG_LIB)/$(ARCH_OUT)libjpeg.a $(LIBC_LIB)/$(ARCH_OUT)liblibc.a # ---- Source files ---- diff --git a/programs/src/installer/Makefile b/programs/src/installer/Makefile index 82050a6..fffcb4a 100644 --- a/programs/src/installer/Makefile +++ b/programs/src/installer/Makefile @@ -6,9 +6,9 @@ MAKEFLAGS += -rR # ---- Toolchain ---- -TOOLCHAIN_PREFIX := $(shell cd ../../.. && pwd)/toolchain/local/bin/x86_64-montauk- +include ../../mk/arch.mk ifeq ($(wildcard $(TOOLCHAIN_PREFIX)gcc),) - CXX = $(error x86_64-montauk toolchain not found. Run ./toolchain/build-montauk-toolchain.sh first) + CXX = $(error $(TOOLCHAIN_MISSING)) else CXX := $(TOOLCHAIN_PREFIX)g++ endif @@ -17,8 +17,8 @@ endif PROG_INC := ../../include LINK_LD := ../../link.ld -BINDIR := ../../bin -OBJDIR := obj +BINDIR := ../../bin$(ARCH_SUFFIX) +OBJDIR := obj$(ARCH_SUFFIX) LIBDIR := ../../lib # ---- Compiler flags ---- @@ -37,8 +37,7 @@ CXXFLAGS := \ -fno-exceptions \ -ffunction-sections \ -fdata-sections \ - -msse \ - -msse2 \ + $(ARCH_FP_FLAGS) \ -MMD -MP \ -I $(PROG_INC) \ -isystem $(PROG_INC)/libc @@ -63,9 +62,9 @@ TARGET := $(BINDIR)/apps/installer/installer.elf all: $(TARGET) -$(TARGET): $(OBJS) $(LINK_LD) Makefile $(LIBDIR)/libc/liblibc.a +$(TARGET): $(OBJS) $(LINK_LD) Makefile $(LIBDIR)/libc/$(ARCH_OUT)liblibc.a mkdir -p $(BINDIR)/apps/installer - $(CXX) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(LIBDIR)/libc/liblibc.a -o $@ + $(CXX) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(LIBDIR)/libc/$(ARCH_OUT)liblibc.a -o $@ $(OBJDIR)/%.o: %.cpp Makefile mkdir -p $(OBJDIR) diff --git a/programs/src/keyboard/Makefile b/programs/src/keyboard/Makefile index 7239611..834376f 100644 --- a/programs/src/keyboard/Makefile +++ b/programs/src/keyboard/Makefile @@ -3,29 +3,29 @@ MAKEFLAGS += -rR .SUFFIXES: -TOOLCHAIN_PREFIX := $(shell cd ../../.. && pwd)/toolchain/local/bin/x86_64-montauk- +include ../../mk/arch.mk ifeq ($(wildcard $(TOOLCHAIN_PREFIX)gcc),) - CXX = $(error x86_64-montauk toolchain not found. Run ./toolchain/build-montauk-toolchain.sh first) + CXX = $(error $(TOOLCHAIN_MISSING)) else CXX := $(TOOLCHAIN_PREFIX)g++ endif PROG_INC := ../../include LINK_LD := ../../link.ld -BINDIR := ../../bin -OBJDIR := obj +BINDIR := ../../bin$(ARCH_SUFFIX) +OBJDIR := obj$(ARCH_SUFFIX) LIBDIR := ../../lib CXXFLAGS := -std=gnu++20 -g -O2 -pipe -Wall -Wextra -Wno-unused-parameter \ -Wno-unused-function -ffreestanding -fno-stack-protector -fno-stack-check \ - -fno-rtti -fno-exceptions -ffunction-sections -fdata-sections -msse -msse2 \ + -fno-rtti -fno-exceptions -ffunction-sections -fdata-sections $(ARCH_FP_FLAGS) \ -MMD -MP -I $(PROG_INC) -isystem $(PROG_INC)/libc LDFLAGS := -nostdlib -Wl,--gc-sections -T $(LINK_LD) SRCS := main.cpp stb_truetype_impl.cpp OBJS := $(addprefix $(OBJDIR)/,$(SRCS:.cpp=.o)) TARGET := $(BINDIR)/apps/keyboard/keyboard.elf -LIBS := $(LIBDIR)/libc/liblibc.a +LIBS := $(LIBDIR)/libc/$(ARCH_OUT)liblibc.a .PHONY: all clean all: $(TARGET) diff --git a/programs/src/libloader/Makefile b/programs/src/libloader/Makefile index fd88028..a7d72ad 100644 --- a/programs/src/libloader/Makefile +++ b/programs/src/libloader/Makefile @@ -1,8 +1,6 @@ # Makefile for libloader -ARCH := x86_64 - -TOOLCHAIN_PREFIX := $(shell cd ../../.. && pwd)/toolchain/local/bin/x86_64-montauk- +include ../../mk/arch.mk CXX := $(TOOLCHAIN_PREFIX)g++ AR := $(TOOLCHAIN_PREFIX)ar @@ -18,29 +16,26 @@ override CXXFLAGS := \ -fno-exceptions \ -ffunction-sections \ -fdata-sections \ - -mno-80387 \ - -mno-mmx \ - -mno-sse \ - -mno-sse2 \ + $(ARCH_NOFP_FLAGS) \ -I ../../include \ -isystem ../../include/libc \ -isystem ../../include/montauk LIBDIR := ../../lib/libloader -LEGACY_BINDIR := ../../bin +LEGACY_BINDIR := ../../bin$(ARCH_SUFFIX) .PHONY: all clean remove-legacy -all: remove-legacy $(LIBDIR)/liblibloader.a +all: remove-legacy $(LIBDIR)/$(ARCH_OUT)liblibloader.a remove-legacy: rm -f $(LEGACY_BINDIR)/liblibloader.a -$(LIBDIR)/liblibloader.a: libloader.cpp - @mkdir -p $(LIBDIR) +$(LIBDIR)/$(ARCH_OUT)liblibloader.a: libloader.cpp + @mkdir -p $(LIBDIR)/$(ARCH_OUT) $(CXX) $(CXXFLAGS) -c libloader.cpp -o libloader.o - $(AR) rcs $(LIBDIR)/liblibloader.a libloader.o + $(AR) rcs $(LIBDIR)/$(ARCH_OUT)liblibloader.a libloader.o rm -f libloader.o clean: - rm -f $(LIBDIR)/liblibloader.a $(LEGACY_BINDIR)/liblibloader.a + rm -f $(LIBDIR)/$(ARCH_OUT)liblibloader.a $(LEGACY_BINDIR)/$(ARCH_OUT)liblibloader.a diff --git a/programs/src/login/Makefile b/programs/src/login/Makefile index ce06ec4..bcb121e 100644 --- a/programs/src/login/Makefile +++ b/programs/src/login/Makefile @@ -6,9 +6,9 @@ MAKEFLAGS += -rR # ---- Toolchain ---- -TOOLCHAIN_PREFIX := $(shell cd ../../.. && pwd)/toolchain/local/bin/x86_64-montauk- +include ../../mk/arch.mk ifeq ($(wildcard $(TOOLCHAIN_PREFIX)gcc),) - CXX = $(error x86_64-montauk toolchain not found. Run ./toolchain/build-montauk-toolchain.sh first) + CXX = $(error $(TOOLCHAIN_MISSING)) else CXX := $(TOOLCHAIN_PREFIX)g++ endif @@ -20,9 +20,8 @@ LIBC_LIB := ../../lib/libc JPEG_LIB := ../../lib/libjpeg BEARSSL := ../../lib/bearssl LINK_LD := ../../link.ld -BINDIR := ../../bin -OBJDIR := obj - +BINDIR := ../../bin$(ARCH_SUFFIX) +OBJDIR := obj$(ARCH_SUFFIX) # ---- Compiler flags ---- CXXFLAGS := \ @@ -39,8 +38,7 @@ CXXFLAGS := \ -fno-exceptions \ -ffunction-sections \ -fdata-sections \ - -msse \ - -msse2 \ + $(ARCH_FP_FLAGS) \ -I $(PROG_INC) \ -isystem $(PROG_INC)/libc \ -I $(BEARSSL)/inc @@ -73,7 +71,7 @@ TARGET := $(BINDIR)/os/login.elf all: $(TARGET) -LIBS := $(JPEG_LIB)/libjpeg.a $(BEARSSL)/libbearssl.a $(LIBC_LIB)/liblibc.a +LIBS := $(JPEG_LIB)/$(ARCH_OUT)libjpeg.a $(BEARSSL)/build$(ARCH_SUFFIX)/libbearssl.a $(LIBC_LIB)/$(ARCH_OUT)liblibc.a $(TARGET): $(OBJS) $(LIBS) $(LINK_LD) Makefile mkdir -p $(BINDIR)/os diff --git a/programs/src/lua/Makefile b/programs/src/lua/Makefile index 1189f99..41c3693 100644 --- a/programs/src/lua/Makefile +++ b/programs/src/lua/Makefile @@ -1,20 +1,20 @@ MAKEFLAGS += -rR .SUFFIXES: -TOOLCHAIN_PREFIX := $(shell cd ../../.. && pwd)/toolchain/local/bin/x86_64-montauk- +include ../../mk/arch.mk ifeq ($(wildcard $(TOOLCHAIN_PREFIX)gcc),) - CC = $(error x86_64-montauk toolchain not found. Run ./toolchain/build-montauk-toolchain.sh first) - AR = $(error x86_64-montauk toolchain not found. Run ./toolchain/build-montauk-toolchain.sh first) + CC = $(error $(TOOLCHAIN_MISSING)) + AR = $(error $(TOOLCHAIN_MISSING)) else CC := $(TOOLCHAIN_PREFIX)gcc AR := $(TOOLCHAIN_PREFIX)ar endif SRCDIR := src -OBJDIR := obj +OBJDIR := obj$(ARCH_SUFFIX) LIBC_DIR := ../../lib/libc -BINDIR := ../../bin/os -LIBDIR := ../../bin/sdk/lua +BINDIR := ../../bin$(ARCH_SUFFIX)/os +LIBDIR := ../../bin$(ARCH_SUFFIX)/sdk/lua CFLAGS := \ -std=gnu11 \ @@ -31,8 +31,7 @@ CFLAGS := \ -fno-stack-check \ -ffunction-sections \ -fdata-sections \ - -msse \ - -msse2 \ + $(ARCH_FP_FLAGS) \ -D__MONTAUKOS__=1 \ -DLUA_COMPAT_5_3 \ -I$(SRCDIR) \ @@ -74,15 +73,15 @@ STAGE_HEADERS := \ all: $(TARGET_LIB) $(TARGET_BIN) $(STAGE_HEADERS) -$(TARGET_LIB): $(BASE_OBJS) $(LIBC_DIR)/liblibc.a +$(TARGET_LIB): $(BASE_OBJS) $(LIBC_DIR)/$(ARCH_OUT)liblibc.a @mkdir -p $(LIBDIR) $(AR) rcs $@ $(BASE_OBJS) -$(TARGET_BIN): $(LUA_MAIN) $(TARGET_LIB) $(LIBC_DIR)/liblibc.a $(LIBC_DIR)/crt1.o $(LIBC_DIR)/crti.o $(LIBC_DIR)/crtn.o +$(TARGET_BIN): $(LUA_MAIN) $(TARGET_LIB) $(LIBC_DIR)/$(ARCH_OUT)liblibc.a $(LIBC_DIR)/$(ARCH_OUT)crt1.o $(LIBC_DIR)/$(ARCH_OUT)crti.o $(LIBC_DIR)/$(ARCH_OUT)crtn.o @mkdir -p $(BINDIR) $(CC) $(CFLAGS) $(LDFLAGS) \ - $(LIBC_DIR)/crt1.o $(LIBC_DIR)/crti.o \ - $(LUA_MAIN) $(TARGET_LIB) $(LIBC_DIR)/liblibc.a $(LIBC_DIR)/crtn.o \ + $(LIBC_DIR)/$(ARCH_OUT)crt1.o $(LIBC_DIR)/$(ARCH_OUT)crti.o \ + $(LUA_MAIN) $(TARGET_LIB) $(LIBC_DIR)/$(ARCH_OUT)liblibc.a $(LIBC_DIR)/$(ARCH_OUT)crtn.o \ -lgcc -o $@ $(LIBDIR)/include/%: $(SRCDIR)/% diff --git a/programs/src/mandelbrot/Makefile b/programs/src/mandelbrot/Makefile index 4886b13..fd1d0f5 100644 --- a/programs/src/mandelbrot/Makefile +++ b/programs/src/mandelbrot/Makefile @@ -6,9 +6,9 @@ MAKEFLAGS += -rR # ---- Toolchain ---- -TOOLCHAIN_PREFIX := $(shell cd ../../.. && pwd)/toolchain/local/bin/x86_64-montauk- +include ../../mk/arch.mk ifeq ($(wildcard $(TOOLCHAIN_PREFIX)gcc),) - CXX = $(error x86_64-montauk toolchain not found. Run ./toolchain/build-montauk-toolchain.sh first) + CXX = $(error $(TOOLCHAIN_MISSING)) else CXX := $(TOOLCHAIN_PREFIX)g++ endif @@ -17,8 +17,8 @@ endif PROG_INC := ../../include LINK_LD := ../../link.ld -BINDIR := ../../bin -OBJDIR := obj +BINDIR := ../../bin$(ARCH_SUFFIX) +OBJDIR := obj$(ARCH_SUFFIX) LIBDIR := ../../lib # ---- Compiler flags ---- @@ -37,8 +37,7 @@ CXXFLAGS := \ -fno-exceptions \ -ffunction-sections \ -fdata-sections \ - -msse \ - -msse2 \ + $(ARCH_FP_FLAGS) \ -I $(PROG_INC) \ -isystem $(PROG_INC)/libc @@ -62,9 +61,9 @@ TARGET := $(BINDIR)/apps/mandelbrot/mandelbrot.elf all: $(TARGET) -$(TARGET): $(OBJS) $(LINK_LD) Makefile $(LIBDIR)/libc/liblibc.a +$(TARGET): $(OBJS) $(LINK_LD) Makefile $(LIBDIR)/libc/$(ARCH_OUT)liblibc.a mkdir -p $(BINDIR)/apps/mandelbrot - $(CXX) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(LIBDIR)/libc/liblibc.a -o $@ + $(CXX) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(LIBDIR)/libc/$(ARCH_OUT)liblibc.a -o $@ $(OBJDIR)/%.o: %.cpp Makefile mkdir -p $(OBJDIR) diff --git a/programs/src/music/Makefile b/programs/src/music/Makefile index 42cb45d..7a75cc4 100644 --- a/programs/src/music/Makefile +++ b/programs/src/music/Makefile @@ -6,9 +6,9 @@ MAKEFLAGS += -rR # ---- Toolchain ---- -TOOLCHAIN_PREFIX := $(shell cd ../../.. && pwd)/toolchain/local/bin/x86_64-montauk- +include ../../mk/arch.mk ifeq ($(wildcard $(TOOLCHAIN_PREFIX)gcc),) - CXX = $(error x86_64-montauk toolchain not found. Run ./toolchain/build-montauk-toolchain.sh first) + CXX = $(error $(TOOLCHAIN_MISSING)) else CXX := $(TOOLCHAIN_PREFIX)g++ endif @@ -17,8 +17,8 @@ endif PROG_INC := ../../include LINK_LD := ../../link.ld -BINDIR := ../../bin -OBJDIR := obj +BINDIR := ../../bin$(ARCH_SUFFIX) +OBJDIR := obj$(ARCH_SUFFIX) LIBDIR := ../../lib # ---- Compiler flags ---- @@ -37,8 +37,7 @@ CXXFLAGS := \ -fno-exceptions \ -ffunction-sections \ -fdata-sections \ - -msse \ - -msse2 \ + $(ARCH_FP_FLAGS) \ -I $(PROG_INC) \ -I . \ -isystem $(PROG_INC)/libc @@ -63,9 +62,9 @@ TARGET := $(BINDIR)/apps/music/music.elf all: $(TARGET) -$(TARGET): $(OBJS) $(LINK_LD) Makefile $(LIBDIR)/libc/liblibc.a +$(TARGET): $(OBJS) $(LINK_LD) Makefile $(LIBDIR)/libc/$(ARCH_OUT)liblibc.a mkdir -p $(BINDIR)/apps/music - $(CXX) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(LIBDIR)/libc/liblibc.a -o $@ + $(CXX) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(LIBDIR)/libc/$(ARCH_OUT)liblibc.a -o $@ $(OBJDIR)/%.o: %.cpp Makefile mkdir -p $(OBJDIR) diff --git a/programs/src/network/Makefile b/programs/src/network/Makefile index 6774b8c..a909ca3 100644 --- a/programs/src/network/Makefile +++ b/programs/src/network/Makefile @@ -4,17 +4,17 @@ MAKEFLAGS += -rR .SUFFIXES: -TOOLCHAIN_PREFIX := $(shell cd ../../.. && pwd)/toolchain/local/bin/x86_64-montauk- +include ../../mk/arch.mk ifeq ($(wildcard $(TOOLCHAIN_PREFIX)gcc),) - CXX = $(error x86_64-montauk toolchain not found. Run ./toolchain/build-montauk-toolchain.sh first) + CXX = $(error $(TOOLCHAIN_MISSING)) else CXX := $(TOOLCHAIN_PREFIX)g++ endif PROG_INC := ../../include LINK_LD := ../../link.ld -BINDIR := ../../bin -OBJDIR := obj +BINDIR := ../../bin$(ARCH_SUFFIX) +OBJDIR := obj$(ARCH_SUFFIX) LIBDIR := ../../lib CXXFLAGS := \ @@ -31,8 +31,7 @@ CXXFLAGS := \ -fno-exceptions \ -ffunction-sections \ -fdata-sections \ - -msse \ - -msse2 \ + $(ARCH_FP_FLAGS) \ -MMD -MP \ -I $(PROG_INC) \ -isystem $(PROG_INC)/libc @@ -46,7 +45,7 @@ SRCS := main.cpp stb_truetype_impl.cpp OBJS := $(addprefix $(OBJDIR)/,$(SRCS:.cpp=.o)) TARGET := $(BINDIR)/apps/network/network.elf -LIBS := $(LIBDIR)/libc/liblibc.a +LIBS := $(LIBDIR)/libc/$(ARCH_OUT)liblibc.a .PHONY: all clean diff --git a/programs/src/paint/Makefile b/programs/src/paint/Makefile index a8ef53a..34c679a 100644 --- a/programs/src/paint/Makefile +++ b/programs/src/paint/Makefile @@ -6,9 +6,9 @@ MAKEFLAGS += -rR # ---- Toolchain ---- -TOOLCHAIN_PREFIX := $(shell cd ../../.. && pwd)/toolchain/local/bin/x86_64-montauk- +include ../../mk/arch.mk ifeq ($(wildcard $(TOOLCHAIN_PREFIX)gcc),) - CXX = $(error x86_64-montauk toolchain not found. Run ./toolchain/build-montauk-toolchain.sh first) + CXX = $(error $(TOOLCHAIN_MISSING)) else CXX := $(TOOLCHAIN_PREFIX)g++ endif @@ -17,8 +17,8 @@ endif PROG_INC := ../../include LINK_LD := ../../link.ld -BINDIR := ../../bin -OBJDIR := obj +BINDIR := ../../bin$(ARCH_SUFFIX) +OBJDIR := obj$(ARCH_SUFFIX) LIBDIR := ../../lib # ---- Compiler flags ---- @@ -37,8 +37,7 @@ CXXFLAGS := \ -fno-exceptions \ -ffunction-sections \ -fdata-sections \ - -msse \ - -msse2 \ + $(ARCH_FP_FLAGS) \ -I $(PROG_INC) \ -isystem $(PROG_INC)/libc @@ -62,9 +61,9 @@ TARGET := $(BINDIR)/apps/paint/paint.elf all: $(TARGET) -$(TARGET): $(OBJS) $(LINK_LD) Makefile $(LIBDIR)/libc/liblibc.a +$(TARGET): $(OBJS) $(LINK_LD) Makefile $(LIBDIR)/libc/$(ARCH_OUT)liblibc.a mkdir -p $(BINDIR)/apps/paint - $(CXX) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(LIBDIR)/libc/liblibc.a -o $@ + $(CXX) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(LIBDIR)/libc/$(ARCH_OUT)liblibc.a -o $@ $(OBJDIR)/%.o: %.cpp Makefile mkdir -p $(OBJDIR) diff --git a/programs/src/pdfviewer/Makefile b/programs/src/pdfviewer/Makefile index 9f9bea4..d73af79 100644 --- a/programs/src/pdfviewer/Makefile +++ b/programs/src/pdfviewer/Makefile @@ -6,9 +6,9 @@ MAKEFLAGS += -rR # ---- Toolchain ---- -TOOLCHAIN_PREFIX := $(shell cd ../../.. && pwd)/toolchain/local/bin/x86_64-montauk- +include ../../mk/arch.mk ifeq ($(wildcard $(TOOLCHAIN_PREFIX)gcc),) - CXX = $(error x86_64-montauk toolchain not found. Run ./toolchain/build-montauk-toolchain.sh first) + CXX = $(error $(TOOLCHAIN_MISSING)) else CXX := $(TOOLCHAIN_PREFIX)g++ endif @@ -17,10 +17,10 @@ endif PROG_INC := ../../include LINK_LD := ../../link.ld -BINDIR := ../../bin -OBJDIR := obj +BINDIR := ../../bin$(ARCH_SUFFIX) +OBJDIR := obj$(ARCH_SUFFIX) LIBDIR := ../../lib -JPEG_LIB := $(LIBDIR)/libjpeg/libjpeg.a +JPEG_LIB := $(LIBDIR)/libjpeg/$(ARCH_OUT)libjpeg.a # ---- Compiler flags ---- @@ -38,8 +38,7 @@ CXXFLAGS := \ -fno-exceptions \ -ffunction-sections \ -fdata-sections \ - -msse \ - -msse2 \ + $(ARCH_FP_FLAGS) \ -I $(PROG_INC) \ -isystem $(PROG_INC)/libc @@ -58,15 +57,15 @@ OBJS := $(addprefix $(OBJDIR)/,$(SRCS:.cpp=.o)) # ---- Target ---- TARGET := $(BINDIR)/apps/pdfviewer/pdfviewer.elf -LOADER_LIB := $(LIBDIR)/libloader/liblibloader.a +LOADER_LIB := $(LIBDIR)/libloader/$(ARCH_OUT)liblibloader.a .PHONY: all clean all: $(TARGET) -$(TARGET): $(OBJS) $(LINK_LD) Makefile $(LOADER_LIB) $(JPEG_LIB) $(LIBDIR)/libc/liblibc.a +$(TARGET): $(OBJS) $(LINK_LD) Makefile $(LOADER_LIB) $(JPEG_LIB) $(LIBDIR)/libc/$(ARCH_OUT)liblibc.a mkdir -p $(BINDIR)/apps/pdfviewer - $(CXX) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(LOADER_LIB) $(JPEG_LIB) $(LIBDIR)/libc/liblibc.a -o $@ + $(CXX) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(LOADER_LIB) $(JPEG_LIB) $(LIBDIR)/libc/$(ARCH_OUT)liblibc.a -o $@ HEADERS := pdfviewer.h diff --git a/programs/src/powermgr/Makefile b/programs/src/powermgr/Makefile index 14c6e3d..29b2b28 100644 --- a/programs/src/powermgr/Makefile +++ b/programs/src/powermgr/Makefile @@ -4,17 +4,17 @@ MAKEFLAGS += -rR .SUFFIXES: -TOOLCHAIN_PREFIX := $(shell cd ../../.. && pwd)/toolchain/local/bin/x86_64-montauk- +include ../../mk/arch.mk ifeq ($(wildcard $(TOOLCHAIN_PREFIX)gcc),) - CXX = $(error x86_64-montauk toolchain not found. Run ./toolchain/build-montauk-toolchain.sh first) + CXX = $(error $(TOOLCHAIN_MISSING)) else CXX := $(TOOLCHAIN_PREFIX)g++ endif PROG_INC := ../../include LINK_LD := ../../link.ld -BINDIR := ../../bin -OBJDIR := obj +BINDIR := ../../bin$(ARCH_SUFFIX) +OBJDIR := obj$(ARCH_SUFFIX) LIBDIR := ../../lib CXXFLAGS := \ @@ -31,8 +31,7 @@ CXXFLAGS := \ -fno-exceptions \ -ffunction-sections \ -fdata-sections \ - -msse \ - -msse2 \ + $(ARCH_FP_FLAGS) \ -MMD -MP \ -I $(PROG_INC) \ -isystem $(PROG_INC)/libc @@ -51,9 +50,9 @@ TARGET := $(BINDIR)/apps/powermgr/powermgr.elf all: $(TARGET) -$(TARGET): $(OBJS) $(LINK_LD) Makefile $(LIBDIR)/libc/liblibc.a +$(TARGET): $(OBJS) $(LINK_LD) Makefile $(LIBDIR)/libc/$(ARCH_OUT)liblibc.a mkdir -p $(BINDIR)/apps/powermgr - $(CXX) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(LIBDIR)/libc/liblibc.a -o $@ + $(CXX) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(LIBDIR)/libc/$(ARCH_OUT)liblibc.a -o $@ $(OBJDIR)/%.o: %.cpp Makefile mkdir -p $(OBJDIR) diff --git a/programs/src/printctl/Makefile b/programs/src/printctl/Makefile index 33a1395..241a6bc 100644 --- a/programs/src/printctl/Makefile +++ b/programs/src/printctl/Makefile @@ -3,9 +3,9 @@ MAKEFLAGS += -rR .SUFFIXES: -TOOLCHAIN_PREFIX := $(shell cd ../../.. && pwd)/toolchain/local/bin/x86_64-montauk- +include ../../mk/arch.mk ifeq ($(wildcard $(TOOLCHAIN_PREFIX)gcc),) - CXX = $(error x86_64-montauk toolchain not found. Run ./toolchain/build-montauk-toolchain.sh first) + CXX = $(error $(TOOLCHAIN_MISSING)) else CXX := $(TOOLCHAIN_PREFIX)g++ endif @@ -15,9 +15,8 @@ LIBC_LIB := ../../lib/libc BEARSSL := ../../lib/bearssl TLS_LIB := ../../lib/tls LINK_LD := ../../link.ld -BINDIR := ../../bin -OBJDIR := obj - +BINDIR := ../../bin$(ARCH_SUFFIX) +OBJDIR := obj$(ARCH_SUFFIX) CXXFLAGS := \ -std=gnu++20 \ -g -O2 -pipe \ @@ -31,10 +30,7 @@ CXXFLAGS := \ -fno-exceptions \ -ffunction-sections \ -fdata-sections \ - -mno-80387 \ - -mno-mmx \ - -mno-sse \ - -mno-sse2 \ + $(ARCH_NOFP_FLAGS) \ -I $(PROG_INC) \ -isystem $(PROG_INC)/libc \ -I $(BEARSSL)/inc @@ -51,9 +47,9 @@ DEPS := $(OBJDIR)/main.d all: $(TARGET) -$(TARGET): $(OBJDIR)/main.o $(LINK_LD) Makefile $(LIBC_LIB)/liblibc.a +$(TARGET): $(OBJDIR)/main.o $(LINK_LD) Makefile $(LIBC_LIB)/$(ARCH_OUT)liblibc.a mkdir -p $(BINDIR)/os - $(CXX) $(CXXFLAGS) $(LDFLAGS) $(OBJDIR)/main.o $(TLS_LIB)/libtls.a $(BEARSSL)/libbearssl.a $(LIBC_LIB)/liblibc.a -o $@ + $(CXX) $(CXXFLAGS) $(LDFLAGS) $(OBJDIR)/main.o $(TLS_LIB)/$(ARCH_OUT)libtls.a $(BEARSSL)/build$(ARCH_SUFFIX)/libbearssl.a $(LIBC_LIB)/$(ARCH_OUT)liblibc.a -o $@ $(OBJDIR)/main.o: main.cpp Makefile mkdir -p $(OBJDIR) diff --git a/programs/src/printd/Makefile b/programs/src/printd/Makefile index 554e1d9..0c2db90 100644 --- a/programs/src/printd/Makefile +++ b/programs/src/printd/Makefile @@ -3,9 +3,9 @@ MAKEFLAGS += -rR .SUFFIXES: -TOOLCHAIN_PREFIX := $(shell cd ../../.. && pwd)/toolchain/local/bin/x86_64-montauk- +include ../../mk/arch.mk ifeq ($(wildcard $(TOOLCHAIN_PREFIX)gcc),) - CXX = $(error x86_64-montauk toolchain not found. Run ./toolchain/build-montauk-toolchain.sh first) + CXX = $(error $(TOOLCHAIN_MISSING)) else CXX := $(TOOLCHAIN_PREFIX)g++ endif @@ -16,9 +16,8 @@ TLS_LIB := ../../lib/tls BEARSSL := ../../lib/bearssl JPEGWRITE := ../../lib/libjpegwrite LINK_LD := ../../link.ld -BINDIR := ../../bin -OBJDIR := obj - +BINDIR := ../../bin$(ARCH_SUFFIX) +OBJDIR := obj$(ARCH_SUFFIX) CXXFLAGS := \ -std=gnu++20 \ -g -O2 -pipe \ @@ -32,8 +31,7 @@ CXXFLAGS := \ -fno-exceptions \ -ffunction-sections \ -fdata-sections \ - -msse \ - -msse2 \ + $(ARCH_FP_FLAGS) \ -I $(PROG_INC) \ -isystem $(PROG_INC)/libc \ -I $(BEARSSL)/inc @@ -45,7 +43,7 @@ LDFLAGS := \ SRCS := main.cpp test_page_jpeg.cpp font_data.cpp stb_truetype_impl.cpp OBJS := $(addprefix $(OBJDIR)/,$(SRCS:.cpp=.o)) -LIBS := $(TLS_LIB)/libtls.a $(BEARSSL)/libbearssl.a $(JPEGWRITE)/libjpegwrite.a $(LIBC_LIB)/liblibc.a +LIBS := $(TLS_LIB)/$(ARCH_OUT)libtls.a $(BEARSSL)/build$(ARCH_SUFFIX)/libbearssl.a $(JPEGWRITE)/$(ARCH_OUT)libjpegwrite.a $(LIBC_LIB)/$(ARCH_OUT)liblibc.a TARGET := $(BINDIR)/os/printd.elf DEPS := $(OBJS:.o=.d) diff --git a/programs/src/printers/Makefile b/programs/src/printers/Makefile index 8bd17d0..4a331c3 100644 --- a/programs/src/printers/Makefile +++ b/programs/src/printers/Makefile @@ -4,17 +4,17 @@ MAKEFLAGS += -rR .SUFFIXES: -TOOLCHAIN_PREFIX := $(shell cd ../../.. && pwd)/toolchain/local/bin/x86_64-montauk- +include ../../mk/arch.mk ifeq ($(wildcard $(TOOLCHAIN_PREFIX)gcc),) - CXX = $(error x86_64-montauk toolchain not found. Run ./toolchain/build-montauk-toolchain.sh first) + CXX = $(error $(TOOLCHAIN_MISSING)) else CXX := $(TOOLCHAIN_PREFIX)g++ endif PROG_INC := ../../include LINK_LD := ../../link.ld -BINDIR := ../../bin -OBJDIR := obj +BINDIR := ../../bin$(ARCH_SUFFIX) +OBJDIR := obj$(ARCH_SUFFIX) LIBDIR := ../../lib CXXFLAGS := \ @@ -31,8 +31,7 @@ CXXFLAGS := \ -fno-exceptions \ -ffunction-sections \ -fdata-sections \ - -msse \ - -msse2 \ + $(ARCH_FP_FLAGS) \ -MMD -MP \ -I $(PROG_INC) \ -isystem $(PROG_INC)/libc \ @@ -47,7 +46,7 @@ SRCS := main.cpp stb_truetype_impl.cpp font_data.cpp OBJS := $(addprefix $(OBJDIR)/,$(SRCS:.cpp=.o)) TARGET := $(BINDIR)/apps/printers/printers.elf -LIBS := $(LIBDIR)/tls/libtls.a $(LIBDIR)/bearssl/libbearssl.a $(LIBDIR)/libc/liblibc.a +LIBS := $(LIBDIR)/tls/$(ARCH_OUT)libtls.a $(LIBDIR)/bearssl/build$(ARCH_SUFFIX)/libbearssl.a $(LIBDIR)/libc/$(ARCH_OUT)liblibc.a .PHONY: all clean diff --git a/programs/src/procmgr/Makefile b/programs/src/procmgr/Makefile index 96cf3fd..bccd521 100644 --- a/programs/src/procmgr/Makefile +++ b/programs/src/procmgr/Makefile @@ -4,17 +4,17 @@ MAKEFLAGS += -rR .SUFFIXES: -TOOLCHAIN_PREFIX := $(shell cd ../../.. && pwd)/toolchain/local/bin/x86_64-montauk- +include ../../mk/arch.mk ifeq ($(wildcard $(TOOLCHAIN_PREFIX)gcc),) - CXX = $(error x86_64-montauk toolchain not found. Run ./toolchain/build-montauk-toolchain.sh first) + CXX = $(error $(TOOLCHAIN_MISSING)) else CXX := $(TOOLCHAIN_PREFIX)g++ endif PROG_INC := ../../include LINK_LD := ../../link.ld -BINDIR := ../../bin -OBJDIR := obj +BINDIR := ../../bin$(ARCH_SUFFIX) +OBJDIR := obj$(ARCH_SUFFIX) LIBDIR := ../../lib CXXFLAGS := \ @@ -31,8 +31,7 @@ CXXFLAGS := \ -fno-exceptions \ -ffunction-sections \ -fdata-sections \ - -msse \ - -msse2 \ + $(ARCH_FP_FLAGS) \ -MMD -MP \ -I $(PROG_INC) \ -isystem $(PROG_INC)/libc @@ -51,9 +50,9 @@ TARGET := $(BINDIR)/apps/procmgr/procmgr.elf all: $(TARGET) -$(TARGET): $(OBJS) $(LINK_LD) Makefile $(LIBDIR)/libc/liblibc.a +$(TARGET): $(OBJS) $(LINK_LD) Makefile $(LIBDIR)/libc/$(ARCH_OUT)liblibc.a mkdir -p $(BINDIR)/apps/procmgr - $(CXX) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(LIBDIR)/libc/liblibc.a -o $@ + $(CXX) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(LIBDIR)/libc/$(ARCH_OUT)liblibc.a -o $@ $(OBJDIR)/%.o: %.cpp Makefile mkdir -p $(OBJDIR) diff --git a/programs/src/rtlsdr/Makefile b/programs/src/rtlsdr/Makefile index 636da5d..b50f027 100644 --- a/programs/src/rtlsdr/Makefile +++ b/programs/src/rtlsdr/Makefile @@ -1,18 +1,18 @@ MAKEFLAGS += -rR .SUFFIXES: -TOOLCHAIN_PREFIX := $(shell cd ../../.. && pwd)/toolchain/local/bin/x86_64-montauk- +include ../../mk/arch.mk CXX := $(TOOLCHAIN_PREFIX)g++ CC := $(TOOLCHAIN_PREFIX)gcc LD := $(TOOLCHAIN_PREFIX)ld STRIP := $(TOOLCHAIN_PREFIX)strip PROG_INC := ../../include -OBJDIR := obj -LIBOUTDIR := ../../bin/os +OBJDIR := obj$(ARCH_SUFFIX) +LIBOUTDIR := ../../bin$(ARCH_SUFFIX)/os LIBC_SRC := ../../lib/libc/libc.c GCC_INCLUDE := $(shell $(CC) -print-file-name=include) -CXXFLAGS := -std=gnu++20 -g -O2 -pipe -Wall -Wextra -ffreestanding -fno-stack-protector -fno-stack-check -fPIC -fvisibility=hidden -fno-rtti -fno-exceptions -ffunction-sections -fdata-sections -mno-80387 -mno-mmx -mno-sse -mno-sse2 -MMD -MP -I $(PROG_INC) -isystem $(PROG_INC)/libc +CXXFLAGS := -std=gnu++20 -g -O2 -pipe -Wall -Wextra -ffreestanding -fno-stack-protector -fno-stack-check -fPIC -fvisibility=hidden -fno-rtti -fno-exceptions -ffunction-sections -fdata-sections $(ARCH_NOFP_FLAGS) -MMD -MP -I $(PROG_INC) -isystem $(PROG_INC)/libc LIBC_CFLAGS := -std=gnu11 -O2 -ffreestanding -fno-stack-protector -fno-stack-check -fPIC -fvisibility=hidden -ffunction-sections -fdata-sections -isystem $(PROG_INC)/libc -isystem $(GCC_INCLUDE) -LDFLAGS := -shared --build-id=none --gc-sections --hash-style=sysv -m elf_x86_64 +LDFLAGS := -shared --build-id=none --gc-sections --hash-style=sysv -m $(ARCH_LD_EMULATION) OBJS := $(OBJDIR)/rtlsdr.o $(OBJDIR)/r820t.o TARGET := $(LIBOUTDIR)/rtlsdr.lib .PHONY: all clean diff --git a/programs/src/screenshot/Makefile b/programs/src/screenshot/Makefile index e9e47ad..6d3c1c8 100644 --- a/programs/src/screenshot/Makefile +++ b/programs/src/screenshot/Makefile @@ -6,9 +6,9 @@ MAKEFLAGS += -rR # ---- Toolchain ---- -TOOLCHAIN_PREFIX := $(shell cd ../../.. && pwd)/toolchain/local/bin/x86_64-montauk- +include ../../mk/arch.mk ifeq ($(wildcard $(TOOLCHAIN_PREFIX)gcc),) - CXX = $(error x86_64-montauk toolchain not found. Run ./toolchain/build-montauk-toolchain.sh first) + CXX = $(error $(TOOLCHAIN_MISSING)) else CXX := $(TOOLCHAIN_PREFIX)g++ endif @@ -23,8 +23,7 @@ LIBC_LIB := $(PROGRAMS)/lib/libc PROG_INC := $(PROGRAMS)/include LINK_LD := $(PROGRAMS)/link.ld BINDIR := $(PROGRAMS)/bin -OBJDIR := obj - +OBJDIR := obj$(ARCH_SUFFIX) # ---- Compiler flags ---- CXXFLAGS := \ @@ -41,8 +40,7 @@ CXXFLAGS := \ -fno-exceptions \ -ffunction-sections \ -fdata-sections \ - -msse \ - -msse2 \ + $(ARCH_FP_FLAGS) \ -MMD -MP \ -I $(PROG_INC) \ -isystem $(PROG_INC)/libc @@ -56,7 +54,7 @@ LDFLAGS := \ # ---- Libraries ---- -LIBS := $(JPEGWRITE_LIB)/libjpegwrite.a $(LOADER_LIB)/liblibloader.a $(LIBC_LIB)/liblibc.a +LIBS := $(JPEGWRITE_LIB)/$(ARCH_OUT)libjpegwrite.a $(LOADER_LIB)/$(ARCH_OUT)liblibloader.a $(LIBC_LIB)/$(ARCH_OUT)liblibc.a # ---- Source files ---- diff --git a/programs/src/sdr/Makefile b/programs/src/sdr/Makefile index 9a4e652..038bdb1 100644 --- a/programs/src/sdr/Makefile +++ b/programs/src/sdr/Makefile @@ -1,18 +1,18 @@ MAKEFLAGS += -rR .SUFFIXES: -TOOLCHAIN_PREFIX := $(shell cd ../../.. && pwd)/toolchain/local/bin/x86_64-montauk- +include ../../mk/arch.mk CXX := $(TOOLCHAIN_PREFIX)g++ PROG_INC := ../../include LINK_LD := ../../link.ld -OBJDIR := obj -TARGET := ../../bin/os/sdr.elf -LIBS := ../../lib/libloader/liblibloader.a ../../lib/libc/liblibc.a -CXXFLAGS := -std=gnu++20 -g -O2 -pipe -Wall -Wextra -ffreestanding -fno-stack-protector -fno-stack-check -fno-rtti -fno-exceptions -ffunction-sections -fdata-sections -mno-80387 -mno-mmx -mno-sse -mno-sse2 -I $(PROG_INC) -isystem $(PROG_INC)/libc +OBJDIR := obj$(ARCH_SUFFIX) +TARGET := ../../bin$(ARCH_SUFFIX)/os/sdr.elf +LIBS := ../../lib/libloader/$(ARCH_OUT)liblibloader.a ../../lib/libc/$(ARCH_OUT)liblibc.a +CXXFLAGS := -std=gnu++20 -g -O2 -pipe -Wall -Wextra -ffreestanding -fno-stack-protector -fno-stack-check -fno-rtti -fno-exceptions -ffunction-sections -fdata-sections $(ARCH_NOFP_FLAGS) -I $(PROG_INC) -isystem $(PROG_INC)/libc LDFLAGS := -nostdlib -Wl,--gc-sections -T $(LINK_LD) .PHONY: all clean all: $(TARGET) $(TARGET): $(OBJDIR)/main.o $(LIBS) $(LINK_LD) Makefile - mkdir -p ../../bin/os + mkdir -p ../../bin$(ARCH_SUFFIX)/os $(CXX) $(CXXFLAGS) $(LDFLAGS) $(OBJDIR)/main.o $(LIBS) -o $@ $(OBJDIR)/main.o: main.cpp Makefile mkdir -p $(OBJDIR) diff --git a/programs/src/settings/Makefile b/programs/src/settings/Makefile index a48f99b..db82536 100644 --- a/programs/src/settings/Makefile +++ b/programs/src/settings/Makefile @@ -3,23 +3,23 @@ MAKEFLAGS += -rR .SUFFIXES: -TOOLCHAIN_PREFIX := $(shell cd ../../.. && pwd)/toolchain/local/bin/x86_64-montauk- +include ../../mk/arch.mk ifeq ($(wildcard $(TOOLCHAIN_PREFIX)gcc),) - CXX = $(error x86_64-montauk toolchain not found. Run ./toolchain/build-montauk-toolchain.sh first) + CXX = $(error $(TOOLCHAIN_MISSING)) else CXX := $(TOOLCHAIN_PREFIX)g++ endif PROG_INC := ../../include LINK_LD := ../../link.ld -BINDIR := ../../bin -OBJDIR := obj +BINDIR := ../../bin$(ARCH_SUFFIX) +OBJDIR := obj$(ARCH_SUFFIX) LIBDIR := ../../lib BEARSSL := ../../lib/bearssl CXXFLAGS := -std=gnu++20 -g -O2 -pipe -Wall -Wextra -Wno-unused-parameter \ -Wno-unused-function -ffreestanding -fno-stack-protector -fno-stack-check \ - -fno-rtti -fno-exceptions -ffunction-sections -fdata-sections -msse -msse2 \ + -fno-rtti -fno-exceptions -ffunction-sections -fdata-sections $(ARCH_FP_FLAGS) \ -MMD -MP -I $(PROG_INC) -isystem $(PROG_INC)/libc \ -I $(BEARSSL)/inc LDFLAGS := -nostdlib -Wl,--gc-sections -T $(LINK_LD) @@ -28,7 +28,7 @@ SRCS := main.cpp stb_truetype_impl.cpp OBJS := $(addprefix $(OBJDIR)/,$(SRCS:.cpp=.o)) TARGET := $(BINDIR)/apps/settings/settings.elf # bearssl: montauk/user.h (account records) needs its headers and hashes. -LIBS := $(BEARSSL)/libbearssl.a $(LIBDIR)/libc/liblibc.a +LIBS := $(BEARSSL)/build$(ARCH_SUFFIX)/libbearssl.a $(LIBDIR)/libc/$(ARCH_OUT)liblibc.a .PHONY: all clean all: $(TARGET) diff --git a/programs/src/shell/Makefile b/programs/src/shell/Makefile index f44fc74..6748e86 100644 --- a/programs/src/shell/Makefile +++ b/programs/src/shell/Makefile @@ -6,9 +6,9 @@ MAKEFLAGS += -rR # ---- Toolchain ---- -TOOLCHAIN_PREFIX := $(shell cd ../../.. && pwd)/toolchain/local/bin/x86_64-montauk- +include ../../mk/arch.mk ifeq ($(wildcard $(TOOLCHAIN_PREFIX)gcc),) - CXX = $(error x86_64-montauk toolchain not found. Run ./toolchain/build-montauk-toolchain.sh first) + CXX = $(error $(TOOLCHAIN_MISSING)) else CXX := $(TOOLCHAIN_PREFIX)g++ endif @@ -17,10 +17,9 @@ endif PROG_INC := ../../include LINK_LD := ../../link.ld -BINDIR := ../../bin +BINDIR := ../../bin$(ARCH_SUFFIX) LIBDIR := ../../lib -OBJDIR := obj - +OBJDIR := obj$(ARCH_SUFFIX) # ---- C++ compiler flags ---- CXXFLAGS := \ @@ -36,10 +35,7 @@ CXXFLAGS := \ -fno-exceptions \ -ffunction-sections \ -fdata-sections \ - -mno-80387 \ - -mno-mmx \ - -mno-sse \ - -mno-sse2 \ + $(ARCH_NOFP_FLAGS) \ -MMD -MP \ -I . \ -I $(PROG_INC) @@ -64,9 +60,9 @@ TARGET := $(BINDIR)/os/shell.elf all: $(TARGET) -$(TARGET): $(OBJS) $(LINK_LD) Makefile $(LIBDIR)/libc/liblibc.a +$(TARGET): $(OBJS) $(LINK_LD) Makefile $(LIBDIR)/libc/$(ARCH_OUT)liblibc.a mkdir -p $(BINDIR)/os - $(CXX) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(LIBDIR)/libc/liblibc.a -o $@ + $(CXX) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(LIBDIR)/libc/$(ARCH_OUT)liblibc.a -o $@ $(OBJDIR)/%.o: %.cpp shell.h Makefile mkdir -p $(OBJDIR) diff --git a/programs/src/spreadsheet/Makefile b/programs/src/spreadsheet/Makefile index 4445f13..1955380 100644 --- a/programs/src/spreadsheet/Makefile +++ b/programs/src/spreadsheet/Makefile @@ -6,9 +6,9 @@ MAKEFLAGS += -rR # ---- Toolchain ---- -TOOLCHAIN_PREFIX := $(shell cd ../../.. && pwd)/toolchain/local/bin/x86_64-montauk- +include ../../mk/arch.mk ifeq ($(wildcard $(TOOLCHAIN_PREFIX)gcc),) - CXX = $(error x86_64-montauk toolchain not found. Run ./toolchain/build-montauk-toolchain.sh first) + CXX = $(error $(TOOLCHAIN_MISSING)) else CXX := $(TOOLCHAIN_PREFIX)g++ endif @@ -17,8 +17,8 @@ endif PROG_INC := ../../include LINK_LD := ../../link.ld -BINDIR := ../../bin -OBJDIR := obj +BINDIR := ../../bin$(ARCH_SUFFIX) +OBJDIR := obj$(ARCH_SUFFIX) LIBDIR := ../../lib # ---- Compiler flags ---- @@ -37,8 +37,7 @@ CXXFLAGS := \ -fno-exceptions \ -ffunction-sections \ -fdata-sections \ - -msse \ - -msse2 \ + $(ARCH_FP_FLAGS) \ -I $(PROG_INC) \ -isystem $(PROG_INC)/libc @@ -57,15 +56,15 @@ OBJS := $(addprefix $(OBJDIR)/,$(SRCS:.cpp=.o)) # ---- Target ---- TARGET := $(BINDIR)/apps/spreadsheet/spreadsheet.elf -LOADER_LIB := $(LIBDIR)/libloader/liblibloader.a +LOADER_LIB := $(LIBDIR)/libloader/$(ARCH_OUT)liblibloader.a .PHONY: all clean all: $(TARGET) -$(TARGET): $(OBJS) $(LINK_LD) Makefile $(LOADER_LIB) $(LIBDIR)/libc/liblibc.a +$(TARGET): $(OBJS) $(LINK_LD) Makefile $(LOADER_LIB) $(LIBDIR)/libc/$(ARCH_OUT)liblibc.a mkdir -p $(BINDIR)/apps/spreadsheet - $(CXX) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(LOADER_LIB) $(LIBDIR)/libc/liblibc.a -o $@ + $(CXX) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(LOADER_LIB) $(LIBDIR)/libc/$(ARCH_OUT)liblibc.a -o $@ $(OBJDIR)/%.o: %.cpp Makefile mkdir -p $(OBJDIR) diff --git a/programs/src/sshd/Makefile b/programs/src/sshd/Makefile index 0d04f72..9c423c0 100644 --- a/programs/src/sshd/Makefile +++ b/programs/src/sshd/Makefile @@ -1,18 +1,18 @@ MAKEFLAGS += -rR .SUFFIXES: -TOOLCHAIN_PREFIX := $(shell cd ../../.. && pwd)/toolchain/local/bin/x86_64-montauk- +include ../../mk/arch.mk CXX := $(TOOLCHAIN_PREFIX)g++ PROG_INC := ../../include LIBDIR := ../../lib LINK_LD := ../../link.ld -OBJDIR := obj -TARGET := ../../bin/os/sshd.elf +OBJDIR := obj$(ARCH_SUFFIX) +TARGET := ../../bin$(ARCH_SUFFIX)/os/sshd.elf CXXFLAGS := -std=gnu++20 -g -O2 -pipe -Wall -Wextra -ffreestanding \ -fno-stack-protector -fno-stack-check -fno-rtti -fno-exceptions \ - -ffunction-sections -fdata-sections -mno-80387 -mno-mmx -mno-sse -mno-sse2 \ + -ffunction-sections -fdata-sections $(ARCH_NOFP_FLAGS) \ -MMD -MP -I $(PROG_INC) -I $(LIBDIR)/bearssl/inc -isystem $(PROG_INC)/libc LDFLAGS := -nostdlib -Wl,--gc-sections -T $(LINK_LD) -LIBS := $(LIBDIR)/bearssl/libbearssl.a $(LIBDIR)/libc/liblibc.a +LIBS := $(LIBDIR)/bearssl/build$(ARCH_SUFFIX)/libbearssl.a $(LIBDIR)/libc/$(ARCH_OUT)liblibc.a .PHONY: all clean all: $(TARGET) $(TARGET): $(OBJDIR)/main.o $(LIBS) $(LINK_LD) Makefile diff --git a/programs/src/sshserver/Makefile b/programs/src/sshserver/Makefile index bfc7334..552f217 100644 --- a/programs/src/sshserver/Makefile +++ b/programs/src/sshserver/Makefile @@ -1,21 +1,21 @@ MAKEFLAGS += -rR .SUFFIXES: -TOOLCHAIN_PREFIX := $(shell cd ../../.. && pwd)/toolchain/local/bin/x86_64-montauk- +include ../../mk/arch.mk CXX := $(TOOLCHAIN_PREFIX)g++ PROG_INC := ../../include LINK_LD := ../../link.ld -BINDIR := ../../bin -OBJDIR := obj +BINDIR := ../../bin$(ARCH_SUFFIX) +OBJDIR := obj$(ARCH_SUFFIX) LIBDIR := ../../lib CXXFLAGS := -std=gnu++20 -g -O2 -pipe -Wall -Wextra -Wno-unused-parameter \ -ffreestanding -fno-stack-protector -fno-stack-check -fno-rtti -fno-exceptions \ - -ffunction-sections -fdata-sections -msse -msse2 -MMD -MP -I $(PROG_INC) \ + -ffunction-sections -fdata-sections $(ARCH_FP_FLAGS) -MMD -MP -I $(PROG_INC) \ -I $(LIBDIR)/bearssl/inc -isystem $(PROG_INC)/libc LDFLAGS := -nostdlib -Wl,--gc-sections -T $(LINK_LD) SRCS := main.cpp stb_truetype_impl.cpp OBJS := $(addprefix $(OBJDIR)/,$(SRCS:.cpp=.o)) TARGET := $(BINDIR)/apps/sshserver/sshserver.elf -LIBS := $(LIBDIR)/bearssl/libbearssl.a $(LIBDIR)/libc/liblibc.a +LIBS := $(LIBDIR)/bearssl/build$(ARCH_SUFFIX)/libbearssl.a $(LIBDIR)/libc/$(ARCH_OUT)liblibc.a .PHONY: all clean all: $(TARGET) $(TARGET): $(OBJS) $(LINK_LD) Makefile $(LIBS) diff --git a/programs/src/syslog/Makefile b/programs/src/syslog/Makefile index ee919ad..84db24e 100644 --- a/programs/src/syslog/Makefile +++ b/programs/src/syslog/Makefile @@ -4,17 +4,17 @@ MAKEFLAGS += -rR .SUFFIXES: -TOOLCHAIN_PREFIX := $(shell cd ../../.. && pwd)/toolchain/local/bin/x86_64-montauk- +include ../../mk/arch.mk ifeq ($(wildcard $(TOOLCHAIN_PREFIX)gcc),) - CXX = $(error x86_64-montauk toolchain not found. Run ./toolchain/build-montauk-toolchain.sh first) + CXX = $(error $(TOOLCHAIN_MISSING)) else CXX := $(TOOLCHAIN_PREFIX)g++ endif PROG_INC := ../../include LINK_LD := ../../link.ld -BINDIR := ../../bin -OBJDIR := obj +BINDIR := ../../bin$(ARCH_SUFFIX) +OBJDIR := obj$(ARCH_SUFFIX) LIBDIR := ../../lib CXXFLAGS := \ @@ -31,8 +31,7 @@ CXXFLAGS := \ -fno-exceptions \ -ffunction-sections \ -fdata-sections \ - -msse \ - -msse2 \ + $(ARCH_FP_FLAGS) \ -I $(PROG_INC) \ -isystem $(PROG_INC)/libc @@ -51,9 +50,9 @@ TARGET := $(BINDIR)/apps/syslog/syslog.elf all: $(TARGET) -$(TARGET): $(OBJS) $(LINK_LD) Makefile $(LIBDIR)/libc/liblibc.a $(LIBDIR)/libloader/liblibloader.a +$(TARGET): $(OBJS) $(LINK_LD) Makefile $(LIBDIR)/libc/$(ARCH_OUT)liblibc.a $(LIBDIR)/libloader/$(ARCH_OUT)liblibloader.a mkdir -p $(BINDIR)/apps/syslog - $(CXX) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(LIBDIR)/libc/liblibc.a $(LIBDIR)/libloader/liblibloader.a -o $@ + $(CXX) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(LIBDIR)/libc/$(ARCH_OUT)liblibc.a $(LIBDIR)/libloader/$(ARCH_OUT)liblibloader.a -o $@ $(OBJDIR)/%.o: %.cpp Makefile mkdir -p $(OBJDIR) diff --git a/programs/src/tcc/Makefile b/programs/src/tcc/Makefile index 40298c7..46f77be 100644 --- a/programs/src/tcc/Makefile +++ b/programs/src/tcc/Makefile @@ -6,11 +6,11 @@ MAKEFLAGS += -rR # ---- Toolchain ---- -TOOLCHAIN_PREFIX := $(shell cd ../../.. && pwd)/toolchain/local/bin/x86_64-montauk- +include ../../mk/arch.mk ifeq ($(wildcard $(TOOLCHAIN_PREFIX)gcc),) - CC = $(error x86_64-montauk toolchain not found. Run ./toolchain/build-montauk-toolchain.sh first) - CXX = $(error x86_64-montauk toolchain not found. Run ./toolchain/build-montauk-toolchain.sh first) - AR = $(error x86_64-montauk toolchain not found. Run ./toolchain/build-montauk-toolchain.sh first) + CC = $(error $(TOOLCHAIN_MISSING)) + CXX = $(error $(TOOLCHAIN_MISSING)) + AR = $(error $(TOOLCHAIN_MISSING)) else CC := $(TOOLCHAIN_PREFIX)gcc CXX := $(TOOLCHAIN_PREFIX)g++ @@ -21,8 +21,8 @@ endif PROG_INC := ../../include LIBDIR := ../../lib -OBJDIR := obj -BINDIR := ../../bin/os +OBJDIR := obj$(ARCH_SUFFIX) +BINDIR := ../../bin$(ARCH_SUFFIX)/os # ---- Compiler flags ---- @@ -42,8 +42,7 @@ CFLAGS := \ -fno-stack-check \ -ffunction-sections \ -fdata-sections \ - -msse \ - -msse2 \ + $(ARCH_FP_FLAGS) \ -fno-tree-loop-distribute-patterns \ -D__MONTAUKOS__=1 \ -DONE_SOURCE=0 \ @@ -93,7 +92,7 @@ TARGET := $(BINDIR)/tcc.elf # ---- CRT objects (staged from shared libc) ---- SHARED_CRT_DIR := $(LIBDIR)/libc -CRT_DIR := ../../bin/sdk/tcc/lib +CRT_DIR := ../../bin$(ARCH_SUFFIX)/sdk/tcc/lib CRT_OBJS := $(CRT_DIR)/crt1.o $(CRT_DIR)/crti.o $(CRT_DIR)/crtn.o # ---- Rules ---- @@ -102,9 +101,9 @@ CRT_OBJS := $(CRT_DIR)/crt1.o $(CRT_DIR)/crti.o $(CRT_DIR)/crtn.o all: $(TARGET) $(CRT_OBJS) $(CRT_DIR)/libc.a -$(TARGET): $(ALL_OBJS) $(LIBDIR)/libc/liblibc.a +$(TARGET): $(ALL_OBJS) $(LIBDIR)/libc/$(ARCH_OUT)liblibc.a @mkdir -p $(BINDIR) - $(CC) $(CFLAGS) $(LDFLAGS) $(ALL_OBJS) $(LIBDIR)/libc/liblibc.a -lgcc -o $@ + $(CC) $(CFLAGS) $(LDFLAGS) $(ALL_OBJS) $(LIBDIR)/libc/$(ARCH_OUT)liblibc.a -lgcc -o $@ $(OBJDIR)/%.o: %.c Makefile config.h montauk_compat.h @mkdir -p $(OBJDIR) @@ -114,7 +113,7 @@ $(OBJDIR)/%.o: %.S Makefile @mkdir -p $(OBJDIR) $(CC) $(CFLAGS) -MMD -MP -c $< -o $@ -$(SHARED_CRT_DIR)/liblibc.a $(SHARED_CRT_DIR)/liblibc-full.a $(SHARED_CRT_DIR)/crt1.o $(SHARED_CRT_DIR)/crti.o $(SHARED_CRT_DIR)/crtn.o: +$(SHARED_CRT_DIR)/$(ARCH_OUT)liblibc.a $(SHARED_CRT_DIR)/liblibc-full.a $(SHARED_CRT_DIR)/crt1.o $(SHARED_CRT_DIR)/crti.o $(SHARED_CRT_DIR)/crtn.o: $(MAKE) -C $(SHARED_CRT_DIR) $(CRT_DIR)/crt1.o: $(SHARED_CRT_DIR)/crt1.o @@ -132,7 +131,7 @@ $(CRT_DIR)/crtn.o: $(SHARED_CRT_DIR)/crtn.o # liblibc-full.a, not liblibc.a: programs compiled on-OS with tcc cannot pass # -u _pf_putfloat, so this sysroot ships the variant with the printf float path # already bound in. See lib/libc/Makefile. -$(CRT_DIR)/libc.a: $(LIBDIR)/libc/liblibc-full.a +$(CRT_DIR)/libc.a: $(LIBDIR)/libc/$(ARCH_OUT)liblibc-full.a @mkdir -p $(CRT_DIR) cp $< $@ diff --git a/programs/src/terminal/Makefile b/programs/src/terminal/Makefile index cedf13c..4b67f05 100644 --- a/programs/src/terminal/Makefile +++ b/programs/src/terminal/Makefile @@ -4,17 +4,17 @@ MAKEFLAGS += -rR .SUFFIXES: -TOOLCHAIN_PREFIX := $(shell cd ../../.. && pwd)/toolchain/local/bin/x86_64-montauk- +include ../../mk/arch.mk ifeq ($(wildcard $(TOOLCHAIN_PREFIX)gcc),) - CXX = $(error x86_64-montauk toolchain not found. Run ./toolchain/build-montauk-toolchain.sh first) + CXX = $(error $(TOOLCHAIN_MISSING)) else CXX := $(TOOLCHAIN_PREFIX)g++ endif PROG_INC := ../../include LINK_LD := ../../link.ld -BINDIR := ../../bin -OBJDIR := obj +BINDIR := ../../bin$(ARCH_SUFFIX) +OBJDIR := obj$(ARCH_SUFFIX) LIBDIR := ../../lib CXXFLAGS := \ @@ -31,8 +31,7 @@ CXXFLAGS := \ -fno-exceptions \ -ffunction-sections \ -fdata-sections \ - -msse \ - -msse2 \ + $(ARCH_FP_FLAGS) \ -I $(PROG_INC) \ -isystem $(PROG_INC)/libc @@ -51,9 +50,9 @@ TARGET := $(BINDIR)/apps/terminal/terminal.elf all: $(TARGET) -$(TARGET): $(OBJS) $(LINK_LD) Makefile $(LIBDIR)/libc/liblibc.a +$(TARGET): $(OBJS) $(LINK_LD) Makefile $(LIBDIR)/libc/$(ARCH_OUT)liblibc.a mkdir -p $(BINDIR)/apps/terminal - $(CXX) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(LIBDIR)/libc/liblibc.a -o $@ + $(CXX) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(LIBDIR)/libc/$(ARCH_OUT)liblibc.a -o $@ $(OBJDIR)/%.o: %.cpp Makefile mkdir -p $(OBJDIR) diff --git a/programs/src/texteditor/Makefile b/programs/src/texteditor/Makefile index 64ef351..43dc5b0 100644 --- a/programs/src/texteditor/Makefile +++ b/programs/src/texteditor/Makefile @@ -6,9 +6,9 @@ MAKEFLAGS += -rR # ---- Toolchain ---- -TOOLCHAIN_PREFIX := $(shell cd ../../.. && pwd)/toolchain/local/bin/x86_64-montauk- +include ../../mk/arch.mk ifeq ($(wildcard $(TOOLCHAIN_PREFIX)gcc),) - CXX = $(error x86_64-montauk toolchain not found. Run ./toolchain/build-montauk-toolchain.sh first) + CXX = $(error $(TOOLCHAIN_MISSING)) else CXX := $(TOOLCHAIN_PREFIX)g++ endif @@ -17,8 +17,8 @@ endif PROG_INC := ../../include LINK_LD := ../../link.ld -BINDIR := ../../bin -OBJDIR := obj +BINDIR := ../../bin$(ARCH_SUFFIX) +OBJDIR := obj$(ARCH_SUFFIX) LIBDIR := ../../lib # ---- Compiler flags ---- @@ -37,8 +37,7 @@ CXXFLAGS := \ -fno-exceptions \ -ffunction-sections \ -fdata-sections \ - -msse \ - -msse2 \ + $(ARCH_FP_FLAGS) \ -I $(PROG_INC) \ -isystem $(PROG_INC)/libc @@ -57,15 +56,15 @@ OBJS := $(addprefix $(OBJDIR)/,$(SRCS:.cpp=.o)) # ---- Target ---- TARGET := $(BINDIR)/apps/texteditor/texteditor.elf -LOADER_LIB := $(LIBDIR)/libloader/liblibloader.a +LOADER_LIB := $(LIBDIR)/libloader/$(ARCH_OUT)liblibloader.a .PHONY: all clean all: $(TARGET) -$(TARGET): $(OBJS) $(LINK_LD) Makefile $(LOADER_LIB) $(LIBDIR)/libc/liblibc.a +$(TARGET): $(OBJS) $(LINK_LD) Makefile $(LOADER_LIB) $(LIBDIR)/libc/$(ARCH_OUT)liblibc.a mkdir -p $(BINDIR)/apps/texteditor - $(CXX) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(LOADER_LIB) $(LIBDIR)/libc/liblibc.a -o $@ + $(CXX) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(LOADER_LIB) $(LIBDIR)/libc/$(ARCH_OUT)liblibc.a -o $@ $(OBJDIR)/%.o: %.cpp Makefile mkdir -p $(OBJDIR) diff --git a/programs/src/timezone/Makefile b/programs/src/timezone/Makefile index 3d5c3f9..9eb56b2 100644 --- a/programs/src/timezone/Makefile +++ b/programs/src/timezone/Makefile @@ -4,17 +4,17 @@ MAKEFLAGS += -rR .SUFFIXES: -TOOLCHAIN_PREFIX := $(shell cd ../../.. && pwd)/toolchain/local/bin/x86_64-montauk- +include ../../mk/arch.mk ifeq ($(wildcard $(TOOLCHAIN_PREFIX)gcc),) - CXX = $(error x86_64-montauk toolchain not found. Run ./toolchain/build-montauk-toolchain.sh first) + CXX = $(error $(TOOLCHAIN_MISSING)) else CXX := $(TOOLCHAIN_PREFIX)g++ endif PROG_INC := ../../include LINK_LD := ../../link.ld -BINDIR := ../../bin -OBJDIR := obj +BINDIR := ../../bin$(ARCH_SUFFIX) +OBJDIR := obj$(ARCH_SUFFIX) LIBDIR := ../../lib CXXFLAGS := \ @@ -31,8 +31,7 @@ CXXFLAGS := \ -fno-exceptions \ -ffunction-sections \ -fdata-sections \ - -msse \ - -msse2 \ + $(ARCH_FP_FLAGS) \ -MMD -MP \ -I $(PROG_INC) \ -isystem $(PROG_INC)/libc @@ -46,7 +45,7 @@ SRCS := main.cpp stb_truetype_impl.cpp font_data.cpp OBJS := $(addprefix $(OBJDIR)/,$(SRCS:.cpp=.o)) TARGET := $(BINDIR)/apps/timezone/timezone.elf -LIBS := $(LIBDIR)/libc/liblibc.a +LIBS := $(LIBDIR)/libc/$(ARCH_OUT)liblibc.a .PHONY: all clean diff --git a/programs/src/video/Makefile b/programs/src/video/Makefile index eefab16..8684b19 100644 --- a/programs/src/video/Makefile +++ b/programs/src/video/Makefile @@ -4,17 +4,17 @@ MAKEFLAGS += -rR .SUFFIXES: -TOOLCHAIN_PREFIX := $(shell cd ../../.. && pwd)/toolchain/local/bin/x86_64-montauk- +include ../../mk/arch.mk ifeq ($(wildcard $(TOOLCHAIN_PREFIX)gcc),) - CXX = $(error x86_64-montauk toolchain not found. Run ./toolchain/build-montauk-toolchain.sh first) + CXX = $(error $(TOOLCHAIN_MISSING)) else CXX := $(TOOLCHAIN_PREFIX)g++ endif PROG_INC := ../../include LINK_LD := ../../link.ld -BINDIR := ../../bin -OBJDIR := obj +BINDIR := ../../bin$(ARCH_SUFFIX) +OBJDIR := obj$(ARCH_SUFFIX) LIBDIR := ../../lib CXXFLAGS := \ @@ -31,8 +31,7 @@ CXXFLAGS := \ -fno-exceptions \ -ffunction-sections \ -fdata-sections \ - -msse \ - -msse2 \ + $(ARCH_FP_FLAGS) \ -I $(PROG_INC) \ -I . \ -isystem $(PROG_INC)/libc @@ -51,9 +50,9 @@ TARGET := $(BINDIR)/apps/video/video.elf all: $(TARGET) -$(TARGET): $(OBJS) $(LINK_LD) Makefile $(LIBDIR)/libc/liblibc.a +$(TARGET): $(OBJS) $(LINK_LD) Makefile $(LIBDIR)/libc/$(ARCH_OUT)liblibc.a mkdir -p $(BINDIR)/apps/video - $(CXX) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(LIBDIR)/libc/liblibc.a -o $@ + $(CXX) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(LIBDIR)/libc/$(ARCH_OUT)liblibc.a -o $@ HEADERS := avi.hpp diff --git a/programs/src/weather/Makefile b/programs/src/weather/Makefile index 2fc4f39..da5ab6b 100644 --- a/programs/src/weather/Makefile +++ b/programs/src/weather/Makefile @@ -6,9 +6,9 @@ MAKEFLAGS += -rR # ---- Toolchain ---- -TOOLCHAIN_PREFIX := $(shell cd ../../.. && pwd)/toolchain/local/bin/x86_64-montauk- +include ../../mk/arch.mk ifeq ($(wildcard $(TOOLCHAIN_PREFIX)gcc),) - CXX = $(error x86_64-montauk toolchain not found. Run ./toolchain/build-montauk-toolchain.sh first) + CXX = $(error $(TOOLCHAIN_MISSING)) else CXX := $(TOOLCHAIN_PREFIX)g++ endif @@ -21,9 +21,8 @@ LIBC_LIB := ../../lib/libc LIBC_INC := ../../include/libc PROG_INC := ../../include LINK_LD := ../../link.ld -BINDIR := ../../bin -OBJDIR := obj - +BINDIR := ../../bin$(ARCH_SUFFIX) +OBJDIR := obj$(ARCH_SUFFIX) # ---- Compiler flags ---- CXXFLAGS := \ @@ -40,8 +39,7 @@ CXXFLAGS := \ -fno-exceptions \ -ffunction-sections \ -fdata-sections \ - -msse \ - -msse2 \ + $(ARCH_FP_FLAGS) \ -I $(PROG_INC) \ -isystem $(LIBC_INC) \ -I $(BEARSSL)/inc @@ -55,7 +53,7 @@ LDFLAGS := \ # ---- Libraries ---- -LIBS := $(TLS_LIB)/libtls.a $(BEARSSL)/libbearssl.a $(LIBC_LIB)/liblibc.a +LIBS := $(TLS_LIB)/$(ARCH_OUT)libtls.a $(BEARSSL)/build$(ARCH_SUFFIX)/libbearssl.a $(LIBC_LIB)/$(ARCH_OUT)liblibc.a # ---- Source files ---- diff --git a/programs/src/wiki/Makefile b/programs/src/wiki/Makefile index 8f10a39..0be6971 100644 --- a/programs/src/wiki/Makefile +++ b/programs/src/wiki/Makefile @@ -6,9 +6,9 @@ MAKEFLAGS += -rR # ---- Toolchain ---- -TOOLCHAIN_PREFIX := $(shell cd ../../.. && pwd)/toolchain/local/bin/x86_64-montauk- +include ../../mk/arch.mk ifeq ($(wildcard $(TOOLCHAIN_PREFIX)gcc),) - CXX = $(error x86_64-montauk toolchain not found. Run ./toolchain/build-montauk-toolchain.sh first) + CXX = $(error $(TOOLCHAIN_MISSING)) else CXX := $(TOOLCHAIN_PREFIX)g++ endif @@ -21,9 +21,8 @@ LIBC_LIB := ../../lib/libc LIBC_INC := ../../include/libc PROG_INC := ../../include LINK_LD := ../../link.ld -BINDIR := ../../bin -OBJDIR := obj - +BINDIR := ../../bin$(ARCH_SUFFIX) +OBJDIR := obj$(ARCH_SUFFIX) # ---- Compiler flags ---- CXXFLAGS := \ @@ -39,10 +38,7 @@ CXXFLAGS := \ -fno-exceptions \ -ffunction-sections \ -fdata-sections \ - -mno-80387 \ - -mno-mmx \ - -mno-sse \ - -mno-sse2 \ + $(ARCH_NOFP_FLAGS) \ -I $(PROG_INC) \ -isystem $(LIBC_INC) \ -I $(BEARSSL)/inc @@ -56,7 +52,7 @@ LDFLAGS := \ # ---- Libraries ---- -LIBS := $(TLS_LIB)/libtls.a $(BEARSSL)/libbearssl.a $(LIBC_LIB)/liblibc.a +LIBS := $(TLS_LIB)/$(ARCH_OUT)libtls.a $(BEARSSL)/build$(ARCH_SUFFIX)/libbearssl.a $(LIBC_LIB)/$(ARCH_OUT)liblibc.a # ---- Target ---- diff --git a/programs/src/wikipedia/Makefile b/programs/src/wikipedia/Makefile index 5e72f1f..cc390af 100644 --- a/programs/src/wikipedia/Makefile +++ b/programs/src/wikipedia/Makefile @@ -6,9 +6,9 @@ MAKEFLAGS += -rR # ---- Toolchain ---- -TOOLCHAIN_PREFIX := $(shell cd ../../.. && pwd)/toolchain/local/bin/x86_64-montauk- +include ../../mk/arch.mk ifeq ($(wildcard $(TOOLCHAIN_PREFIX)gcc),) - CXX = $(error x86_64-montauk toolchain not found. Run ./toolchain/build-montauk-toolchain.sh first) + CXX = $(error $(TOOLCHAIN_MISSING)) else CXX := $(TOOLCHAIN_PREFIX)g++ endif @@ -21,9 +21,8 @@ LIBC_LIB := ../../lib/libc LIBC_INC := ../../include/libc PROG_INC := ../../include LINK_LD := ../../link.ld -BINDIR := ../../bin -OBJDIR := obj - +BINDIR := ../../bin$(ARCH_SUFFIX) +OBJDIR := obj$(ARCH_SUFFIX) # ---- Compiler flags ---- CXXFLAGS := \ @@ -40,8 +39,7 @@ CXXFLAGS := \ -fno-exceptions \ -ffunction-sections \ -fdata-sections \ - -msse \ - -msse2 \ + $(ARCH_FP_FLAGS) \ -I $(PROG_INC) \ -isystem $(LIBC_INC) \ -I $(BEARSSL)/inc @@ -55,7 +53,7 @@ LDFLAGS := \ # ---- Libraries ---- -LIBS := $(TLS_LIB)/libtls.a $(BEARSSL)/libbearssl.a $(LIBC_LIB)/liblibc.a +LIBS := $(TLS_LIB)/$(ARCH_OUT)libtls.a $(BEARSSL)/build$(ARCH_SUFFIX)/libbearssl.a $(LIBC_LIB)/$(ARCH_OUT)liblibc.a # ---- Source files ---- diff --git a/programs/src/wordprocessor/Makefile b/programs/src/wordprocessor/Makefile index ef8b33a..4390608 100644 --- a/programs/src/wordprocessor/Makefile +++ b/programs/src/wordprocessor/Makefile @@ -4,17 +4,17 @@ MAKEFLAGS += -rR .SUFFIXES: -TOOLCHAIN_PREFIX := $(shell cd ../../.. && pwd)/toolchain/local/bin/x86_64-montauk- +include ../../mk/arch.mk ifeq ($(wildcard $(TOOLCHAIN_PREFIX)gcc),) - CXX = $(error x86_64-montauk toolchain not found. Run ./toolchain/build-montauk-toolchain.sh first) + CXX = $(error $(TOOLCHAIN_MISSING)) else CXX := $(TOOLCHAIN_PREFIX)g++ endif PROG_INC := ../../include LINK_LD := ../../link.ld -BINDIR := ../../bin -OBJDIR := obj +BINDIR := ../../bin$(ARCH_SUFFIX) +OBJDIR := obj$(ARCH_SUFFIX) LIBDIR := ../../lib CXXFLAGS := \ @@ -31,8 +31,7 @@ CXXFLAGS := \ -fno-exceptions \ -ffunction-sections \ -fdata-sections \ - -msse \ - -msse2 \ + $(ARCH_FP_FLAGS) \ -I $(PROG_INC) \ -isystem $(PROG_INC)/libc \ -I ../../lib/bearssl/inc @@ -44,8 +43,8 @@ LDFLAGS := \ SRCS := main.cpp document.cpp render.cpp input.cpp print_export.cpp stb_truetype_impl.cpp OBJS := $(addprefix $(OBJDIR)/,$(SRCS:.cpp=.o)) -LOADER_LIB := $(LIBDIR)/libloader/liblibloader.a -LIBS := $(LOADER_LIB) $(LIBDIR)/tls/libtls.a $(LIBDIR)/bearssl/libbearssl.a $(LIBDIR)/libjpegwrite/libjpegwrite.a $(LIBDIR)/libc/liblibc.a +LOADER_LIB := $(LIBDIR)/libloader/$(ARCH_OUT)liblibloader.a +LIBS := $(LOADER_LIB) $(LIBDIR)/tls/$(ARCH_OUT)libtls.a $(LIBDIR)/bearssl/build$(ARCH_SUFFIX)/libbearssl.a $(LIBDIR)/libjpegwrite/$(ARCH_OUT)libjpegwrite.a $(LIBDIR)/libc/$(ARCH_OUT)liblibc.a TARGET := $(BINDIR)/apps/wordprocessor/wordprocessor.elf diff --git a/scripts/copy_fonts.sh b/scripts/copy_fonts.sh index d0a68e7..d4abddc 100755 --- a/scripts/copy_fonts.sh +++ b/scripts/copy_fonts.sh @@ -8,7 +8,7 @@ set -e SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" -FONT_DST="$PROJECT_ROOT/programs/bin/os/fonts" +FONT_DST="$PROJECT_ROOT/programs/${PROGRAMS_BIN:-bin}/os/fonts" mkdir -p "$FONT_DST" diff --git a/scripts/copy_icons.sh b/scripts/copy_icons.sh index ba89a0e..ac0e715 100755 --- a/scripts/copy_icons.sh +++ b/scripts/copy_icons.sh @@ -9,7 +9,7 @@ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" ICON_SRC="$PROJECT_ROOT/programs/gui/icons/Flat-Remix-Blue-Light-darkPanel" -ICON_DST="$PROJECT_ROOT/programs/bin/os/icons" +ICON_DST="$PROJECT_ROOT/programs/${PROGRAMS_BIN:-bin}/os/icons" mkdir -p "$ICON_DST" diff --git a/scripts/install_apps.sh b/scripts/install_apps.sh index 21fad15..cc1c896 100755 --- a/scripts/install_apps.sh +++ b/scripts/install_apps.sh @@ -9,7 +9,8 @@ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" SRC="$PROJECT_ROOT/programs/src" -BIN="$PROJECT_ROOT/programs/bin" +# PROGRAMS_BIN: the output tree, bin (x86_64) or bin-. +BIN="$PROJECT_ROOT/programs/${PROGRAMS_BIN:-bin}" ICON_SRC="$PROJECT_ROOT/programs/gui/icons/Flat-Remix-Blue-Light-darkPanel" # App definitions: name|icon_source_path diff --git a/toolchain/README.md b/toolchain/README.md index af9546b..e7b4c61 100644 --- a/toolchain/README.md +++ b/toolchain/README.md @@ -6,11 +6,16 @@ Two cross toolchains live here, both installed to `toolchain/local/`: |--------|--------|---------| | `build-toolchain.sh` | `x86_64-elf` | Bare-metal compiler for the kernel | | `build-montauk-toolchain.sh` | `x86_64-montauk` | OS-aware compiler for userspace programs | +| `build-montauk-toolchain.sh aarch64` | `aarch64-montauk` | the same for the ARM port | Both use Binutils 2.43.1 + GCC 14.2.0 and share the source trees in `src/`. The Montauk target is added by the patches in `patches/` plus the target header `files/montauk.h` (installed as -`gcc/config/montauk.h` in the GCC tree). +`gcc/config/montauk.h` in the GCC tree). The AArch64 target is a second +pair of patches (`*-montauk-aarch64.patch`) applied on top, with its +target header `files/aarch64-montauk.h` (installed as +`gcc/config/aarch64/montauk.h`). The ARM kernel is built with clang, not +with a bare-metal GCC. ## The x86_64-montauk target @@ -42,6 +47,27 @@ The in-tree programs are built `-fno-exceptions -fno-rtti` (the project convention), but that is a project style choice, not a toolchain limit — see the STL section below. +## The aarch64-montauk target + +`./toolchain/build-montauk-toolchain.sh aarch64` builds +`aarch64-montauk-gcc/g++` next to the x86 compilers, with its sysroot in +`toolchain/sysroot-aarch64/` and its libc from +`programs/lib/libc/build-aarch64/`. On a first build the libc cannot be +compiled yet, so the script builds GCC against the headers alone and +completes the sysroot afterwards. The target matches x86_64-montauk +(static `ET_EXEC` at 0x400000, 4 KiB segment alignment, the same crt +files and `-lc`), plus two defaults chosen so the shared userspace +behaves the same on both architectures: + +- `-fsigned-char`: plain `char` is signed, as on x86 (AAPCS64 makes it + unsigned). The GUI's CP1252 text handling assumes signed bytes. +- `-mno-outline-atomics`: inline LL/SC atomics. Outline atomics choose + LSE at run time from HWCAP, which Montauk does not provide, and their + helpers are in libgcc, which `-nostdlib` programs never link. + +`make ARCH=aarch64` at the repository root builds the userspace with it +(into `programs/bin-aarch64/`); see `programs/mk/arch.mk`. + ## C++ standard library (hosted libstdc++) `build-montauk-toolchain.sh` builds and installs a **hosted** libstdc++ diff --git a/toolchain/build-montauk-toolchain.sh b/toolchain/build-montauk-toolchain.sh index 1f9b1e2..795f6f2 100755 --- a/toolchain/build-montauk-toolchain.sh +++ b/toolchain/build-montauk-toolchain.sh @@ -1,9 +1,10 @@ #!/usr/bin/env bash # -# build-montauk-toolchain.sh — Build an x86_64-montauk cross compiler +# build-montauk-toolchain.sh — Build an -montauk cross compiler # (Binutils + GCC) for MontaukOS userspace programs. # -# Usage: ./toolchain/build-montauk-toolchain.sh +# Usage: ./toolchain/build-montauk-toolchain.sh [x86_64|aarch64] +# (or ARCH=aarch64 ./toolchain/build-montauk-toolchain.sh) # # Unlike the bare-metal x86_64-elf toolchain (build-toolchain.sh), this # target knows the Montauk userspace ABI: it links static ET_EXEC @@ -13,9 +14,11 @@ # # The toolchain is installed to toolchain/local/ and provides: # x86_64-montauk-gcc, x86_64-montauk-g++, x86_64-montauk-ld, etc. +# (aarch64-montauk-* for ARCH=aarch64; both can live side by side). # # The target sysroot (libc headers + libs) is assembled into -# toolchain/sysroot/ from programs/include/libc and programs/lib/libc. +# toolchain/sysroot/ (x86_64) or toolchain/sysroot-/ from +# programs/include/libc and programs/lib/libc. # Re-run this script after changing libc headers or rebuilding libc to # refresh the sysroot (the sysroot step always runs; compiler builds # are skipped once installed). @@ -27,7 +30,12 @@ set -euo pipefail # ── Versions (kept in lockstep with build-toolchain.sh) ─────────────────────── BINUTILS_VERSION="2.43.1" GCC_VERSION="14.2.0" -TARGET="x86_64-montauk" +ARCH="${1:-${ARCH:-x86_64}}" +case "${ARCH}" in + x86_64|aarch64) ;; + *) echo "Unsupported architecture: ${ARCH}" >&2; exit 1 ;; +esac +TARGET="${ARCH}-montauk" # ── Directories ─────────────────────────────────────────────────────────────── SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" @@ -35,7 +43,13 @@ REPO_DIR="$(dirname "${SCRIPT_DIR}")" PREFIX="${SCRIPT_DIR}/local" SRC_DIR="${SCRIPT_DIR}/src" BUILD_DIR="${SCRIPT_DIR}/build" -SYSROOT="${SCRIPT_DIR}/sysroot" +if [[ "${ARCH}" == x86_64 ]]; then + SYSROOT="${SCRIPT_DIR}/sysroot" + BUILD_SUFFIX="" +else + SYSROOT="${SCRIPT_DIR}/sysroot-${ARCH}" + BUILD_SUFFIX="-${ARCH}" +fi PATCH_DIR="${SCRIPT_DIR}/patches" FILES_DIR="${SCRIPT_DIR}/files" @@ -104,54 +118,87 @@ apply_patch() { fi } +# The AArch64 target is a second patch on top of the first. +apply_arch_patch() { + local dir="$1" patch="$2" marker="$3" + if grep -q "aarch64-\*-montauk" "${dir}/${marker}"; then + bold "Already patched for aarch64: $(basename "${dir}")" + else + bold "Patching $(basename "${dir}") for aarch64..." + patch -d "${dir}" -p1 < "${patch}" + fi +} + apply_patch "${SRC_DIR}/binutils-${BINUTILS_VERSION}" "${PATCH_DIR}/binutils-${BINUTILS_VERSION}-montauk.patch" apply_patch "${SRC_DIR}/gcc-${GCC_VERSION}" "${PATCH_DIR}/gcc-${GCC_VERSION}-montauk.patch" +apply_arch_patch "${SRC_DIR}/binutils-${BINUTILS_VERSION}" \ + "${PATCH_DIR}/binutils-${BINUTILS_VERSION}-montauk-aarch64.patch" bfd/config.bfd +apply_arch_patch "${SRC_DIR}/gcc-${GCC_VERSION}" \ + "${PATCH_DIR}/gcc-${GCC_VERSION}-montauk-aarch64.patch" gcc/config.gcc cp "${FILES_DIR}/montauk.h" "${SRC_DIR}/gcc-${GCC_VERSION}/gcc/config/montauk.h" +cp "${FILES_DIR}/aarch64-montauk.h" "${SRC_DIR}/gcc-${GCC_VERSION}/gcc/config/aarch64/montauk.h" # ── Assemble the target sysroot ─────────────────────────────────────────────── # usr/include — the Montauk libc headers (self-contained C; stddef/stdint/ # stdarg come from GCC itself) plus the montauk/ SDK headers. # usr/lib — crt startup objects and the libc static library. -bold "Assembling sysroot from programs/lib/libc..." -make -C "${REPO_DIR}/programs" libc >/dev/null - -rm -rf "${SYSROOT}" -mkdir -p "${SYSROOT}/usr/include" "${SYSROOT}/usr/lib" -cp -r "${REPO_DIR}/programs/include/libc/." "${SYSROOT}/usr/include/" -cp -r "${REPO_DIR}/programs/include/montauk" "${SYSROOT}/usr/include/montauk" -cp -r "${REPO_DIR}/programs/include/Api" "${SYSROOT}/usr/include/Api" -# Freestanding C++ headers (, , , ...) — -# the subset the kernel and the in-tree programs build against. This is -# NOT the whole C++ story: a hosted libstdc++ is built further down and -# installs its own headers under ${PREFIX}/x86_64-montauk/include/c++. -# That directory comes first on the include path and this one comes -# last, so a plain g++ invocation gets the hosted headers and these are -# shadowed. See "C++ standard library" in README.md. -cp -r "${REPO_DIR}/kernel/freestnd-cxx-hdrs/x86_64/include/." "${SYSROOT}/usr/include/" -cp "${REPO_DIR}/programs/lib/libc/crt1.o" \ - "${REPO_DIR}/programs/lib/libc/crti.o" \ - "${REPO_DIR}/programs/lib/libc/crtn.o" "${SYSROOT}/usr/lib/" -cp "${REPO_DIR}/programs/lib/libc/liblibc.a" "${SYSROOT}/usr/lib/libc.a" -# libm is an empty stand-in (math lives inside libc.a; the g++ driver -# links -lm unconditionally). libstdc++ is copied from the toolchain -# once built - the empty stand-in only bridges the first bootstrap. -ar rcs "${SYSROOT}/usr/lib/libm.a" -if [[ -f "${PREFIX}/x86_64-montauk/lib/libstdc++.a" ]]; then - cp "${PREFIX}/x86_64-montauk/lib/libstdc++.a" "${SYSROOT}/usr/lib/libstdc++.a" -else - ar rcs "${SYSROOT}/usr/lib/libstdc++.a" +LIBC_DIR="${REPO_DIR}/programs/lib/libc" +if [[ "${ARCH}" != x86_64 ]]; then + LIBC_DIR="${LIBC_DIR}/build-${ARCH}" fi -green "Sysroot ready." + +# On a first build for a new architecture the libc cannot be compiled yet +# (it needs this compiler): the sysroot then holds only headers, which is +# all building GCC needs, and is completed once GCC exists. +assemble_sysroot() { + bold "Assembling sysroot from programs/lib/libc..." + local have_libc=1 + make -C "${REPO_DIR}/programs" libc ARCH="${ARCH}" >/dev/null 2>&1 || have_libc=0 + [[ -f "${LIBC_DIR}/liblibc.a" && -f "${LIBC_DIR}/crt1.o" ]] || have_libc=0 + + rm -rf "${SYSROOT}" + mkdir -p "${SYSROOT}/usr/include" "${SYSROOT}/usr/lib" + cp -r "${REPO_DIR}/programs/include/libc/." "${SYSROOT}/usr/include/" + cp -r "${REPO_DIR}/programs/include/montauk" "${SYSROOT}/usr/include/montauk" + cp -r "${REPO_DIR}/programs/include/Api" "${SYSROOT}/usr/include/Api" + # Freestanding C++ headers (, , , ...) — + # the subset the kernel and the in-tree programs build against. This is + # NOT the whole C++ story: a hosted libstdc++ is built further down and + # installs its own headers under ${PREFIX}/${TARGET}/include/c++. + # That directory comes first on the include path and this one comes + # last, so a plain g++ invocation gets the hosted headers and these are + # shadowed. See "C++ standard library" in README.md. + cp -r "${REPO_DIR}/kernel/freestnd-cxx-hdrs/${ARCH}/include/." "${SYSROOT}/usr/include/" + if [[ ${have_libc} == 1 ]]; then + cp "${LIBC_DIR}/crt1.o" "${LIBC_DIR}/crti.o" "${LIBC_DIR}/crtn.o" "${SYSROOT}/usr/lib/" + cp "${LIBC_DIR}/liblibc.a" "${SYSROOT}/usr/lib/libc.a" + else + bold "libc not built yet - sysroot has headers only." + fi + # libm is an empty stand-in (math lives inside libc.a; the g++ driver + # links -lm unconditionally). libstdc++ is copied from the toolchain + # once built - the empty stand-in only bridges the first bootstrap. + ar rcs "${SYSROOT}/usr/lib/libm.a" + if [[ -f "${PREFIX}/${TARGET}/lib/libstdc++.a" ]]; then + cp "${PREFIX}/${TARGET}/lib/libstdc++.a" "${SYSROOT}/usr/lib/libstdc++.a" + else + ar rcs "${SYSROOT}/usr/lib/libstdc++.a" + fi + green "Sysroot ready." + return 0 +} + +assemble_sysroot # ── Build Binutils ──────────────────────────────────────────────────────────── if [[ -x "${PREFIX}/bin/${TARGET}-ld" ]]; then bold "Binutils already installed — skipping." else bold "Building Binutils ${BINUTILS_VERSION} for ${TARGET}..." - rm -rf "${BUILD_DIR}/binutils-montauk" - mkdir -p "${BUILD_DIR}/binutils-montauk" + rm -rf "${BUILD_DIR}/binutils-montauk${BUILD_SUFFIX}" + mkdir -p "${BUILD_DIR}/binutils-montauk${BUILD_SUFFIX}" ( - cd "${BUILD_DIR}/binutils-montauk" + cd "${BUILD_DIR}/binutils-montauk${BUILD_SUFFIX}" "${SRC_DIR}/binutils-${BINUTILS_VERSION}/configure" \ --target="${TARGET}" \ --prefix="${PREFIX}" \ @@ -174,10 +221,10 @@ if [[ -x "${PREFIX}/bin/${TARGET}-gcc" ]]; then bold "GCC already installed — skipping." else bold "Building GCC ${GCC_VERSION} for ${TARGET}..." - rm -rf "${BUILD_DIR}/gcc-montauk" - mkdir -p "${BUILD_DIR}/gcc-montauk" + rm -rf "${BUILD_DIR}/gcc-montauk${BUILD_SUFFIX}" + mkdir -p "${BUILD_DIR}/gcc-montauk${BUILD_SUFFIX}" ( - cd "${BUILD_DIR}/gcc-montauk" + cd "${BUILD_DIR}/gcc-montauk${BUILD_SUFFIX}" "${SRC_DIR}/gcc-${GCC_VERSION}/configure" \ --target="${TARGET}" \ --prefix="${PREFIX}" \ @@ -203,6 +250,11 @@ else green "GCC and libstdc++ installed." fi +# A first build for this architecture had no libc: complete the sysroot. +if [[ ! -f "${SYSROOT}/usr/lib/libc.a" ]] || [[ ! -s "${SYSROOT}/usr/lib/libstdc++.a" ]]; then + assemble_sysroot +fi + # ── Done ────────────────────────────────────────────────────────────────────── echo green "=== ${TARGET} cross compiler ready ===" diff --git a/toolchain/files/aarch64-montauk.h b/toolchain/files/aarch64-montauk.h new file mode 100644 index 0000000..55e290d --- /dev/null +++ b/toolchain/files/aarch64-montauk.h @@ -0,0 +1,43 @@ +/* + * aarch64-montauk.h + * GCC target definitions for aarch64-montauk userspace + * (installed as gcc/config/aarch64/montauk.h) + * Copyright (c) 2026 Daniel Hammer + * + * Programs are static, non-PIE ET_EXEC images loaded by the kernel + * ELF loader (kernel/src/Sched/ElfLoader.cpp) at their linked + * address. The loader maps 4 KiB pages, so segments must not use + * the 64 KiB AArch64 default alignment. +*/ + +#undef TARGET_OS_CPP_BUILTINS +#define TARGET_OS_CPP_BUILTINS() \ + do { \ + builtin_define("__montauk__"); \ + builtin_define("__MONTAUK__"); \ + builtin_assert("system=montauk"); \ + } while (0) + +/* Inline LL/SC atomics: outline atomics pick LSE at run time from HWCAP, + which Montauk does not provide, and their helpers live in libgcc, which + -nostdlib programs never link. + Signed plain char, as on x86_64-montauk: the userspace is shared between + the architectures and its CP1252 text handling assumes it. + -moutline-atomics / -funsigned-char still override. */ +#undef CC1_SPEC +#define CC1_SPEC "%{!moutline-atomics:-mno-outline-atomics} %{!funsigned-char:-fsigned-char}" + +#undef LINK_SPEC +#define LINK_SPEC \ + "-maarch64elf -X -z max-page-size=0x1000 %{shared:-shared} %{!shared:-static}" + +/* As on x86_64-montauk: crt1/crti/crtn from the Montauk libc, + crtbegin/crtend from libgcc. */ +#undef STARTFILE_SPEC +#define STARTFILE_SPEC "crt1.o%s crti.o%s crtbegin.o%s" + +#undef ENDFILE_SPEC +#define ENDFILE_SPEC "crtend.o%s crtn.o%s" + +#undef LIB_SPEC +#define LIB_SPEC "-lc" diff --git a/toolchain/patches/binutils-2.43.1-montauk-aarch64.patch b/toolchain/patches/binutils-2.43.1-montauk-aarch64.patch new file mode 100644 index 0000000..5dd5382 --- /dev/null +++ b/toolchain/patches/binutils-2.43.1-montauk-aarch64.patch @@ -0,0 +1,35 @@ +--- a/bfd/config.bfd ++++ b/bfd/config.bfd +@@ -248,6 +248,11 @@ + targ_selvecs="aarch64_elf64_be_vec aarch64_elf32_le_vec aarch64_elf32_be_vec arm_elf32_le_vec arm_elf32_be_vec aarch64_pei_le_vec aarch64_pe_le_vec" + want64=true + ;; ++ aarch64-*-montauk*) ++ targ_defvec=aarch64_elf64_le_vec ++ targ_selvecs=aarch64_elf64_be_vec ++ want64=true ++ ;; + aarch64-*-pe* | aarch64-*-mingw*) + targ_defvec=aarch64_pe_le_vec + targ_selvecs="aarch64_pe_le_vec aarch64_pei_le_vec aarch64_elf64_le_vec aarch64_elf64_be_vec aarch64_elf32_le_vec aarch64_elf32_be_vec arm_elf32_le_vec arm_elf32_be_vec pdb_vec" +--- a/gas/configure.tgt ++++ b/gas/configure.tgt +@@ -128,6 +128,7 @@ + case ${generic_target} in + aarch64*-*-elf*) fmt=elf;; + aarch64*-*-fuchsia*) fmt=elf;; ++ aarch64*-*-montauk*) fmt=elf;; + aarch64*-*-haiku*) fmt=elf em=haiku ;; + aarch64*-*-genode*) fmt=elf;; + aarch64*-*-linux*) fmt=elf em=linux +--- a/ld/configure.tgt ++++ b/ld/configure.tgt +@@ -89,6 +89,8 @@ + targ_emul=aarch64elf + targ_extra_emuls="aarch64elf32 aarch64elf32b aarch64elfb armelf armelfb" + ;; ++aarch64-*-montauk*) targ_emul=aarch64elf ++ ;; + aarch64-*-cloudabi*) targ_emul=aarch64cloudabi + targ_extra_emuls=aarch64cloudabib + ;; diff --git a/toolchain/patches/gcc-14.2.0-montauk-aarch64.patch b/toolchain/patches/gcc-14.2.0-montauk-aarch64.patch new file mode 100644 index 0000000..bb008bb --- /dev/null +++ b/toolchain/patches/gcc-14.2.0-montauk-aarch64.patch @@ -0,0 +1,40 @@ +--- a/gcc/config.gcc ++++ b/gcc/config.gcc +@@ -1189,7 +1189,7 @@ + esac + + case ${target} in +-aarch64*-*-elf | aarch64*-*-fuchsia* | aarch64*-*-rtems*) ++aarch64*-*-elf | aarch64*-*-fuchsia* | aarch64*-*-rtems* | aarch64*-*-montauk*) + tm_file="${tm_file} elfos.h newlib-stdint.h" + tm_file="${tm_file} aarch64/aarch64-elf.h aarch64/aarch64-errata.h aarch64/aarch64-elf-raw.h" + tmake_file="${tmake_file} aarch64/t-aarch64" +@@ -1204,6 +1204,11 @@ + tm_file="${tm_file} aarch64/rtems.h rtems.h" + tmake_file="${tmake_file} aarch64/t-aarch64-rtems" + ;; ++ aarch64-*-montauk*) ++ tm_file="${tm_file} aarch64/montauk.h" ++ # As for x86_64-montauk: the libc has no stdint.h of its own. ++ use_gcc_stdint=provide ++ ;; + esac + case $target in + aarch64_be-*) +--- a/libgcc/config.host ++++ b/libgcc/config.host +@@ -418,6 +418,14 @@ + tmake_file="${tmake_file} t-dfprules" + md_unwind_header=aarch64/aarch64-unwind.h + ;; ++aarch64*-*-montauk*) ++ extra_parts="$extra_parts crtbegin.o crtend.o crtfastmath.o" ++ tmake_file="${tmake_file} ${cpu_type}/t-aarch64" ++ tmake_file="${tmake_file} ${cpu_type}/t-lse t-slibgcc-libgcc" ++ tmake_file="${tmake_file} ${cpu_type}/t-softfp t-softfp t-crtfm" ++ tmake_file="${tmake_file} t-dfprules" ++ md_unwind_header=aarch64/aarch64-unwind.h ++ ;; + aarch64*-*-freebsd*) + extra_parts="$extra_parts crtfastmath.o" + tmake_file="${tmake_file} ${cpu_type}/t-aarch64"