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