// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "firmware_blob.h"

#include <lib/ddk/debug.h>
#include <lib/zx/vmar.h>
#include <zircon/assert.h>

#include <limits>
#include <vector>

namespace amlogic_decoder {

constexpr bool kFirmwareIsSigned = true;

FirmwareBlob::~FirmwareBlob() {
  if (vmo_)
    zx::vmar::root_self()->unmap(ptr_, fw_size_);
}

zx_status_t FirmwareBlob::LoadFirmware(zx_device_t* device) {
  zx_status_t status =
      load_firmware(device, "amlogic_video_ucode.bin", vmo_.reset_and_get_address(), &fw_size_);
  if (status != ZX_OK) {
    DECODE_ERROR("Couldn't load amlogic firmware");
    return status;
  }

  status =
      zx::vmar::root_self()->map(ZX_VM_PERM_READ | ZX_VM_ALLOW_FAULTS, 0, vmo_, 0, fw_size_, &ptr_);
  if (status != ZX_OK) {
    DECODE_ERROR("Couldn't map amlogic firmware");
    return status;
  }

  enum {
    kSignatureSize = 256,
    kPackageHeaderSize = 256,
  };
  uint8_t* data = reinterpret_cast<uint8_t*>(ptr_);
  struct PackageEntryHeader {
    union {
      struct {
        char name[32];
        char format[32];
        char cpu[32];
        uint32_t length;
      } data;
      uint8_t data_bytes[256];
    };
  };

  struct FirmwareHeader {
    union {
      struct {
        uint32_t magic;
        uint32_t checksum;
        uint8_t name[32];
        uint8_t cpu[16];
        uint8_t format[32];
        uint8_t version[32];
        uint8_t author[32];
        uint8_t date[32];
        uint8_t commit[16];
        uint32_t data_size;
        uint8_t time;
      } data;
      uint8_t data_bytes[512];
    };
  };
  uint64_t offset;
  if (kFirmwareIsSigned) {
    offset = kSignatureSize + kPackageHeaderSize;
  } else {
    offset = kPackageHeaderSize;
  }
  while (offset < fw_size_) {
    if (offset + sizeof(PackageEntryHeader) > fw_size_) {
      DECODE_ERROR("PackageHeader doesn't fit in data");
      return ZX_ERR_NO_MEMORY;
    }

    auto header = reinterpret_cast<PackageEntryHeader*>(data + offset);

    offset += sizeof(PackageEntryHeader);
    uint32_t package_length = header->data.length;
    if (offset + package_length > fw_size_) {
      DECODE_ERROR("Package too long");
      return ZX_ERR_NO_MEMORY;
    }
    if (sizeof(FirmwareHeader) > package_length) {
      DECODE_ERROR("FirmwareHeader doesn't fit in data %d", package_length);
      return ZX_ERR_NO_MEMORY;
    }

    FirmwareHeader* firmware_data = reinterpret_cast<FirmwareHeader*>(data + offset);
    uint32_t firmware_length = firmware_data->data.data_size;
    if (static_cast<uint64_t>(firmware_length) + sizeof(FirmwareHeader) > package_length) {
      DECODE_ERROR("Firmware data doesn't fit in data %d %ld %d", firmware_length,
                   sizeof(FirmwareHeader), package_length);
      return ZX_ERR_NO_MEMORY;
    }

    char firmware_cpu[sizeof(header->data.cpu) + 1] = {};
    char firmware_format[sizeof(header->data.format) + 1] = {};
    memcpy(firmware_cpu, header->data.cpu, sizeof(header->data.cpu));
    memcpy(firmware_format, header->data.format, sizeof(header->data.format));

    constexpr bool kLogFirmwares = false;
    if (kLogFirmwares) {
      // To help diagnose firmware loading problems.
      char firmware_name[sizeof(header->data.name) + 1] = {};
      memcpy(firmware_name, header->data.name, sizeof(header->data.name));
      LOG(INFO, "firmware_format: %s firmware_cpu: %s firmware_name: %s",
          std::string(firmware_format).c_str(), std::string(firmware_cpu).c_str(),
          std::string(firmware_name).c_str());
    }

    FirmwareCode code = {offset + sizeof(FirmwareHeader), firmware_length};
    firmware_code_[FirmwareKey{.cpu = firmware_cpu, .format = firmware_format}] = code;

    offset += package_length;
  }
  return ZX_OK;
}

namespace {

std::string FirmwareTypeToFormat(FirmwareBlob::FirmwareType type) {
  switch (type) {
    case FirmwareBlob::FirmwareType::kDec_Mpeg12:
      return "mpeg12";
    case FirmwareBlob::FirmwareType::kDec_Mpeg4_3:
      return "divx311";
    case FirmwareBlob::FirmwareType::kDec_Mpeg4_4:
      return "divx4x";
    case FirmwareBlob::FirmwareType::kDec_Mpeg4_5:
      return "xvid";
    case FirmwareBlob::FirmwareType::kDec_H263:
      return "h263";
    case FirmwareBlob::FirmwareType::kDec_Mjpeg:
      return "mjpeg";
    case FirmwareBlob::FirmwareType::kDec_Mjpeg_Multi:
      return "mjpeg_multi";
    case FirmwareBlob::FirmwareType::kDec_Real_v8:
      return "real_v8";
    case FirmwareBlob::FirmwareType::kDec_Real_v9:
      return "real_v9";
    case FirmwareBlob::FirmwareType::kDec_Vc1:
      return "vc1";
    case FirmwareBlob::FirmwareType::kDec_Avs:
      return "avs";
    case FirmwareBlob::FirmwareType::kDec_H264:
      return "h264";
    case FirmwareBlob::FirmwareType::kDec_H264_4k2k:
      return "h264_4k2k";
    case FirmwareBlob::FirmwareType::kDec_H264_4k2k_Single:
      return "h264_4k2k_single";
    case FirmwareBlob::FirmwareType::kDec_H264_Mvc:
      return "h264_mvc";
    case FirmwareBlob::FirmwareType::kDec_H264_Multi:
      return "h264_multi";
    case FirmwareBlob::FirmwareType::kDec_Hevc:
      return "hevc";
    case FirmwareBlob::FirmwareType::kDec_Hevc_Mmu:
      return "hevc_mmu";
    case FirmwareBlob::FirmwareType::kDec_Vp9:
      return "vp9";
    case FirmwareBlob::FirmwareType::kDec_Vp9_Mmu:
      return "vp9_mmu";
    case FirmwareBlob::FirmwareType::kEnc_H264:
      return "h264_enc";
    case FirmwareBlob::FirmwareType::kEnc_Jpeg:
      return "jpeg_enc";
    // value 22 kPackage is missing intentionally - 22 isn't a firmware
    case FirmwareBlob::FirmwareType::kDec_H264_Multi_Mmu:
      return "h264_multi_mmu";
    case FirmwareBlob::FirmwareType::kDec_Hevc_G12a:
      return "hevc_g12a";
    case FirmwareBlob::FirmwareType::kDec_Vp9_G12a:
      return "vp9_g12a";
    case FirmwareBlob::FirmwareType::kDec_Avs2:
      return "avs2";
    case FirmwareBlob::FirmwareType::kDec_Avs2_Mmu:
      return "avs2_mmu";
    case FirmwareBlob::FirmwareType::kDec_Avs_Gxm:
      return "avs_gxm";
    case FirmwareBlob::FirmwareType::kDec_Avs_NoCabac:
      return "avs_no_cabac";
    case FirmwareBlob::FirmwareType::kDec_H264_Multi_Gxm:
      return "h264_multi_gxm";
    case FirmwareBlob::FirmwareType::kDec_H264_Mvc_Gxm:
      return "h264_mvc_gxm";
    case FirmwareBlob::FirmwareType::kDec_Vc1_G12a:
      return "vc1_g12a";
    default:
      LOG(ERROR, "Unrecognized firmware type: %d", static_cast<int>(type));
      return "";
  }
}

std::vector<std::string> DeviceTypeToCpu(DeviceType device_type) {
  std::vector<std::string> cpu_names;
  switch (device_type) {
    case DeviceType::kGXM:
      cpu_names.push_back("gxm");
      break;
    case DeviceType::kG12B:
      cpu_names.push_back("g12b");
      // Sometimes G12b shares firmware with G12a and GXM. But always match G12b before G12a, then
      // GXM. Do not change the order!
      cpu_names.push_back("g12a");
      cpu_names.push_back("gxm");
      break;
    case DeviceType::kG12A:
      cpu_names.push_back("g12a");
      break;
    case DeviceType::kSM1:
      cpu_names.push_back("sm1");
      break;
    default:
      LOG(ERROR, "Unrecognized device type: %d", static_cast<int>(device_type));
  }
  return cpu_names;
}

}  // namespace

zx_status_t FirmwareBlob::GetFirmwareData(FirmwareType firmware_type, uint8_t** data_out,
                                          uint32_t* size_out) {
  auto cpu_names = DeviceTypeToCpu(device_type_);
  auto format_name = FirmwareTypeToFormat(firmware_type);
  if (cpu_names.empty() || format_name.empty())
    return ZX_ERR_INVALID_ARGS;
  for (auto& cpu_name : cpu_names) {
    auto it = firmware_code_.find(FirmwareKey{.cpu = cpu_name, .format = format_name});
    if (it != firmware_code_.end()) {
      *data_out = reinterpret_cast<uint8_t*>(ptr_) + it->second.offset;
      *size_out = it->second.size;
      LOG(INFO, "Got firmware with cpu_name %s and format %s for type %d and device type %d",
          &cpu_name[0], &format_name[0], static_cast<int>(firmware_type),
          static_cast<int>(device_type_));
      return ZX_OK;
    }
  }
  DECODE_ERROR("Couldn't find firmware for type: %d and device type: %d",
               static_cast<int>(firmware_type), static_cast<int>(device_type_));
  return ZX_ERR_INVALID_ARGS;
}

void FirmwareBlob::GetWholeBlob(uint8_t** data_out, uint32_t* size_out) {
  // This must not be called if LoadFirmware() failed.
  ZX_DEBUG_ASSERT(ptr_);
  ZX_DEBUG_ASSERT(fw_size_ <= std::numeric_limits<uint32_t>::max());
  *data_out = reinterpret_cast<uint8_t*>(ptr_);
  *size_out = static_cast<uint32_t>(fw_size_);
}

void FirmwareBlob::LoadFakeFirmwareForTesting(FirmwareType firmware_type, uint8_t* data,
                                              uint32_t size) {
  auto cpu_names = DeviceTypeToCpu(device_type_);
  std::string format_name = FirmwareTypeToFormat(firmware_type);
  assert(ptr_ == 0);

  ptr_ = reinterpret_cast<uintptr_t>(data);
  firmware_code_[FirmwareKey{.cpu = cpu_names[0], .format = format_name}].size = size;
  firmware_code_[FirmwareKey{.cpu = cpu_names[0], .format = format_name}].offset = 0;
}

}  // namespace amlogic_decoder
