/*
    * BootProtocol.hpp
    * The Montauk Boot Contract: handoff state + adapter interface
    * Copyright (c) 2026 Daniel Hammer
*/

#pragma once
#include "BootInfo.hpp"

// ====================================================================
// The Montauk Boot Contract -- Part 1: the HANDOFF STATE
// ====================================================================
//
// BootInfo.hpp specifies the DATA the bootloader must produce.  This file
// specifies the MACHINE STATE the bootloader must establish before it
// transfers control to the kernel, and the single function an adapter must
// implement to produce the BootInfo.
//
// A conforming bootloader MUST, before jumping to the kernel entry point
// (the ELF entry symbol `kmain`), guarantee the following on the bootstrap
// processor.  These mirror the guarantees the kernel currently relies on;
// a novel "Montauk Loader" need only reproduce them to be a drop-in.
//
//   x86_64 handoff state:
//   ---------------------
//     * CPU is in 64-bit long mode, CPL 0, interrupts DISABLED (IF=0).
//     * Paging is ENABLED with a valid 4-level (or 5-level) page table in
//       CR3.  The page table must contain:
//         - The kernel image, mapped at its linked higher-half virtual
//           addresses (this kernel links at 0xffffffff80000000; see
//           linker-x86_64.ld) with appropriate per-segment permissions.
//         - A Higher-Half Direct Map (HHDM): all usable physical RAM (and
//           the framebuffer / firmware regions the kernel must reach)
//           mapped linearly at `physical + BootInfo::hhdmBase`.  The kernel
//           resolves its own physical load address by walking CR3, so the
//           kernel's higher-half pages must resolve to physical frames.
//     * A valid, naturally-aligned stack of at least a few KiB, with
//       RSP 16-byte aligned per the SysV ABI at the point of entry.
//     * GDT with valid 64-bit code/data descriptors loaded.  (The kernel
//       installs its own GDT/IDT immediately, so the bootloader's table
//       need only be valid enough to survive the first instructions.)
//     * A20 enabled, SSE/CR0/CR4 in a sane state (the kernel re-enables
//       SSE itself; it must not fault before then).
//     * The control register/MSR state required for the above (EFER.LME,
//       CR4.PAE, CR0.PG/PE) set consistently.
//
//   Application processors (APs):
//   ----------------------------
//     APs need not be running on entry.  They must be parked such that a
//     later call to SmpInfo::startCpu (see BootInfo.hpp) can resume each
//     one into the SAME handoff state described above, on a
//     bootloader-supplied stack, executing the kernel-provided entry.
//
//   Firmware tables:
//   ---------------
//     If the platform is UEFI, EFI runtime services must still be callable
//     (the relevant regions discoverable through BootInfo::efi); the
//     bootloader must NOT have called ExitBootServices in a way that
//     invalidates runtime services, and must report the RSDP it found.
//
// ====================================================================
// The Montauk Boot Contract -- Part 2: the ADAPTER INTERFACE
// ====================================================================
//
// Each supported bootloader provides exactly ONE translation unit (an
// "adapter", e.g. Protocols/LimineProtocol.cpp) that:
//
//   (a) emits whatever request/handshake structures that bootloader's
//       protocol requires (kept entirely inside the adapter so the rest of
//       the kernel never sees bootloader-specific types), and
//
//   (b) implements `montauk::boot::Acquire()` below, translating the
//       bootloader's native responses into a Montauk-native BootInfo.
//
// Linking two adapters into one kernel is a link-time error (duplicate
// definition of Acquire), which is intentional: a kernel build targets one
// boot protocol.  To support a new bootloader, add a new adapter .cpp and
// build against it instead.
// ====================================================================

namespace montauk::boot {

    // Implemented by the active bootloader adapter.
    //
    // Populates `out` with everything the kernel needs.  Returns true on
    // success.  Returns false if the boot environment is unusable or the
    // bootloader's protocol revision is unsupported -- in which case the
    // kernel halts (it cannot meaningfully run).
    //
    // Contract for the implementer:
    //   * Set out.contractVersion = ContractVersion.
    //   * Set out.loaderName to a non-null human-readable string.
    //   * Always populate hhdmBase and memoryMap (required).
    //   * Set the Feature bit for, and populate, every optional block the
    //     bootloader provided; leave the bit clear otherwise.
    //   * Perform NO kernel logging and allocate NO kernel memory: this runs
    //     before the page-frame allocator and heap exist.  Translate only.
    bool Acquire(BootInfo& out);

}
