/*
 * 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_off_cal.txt",
	"rgb_b_on_cal.txt",
	"rgb_c_off_cal.txt",
	"rgb_c_on_cal.txt",
	"rgb_g_off_cal.txt",
	"rgb_g_on_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);
}
