// SPDX-License-Identifier: MPL-2.0
#ifndef BP_LIB_VYX_H
#define BP_LIB_VYX_H
#include <Uefi.h>
#include "disk.h"
#include "common/versions.h"
#define BP_VYX_SUPPORTED_VERSION VY_COMMON_VERSIONS_VYX
#define BP_VYX_SHELTER_BOOT_CONFIG_VA 0x00180000
#define BP_VYX_SHELTER_MEMORY_MAP_PAGES_COUNT 16
#define BP_VYX_SHELTER_MEMORY_MAP_VA 0x00190000
#define BP_VYX_SHELTER_PT_PAGE_COUNT 4096
#define BP_VYX_SHELTER_LOGGING_RING_BUFFER_VA 0xFFFFFFFFF0000000ULL
#define BP_VYX_PAYLOAD_EXECUTABLE (1<<0)
#define BP_VYX_PAYLOAD_WRITABLE (1<<1)
#pragma pack(1)
typedef struct {
  UINT8 sig[3];
  UINT16 vyx_ver;
  UINT64 text_offset;
  UINT64 stack_base;
  UINT64 text_size_padded;
  UINT64 data_size_padded;
  UINT64 rodata_size_padded;
  UINT64 bss_size_padded;
  UINT64 payload_count;
} bp_vyx_VYX_HEADER;
#pragma pack()
#pragma pack(1)
typedef struct {
  UINT8 sig[8];
  UINT32 payload_size_bytes;
  UINT32 payload_pages_count;
  UINT8 map_flags;
  UINT64 load_address;
} bp_vyx_PAYLOAD_HEADER;
#pragma pack()
typedef struct {
  EFI_PHYSICAL_ADDRESS text_addr_phys;
  EFI_PHYSICAL_ADDRESS data_addr_phys;
  EFI_PHYSICAL_ADDRESS rodata_addr_phys;
  EFI_PHYSICAL_ADDRESS bss_addr_phys;
  EFI_PHYSICAL_ADDRESS stack_addr_phys;
  EFI_PHYSICAL_ADDRESS keycard_addr_phys;
  EFI_PHYSICAL_ADDRESS shelter_boot_config_addr_phys;
  UINTN shelter_boot_config_pages_count;
  EFI_PHYSICAL_ADDRESS shelter_memory_map_addr_phys;
  EFI_PHYSICAL_ADDRESS shelter_page_table_addr_phys;
  EFI_PHYSICAL_ADDRESS shelter_logging_ring_buffer_addr_phys;
  UINTN shelter_logging_ring_buffer_pages_count;
  UINTN keycard_page_count;
  UINT64 payload_count;
  UINT32 *payloads_page_count_array;
  UINT8 *payloads_map_flags_array;
  EFI_PHYSICAL_ADDRESS *payloads_addr_phys_array;
  EFI_VIRTUAL_ADDRESS *payloads_addr_virt_array;
} bp_vyx_LOADER_SETTING;
typedef struct __attribute__((aligned(8))) {
  BOOLEAN fb_present;
  EFI_VIRTUAL_ADDRESS fb_pa;
  UINT32 white_pixel_value;
  UINT32 gray_pixel_value;
  UINT64 size_in_bytes;
  UINT32 fb_height;
  UINT32 fb_width;
  UINT16 text_x;
  UINT16 text_y;
  UINT16 text_width;
  UINT16 text_height;
} bp_vyx_SHELTER_FB_CONFIG;
typedef struct __attribute__((aligned(8))) {
  UINT8 sig_start[8];
  UINT8 log_level;
  UINT16 page_table_allocator_level;
  EFI_PHYSICAL_ADDRESS page_table_pool_pa;
  EFI_VIRTUAL_ADDRESS page_table_pool_va;
  BOOLEAN test_benchmark;
  UINT64 bench_iterations;
  BOOLEAN log_disable_serial_port;
  BOOLEAN disable_serial_port;
  UINT16 log_ring_size;
  UINT64 acpi_rsdp;
  UINT8 acpi_ver;
  UINT16 kbd_events_queue_capacity;
  bp_vyx_SHELTER_FB_CONFIG fb_config;
  UINT8 sig_end[8];
} bp_vyx_SHELTER_BOOT_CONFIG;
#pragma pack(1)
typedef struct {
  UINT32 type;
  UINT64 physical_start;
  UINT64 pages_count;
  UINT64 attributes;
} bp_vyx_SHELTER_MEMORY_MAP_ENTRY;
#pragma pack()
#pragma pack(1)
typedef struct {
  UINT8 sig_start[8];
  UINT64 entry_count;
  UINT64 entry_size;
  UINT8 mmap_syntax_version;
} bp_vyx_SHELTER_MEMORY_MAP_HEADER;
#pragma pack()
EFI_STATUS bp_vyx_get_header(bp_disk_FILE *file,bp_vyx_VYX_HEADER **header);
EFI_STATUS bp_vyx_create_shelter_boot_conf(UINT8 log_level,BOOLEAN test_benchmark,UINT64 bench_iterations,BOOLEAN log_disable_serial_port,BOOLEAN disable_serial_port,UINT16 log_ring_size,UINT64 acpi_rsdp,UINT8 acpi_ver,UINT16 kbd_events_queue_capacity,bp_vyx_SHELTER_BOOT_CONFIG *boot_config);
EFI_STATUS bp_vyx_init_pt_pool_allocator();
UINT64 bp_vyx_get_pt_pool_allocator();
EFI_PHYSICAL_ADDRESS bp_vyx_pt_pool_alloc_one_page(EFI_PHYSICAL_ADDRESS pt_pool_base);
EFI_STATUS bp_vyx_setup_physical_pages(bp_vyx_VYX_HEADER *header,bp_disk_FILE *vyx_file,bp_disk_FILE *keycard_file,bp_vyx_SHELTER_BOOT_CONFIG *shelter_boot_config,bp_vyx_LOADER_SETTING **loader_setting);
EFI_STATUS bp_vyx_create_page_table(bp_vyx_VYX_HEADER *header,bp_vyx_LOADER_SETTING *settings,EFI_PHYSICAL_ADDRESS *page_table_address,EFI_VIRTUAL_ADDRESS *stack_address,EFI_VIRTUAL_ADDRESS *page_table_pool_va);
#endif
