/*
 * Copyright (c) 2026, Chloe M.
 * Provided under the BSD-3 clause.
 *
 * Description: Boot protocol abstraction layer
 * Author:      Chloe M.
 */

#ifndef _KE_BPAL_H_
#define _KE_BPAL_H_ 1

#include <ptapi/status.h>
#include <ptdef.h>

/*
 * Valid memory types
 */
typedef enum {
    MEMORY_USABLE,
    MEMORY_RESERVED,
    MEMORY_ACPI_RECLAIM,
    MEMORY_ACPI_NVS,
    MEMORY_BAD,
    MEMORY_BOOTLOADER,
    MEMORY_KERNEL,
    MEMORY_FRAMEBUFFER,
    MEMORY_ACPI_TABLES
} MEM_TYPE;

/*
 * Memory map entry
 *
 * @Base:   Entry base
 * @Length: Entry length
 * @Type:   Entry type
 */
typedef struct {
    UQUAD Base;
    UQUAD Length;
    UQUAD Type;
} MEMMAP_ENTRY;

/*
 * Represents a framebuffer
 */
typedef struct {
    VOID *Address;
    UQUAD Width;
    UQUAD Height;
    UQUAD Pitch;
    SHORT Bpp;
    UCHAR RedMaskSize;
    UCHAR RedMaskShift;
    UCHAR GreenMaskSize;
    UCHAR GreenMaskShift;
    UCHAR BlueMaskSize;
    UCHAR BlueMaskShift;
} BPAL_FRAMEBUFFER;

/*
 * Bootloader module
 *
 * @Data: Data backed by module
 * @Length: Length of data in bytes
 */
typedef struct {
    VOID *Data;
    USIZE Length;
} BPAL_MODULE;

/*
 * Represents a handle for the boot protocol abstraction
 * layer containing data filled in by the bootloader.
 *
 * @KernelBase:     Represents the kernel load base
 * @RsdpBase:       RSDP base address
 * @Framebuffer:    Framebuffer information
 * @MemEntryIdx:    Callback to get memory map entry by index
 */
typedef struct {
    UPTR KernelBase;
    VOID *RsdpBase;
    BPAL_FRAMEBUFFER Framebuffer;
    PT_STATUS(*MemEntryIdx)(USIZE Idx, MEMMAP_ENTRY *Result);
    PT_STATUS(*ModuleLookup)(CHAR *Path, BPAL_MODULE *Result);
} BPAL_HANDLE;

/*
 * Initialize the boot protocol abstraction layer
 */
VOID KeBpalInit(VOID);

/*
 * Obtain the BPAL handle
 *
 * @Result: Result is written here
 */
VOID KeBpalGetHandle(BPAL_HANDLE *Result);

/* Backend protocol init */
VOID KeBpalLimineInit(BPAL_HANDLE *Result);

/*
 * Obtain the kernel load virtual memory base
 */
ALWAYS_INLINE static inline UPTR
KeBpalLoadBase(VOID)
{
    BPAL_HANDLE Handle;

    KeBpalGetHandle(&Handle);
    return Handle.KernelBase;
}

#endif  /* !_KE_BPAL_H_ */
