/*
 * Copyright (c) 2026, Chloe M.
 * Provided under the BSD-3 clause.
 *
 * Description: Multi-processing
 * Author:      Chloe M.
 */

#include <ptdef.h>
#include <ex/trace.h>
#include <drivers/acpi/acpi.h>
#include <drivers/acpi/tables.h>
#include <ke/bugcheck.h>
#include <machine/lapic.h>

/* Max processors to bootstrap */
#define CPU_MAX 64

#define DTRACE(Fmt, ...) \
    TRACE("[ MP ]: " Fmt, ##__VA_ARGS__)

/* Number of processor cores */
static USHORT CoreCount = 0;

/*
 * Bootstrap a single core
 *
 * @LocalApic: Local APIC descriptor of core to bootstrap
 *
 * TODO: This is a stub
 */
static VOID
BootstrapCore(ACPI_LOCAL_APIC *LocalApic)
{
    if (LocalApic == NULL) {
        return;
    }

    ++CoreCount;
}

static VOID
MpBootstrap(VOID)
{
    ACPI_MADT *Madt;
    UCHAR *Ptr, *EndPtr;
    ACPI_APIC_HEADER *Header;
    ACPI_LOCAL_APIC *LocalApic;

    Madt = AcpiQuery("APIC");
    if (Madt == NULL) {
        KeBugCheck(
            BUGCHECK_MISC,
            "unable to detect ACPI MADT table\n"
        );
    }

    Ptr = PTR_OFFSET(Madt, sizeof(ACPI_MADT));
    EndPtr = PTR_OFFSET(Ptr, Madt->Header.Length);

    /* Iterate every interrupt controller entry */
    while (Ptr < EndPtr) {
        Header = (ACPI_APIC_HEADER *)Ptr;

        switch (Header->Type) {
        case APIC_TYPE_LOCAL_APIC:
            LocalApic = (ACPI_LOCAL_APIC *)Header;
            BootstrapCore(LocalApic);
            break;
        }

        Ptr = PTR_OFFSET(Ptr, Header->Length);
    }

    DTRACE("detected %d processor core(s)\n", CoreCount);
}

VOID
HalMpBootstrap(VOID)
{
    MpBootstrap();
}
