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

#include <common.h>

#include <dm/uclass.h>
#include <emmc_storage.h>
#include <fs.h>
#include <linux/mtd/partitions.h>
#include <part.h>
#include <version.h>
#include <wdt.h>
#include <zbi/zbi.h>
#include <zircon/boot_args.h>
#include <zircon/vboot.h>
#include <zircon/zircon.h>
#include <lib/zircon_boot/zbi_utils.h>

#include <asm/arch/reboot.h>
#include <asm/arch/secure_apb.h>
#include <asm/io.h>

#include "factory.h"

#include "override_reboot_mode.h"

#define PDEV_VID_GOOGLE 3
#define PDEV_PID_NELSON 10
// Elaine has 1 cluster of 4 cpus.
#define ELAINE_NUM_CPU 4

#define NVRAM_LENGTH (8 * 1024)

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 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_NELSON,
	.board_name = "nelson",
};

#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 int add_reboot_reason(zbi_header_t *zbi, size_t capacity)
{
	// See cmd/amlogic/cmd_reboot.c
	const uint32_t reboot_mode_val = get_rebootmode_value();

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

static int add_cpu_topology(zbi_header_t *zbi, size_t capacity)
{
	zbi_topology_node_t nodes[ELAINE_NUM_CPU + 1];

	zbi_topology_cluster_t cluster = {
		.performance_class = 1,
	};

	zbi_topology_node_t cluster_node = {
		.entity_type = ZBI_TOPOLOGY_ENTITY_CLUSTER,
		.parent_index = ZBI_TOPOLOGY_NO_PARENT,
		.entity = { .cluster = cluster },
	};
	nodes[0] = cluster_node;

	for (int cpu = 0; cpu < ELAINE_NUM_CPU; cpu++) {
		zbi_topology_arm_info_t arm_info = {
			.cluster_1_id = cpu,
			.cpu_id = 0,
			.gic_id = cpu,
		};

		zbi_topology_processor_t processor = {
			.logical_ids = { cpu },
			.logical_id_count = 1,
			.flags =
				(cpu == 0) ? ZBI_TOPOLOGY_PROCESSOR_PRIMARY : 0,
			.architecture = ZBI_TOPOLOGY_ARCH_ARM,
			.architecture_info = { arm_info },
		};

		zbi_topology_node_t node = {
			.entity_type = ZBI_TOPOLOGY_ENTITY_PROCESSOR,
			.parent_index = 0,
			.entity = { .processor = processor },
		};

		nodes[cpu + 1] = node;
	}

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

#define FACTORY_MAC_ADDR_BUFF_LEN 30

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(ELAINE_FACTORY_IF, ELAINE_FACTORY_PART,
			   FS_TYPE_EXT)) {
		printf("set_blk_dev %s-%s failed.\n", ELAINE_FACTORY_IF,
		       ELAINE_FACTORY_PART);
		return -1;
	}

	if (fs_read(ELAINE_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 != ELAINE_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));
}

// 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)
{
	char buffer[32];
	int length = snprintf(buffer, sizeof(buffer), "zvb.current_slot=%s",
			      g_tpl_slot);
	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);
}

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

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

// 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

// 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

#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.");

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

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

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

static int add_panel_type(zbi_header_t *zbi, size_t capacity)
{
	enum {
		// These values are shared with the Fuchsia GT6853 touch driver,
		// and must be kept in sync.
		kPanelTypeKdFiti9364 = 1,
		kPanelTypeBoeFiti9364 = 2,
		kPanelTypeInxFiti9364 = 3,
		kPanelTypeKdFiti9365 = 4,
		kPanelTypeBoeFiti9365 = 5,
		kPanelTypeBoeSit7703 = 6,
	};

	const char *panel_type = env_get("panel_type");
	if (!panel_type) {
		return -1;
	}

	uint32_t panel_type_id = 0;
	if (!strcmp(panel_type, "boe_fiti9364_7")) {
		panel_type_id = kPanelTypeBoeFiti9364;
	} else if (!strcmp(panel_type, "kd_fiti9364_7")) {
		panel_type_id = kPanelTypeKdFiti9364;
	} else if (!strcmp(panel_type, "inx_fiti9364_7")) {
		panel_type_id = kPanelTypeInxFiti9364;
	} else if (!strcmp(panel_type, "boe_fiti9365_7")) {
		panel_type_id = kPanelTypeBoeFiti9365;
	} else if (!strcmp(panel_type, "kd_fiti9365_7")) {
		panel_type_id = kPanelTypeKdFiti9365;
	} else if (!strcmp(panel_type, "boe_sit7703_7")) {
		panel_type_id = kPanelTypeBoeSit7703;
	} else {
		// This is expected on P0/P1 boards, which use different
		// panel_type strings.
		return 0;
	}

	// The touch controller will be left with a default config if this
	// fails, but it should still work.
	return append_zbi_item_or_log(zbi, capacity, ZBI_TYPE_DRV_BOARD_PRIVATE,
				      0, &panel_type_id, sizeof(panel_type_id));
}

const char *factory_file_list[] = {
	// From vendor/google/app/factory_configs/nelson/fuchsia.factory.MiscFactoryStoreProvider.config
	"hw.txt",
	"locale_list.txt",
	"mac_addr",
	"serial.txt",
	"rgb_b_led_cal.txt",
	"rgb_b_off_cal.txt",
	"rgb_b_on_cal.txt",
	"rgb_c_led_cal.txt",
	"rgb_c_off_cal.txt",
	"rgb_c_on_cal.txt",
	"rgb_g_led_cal.txt",
	"rgb_g_off_cal.txt",
	"rgb_g_on_cal.txt",
	"rgb_r_led_cal.txt",
	"rgb_r_off_cal.txt",
	"rgb_r_on_cal.txt",
	"sounds/unmute.opus",
	"sounds/err_no_lang_pack.opus",
	"sounds/error.opus",
	"sounds/mic_muted_warning.opus",
	"sounds/welcome.opus",
	"sounds/mute.opus",
	"sounds/fdr.opus",

	// From vendor/google/app/factory_configs/nelson/fuchsia.factory.AlphaFactoryStoreProvider.config
	"nf.key",

	// From vendor/google/app/factory_configs/nelson/fuchsia.factory.CastCredentialsFactoryStoreProvider.config
	"client.crt",
	"client.key",

	// From vendor/google/app/factory_configs/nelson/fuchsia.factory.PlayReadyFactoryStoreProvider.config
	"pr3.crt",
	"pr3.key",

	// From vendor/google/app/factory_configs/nelson/fuchsia.factory.WidevineFactoryStoreProvider.config
	"wv.key",

	// From vendor/google/app/factory_configs/nelson/fuchsia.factory.WeaveFactoryStoreProvider.config
	"weave.crt",
	"weave_device_id",
	"weave.key",
	"weave_pairing_code",
};

bool read_factory(void *context, const char *name, size_t capacity,
		  void *output, size_t *out_len)
{
	if (fs_set_blk_dev(ELAINE_FACTORY_IF, ELAINE_FACTORY_PART,
			   FS_TYPE_EXT)) {
		printf("set_blk_dev %s-%s failed.\n", ELAINE_FACTORY_IF,
		       ELAINE_FACTORY_PART);
		return false;
	}

	loff_t len_read;
	if (fs_read(name, (ulong)output, 0, capacity, &len_read)) {
		printf("Failed to read file %s from Factory partition\n", name);
		return false;
	}

	*out_len = (size_t)len_read;
	return true;
}

static int append_factory_files(zbi_header_t *zbi, size_t capacity)
{
	return AppendBootfsFactoryFiles(zbi, capacity, factory_file_list,
					ARRAY_SIZE(factory_file_list),
					read_factory, NULL) == ZBI_RESULT_OK ?
		       0 :
		       1;
}

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

	// 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_serial_number(zbi, capacity));

	RETURN_IF_NONZERO(add_mac_addresses(zbi, capacity));

	RETURN_IF_NONZERO(add_cmdline_entropy(zbi, capacity));

	add_panel_type(zbi, capacity);

	// 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_IF_NONZERO(append_factory_files(zbi, capacity));

	return 0;
}

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