/*
 * Copyright (C) 2024 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, embodiment or
 * 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.
 *
 * SPDX-License-Identifier: Apache-2.0 OR BSD-2-Clause-Patent
 *
 * This file is dual-licensed under Apache 2.0 and BSD-2-Clause-Patent.
 * You may choose to use this file under the terms of either:
 *  (a) the Apache License, Version 2.0, or
 *  (b) the BSD 2-Clause Patent License.
 *
 * Unless you expressly elect the BSD-2-Clause-Patent terms, the Apache-2.0
 * license terms apply by default.
 */

#ifndef __GBL_EFI_BOOT_CONTROL_PROTOCOL_H__
#define __GBL_EFI_BOOT_CONTROL_PROTOCOL_H__

#include <gbl_efi_common.h>

static const uint64_t GBL_EFI_BOOT_CONTROL_PROTOCOL_REVISION = GBL_PROTOCOL_REVISION(1, 0);

EFI_ENUM(GblEfiUnbootableReason, uint8_t, GBL_EFI_UNBOOTABLE_REASON_UNKNOWN_REASON,
         GBL_EFI_UNBOOTABLE_REASON_NO_MORE_TRIES, GBL_EFI_UNBOOTABLE_REASON_SYSTEM_UPDATE,
         GBL_EFI_UNBOOTABLE_REASON_USER_REQUESTED, GBL_EFI_UNBOOTABLE_REASON_VERIFICATION_FAILURE);

EFI_ENUM(GblEfiOneShotBootMode, uint32_t, GBL_EFI_ONE_SHOT_BOOT_MODE_NONE,
         GBL_EFI_ONE_SHOT_BOOT_MODE_BOOTLOADER, GBL_EFI_ONE_SHOT_BOOT_MODE_RECOVERY);

typedef struct {
  // One UTF-8 encoded single character
  uint32_t suffix;
  // Any value other than those explicitly enumerated in EFI_UNBOOTABLE_REASON
  // will be interpreted as UNKNOWN_REASON.
  GblEfiUnbootableReason unbootable_reason;
  uint8_t priority;
  // Number of remaining tries to attempt to boot the slot
  uint8_t remaining_tries;
  // Value of 1 if slot has successfully booted
  uint8_t successful;
} GblEfiSlotInfo;

typedef struct {
  size_t kernel_size;
  efi_physical_addr_t kernel;
  size_t ramdisk_size;
  efi_physical_addr_t ramdisk;
  size_t device_tree_size;
  efi_physical_addr_t device_tree;
  uint64_t reserved[8];
} GblEfiLoadedOs;

typedef struct GblEfiBootControlProtocol {
  uint64_t revision;
  // Slot metadata query methods
  efi_status_t (*get_slot_count)(struct GblEfiBootControlProtocol* self,
                              /* out */ uint8_t* slot_count);
  efi_status_t (*get_slot_info)(struct GblEfiBootControlProtocol* self,
                             /* in */ uint8_t index,
                             /* out */ GblEfiSlotInfo* info);
  efi_status_t (*get_current_slot)(struct GblEfiBootControlProtocol* self,
                                /* out */ GblEfiSlotInfo* info);
  // Slot metadata manipulation methods
  efi_status_t (*set_active_slot)(struct GblEfiBootControlProtocol* self,
                               /* in */ uint8_t index);
  // Boot control methods
  efi_status_t (*get_one_shot_boot_mode)(struct GblEfiBootControlProtocol* self,
                                      /* out */ GblEfiOneShotBootMode* mode);
  efi_status_t (*handle_loaded_os)(struct GblEfiBootControlProtocol* self,
                                /* in */ const GblEfiLoadedOs* os);
} GblEfiBootControlProtocol;

#endif  // __GBL_EFI_BOOT_CONTROL_PROTOCOL_H__
