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

#include <common.h>
#include <fs.h>
#include <version.h>
#include <zircon_uboot/zircon.h>

#define PDEV_VID_GOOGLE		3
#define PDEV_PID_SHERLOCK	5

#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 = 0x80000000, // 2 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_SHERLOCK,
	.board_name = "sherlock",
};

enum {
	PART_TPL,
	PART_FTS,
	PART_FACTORY,
	PART_ZIRCON_B,
	PART_ZIRCON_A,
	PART_ZIRCON_R,
	PART_FVM,
	PART_SYS_CONFIG,
	PART_MIGRATION,
	PART_COUNT,
};

#define PUDDY_FACTORY_IF		"mmc"
#define PUDDY_FACTORY_PART		"1:5"
#define FACTORY_MAC_ADDR_BUFF_LEN	30
#define PUDDY_FACTORY_MACADDR_FILE	"mac_addr"
#define FACTORY_MAC_ADDR_FILE_LEN	25

static int add_mac_addresses(zbi_header_t* zbi) {
	char buffer[FACTORY_MAC_ADDR_BUFF_LEN];
	u64 fullmac[2];
	u8 mac_addr[6];
	int len_read;
	int mac_num, i;

	if (fs_set_blk_dev(PUDDY_FACTORY_IF, PUDDY_FACTORY_PART,
			   FS_TYPE_EXT)) {
		printf("set_blk_dev %s-%s failed.\n",
		       PUDDY_FACTORY_IF, PUDDY_FACTORY_PART);
		return -1;
	}

	if (fs_read(PUDDY_FACTORY_MACADDR_FILE, buffer, 0,
		    FACTORY_MAC_ADDR_BUFF_LEN, &len_read)) {
		printf("Failed to read Mac Addresses from Factory partition\n");
	}
	if (len_read != FACTORY_MAC_ADDR_FILE_LEN) {
		printf("Factory MAC Addr File length (%d) incorrect.\n",
		       len_read);
		return -1;
	}
	buffer[len_read] = '\0';

	/*
	 * "buffer" should now contain two hex strings separated by \n,
	 * for a total of 25 bytes. Separate into 2 C strings and convert.
	 */
	buffer[len_read/2] = '\0';
	fullmac[0] = simple_strtoull(buffer, NULL, 16);
	fullmac[1] = simple_strtoull(&buffer[(len_read/2)+1], NULL, 16);

	for (mac_num = 0; mac_num < ARRAY_SIZE(fullmac); mac_num++) {
		for (i = ARRAY_SIZE(mac_addr)-1; i >= 0; i--) {
			mac_addr[i] = (u8) (fullmac[mac_num] & 0xff);
			fullmac[mac_num] >>= 8;
		}
		zircon_append_boot_item(zbi, ZBI_TYPE_DRV_MAC_ADDRESS, mac_num,
				        mac_addr, sizeof(mac_addr));
	}

	return 0;
}

static void add_board_info(zbi_header_t* zbi)
{
	zbi_board_info_t board_info = {};
	char* s;
	if (((s = env_get("hw_id")) != NULL) && (*s != '\0')) {
		uint32_t hw_id = simple_strtoul(s, NULL, 16);
		board_info.revision = hw_id;
	} else {
		printf("Failed to retrieve Board Revision\n");
	}

	zircon_append_boot_item(zbi, ZBI_TYPE_DRV_BOARD_INFO, 0, &board_info,
				sizeof(board_info));
}

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 board-specific information */
	add_board_info(zbi);

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

	int ret = add_mac_addresses(zbi);

	if (ret < 0) {
		printf("ERROR: unable to read MAC addresses from the"
		       " factory partition!\n");
	}
	return 0;
}
