/*
 * Copyright (c) 2018 The Fuchsia Authors
 *
 * SPDX-License-Identifier:	BSD-3-Clause
 */

#include <common.h>
#include <storage.h>
#include <version.h>
#include <zircon-estelle/zircon.h>
#include <zircon-estelle/partition.h>

#define PDEV_VID_GOOGLE             3
#define PDEV_PID_ASTRO              3

#define NVRAM_LENGTH                (8 * 1024)

static const zbi_cpu_config_t cpu_config = {
	.cluster_count = 1,
	.clusters = {
		     {
		      .cpu_count = 4,
		      },
		     },
};

static const zbi_mem_range_t mem_config[] = {
	{
	 .type = ZBI_MEM_RANGE_RAM,
	 .length = 0x60000000,	// 1.5 GB
	 },
	{
	 .type = ZBI_MEM_RANGE_PERIPHERAL,
	 .paddr = 0xf5800000,
	 .length = 0x0a800000,
	 },
	// secmon_reserved:linux,secmon
	{
	 .type = ZBI_MEM_RANGE_RESERVED,
	 .paddr = 0x05000000,
	 .length = 0x2400000,
	 },
	// logo_reserved:linux,meson-fb
	{
	 .type = ZBI_MEM_RANGE_RESERVED,
	 .paddr = 0x5f800000,
	 .length = 0x800000,
	 },
};

static const dcfg_simple_t uart_driver = {
	.mmio_phys = 0xff803000,
	.irq = 225,
};

static const dcfg_arm_gicv2_driver_t gicv2_driver = {
	.mmio_phys = 0xffc00000,
	.gicd_offset = 0x1000,
	.gicc_offset = 0x2000,
	.gich_offset = 0x4000,
	.gicv_offset = 0x6000,
	.ipi_base = 5,
};

static const dcfg_arm_psci_driver_t psci_driver = {
	.use_hvc = false,
	.reboot_args = {1, 0, 0},
	.reboot_bootloader_args = {4, 0, 0},
	.reboot_recovery_args = {2, 0, 0},
};

static const dcfg_arm_generic_timer_driver_t timer_driver = {
	.irq_phys = 30,
};

static const zbi_platform_id_t platform_id = {
	.vid = PDEV_VID_GOOGLE,
	.pid = PDEV_PID_ASTRO,
	.board_name = "astro",
};

bool zircon_is_vboot_enabled(void)
{
	return true;
}

bool zircon_is_vboot_unlock_enabled(void)
{
	return false;
}

int zircon_vboot_disable_vboot_unlock(void)
{
	return -1;
}

int zircon_vboot_set_unlock(bool unlock)
{
	return -1;
}

static void add_partition_map(zbi_header_t * zbi)
{
	const zbi_partition_map_t *partition_map = zircon_get_partition_map();
	if (partition_map == NULL) {
		printf("WARNING: zircon partition map is not defined.\n");
		return;
	}
	zircon_append_boot_item(zbi, ZBI_TYPE_DRV_PARTITION_MAP, 0,
				partition_map,
				sizeof(zbi_partition_map_t) +
				partition_map->partition_count *
				sizeof(zbi_partition_t));
}

int zircon_preboot(zbi_header_t * zbi)
{
	// add CPU configuration
	zircon_append_boot_item(zbi, ZBI_TYPE_CPU_CONFIG, 0, &cpu_config,
				sizeof(zbi_cpu_config_t) +
				sizeof(zbi_cpu_cluster_t) *
				cpu_config.cluster_count);

	// allocate crashlog save area before 0x5f800000-0x60000000 reserved area
	zbi_nvram_t nvram;
	nvram.base = 0x5f800000 - NVRAM_LENGTH;
	nvram.length = NVRAM_LENGTH;
	zircon_append_boot_item(zbi, ZBI_TYPE_NVRAM, 0, &nvram, sizeof(nvram));

	// add memory configuration
	zircon_append_boot_item(zbi, ZBI_TYPE_MEM_CONFIG, 0, &mem_config,
				sizeof(mem_config));

	// add kernel drivers
	zircon_append_boot_item(zbi, ZBI_TYPE_KERNEL_DRIVER, KDRV_AMLOGIC_UART,
				&uart_driver, sizeof(uart_driver));
	zircon_append_boot_item(zbi, ZBI_TYPE_KERNEL_DRIVER, KDRV_ARM_GIC_V2,
				&gicv2_driver, sizeof(gicv2_driver));
	zircon_append_boot_item(zbi, ZBI_TYPE_KERNEL_DRIVER, KDRV_ARM_PSCI,
				&psci_driver, sizeof(psci_driver));
	zircon_append_boot_item(zbi, ZBI_TYPE_KERNEL_DRIVER,
				KDRV_ARM_GENERIC_TIMER, &timer_driver,
				sizeof(timer_driver));

	char uboot_ver[] = "bootloader.name=" U_BOOT_VERSION_STRING;
	// Zircon's cmdline parameters cannot contain spaces so
	// convert spaces in autogenerated U-boot version string
	// to underscores.
	// See zircon/docs/kernel_cmdline.md
	int i;
	int len = strlen(uboot_ver);
	for (i = 0; i < len; i++) {
		if (uboot_ver[i] == ' ') {
			uboot_ver[i] = '_';
		}
	}

	zircon_append_boot_item(zbi, ZBI_TYPE_CMDLINE, 0, uboot_ver, len + 1);

	// add platform ID
	zircon_append_boot_item(zbi, ZBI_TYPE_PLATFORM_ID, 0, &platform_id,
				sizeof(platform_id));

	add_partition_map(zbi);

	return 0;
}
