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

#include <common.h>
#include <fs.h>
#include <version.h>
#include <zircon/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 = 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_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;
}

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,
				strlen(uboot_ver) + 1);

	/* 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;
}
