/*
 * 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 NEWMAN_FACTORY_IF		"mmc"
#define NEWMAN_FACTORY_PART		"1:5"
#define FACTORY_MAC_ADDR_BUFF_LEN	30
#define NEWMAN_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(NEWMAN_FACTORY_IF, NEWMAN_FACTORY_PART,
			   FS_TYPE_EXT)) {
		printf("set_blk_dev %s-%s failed.\n",
		       NEWMAN_FACTORY_IF, NEWMAN_FACTORY_PART);
		return -1;
	}

	if (fs_read(NEWMAN_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;
}
