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

#include <asm/arch/secure_apb.h>
#include <asm/arch/timer.h>
#include <command.h>
#include <asm/arch/reboot.h>
#include <asm/arch/secure_apb.h>
#include <asm/io.h>
#include <common.h>
#include <dm/uclass.h>
#include <fs.h>
#include <version.h>
#include <wdt.h>
#include <zbi/zbi.h>
#include <zircon/boot/bootfs.h>
#include <zircon/boot/image.h>
#include <zircon_uboot/boot_args.h>
#include <zircon_uboot/vboot.h>
#include <zircon_uboot/zircon.h>

#include "factory.h"

// bitmask for determining whether the RNG_USR_DATA register is ready.
// // This mask should be applied to the RNG_USR_STS register.
// // 0: The RNG_USR_DATA register is not ready to be read from.
// // 1: The RNG_USR_DATA register is ready to be read from.
#define USR_RAND32_RDY 0x1

#define PDEV_VID_GOOGLE 3
#define PDEV_PID_SHERLOCK 5

#define NVRAM_LENGTH (8 * 1024)

// Size of the CMDLINE entropy string.
#define CMDLINE_ENTROPY_SIZE 1024

// Random bits to pass to zircon.
#define CMDLINE_ENTROPY_BITS 256

// Deadline for time waiting for the RNG_USR_STS register to be ready.
// This is a very generous value, given that after reading from
// the hw rng, we should expect it to be available after
// HW_RNG_RESEEDING_INTERVAL_MICROS.
#define ENTROPY_COLLECTION_DEADLINE_MICROS 100000

// HW RNG is reseeded every 40 microseconds.
#define HW_RNG_RESEEDING_INTERVAL_MICROS 40

#define ENTROPY_BITS_PER_CHAR 4

static const char zircon_entropy_arg[] = "kernel.entropy-mixin=";
static char entropy_cmdline[CMDLINE_ENTROPY_SIZE] = { 0 };

_Static_assert(CMDLINE_ENTROPY_BITS % 32 == 0,
	       "Requested entropy must be a multiple of 32");

_Static_assert((CMDLINE_ENTROPY_BITS / ENTROPY_BITS_PER_CHAR) +
			       sizeof(zircon_entropy_arg) <
		       CMDLINE_ENTROPY_SIZE,
	       "Requested entropy doesn't fit in cmdline.");

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 = 0x76800000,
		.length = 0x800000,
	},
	/* linux,usable-memory */
	{
		.type = ZBI_MEM_RANGE_RESERVED,
		.paddr = 0x00000000,
		.length = 0x100000,
	},
};

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 = 0,
};

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 dcfg_amlogic_rng_driver_t rng_driver = {
	.rng_data_phys = (uint64_t)P_RNG_USR_DATA,
	.rng_status_phys = (uint64_t)P_RNG_USR_STS,
	.rng_refresh_interval_usec = HW_RNG_RESEEDING_INTERVAL_MICROS,
};

#define WDT_CTRL 0xffd0f0d0
#define WDT_PET 0xffd0f0dc

#define WATCHDOG_TIMEOUT_SECONDS 5
#define SECONDS_TO_NANOSECONDS 1000000000LL

static dcfg_generic_32bit_watchdog_t watchdog_driver = {
	.pet_action = {
		.addr = WDT_PET,
		.clr_mask = 0xffffffff,
		.set_mask = 0x00000000,
	},
	.enable_action = {
		.addr = WDT_CTRL,
		.clr_mask = 0x00000000,
		.set_mask = 0x00040000,
	},
	.disable_action = {
		.addr = WDT_CTRL,
		.clr_mask = 0x00040000,
		.set_mask = 0x00000000,
	},
	.watchdog_period_nsec =
		WATCHDOG_TIMEOUT_SECONDS * SECONDS_TO_NANOSECONDS,
	.flags = KDRV_GENERIC_32BIT_WATCHDOG_FLAG_ENABLED,
};

/**
 * disable_watchdog_petting() - disable petting of watchdog
 *
 * The function disables the petting function of watchdog driver by
 * faking a pet_action.addr and setting the set_mask anc clr_mask
 * field to be 0.
 *
 * It is mainly used for testing watchdog after booting into zircon.
 * i.e., whether it triggers a reboot if zircon is not able to pet it in time
 */
void disable_watchdog_petting(void)
{
	watchdog_driver.pet_action.addr = watchdog_driver.enable_action.addr;
	watchdog_driver.pet_action.set_mask = 0; // no set
	watchdog_driver.pet_action.clr_mask = 0; // no clear
}

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,
};

int append_zbi_item_or_log(void *zbi, size_t capacity, uint32_t type,
			   uint32_t extra, const void *payload, size_t size)
{
	if (size > 0xFFFFFFFFU) {
		printf("Error: ZBI item 0x%08X/0x%X is too large (%zu bytes)\n",
		       type, extra, size);
		return -1;
	}

	zbi_result_t result = zbi_create_entry_with_payload(
		zbi, capacity, type, extra, 0 /*flags*/, payload, size);
	if (result != ZBI_RESULT_OK) {
		printf("Error: Failed to add ZBI item 0x%08X/0x%X (code %d)\n",
		       type, extra, result);
		return -1;
	}

	return 0;
}

static void *mandatory_memset(void *dst, int c, size_t n)
{
	volatile unsigned char *out = dst;
	size_t i = 0;

	for (i = 0; i < n; ++i) {
		out[i] = (unsigned char)c;
	}
	return dst;
}

#define FACTORY_MAC_ADDR_BUFF_LEN 30

/* fs_read() takes a ulong address to read into, make sure this is actually
   big enough to hold any memory address. */
_Static_assert(sizeof(ulong) >= sizeof(char *),
	       "fs_read() address type is too small");

static int add_mac_addresses(zbi_header_t *zbi, size_t capacity)
{
	char buffer[FACTORY_MAC_ADDR_BUFF_LEN];
	u64 fullmac[2];
	u8 mac_addr[6];
	loff_t 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_MAC_ADDR_FILE, (ulong)buffer, 0,
		    FACTORY_MAC_ADDR_BUFF_LEN, &len_read)) {
		printf("Failed to read Mac Addresses from Factory partition\n");
		return -1;
	}
	if (len_read != NEWMAN_FACTORY_MAC_ADDR_FILE_LEN) {
		printf("Factory MAC Addr File length (%lld) 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;
		}
		if (append_zbi_item_or_log(zbi, capacity,
					   ZBI_TYPE_DRV_MAC_ADDRESS, mac_num,
					   mac_addr, sizeof(mac_addr))) {
			return -1;
		}
	}

	return 0;
}

static int add_serial_number(zbi_header_t *zbi, size_t capacity)
{
	char *s;
	if (!(s = env_get("serial#")) || (*s == '\0')) {
		printf("%s: Failed to retrieve serial number.\n", __func__);
		return -1;
	}
	return append_zbi_item_or_log(zbi, capacity, ZBI_TYPE_SERIAL_NUMBER, 0,
				      s, strlen(s));
}

static int add_board_info(zbi_header_t *zbi, size_t capacity)
{
	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 {
		// Should we error out here? Existing behavior was to continue adding
		// board_info with a default 0 "revision"; keep this behavior for now,
		// but it might make more sense to just skip this item instead if we
		// can determine nothing in the OS depends on it being present.
		printf("Failed to retrieve Board Revision\n");
	}

	return append_zbi_item_or_log(zbi, capacity, ZBI_TYPE_DRV_BOARD_INFO, 0,
				      &board_info, sizeof(board_info));
}

// Define a cpu topology for the system that captures how all of the cores are
// connected and grouped. Since this is a GICv2 system we include the ID for the
// cores, especially since it is a tricky one with a gap between the little and
// big clusters.
static int add_cpu_topology(zbi_header_t *zbi, size_t capacity)
{
	int index = 0;
	int logical_processor = 0;
	int big_cluster = 0, little_cluster = 0;

	zbi_topology_node_t nodes[8];

	little_cluster = index++;
	nodes[little_cluster] =
		(zbi_topology_node_t){ .entity_type =
					       ZBI_TOPOLOGY_ENTITY_CLUSTER,
				       .parent_index = ZBI_TOPOLOGY_NO_PARENT,
				       .entity = {
					       .cluster = {
						       .performance_class =
							       0, // low performance cluster
					       } } };

	nodes[index++] =
		(zbi_topology_node_t){ .entity_type =
					       ZBI_TOPOLOGY_ENTITY_PROCESSOR,
				       .parent_index = little_cluster,
				       .entity = {
					       .processor = {
						       .logical_ids = { logical_processor++ },
						       .logical_id_count = 1,
						       .flags =
							       ZBI_TOPOLOGY_PROCESSOR_PRIMARY,
						       .architecture =
							       ZBI_TOPOLOGY_ARCH_ARM,
						       .architecture_info = {
							       .arm = {
								       .cluster_1_id =
									       0,
								       .cpu_id =
									       0,
								       .gic_id =
									       0,
							       } } } } };
	nodes[index++] =
		(zbi_topology_node_t){ .entity_type =
					       ZBI_TOPOLOGY_ENTITY_PROCESSOR,
				       .parent_index = little_cluster,
				       .entity = {
					       .processor = {
						       .logical_ids = { logical_processor++ },
						       .logical_id_count = 1,
						       .flags = 0,
						       .architecture =
							       ZBI_TOPOLOGY_ARCH_ARM,
						       .architecture_info = {
							       .arm = {
								       .cluster_1_id =
									       0,
								       .cpu_id =
									       1,
								       .gic_id =
									       1,
							       } } } } };

	big_cluster = index++;
	nodes[big_cluster] =
		(zbi_topology_node_t){ .entity_type =
					       ZBI_TOPOLOGY_ENTITY_CLUSTER,
				       .parent_index = ZBI_TOPOLOGY_NO_PARENT,
				       .entity = {
					       .cluster = {
						       .performance_class =
							       1, // high performance cluster
					       } } };

	nodes[index++] =
		(zbi_topology_node_t){ .entity_type =
					       ZBI_TOPOLOGY_ENTITY_PROCESSOR,
				       .parent_index = big_cluster,
				       .entity = {
					       .processor = {
						       .logical_ids = { logical_processor++ },
						       .logical_id_count = 1,
						       .flags = 0,
						       .architecture =
							       ZBI_TOPOLOGY_ARCH_ARM,
						       .architecture_info = {
							       .arm = {
								       .cluster_1_id =
									       1,
								       .cpu_id =
									       0,
								       .gic_id =
									       4,
							       } } } } };
	nodes[index++] =
		(zbi_topology_node_t){ .entity_type =
					       ZBI_TOPOLOGY_ENTITY_PROCESSOR,
				       .parent_index = big_cluster,
				       .entity = {
					       .processor = {
						       .logical_ids = { logical_processor++ },
						       .logical_id_count = 1,
						       .flags = 0,
						       .architecture =
							       ZBI_TOPOLOGY_ARCH_ARM,
						       .architecture_info = {
							       .arm = {
								       .cluster_1_id =
									       1,
								       .cpu_id =
									       1,
								       .gic_id =
									       5,
							       } } } } };
	nodes[index++] =
		(zbi_topology_node_t){ .entity_type =
					       ZBI_TOPOLOGY_ENTITY_PROCESSOR,
				       .parent_index = big_cluster,
				       .entity = {
					       .processor = {
						       .logical_ids = { logical_processor++ },
						       .logical_id_count = 1,
						       .flags = 0,
						       .architecture =
							       ZBI_TOPOLOGY_ARCH_ARM,
						       .architecture_info = {
							       .arm = {
								       .cluster_1_id =
									       1,
								       .cpu_id =
									       2,
								       .gic_id =
									       6,
							       } } } } };
	nodes[index++] =
		(zbi_topology_node_t){ .entity_type =
					       ZBI_TOPOLOGY_ENTITY_PROCESSOR,
				       .parent_index = big_cluster,
				       .entity = {
					       .processor = {
						       .logical_ids = { logical_processor++ },
						       .logical_id_count = 1,
						       .flags = 0,
						       .architecture =
							       ZBI_TOPOLOGY_ARCH_ARM,
						       .architecture_info = {
							       .arm = {
								       .cluster_1_id =
									       1,
								       .cpu_id =
									       3,
								       .gic_id =
									       7,
							       } } } } };

	return append_zbi_item_or_log(zbi, capacity, ZBI_TYPE_CPU_TOPOLOGY,
				      sizeof(zbi_topology_node_t), &nodes,
				      sizeof(zbi_topology_node_t) * index);
}

static int add_reboot_reason(zbi_header_t *zbi, size_t capacity)
{
	// See cmd/amlogic/cmd_reboot.c
	const uint32_t reboot_mode_val = ((readl(AO_SEC_SD_CFG15) >> 12) & 0xf);

	zbi_hw_reboot_reason_t reboot_reason;
	switch (reboot_mode_val) {
	case AMLOGIC_COLD_BOOT:
		reboot_reason = ZBI_HW_REBOOT_COLD;
		break;
	case AMLOGIC_NORMAL_BOOT:
	case AMLOGIC_FACTORY_RESET_REBOOT:
	case AMLOGIC_UPDATE_REBOOT:
	case AMLOGIC_FASTBOOT_REBOOT:
	case AMLOGIC_SUSPEND_REBOOT:
	case AMLOGIC_HIBERNATE_REBOOT:
	case AMLOGIC_BOOTLOADER_REBOOT:
	case AMLOGIC_SHUTDOWN_REBOOT:
	case AMLOGIC_RPMBP_REBOOT:
	case AMLOGIC_QUIESCENT_REBOOT:
	case AMLOGIC_CRASH_REBOOT:
	case AMLOGIC_KERNEL_PANIC:
	case AMLOGIC_RECOVERY_QUIESCENT_REBOOT:
		reboot_reason = ZBI_HW_REBOOT_WARM;
		break;
	case AMLOGIC_WATCHDOG_REBOOT:
		reboot_reason = ZBI_HW_REBOOT_WATCHDOG;
		break;
	default:
		reboot_reason = ZBI_HW_REBOOT_UNDEFINED;
		break;
	}

	return append_zbi_item_or_log(zbi, capacity, ZBI_TYPE_HW_REBOOT_REASON,
				      0, &reboot_reason, sizeof(reboot_reason));
}

#define WATCHDOG_DEV_NAME "watchdog"
static void start_meson_watchdog(void)
{
	struct udevice *wdt_dev;
	int ret = uclass_get_device_by_name(UCLASS_WDT, WATCHDOG_DEV_NAME,
					    &wdt_dev);
	if (ret < 0) {
		printf("failed to get meson watchdog\n");
		return;
	}

	printf("starting meson watchdog\n");
	// Note: the watchdog uclass expects a timeout in milliseconds, but the
	// Amlogic code uses seconds instead.
	wdt_start(wdt_dev, WATCHDOG_TIMEOUT_SECONDS, 0);
	wdt_reset(wdt_dev);
}

// fills an 8 char buffer with the lowercase hex representation of the given
// value.
// WARNING this does not add a '\0' to the end of the buffer.
static inline void uint32_to_hex(uint32_t val, char buf[static 8])
{
	static const char hex[] = "0123456789abcdef";
	int i = 0;

	for (i = 7; i >= 0; i--) {
		buf[i] = hex[val & 0xF];
		val >>= 4;
	}
}

// Reads a value from the userspace hardware random number generator.
//
// This assumes that the drng has been previously seeded. Callers should
// poll P_RNG_USR_STS beforehand to make sure that a reseed occurred.
static inline uint32_t read_hw_rng(void)
{
	return readl(P_RNG_USR_DATA);
}

// Gathers CMDLINE_ENTROPY_BITS bits of entropy from the hardware random
// number generator and appends it as a ZBI_TYPE_CMDLINE for zircon to seed
// its cprng.
//
// This function will sleep a maximum of HW_RNG_RESEEDING_INTERVAL_MICROS *
// (CMDLINE_ENTROPY_BITS / 32) + ENTROPY_COLLECTION_DEADLINE_MICROS.
// If the function can't gather enough entropy after after exceeding
// the deadline, it will return -1 and the cmdline zbi will not be added.
static int add_cmdline_entropy(zbi_header_t *zbi, size_t capacity)
{
	strcpy(entropy_cmdline, zircon_entropy_arg);
	char *entropy = entropy_cmdline + strlen(zircon_entropy_arg);
	uint32_t elapsed_time_us = 0;
	int i = 0;

	for (i = 0; i < CMDLINE_ENTROPY_BITS; i += 32) {
		// Reading a 1 in the RNG_USR_STS means that the
		// hw rng has been reseeded. Wait until we see a 1,
		// without exceeding the global deadline.
		while ((readl(P_RNG_USR_STS) & USR_RAND32_RDY) != 1) {
			udelay(1);
			elapsed_time_us++;
			if (elapsed_time_us >
			    ENTROPY_COLLECTION_DEADLINE_MICROS) {
				return -1;
			}
		}

		uint32_to_hex(read_hw_rng(), entropy);
		entropy += 8;

		// According to the docs, this should guarantee a reseed.
		udelay(HW_RNG_RESEEDING_INTERVAL_MICROS);
	}
	*entropy = '\0';

	int ret = append_zbi_item_or_log(zbi, capacity, ZBI_TYPE_CMDLINE, 0,
					 entropy_cmdline,
					 sizeof(entropy_cmdline));

	mandatory_memset(entropy_cmdline, '\0', sizeof(entropy_cmdline));
	return ret;
}

// Buffer to keep staged ZBI files.
// We store these in their own ZBI container, which takes up a little extra
// space due to ZBI headers, but makes copying them over to the actual ZBI
// trivial.
//
// The test team needs to be able to put up to 3 SSH keys on a single device
// so make sure it's at least big enough for that.
static uint8_t zbi_files[4096] __attribute__((aligned(ZBI_ALIGNMENT)));
static bool zbi_files_initialized = false;

int zircon_stage_zbi_file(const char *name, const uint8_t *data,
			  size_t data_len)
{
	size_t name_len = strlen(name);
	if (name_len > U8_MAX) {
		printf("ZBI filename too long");
		return -1;
	}

	// Payload = (name_length_byte + name + data), size must fit in a uint32_t.
	size_t payload_length = 1 + name_len + data_len;
	if (payload_length > U32_MAX || payload_length < data_len) {
		printf("ZBI file data too large");
		return -1;
	}

	if (!zbi_files_initialized) {
		zbi_result_t result = zbi_init(zbi_files, sizeof(zbi_files));
		if (result != ZBI_RESULT_OK) {
			printf("Failed to initialize zbi_files: %d\n", result);
			return -1;
		}
		zbi_files_initialized = true;
	}

	void *payload_as_void = NULL;
	zbi_result_t result =
		zbi_create_entry(zbi_files, sizeof(zbi_files),
				 ZBI_TYPE_BOOTLOADER_FILE, 0, 0, payload_length,
				 &payload_as_void);
	if (result != ZBI_RESULT_OK) {
		printf("Failed to create ZBI file entry: %d\n", result);
		return -1;
	}

	uint8_t *payload = payload_as_void;
	payload[0] = name_len;
	memcpy(&payload[1], name, name_len);
	memcpy(&payload[1 + name_len], data, data_len);

	return 0;
}

static int add_staged_zbi_files(zbi_header_t *zbi, size_t capacity)
{
	if (!zbi_files_initialized) {
		return 0;
	}

	zbi_result_t result = zbi_extend(zbi, capacity, zbi_files);
	if (result != ZBI_RESULT_OK) {
		printf("Failed to add staged ZBI files: %d\n", result);
		return -1;
	}

	printf("Added staged ZBI files with total ZBI size %u\n",
	       ((zbi_header_t *)zbi_files)->length);
	return 0;
}

static int add_current_slot(zbi_header_t *zbi, size_t capacity,
			    AbrSlotIndex slot)
{
	const char *suffix = AbrGetSlotSuffix(slot);
	if (suffix[0] == '\0') {
		printf("Invalid AbrSlotIndex: %d\n", slot);
		return -1;
	}

	char buffer[32];
	int length =
		snprintf(buffer, sizeof(buffer), "zvb.current_slot=%s", suffix);
	if (length >= sizeof(buffer)) {
		printf("current_slot string too large: '%s'\n", buffer);
		return -1;
	}

	return append_zbi_item_or_log(zbi, capacity, ZBI_TYPE_CMDLINE, 0,
				      buffer, length + 1);
}

// The list contains all files on factory filesystem
static const char *const factory_file_list[] = {
	"client.crt",
	"client.key",
	"hw.txt",
	"locale_list.txt",
	"mac_addr",
	"nf.key",
	"pr3.crt",
	"pr3.key",
	"rgb_b_leda_cal.txt",
	"rgb_b_ledg_cal.txt",
	"rgb_b_off_cal.txt",
	"rgb_b_on_cal.txt",
	"rgb_c_leda_cal.txt",
	"rgb_c_ledg_cal.txt",
	"rgb_c_off_cal.txt",
	"rgb_c_on_cal.txt",
	"rgb_g_leda_cal.txt",
	"rgb_g_ledg_cal.txt",
	"rgb_g_off_cal.txt",
	"rgb_g_on_cal.txt",
	"rgb_r_leda_cal.txt",
	"rgb_r_ledg_cal.txt",
	"rgb_r_off_cal.txt",
	"rgb_r_on_cal.txt",
	"serial.txt",
	"sounds/error.opus",
	"sounds/err_no_lang_pack.opus",
	"sounds/fdr.opus",
	"sounds/mic_muted_warning.opus",
	"sounds/mute.opus",
	"sounds/unmute.opus",
	"sounds/welcome.opus",
	"weave.crt",
	"weave.key",
	"weave_device_id",
	"weave_pairing_code",
	"wv.key",
};

/* Adds a single bootfs factory file to the ZBI payload.
 *
 * @filename: ext4 filename.
 * @data_off: offset from the payload start to this file's data.
 * @max_bootfs_size: maximum payload size.
 * @direntry_start: pointer to this file's zbi_bootfs_dirent_t in the payload
 *                  buffer. Will be advanced past this entry on success,
 *                  including padding.
 * @payload_start: pointer to this file's data in the payload buffer. Will be
 *                 advanced past this data on success, including padding.
 * @data_len: will be filled with the file's data length.
 *
 * Returns 0 on success, nonzero on failure.
 */
static int add_factory_file(const char *filename, uint32_t data_off,
			    uint32_t max_bootfs_size, uint8_t **direntry_start,
			    uint8_t **payload_start, uint32_t *data_len)
{
	const uint32_t name_len = strlen(filename) + 1;
	const uint32_t max_data_size =
		(max_bootfs_size - data_off) & ~(ZBI_BOOTFS_PAGE_SIZE - 1);

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

	loff_t len_read;
	if (fs_read(filename, (ulong)*payload_start, 0, max_data_size,
		    &len_read)) {
		printf("Failed to read file %s from Factory partition\n",
		       filename);
		return -1;
	}

	if (len_read > UINT_MAX) {
		printf("File size overloads UINT32_MAX\n");
		return -1;
	}

	*data_len = (uint32_t)len_read;
	*payload_start += *data_len;

	uint32_t data_pad_size = ZBI_BOOTFS_PAGE_ALIGN(*data_len) - *data_len;
	memset(*payload_start, 0, data_pad_size);
	*payload_start += data_pad_size;

	// The caller has already reserved space for the dirent structures and
	// filenames in the buffer, so we don't need to check for overflow here.
	zbi_bootfs_dirent_t *entry_hdr =
		(zbi_bootfs_dirent_t *)(*direntry_start);
	entry_hdr->name_len = name_len;
	entry_hdr->data_len = *data_len;
	entry_hdr->data_off = data_off;

	*direntry_start += offsetof(zbi_bootfs_dirent_t, name);
	memcpy(*direntry_start, filename, name_len);
	*direntry_start += name_len;

	uint32_t full_dirent_size = ZBI_BOOTFS_DIRENT_SIZE(name_len);
	uint32_t after_name_offset =
		offsetof(zbi_bootfs_dirent_t, name[name_len]);
	uint32_t dirent_pad_size = full_dirent_size - after_name_offset;
	memset(*direntry_start, 0, dirent_pad_size);
	*direntry_start += dirent_pad_size;

	return 0;
}

/* Loads factory files into a BOOTFS ZBI payload.
 *
 * @bootfs_header: start of the payload buffer to fill.
 * @max_bootfs_size: maximum payload size.
 * @file_count: number of files in the ZBI item.
 * @dirsize: size in bytes of the zbi_bootfs_dirent_t array.
 * @bootfs_size: set to the actual payload size.
 *
 * Returns 0 on success, nonzero on failure.
 */
static int add_bootfs_factory_files(zbi_bootfs_header_t *bootfs_header,
				    uint32_t max_bootfs_size,
				    uint32_t file_count, uint32_t dirsize,
				    uint32_t *bootfs_size)
{
	if (sizeof(*bootfs_header) > max_bootfs_size) {
		printf("ERROR: can't fit bootfs header in ZBI payload (%zu > %u)\n",
		       sizeof(*bootfs_header), max_bootfs_size);
		return 1;
	}
	bootfs_header->magic = ZBI_BOOTFS_MAGIC;
	bootfs_header->dirsize = dirsize;
	bootfs_header->reserved0 = 0;
	bootfs_header->reserved1 = 0;

	uint32_t dir_entries_end_offset = dirsize + sizeof(zbi_bootfs_header_t);
	uint32_t data_off = ZBI_BOOTFS_PAGE_ALIGN(dir_entries_end_offset);
	if (data_off < dirsize) {
		printf("ERROR: bootfs dirsize overflow (dirsize = %u, data_off = %u)\n",
		       dirsize, data_off);
		return 1;
	}
	if (data_off > max_bootfs_size) {
		printf("ERROR: can't fit bootfs dir entries in ZBI payload (%u > %u)\n",
		       data_off, max_bootfs_size);
		return 1;
	}

	uint8_t *header_start = (uint8_t *)bootfs_header;
	uint8_t *entry_ptr = header_start + sizeof(zbi_bootfs_header_t);
	uint8_t *payload_padding_start = header_start + dir_entries_end_offset;
	uint8_t *payload_start = header_start + data_off;

	memset(payload_padding_start, 0,
	       (size_t)(payload_start - payload_padding_start));

	uint32_t i;
	for (i = 0; i < file_count; i++) {
		const char *const filename = factory_file_list[i];
		uint32_t data_len = 0;

		payload_padding_start = payload_start;
		int ret =
			add_factory_file(filename, data_off, max_bootfs_size,
					 &entry_ptr, &payload_start, &data_len);
		if (ret != 0) {
			// Log the error, but try to keep going and add the rest of the
			// factory files.
			printf("ERROR: failed to add factory file %s\n",
			       filename);
		}
		payload_padding_start += data_len;

		data_off += ZBI_BOOTFS_PAGE_ALIGN(data_len);
		memset(payload_padding_start, 0,
		       (size_t)(payload_start - payload_padding_start));
	}

	*bootfs_size = data_off;
	return 0;
}

/* Adds a ZBI item containing the factory files to the given container.
 *
 * On Newman, factory files are stored in a ext4 partition. It has been observed
 * that some devices have ext4 64 bit flag set, which causes fuchsia to refuse
 * to process. Therefore, we instead pass all files as ZBI items to fuchsia
 * directly from the bootloader.
 *
 * @zbi: ZBI container to add the factory files to.
 * @capacity: ZBI container max capacity.
 *
 * Returns 0 on success, nonzero on failure.
 */
static int add_factory_data(zbi_header_t *zbi, size_t capacity)
{
	// Add an empty ZBI header for factory data. Factory data is formated as BOOTFS.
	// BOOTFS is a trivial "filesystem" format.
	//
	// It consists of a zbi_bootfs_header_t followed by a series of zbi_bootfs_dirent_t structs.
	// After the zbi_bootfs_dirent_t structs, file data is placed.
	// File data offsets are page aligned (multiple of 4096).
	// zbi_bootfs_dirent_t structs start on uint32 boundaries.
	void *payload = NULL;
	uint32_t max_payload_size = 0;
	zbi_result_t result = zbi_get_next_entry_payload(
		zbi, capacity, &payload, &max_payload_size);
	if (result != ZBI_RESULT_OK) {
		printf("ERROR: zbi_get_next_entry_payload() failed: %d\n",
		       result);
		return 1;
	}

	// Determine how much space is needed to store all of the directory entries.
	uint32_t dirsize = 0;
	uint32_t file_count = (uint32_t)(sizeof(factory_file_list) /
					 sizeof(*factory_file_list));

	uint32_t i;
	for (i = 0; i < file_count; i++) {
		const char *const filename = factory_file_list[i];
		dirsize += ZBI_BOOTFS_DIRENT_SIZE(strlen(filename) + 1);
	}

	// Mark the start of the zbi_bootfs_header_t.
	// This header is bootfs-specific and stores data related to the number of
	// directory entries.
	uint32_t bootfs_size = 0;
	int ret = add_bootfs_factory_files((zbi_bootfs_header_t *)payload,
					   max_payload_size, file_count,
					   dirsize, &bootfs_size);
	if (ret != 0) {
		printf("ERROR: add_bootfs_factory_files() failed\n");
		return ret;
	}

	// Finally, add the ZBI item using the newly created payload.
	result =
		zbi_create_entry(zbi, capacity, ZBI_TYPE_STORAGE_BOOTFS_FACTORY,
				 0, 0, bootfs_size, NULL);
	if (result != ZBI_RESULT_OK) {
		printf("ERROR: zbi_create_entry() failed: %d\n", result);
		return 1;
	}
	return 0;
}

/* We do this a lot in zircon_fixup_zbi(), a macro helps with boilerplate.
 * Generally it's best to fail loudly if we can't add a ZBI item; we want to
 * know immediately if ZBI items are missing, not later when random things
 * stop working in the OS. */
#define RETURN_IF_NONZERO(val)                                                 \
	do {                                                                   \
		int ret = (val);                                               \
		if (ret != 0) {                                                \
			return ret;                                            \
		}                                                              \
	} while (0)


int zircon_fixup_zbi_no_slot(zbi_header_t *zbi, size_t capacity) {
	/*
	 * allocate crashlog save area before 0x5f800000-0x60000000
	 * reserved area
	 */
	zbi_nvram_t nvram;

	nvram.base = 0x5f800000 - NVRAM_LENGTH;
	nvram.length = NVRAM_LENGTH;
	RETURN_IF_NONZERO(append_zbi_item_or_log(zbi, capacity, ZBI_TYPE_NVRAM,
						 0, &nvram, sizeof(nvram)));

	/* add memory configuration */
	RETURN_IF_NONZERO(
		append_zbi_item_or_log(zbi, capacity, ZBI_TYPE_MEM_CONFIG, 0,
				       &mem_config, sizeof(mem_config)));

	/* add kernel drivers */
	RETURN_IF_NONZERO(append_zbi_item_or_log(
		zbi, capacity, ZBI_TYPE_KERNEL_DRIVER, KDRV_AMLOGIC_UART,
		&uart_driver, sizeof(uart_driver)));
	RETURN_IF_NONZERO(append_zbi_item_or_log(
		zbi, capacity, ZBI_TYPE_KERNEL_DRIVER, KDRV_ARM_GIC_V2,
		&gicv2_driver, sizeof(gicv2_driver)));
	RETURN_IF_NONZERO(append_zbi_item_or_log(
		zbi, capacity, ZBI_TYPE_KERNEL_DRIVER, KDRV_ARM_PSCI,
		&psci_driver, sizeof(psci_driver)));
	RETURN_IF_NONZERO(append_zbi_item_or_log(
		zbi, capacity, ZBI_TYPE_KERNEL_DRIVER, KDRV_ARM_GENERIC_TIMER,
		&timer_driver, sizeof(timer_driver)));
	RETURN_IF_NONZERO(append_zbi_item_or_log(
		zbi, capacity, ZBI_TYPE_KERNEL_DRIVER,
		KDRV_GENERIC_32BIT_WATCHDOG, &watchdog_driver,
		sizeof(watchdog_driver)));
	RETURN_IF_NONZERO(append_zbi_item_or_log(
		zbi, capacity, ZBI_TYPE_KERNEL_DRIVER, KDRV_AMLOGIC_RNG,
		&rng_driver, sizeof(rng_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] = '_';
		}
	}

	RETURN_IF_NONZERO(append_zbi_item_or_log(
		zbi, capacity, ZBI_TYPE_CMDLINE, 0, uboot_ver, len + 1));

	if (add_serial_number(zbi, capacity) != 0) {
		// TODO(b/171923279): actually error out here once we can handle
		// empty factory partitions.
		printf("ERROR: failed to add serial number\n");
	}

	/* Add board-specific information */
	RETURN_IF_NONZERO(add_board_info(zbi, capacity));

	/* add platform ID */
	RETURN_IF_NONZERO(
		append_zbi_item_or_log(zbi, capacity, ZBI_TYPE_PLATFORM_ID, 0,
				       &platform_id, sizeof(platform_id)));

	RETURN_IF_NONZERO(add_cpu_topology(zbi, capacity));

	RETURN_IF_NONZERO(add_cmdline_entropy(zbi, capacity));

	RETURN_IF_NONZERO(add_factory_data(zbi, capacity));

	if (add_mac_addresses(zbi, capacity) != 0) {
		// TODO(b/171923279): actually error out here once we can handle
		// empty factory partitions.
		printf("ERROR: failed to add MAC address\n");
	}

	// Only append extra cmdline args if unlocked
	bool unlocked;
	if (zircon_vboot_is_unlocked(&unlocked)) {
		fprintf(stderr, "Error: unable to get unlock status\n");
	} else if (unlocked) {
		if (zircon_append_cmdline(zbi, capacity)) {
			fprintf(stderr, "ERROR: unable to append boot_args.\n");
			return -1;
		}
	}

	RETURN_IF_NONZERO(add_reboot_reason(zbi, capacity));

	if (watchdog_driver.flags & KDRV_GENERIC_32BIT_WATCHDOG_FLAG_ENABLED) {
		start_meson_watchdog();
	}

	RETURN_IF_NONZERO(add_staged_zbi_files(zbi, capacity));

	return 0;
}

int zircon_fixup_zbi(zbi_header_t *zbi, size_t capacity, AbrSlotIndex slot)
{
	RETURN_IF_NONZERO(add_current_slot(zbi, capacity, slot));
	return zircon_fixup_zbi_no_slot(zbi, capacity);
}
