// 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 <ddk/debug.h>
#include <lib/zx/vmar.h>

#include "macros.h"

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\n");
    return status;
  }

  zx::vmar::root_self()->map(0, vmo_, 0, fw_size_, ZX_VM_PERM_READ, &ptr_);
  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 = kSignatureSize + kPackageHeaderSize;
  while (offset < fw_size_) {
    if (offset + sizeof(PackageEntryHeader) > fw_size_) {
      DECODE_ERROR("PackageHeader doesn't fit in data\n");
      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\n");
      return ZX_ERR_NO_MEMORY;
    }
    if (sizeof(FirmwareHeader) > package_length) {
      DECODE_ERROR("FirmwareHeader doesn't fit in data %d\n", 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\n",
                   firmware_length, sizeof(FirmwareHeader), package_length);
      return ZX_ERR_NO_MEMORY;
    }

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

    FirmwareCode code = {offset + sizeof(FirmwareHeader), firmware_length};
    firmware_code_[std::string(firmware_format)] = code;

    offset += package_length;
  }
  return ZX_OK;
}

namespace {
std::string FirmwareTypeToName(FirmwareBlob::FirmwareType type) {
  switch (type) {
    case FirmwareBlob::FirmwareType::kMPEG12:
      return "mpeg12";
      break;
    case FirmwareBlob::FirmwareType::kH264:
      return "h264";
      break;
    case FirmwareBlob::FirmwareType::kVp9Mmu:
      return "vp9_mmu";
      break;
    case FirmwareBlob::FirmwareType::kVp9MmuG12a:
      return "vp9_g12a";
      break;
    default:
      DECODE_ERROR("Invalid firmware type: %d\n", type);
      return "";
  }
}
}  // namespace
zx_status_t FirmwareBlob::GetFirmwareData(FirmwareType firmware_type,
                                          uint8_t** data_out,
                                          uint32_t* size_out) {
  std::string format_name = FirmwareTypeToName(firmware_type);
  if (format_name == "")
    return ZX_ERR_INVALID_ARGS;
  auto it = firmware_code_.find(format_name);
  if (it == firmware_code_.end()) {
    DECODE_ERROR("Couldn't find firmware type: %d\n", firmware_type);
    return ZX_ERR_INVALID_ARGS;
  }
  *data_out = reinterpret_cast<uint8_t*>(ptr_) + it->second.offset;
  *size_out = it->second.size;
  return ZX_OK;
}

void FirmwareBlob::LoadFakeFirmwareForTesting(FirmwareType firmware_type,
                                              uint8_t* data, uint32_t size) {
  std::string format_name = FirmwareTypeToName(firmware_type);
  assert(ptr_ == 0);

  ptr_ = reinterpret_cast<uintptr_t>(data);

  firmware_code_[format_name].size = size;
  firmware_code_[format_name].offset = 0;
}
