#pragma once

typedef unsigned char      uint8_t;
typedef unsigned short     uint16_t;
typedef unsigned int       uint32_t;
typedef unsigned long long uint64_t;
typedef signed char        int8_t;
typedef signed short       int16_t;
typedef signed int         int32_t;
typedef signed long long   int64_t;
typedef uint64_t           size_t;
typedef int64_t            ssize_t;
typedef uint64_t           uintptr_t;

#define NULL ((void*)0)

typedef uint8_t  BOOLEAN;
typedef int64_t  INTN;
typedef uint64_t UINTN;
typedef uint64_t EFI_STATUS;
typedef uint64_t EFI_PHYSICAL_ADDRESS;
typedef uint64_t EFI_VIRTUAL_ADDRESS;
typedef void    *EFI_HANDLE;

struct EFI_GUID {
    uint32_t Data1;
    uint16_t Data2;
    uint16_t Data3;
    uint8_t  Data4[8];
};

struct EFI_TABLE_HEADER {
    uint64_t Signature;
    uint32_t Revision;
    uint32_t HeaderSize;
    uint32_t CRC32;
    uint32_t Reserved;
};

typedef struct {
    uint32_t Type;
    uint32_t _pad;
    EFI_PHYSICAL_ADDRESS PhysicalStart;
    EFI_VIRTUAL_ADDRESS  VirtualStart;
    uint64_t NumberOfPages;
    uint64_t Attribute;
} EFI_MEMORY_DESCRIPTOR;

#define EFI_MEMORY_TYPE_RESERVED           0
#define EFI_MEMORY_TYPE_LOADER_CODE        1
#define EFI_MEMORY_TYPE_LOADER_DATA        2
#define EFI_MEMORY_TYPE_BOOT_SERVICES_CODE 3
#define EFI_MEMORY_TYPE_BOOT_SERVICES_DATA 4
#define EFI_MEMORY_TYPE_CONVENTIONAL       7

#define EFI_SUCCESS       0
#define EFI_BUFFER_TOO_SMALL 0x8000000000000005ULL
#define EFI_NOT_FOUND     0x800000000000000EULL
#define EFI_NOT_READY     0x8000000000000006ULL
#define EFI_DEVICE_ERROR  0x8000000000000007ULL
#define EFI_INVALID_PARAMETER 0x8000000000000002ULL
#define EFI_ERROR(s)      (((int64_t)(s)) < 0)

typedef struct {
    uint32_t Version;
    uint32_t HorizontalResolution;
    uint32_t VerticalResolution;
    uint32_t PixelFormat;
    struct {
        uint32_t RedMask;
        uint32_t GreenMask;
        uint32_t BlueMask;
        uint32_t ReservedMask;
    } PixelInformation;
    uint32_t PixelsPerScanLine;
} EFI_GRAPHICS_OUTPUT_MODE_INFORMATION;

typedef struct {
    uint32_t MaxMode;
    uint32_t Mode;
    EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info;
    uint64_t SizeOfInfo;
    uint64_t FrameBufferBase;
    uint64_t FrameBufferSize;
} EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE;

typedef struct {
    EFI_STATUS (__attribute__((ms_abi)) *QueryMode)(void*, uint32_t, uint64_t*, EFI_GRAPHICS_OUTPUT_MODE_INFORMATION**);
    EFI_STATUS (__attribute__((ms_abi)) *SetMode)(void*, uint64_t);
    EFI_STATUS (__attribute__((ms_abi)) *Blt)(void*, void*, uint32_t, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t);
    EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE *Mode;
} EFI_GRAPHICS_OUTPUT_PROTOCOL;

typedef struct EFI_BOOT_SERVICES {
    struct EFI_TABLE_HEADER Hdr;
    void *RaiseTPL;
    void *RestoreTPL;
    EFI_STATUS (__attribute__((ms_abi)) *AllocatePages)(uint32_t, uint32_t, uint64_t, EFI_PHYSICAL_ADDRESS*);
    EFI_STATUS (__attribute__((ms_abi)) *FreePages)(EFI_PHYSICAL_ADDRESS, uint64_t);
    EFI_STATUS (__attribute__((ms_abi)) *GetMemoryMap)(uint64_t*, EFI_MEMORY_DESCRIPTOR*, uint64_t*, uint64_t*, uint32_t*);
    EFI_STATUS (__attribute__((ms_abi)) *AllocatePool)(uint32_t, uint64_t, void**);
    EFI_STATUS (__attribute__((ms_abi)) *FreePool)(void*);
    void *CreateEvent;
    void *SetTimer;
    EFI_STATUS (__attribute__((ms_abi)) *WaitForEvent)(uint64_t, void**, uint64_t*);
    void *SignalEvent;
    void *CloseEvent;
    void *CheckEvent;
    void *InstallProtocolInterface;
    void *ReinstallProtocolInterface;
    void *UninstallProtocolInterface;
    EFI_STATUS (__attribute__((ms_abi)) *HandleProtocol)(EFI_HANDLE, struct EFI_GUID*, void**);
    void *Reserved;
    void *RegisterProtocolNotify;
    void *LocateHandle;
    void *LocateDevicePath;
    EFI_STATUS (__attribute__((ms_abi)) *InstallConfigurationTable)(struct EFI_GUID*, void*);
    void *LoadImage;
    void *StartImage;
    void *Exit;
    void *UnloadImage;
    EFI_STATUS (__attribute__((ms_abi)) *ExitBootServices)(EFI_HANDLE, uint64_t);
    void *GetNextMonotonicCount;
    void *Stall;
    void *SetWatchdogTimer;
    EFI_STATUS (__attribute__((ms_abi)) *ConnectController)(void*, void*, void*, BOOLEAN);
    void *DisconnectController;
    void *OpenProtocol;
    void *CloseProtocol;
    void *OpenProtocolInformation;
    void *ProtocolsPerHandle;
    void *LocateHandleBuffer;
    EFI_STATUS (__attribute__((ms_abi)) *LocateProtocol)(struct EFI_GUID*, void*, void**);
    void *InstallMultipleProtocolInterfaces;
    void *UninstallMultipleProtocolInterfaces;
    void *CalculateCrc32;
    void *CopyMem;
    void *SetMem;
    void *CreateEventEx;
} EFI_BOOT_SERVICES;

typedef struct EFI_RUNTIME_SERVICES {
    struct EFI_TABLE_HEADER Hdr;
    void *GetTime;
    void *SetTime;
    void *GetWakeupTime;
    void *SetWakeupTime;
    EFI_STATUS (__attribute__((ms_abi)) *SetVirtualAddressMap)(uint64_t, uint64_t, uint32_t, EFI_MEMORY_DESCRIPTOR*);
    EFI_STATUS (__attribute__((ms_abi)) *ConvertPointer)(uint64_t, void**);
} EFI_RUNTIME_SERVICES;

struct EFI_CONFIGURATION_TABLE {
    struct EFI_GUID VendorGuid;
    void *VendorTable;
};

typedef struct {
    struct EFI_TABLE_HEADER Hdr;
    void *FirmwareVendor;
    uint32_t FirmwareRevision;
    EFI_HANDLE ConsoleInHandle;
    void *ConIn;
    EFI_HANDLE ConsoleOutHandle;
    void *ConOut;
    EFI_HANDLE StandardErrorHandle;
    void *StdErr;
    EFI_RUNTIME_SERVICES *RuntimeServices;
    EFI_BOOT_SERVICES *BootServices;
    uint64_t NumberOfTableEntries;
    struct EFI_CONFIGURATION_TABLE *ConfigurationTable;
} EFI_SYSTEM_TABLE;
