// Copyright 2017 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 <stdio.h>
#include <string.h>
#include <xefi.h>
#include <zircon/pixelformat.h>

#include "osboot.h"

static efi_guid AcpiTableGUID = ACPI_TABLE_GUID;
static efi_guid Acpi2TableGUID = ACPI_20_TABLE_GUID;
static efi_guid SmbiosTableGUID = SMBIOS_TABLE_GUID;
static efi_guid Smbios3TableGUID = SMBIOS3_TABLE_GUID;
static uint8_t ACPI_RSD_PTR[8] = "RSD PTR ";
static uint8_t SmbiosAnchor[4] = "_SM_";
static uint8_t Smbios3Anchor[5] = "_SM3_";

uint64_t find_acpi_root(efi_handle img, efi_system_table* sys) {
  efi_configuration_table* cfgtab = sys->ConfigurationTable;
  for (size_t i = 0; i < sys->NumberOfTableEntries; i++) {
    if (xefi_cmp_guid(&cfgtab[i].VendorGuid, &AcpiTableGUID) &&
        xefi_cmp_guid(&cfgtab[i].VendorGuid, &Acpi2TableGUID)) {
      // not an ACPI table
      continue;
    }
    if (memcmp(cfgtab[i].VendorTable, ACPI_RSD_PTR, 8)) {
      // not the Root Description Pointer
      continue;
    }
    return (uint64_t)cfgtab[i].VendorTable;
  }
  return 0;
}

uint64_t find_smbios(efi_handle img, efi_system_table* sys) {
  efi_configuration_table* cfgtab = sys->ConfigurationTable;
  for (size_t i = 0; i < sys->NumberOfTableEntries; i++) {
    if (!xefi_cmp_guid(&cfgtab[i].VendorGuid, &SmbiosTableGUID)) {
      if (!memcmp(cfgtab[i].VendorTable, SmbiosAnchor, sizeof(SmbiosAnchor))) {
        return (uint64_t)cfgtab[i].VendorTable;
      }
    } else if (!xefi_cmp_guid(&cfgtab[i].VendorGuid, &Smbios3TableGUID)) {
      if (!memcmp(cfgtab[i].VendorTable, Smbios3Anchor, sizeof(Smbios3Anchor))) {
        return (uint64_t)cfgtab[i].VendorTable;
      }
    }
  }
  return 0;
}

static void get_bit_range(uint32_t mask, int* high, int* low) {
  *high = -1;
  *low = -1;
  int idx = 0;
  while (mask) {
    if (*low < 0 && (mask & 1))
      *low = idx;
    idx++;
    mask >>= 1;
  }
  *high = idx - 1;
}

static int get_zx_pixel_format_from_bitmask(efi_pixel_bitmask bitmask) {
  int r_hi = -1, r_lo = -1, g_hi = -1, g_lo = -1, b_hi = -1, b_lo = -1;

  get_bit_range(bitmask.RedMask, &r_hi, &r_lo);
  get_bit_range(bitmask.GreenMask, &g_hi, &g_lo);
  get_bit_range(bitmask.BlueMask, &b_hi, &b_lo);

  if (r_lo < 0 || g_lo < 0 || b_lo < 0) {
    goto unsupported;
  }

  if ((r_hi == 23 && r_lo == 16) && (g_hi == 15 && g_lo == 8) && (b_hi == 7 && b_lo == 0)) {
    return ZX_PIXEL_FORMAT_RGB_x888;
  }

  if ((r_hi == 7 && r_lo == 5) && (g_hi == 4 && g_lo == 2) && (b_hi == 1 && b_lo == 0)) {
    return ZX_PIXEL_FORMAT_RGB_332;
  }

  if ((r_hi == 15 && r_lo == 11) && (g_hi == 10 && g_lo == 5) && (b_hi == 4 && b_lo == 0)) {
    return ZX_PIXEL_FORMAT_RGB_565;
  }

  if ((r_hi == 7 && r_lo == 6) && (g_hi == 5 && g_lo == 4) && (b_hi == 3 && b_lo == 2)) {
    return ZX_PIXEL_FORMAT_RGB_2220;
  }

unsupported:
  printf("unsupported pixel format bitmask: r %08x / g %08x / b %08x\n", bitmask.RedMask,
         bitmask.GreenMask, bitmask.BlueMask);
  return ZX_PIXEL_FORMAT_NONE;
}

uint32_t get_zx_pixel_format(efi_graphics_output_protocol* gop) {
  efi_graphics_pixel_format efi_fmt = gop->Mode->Info->PixelFormat;
  switch (efi_fmt) {
    case PixelBlueGreenRedReserved8BitPerColor:
      return ZX_PIXEL_FORMAT_RGB_x888;
    case PixelBitMask:
      return get_zx_pixel_format_from_bitmask(gop->Mode->Info->PixelInformation);
    default:
      printf("unsupported pixel format %d!\n", efi_fmt);
      return ZX_PIXEL_FORMAT_NONE;
  }
}
