/*
 * Copyright (C) 2023 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

#ifndef __EFI_TYPES_H__
#define __EFI_TYPES_H__

typedef void* EfiHandle;
typedef uint8_t char8_t;
typedef uint16_t char16_t;
typedef void* EfiEvent;
typedef uint64_t EfiPhysicalAddr;
typedef uint64_t EfiVirtualAddr;

typedef struct EfiTableHeader {
  uint64_t signature;
  uint32_t revision;
  uint32_t header_size;
  uint32_t crc32;
  uint32_t reserved;
} EfiTableHeader;

typedef struct EfiGuid {
  uint32_t data1;
  uint16_t data2;
  uint16_t data3;
  uint8_t data4[8];
} EfiGuid;

typedef struct EfiMemoryAttributesTableHeader {
  uint32_t version;
  uint32_t number_of_entries;
  uint32_t descriptor_size;
  uint32_t reserved;
} EfiMemoryAttributesTableHeader;

typedef enum EFI_MEMORY_ATTRIBUTE : uint64_t {
  EMA_UC = 0x0000000000000001, /* uncached */
  EMA_WC = 0x0000000000000002, /* write-coalescing */
  EMA_WT = 0x0000000000000004, /* write-through */
  EMA_WB = 0x0000000000000008, /* write-back */
  EMA_WP = 0x0000000000001000, /* write-protect */
  EMA_RP = 0x0000000000002000, /* read-protect */
  EMA_XP = 0x0000000000004000, /* execute-protect */
  EMA_RUNTIME = 0x8000000000000000,
} EfiMemoryAttribute;

typedef struct EfiMemoryDescriptor {
  uint32_t memory_type;
  uint32_t padding;
  EfiPhysicalAddr physical_start;
  EfiVirtualAddr virtual_start;
  uint64_t number_of_pages;
  uint64_t attributes;
} EfiMemoryDescriptor;

typedef struct EfiTime {
  uint16_t year;
  uint8_t month;
  uint8_t day;
  uint8_t hour;
  uint8_t minute;
  uint8_t second;
  uint8_t pad1;
  uint32_t nanosecond;
  int16_t timezone;
  uint8_t daylight;
  uint8_t pad2;
} EfiTime;

typedef struct EfiTimeCapabilities {
  uint32_t resolution;
  uint32_t accuracy;
  bool sets_to_zero;
} EfiTimeCapabilities;

typedef struct EfiCapsuleHeader {
  EfiGuid CapsuleGuid;
  uint32_t HeaderSize;
  uint32_t Flags;
  uint32_t CapsuleImageSize;
} EfiCapsuleHeader;

typedef void (*EfiEventNotify)(EfiEvent event, void* ctx);

typedef enum EFI_EVENT_TYPE : uint32_t {
  TIMER = 0x80000000,
  RUNTIME = 0x40000000,
  NOTIFY_WAIT = 0x00000100,
  NOTIFY_SIGNAL = 0x00000200,
  SIGNAL_EXIT_BOOT_SERVICES = 0x00000201,
  SIGNAL_VIRTUAL_ADDRESS_CHANGE = 0x60000202,
} EfiEventType;

typedef enum EFI_TPL : size_t {
  APPLICATION = 4,
  CALLBACK = 8,
  NOTIFY = 16,
  HIGH_LEVEL = 31,
} EfiTpl;

typedef enum EFI_TIMER_DELAY {
  TIMER_CANCEL,
  TIMER_PERIODIC,
  TIMER_RELATIVE
} EfiTimerDelay;

typedef enum {
  RESERVED_MEMORY_TYPE,
  LOADER_CODE,
  LOADER_DATA,
  BOOT_SERVICES_CODE,
  BOOT_SERVICES_DATA,
  RUNTIME_SERVICES_CODE,
  RUNTIME_SERVICES_DATA,
  CONVENTIONAL_MEMORY,
  UNUSABLE_MEMORY,
  ACPIRECLAIM_MEMORY,
  ACPIMEMORY_NVS,
  MEMORY_MAPPED_IO,
  MEMORY_MAPPED_IOPORT_SPACE,
  PAL_CODE,
  PERSISTENT_MEMORY,
  MAX_MEMORY_TYPE
} EFI_MEMORY_TYPE;

typedef EFI_MEMORY_TYPE EfiMemoryType;

typedef enum {
  EFI_RESET_COLD,
  EFI_RESET_WARM,
  EFI_RESET_SHUTDOWN,
  EFI_RESET_PLATFORM_SPECIFIC
} EFI_RESET_TYPE;

typedef EFI_RESET_TYPE EfiResetType;

#define EFI_ERROR_MASK ((uintptr_t)INTPTR_MAX + 1)
#define EFI_ERR(x) (EFI_ERROR_MASK | (x))

typedef enum EFI_STATUS : uintptr_t {
  SUCCESS = 0u,
  LOAD_ERROR = EFI_ERR(1),
  INVALID_PARAMETER = EFI_ERR(2),
  UNSUPPORTED = EFI_ERR(3),
  BAD_BUFFER_SIZE = EFI_ERR(4),
  BUFFER_TOO_SMALL = EFI_ERR(5),
  NOT_READY = EFI_ERR(6),
  DEVICE_ERROR = EFI_ERR(7),
  WRITE_PROTECTED = EFI_ERR(8),
  OUT_OF_RESOURCES = EFI_ERR(9),
  VOLUME_CORRUPTED = EFI_ERR(10),
  VOLUME_FULL = EFI_ERR(11),
  NO_MEDIA = EFI_ERR(12),
  MEDIA_CHANGED = EFI_ERR(13),
  NOT_FOUND = EFI_ERR(14),
  ACCESS_DENIED = EFI_ERR(15),
  NO_RESPONSE = EFI_ERR(16),
  NO_MAPPING = EFI_ERR(17),
  TIMEOUT = EFI_ERR(18),
  NOT_STARTED = EFI_ERR(19),
  ALREADY_STARTED = EFI_ERR(20),
  ABORTED = EFI_ERR(21),
  ICMP_ERROR = EFI_ERR(22),
  TFTP_ERROR = EFI_ERR(23),
  PROTOCOL_ERROR = EFI_ERR(24),
  INCOMPATIBLE_VERSION = EFI_ERR(25),
  SECURITY_VIOLATION = EFI_ERR(26),
  CRC_ERROR = EFI_ERR(27),
  END_OF_MEDIA = EFI_ERR(28),
  END_OF_FILE = EFI_ERR(31),
  INVALID_LANGUAGE = EFI_ERR(32),
  COMPROMISED_DATA = EFI_ERR(33),
  IP_ADDRESS_CONFLICT = EFI_ERR(34),
  HTTP_ERROR = EFI_ERR(35),
  CONNECTION_FIN = EFI_ERR(104),
  CONNECTION_RESET = EFI_ERR(105),
  CONNECTION_REFUSED = EFI_ERR(106),
} EfiStatus;

#endif  // __EFI_TYPES_H__
