/* Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include <ctype.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#if !defined(__FreeBSD__) && !defined(__OpenBSD__)
#include <linux/nvram.h>
#include <linux/version.h>
#endif
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/utsname.h>
#include <unistd.h>

#include "crossystem_arch.h"
#include "crossystem.h"
#include "crossystem_vbnv.h"
#include "host_common.h"
#include "vboot_struct.h"

/* ACPI constants from Chrome OS Main Processor Firmware Spec */
/* Boot reasons from BINF.0, from early H2C firmware */
/* Unknown */
#define BINF0_UNKNOWN                  0
/* Normal boot to Chrome OS */
#define BINF0_NORMAL                   1
/* Developer mode boot (developer mode warning displayed) */
#define BINF0_DEVELOPER                2
/* Recovery initiated by user, using recovery button */
#define BINF0_RECOVERY_BUTTON          3
/* Recovery initiated by user pressing a key at developer mode warning
 * screen */
#define BINF0_RECOVERY_DEV_SCREEN_KEY  4
/* Recovery caused by BIOS failed signature check (neither rewritable
 * firmware was valid) */
#define BINF0_RECOVERY_RW_FW_BAD       5
/* Recovery caused by no OS kernel detected */
#define BINF0_RECOVERY_NO_OS           6
/* Recovery caused by OS kernel failed signature check */
#define BINF0_RECOVERY_BAD_OS          7
/* Recovery initiated by OS */
#define BINF0_RECOVERY_OS_INITIATED    8
/* OS-initiated S3 diagnostic path (debug mode boot) */
#define BINF0_S3_DIAGNOSTIC_PATH       9
/* S3 resume failed */
#define BINF0_S3_RESUME_FAILED        10
/* Recovery caused by TPM error */
#define BINF0_RECOVERY_TPM_ERROR      11
/* CHSW bitflags */
#define CHSW_RECOVERY_BOOT     0x00000002
#define CHSW_RECOVERY_EC_BOOT  0x00000004
#define CHSW_DEV_BOOT          0x00000020
/* CMOS reboot field bitflags */
#define CMOSRF_RECOVERY        0x80
#define CMOSRF_DEBUG_RESET     0x40
#define CMOSRF_TRY_B           0x20
/* GPIO signal types */
#define GPIO_SIGNAL_TYPE_RECOVERY 1
#define GPIO_SIGNAL_TYPE_DEPRECATED_DEV 2  /* Deprecated; see chromium:942901 */
#define GPIO_SIGNAL_TYPE_WP 3
#define GPIO_SIGNAL_TYPE_PHASE_ENFORCEMENT 4

/* Base name for ACPI files */
#define ACPI_BASE_PATH "/sys/devices/platform/chromeos_acpi"
/* Paths for frequently used ACPI files */
#define ACPI_BINF_PATH ACPI_BASE_PATH "/BINF"
#define ACPI_CHNV_PATH ACPI_BASE_PATH "/CHNV"
#define ACPI_CHSW_PATH ACPI_BASE_PATH "/CHSW"
#define ACPI_GPIO_PATH ACPI_BASE_PATH "/GPIO"
#define ACPI_VBNV_PATH ACPI_BASE_PATH "/VBNV"
#define ACPI_VDAT_PATH ACPI_BASE_PATH "/VDAT"

/* Base name for GPIO files */
#define GPIO_BASE_PATH "/sys/class/gpio"
#define GPIO_EXPORT_PATH GPIO_BASE_PATH "/export"

/* Filename for NVRAM file */
#define NVRAM_PATH "/dev/nvram"

/* Filename for legacy firmware update tries */
#define NEED_FWUPDATE_PATH "/mnt/stateful_partition/.need_firmware_update"

/* Filenames for PCI Vendor and Device IDs */
#define PCI_VENDOR_ID_PATH "/sys/bus/pci/devices/0000:00:00.0/vendor"
#define PCI_DEVICE_ID_PATH "/sys/bus/pci/devices/0000:00:00.0/device"

typedef struct {
	unsigned int base;
	unsigned int uid;
} Basemapping;

static void VbFixCmosChecksum(FILE* file)
{
#if !defined(__FreeBSD__) && !defined(__OpenBSD__)
	int fd = fileno(file);
	ioctl(fd, NVRAM_SETCKS);
#endif
}


static int VbCmosRead(unsigned offs, size_t size, void *ptr)
{
	size_t res;
	FILE* f;

	f = fopen(NVRAM_PATH, "rb");
	if (!f)
		return -1;

	if (0 != fseek(f, offs, SEEK_SET)) {
		fclose(f);
		return -1;
	}

	res = fread(ptr, size, 1, f);
	if (1 != res && errno == EIO && ferror(f)) {
		VbFixCmosChecksum(f);
		res = fread(ptr, size, 1, f);
	}

	fclose(f);
	return (1 == res) ? 0 : -1;
}


static int VbCmosWrite(unsigned offs, size_t size, const void *ptr)
{
	size_t res;
	FILE* f;

	f = fopen(NVRAM_PATH, "w+b");
	if (!f)
		return -1;

	if (0 != fseek(f, offs, SEEK_SET)) {
		fclose(f);
		return -1;
	}

	res = fwrite(ptr, size, 1, f);
	if (1 != res && errno == EIO && ferror(f)) {
		VbFixCmosChecksum(f);
		res = fwrite(ptr, size, 1, f);
	}

	fclose(f);
	return (1 == res) ? 0 : -1;
}


int vb2_read_nv_storage(struct vb2_context *ctx)
{
	unsigned offs, blksz;
	unsigned expectsz = vb2_nv_get_size(ctx);

	/* Get the byte offset from VBNV */
	if (ReadFileInt(ACPI_VBNV_PATH ".0", &offs) < 0)
		return -1;
	if (ReadFileInt(ACPI_VBNV_PATH ".1", &blksz) < 0)
		return -1;
	if (expectsz > blksz)
		return -1;  /* NV storage block is too small */

	if (0 != VbCmosRead(offs, expectsz, ctx->nvdata))
		return -1;

	return 0;
}


int vb2_write_nv_storage(struct vb2_context *ctx)
{
	unsigned offs, blksz;
	unsigned expectsz = vb2_nv_get_size(ctx);

	if (!(ctx->flags & VB2_CONTEXT_NVDATA_CHANGED))
		return 0;  /* Nothing changed, so no need to write */

	/* Get the byte offset from VBNV */
	if (ReadFileInt(ACPI_VBNV_PATH ".0", &offs) < 0)
		return -1;
	if (ReadFileInt(ACPI_VBNV_PATH ".1", &blksz) < 0)
		return -1;
	if (expectsz > blksz)
		return -1;  /* NV storage block is too small */

	if (0 != VbCmosWrite(offs, expectsz, ctx->nvdata))
		return -1;

	/* Also attempt to write using flashrom if using vboot2 */
	VbSharedDataHeader *sh = VbSharedDataRead();
	if (sh) {
		if (sh->flags & VBSD_BOOT_FIRMWARE_VBOOT2)
			vb2_write_nv_storage_flashrom(ctx);
		free(sh);
	}

	return 0;
}


/*
 * Get buffer data from ACPI.
 *
 * Buffer data is expected to be represented by a file which is a text dump of
 * the buffer, representing each byte by two hex numbers, space and newline
 * separated.
 *
 * On success, stores the amount of data read in bytes to *buffer_size; on
 * erros, sets *buffer_size=0.
 *
 * Input - ACPI file name to get data from.
 *
 * Output: a pointer to AcpiBuffer structure containing the binary
 *         representation of the data. The caller is responsible for
 *         deallocating the pointer, this will take care of both the structure
 *         and the buffer. Null in case of error.
 */
static uint8_t* VbGetBuffer(const char* filename, int* buffer_size)
{
	FILE* f = NULL;
	char* file_buffer = NULL;
	uint8_t* output_buffer = NULL;
	uint8_t* return_value = NULL;

	/* Assume error until proven otherwise */
	if (buffer_size)
		*buffer_size = 0;

	do {
		struct stat fs;
		uint8_t* output_ptr;
		int rv, i, real_size;
		int parsed_size = 0;

		int fd = open(filename, O_RDONLY);
		if (fd == -1)
			break;

		rv = fstat(fd, &fs);
		if (rv || !S_ISREG(fs.st_mode)) {
			close(fd);
			break;
		}

		f = fdopen(fd, "r");
		if (!f) {
			close(fd);
			break;
		}

		file_buffer = malloc(fs.st_size + 1);
		if (!file_buffer)
			break;

		real_size = fread(file_buffer, 1, fs.st_size, f);
		if (!real_size)
			break;
		file_buffer[real_size] = '\0';

		/* Each byte in the output will replace two characters and a
		 * space in the input, so the output size does not exceed input
		 * side/3 (a little less if account for newline characters). */
		output_buffer = malloc(real_size/3);
		if (!output_buffer)
			break;
		output_ptr = output_buffer;

		/* process the file contents */
		for (i = 0; i < real_size; i++) {
			char* base, *end;

			base = file_buffer + i;

			if (!isxdigit(*base))
				continue;

			output_ptr[parsed_size++] =
					strtol(base, &end, 16) & 0xff;

			if ((end - base) != 2)
				/* Input file format error */
				break;

			/* skip the second character and the following space */
			i += 2;
		}

		if (i == real_size) {
			/* all is well */
			return_value = output_buffer;
			output_buffer = NULL; /* prevent it from deallocating */
			if (buffer_size)
				*buffer_size = parsed_size;
		}
	} while(0);

	/* wrap up */
	if (f)
		fclose(f);

	if (file_buffer)
		free(file_buffer);

	if (output_buffer)
		free(output_buffer);

	return return_value;
}


VbSharedDataHeader* VbSharedDataRead(void)
{
	VbSharedDataHeader* sh;
	int got_size = 0;
	int expect_size;

	sh = (VbSharedDataHeader*)VbGetBuffer(ACPI_VDAT_PATH, &got_size);
	if (!sh)
		return NULL;

	/* Make sure the size is sufficient for the struct version we got.
	 * Check supported old versions first. */
	if (1 == sh->struct_version)
		expect_size = VB_SHARED_DATA_HEADER_SIZE_V1;
	else {
		/* There'd better be enough data for the current header size. */
		expect_size = sizeof(VbSharedDataHeader);
	}

	if (got_size < expect_size) {
		free(sh);
		return NULL;
	}
	if (sh->data_size > got_size)
		sh->data_size = got_size;  /* Truncated read */

	return sh;
}


/* Read the CMOS reboot field in NVRAM.
 *
 * Returns 0 if the mask is clear in the field, 1 if set, or -1 if error. */
static int VbGetCmosRebootField(uint8_t mask)
{
	unsigned chnv;
	uint8_t nvbyte;

	/* Get the byte offset from CHNV */
	if (ReadFileInt(ACPI_CHNV_PATH, &chnv) < 0)
		return -1;

	if (0 != VbCmosRead(chnv, 1, &nvbyte))
		return -1;

	return (nvbyte & mask ? 1 : 0);
}


/* Write the CMOS reboot field in NVRAM.
 *
 * Sets (value=0) or clears (value!=0) the mask in the byte.
 *
 * Returns 0 if success, or -1 if error. */
static int VbSetCmosRebootField(uint8_t mask, int value)
{
	unsigned chnv;
	uint8_t nvbyte;

	/* Get the byte offset from CHNV */
	if (ReadFileInt(ACPI_CHNV_PATH, &chnv) < 0)
		return -1;

	if (0 != VbCmosRead(chnv, 1, &nvbyte))
		return -1;

	/* Set/clear the mask */
	if (value)
		nvbyte |= mask;
	else
		nvbyte &= ~mask;

	/* Write the byte back */
	if (0 != VbCmosWrite(chnv, 1, &nvbyte))
		return -1;

	/* Success */
	return 0;
}


/* Read the active main firmware type into the destination buffer.
 * Passed the destination and its size.  Returns the destination, or
 * NULL if error. */
static const char* VbReadMainFwType(char* dest, int size)
{
	unsigned value;

	/* Try reading type from BINF.3 */
	if (ReadFileInt(ACPI_BINF_PATH ".3", &value) == 0) {
		switch(value) {
			case BINF3_LEGACY:
				return StrCopy(dest, "legacy", size);
			case BINF3_NETBOOT:
				return StrCopy(dest, "netboot", size);
			case BINF3_RECOVERY:
				return StrCopy(dest, "recovery", size);
			case BINF3_NORMAL:
				return StrCopy(dest, "normal", size);
			case BINF3_DEVELOPER:
				return StrCopy(dest, "developer", size);
			default:
				break;  /* Fall through to legacy handling */
		}
	}

	/* Fall back to BINF.0 for legacy systems like Mario. */
	if (ReadFileInt(ACPI_BINF_PATH ".0", &value) < 0)
		/* Both BINF.0 and BINF.3 are missing, so this isn't Chrome OS
		 * firmware. */
		return StrCopy(dest, "nonchrome", size);

	switch(value) {
		case BINF0_NORMAL:
			return StrCopy(dest, "normal", size);
		case BINF0_DEVELOPER:
			return StrCopy(dest, "developer", size);
		case BINF0_RECOVERY_BUTTON:
		case BINF0_RECOVERY_DEV_SCREEN_KEY:
		case BINF0_RECOVERY_RW_FW_BAD:
		case BINF0_RECOVERY_NO_OS:
		case BINF0_RECOVERY_BAD_OS:
		case BINF0_RECOVERY_OS_INITIATED:
		case BINF0_RECOVERY_TPM_ERROR:
			/* Assorted flavors of recovery boot reason. */
			return StrCopy(dest, "recovery", size);
		default:
			/* Other values don't map cleanly to firmware type. */
			return NULL;
	}
}


/* Read the recovery reason.  Returns the reason code or -1 if error. */
static vb2_error_t VbGetRecoveryReason(void)
{
	unsigned value;

	/* Try reading type from BINF.4 */
	if (ReadFileInt(ACPI_BINF_PATH ".4", &value) == 0)
		return value;

	/* Fall back to BINF.0 for legacy systems like Mario. */
	if (ReadFileInt(ACPI_BINF_PATH ".0", &value) < 0)
		return -1;
	switch(value) {
		case BINF0_NORMAL:
		case BINF0_DEVELOPER:
			return VB2_RECOVERY_NOT_REQUESTED;
		case BINF0_RECOVERY_BUTTON:
			return VB2_RECOVERY_RO_MANUAL;
		case BINF0_RECOVERY_RW_FW_BAD:
			return VB2_RECOVERY_RO_INVALID_RW;
		case BINF0_RECOVERY_NO_OS:
			return VB2_RECOVERY_RW_NO_KERNEL;
		case BINF0_RECOVERY_BAD_OS:
			return VB2_RECOVERY_RW_INVALID_OS;
		case BINF0_RECOVERY_OS_INITIATED:
			return VB2_RECOVERY_LEGACY;
		default:
			/* Other values don't map cleanly to firmware type. */
			return -1;
	}
}

/* Physical GPIO number <N> may be accessed through /sys/class/gpio/gpio<M>/,
 * but <N> and <M> may differ by some offset <O>. To determine that constant,
 * we look for a directory named /sys/class/gpio/gpiochip<O>/. If there's not
 * exactly one match for that, we're SOL.
 */
static int FindGpioChipOffset(unsigned *gpio_num, unsigned *offset,
			      const char *name)
{
	DIR *dir;
	struct dirent *ent;
	int match = 0;

	dir = opendir(GPIO_BASE_PATH);
	if (!dir) {
		return 0;
	}

	while(0 != (ent = readdir(dir))) {
		if (1 == sscanf(ent->d_name, "gpiochip%u", offset)) {
			match++;
		}
	}

	closedir(dir);
	return (1 == match);
}

/* Physical GPIO number <N> may be accessed through /sys/class/gpio/gpio<M>/,
 * but <N> and <M> may differ by some offset <O>. To determine that constant,
 * we look for a directory named /sys/class/gpio/gpiochip<O>/ and check for
 * a 'label' file inside of it to find the expected the controller name.
 */
static int FindGpioChipOffsetByLabel(unsigned *gpio_num, unsigned *offset,
				     const char *name)
{
	DIR *dir;
	struct dirent *ent;
	char filename[128];
	char chiplabel[128];
	int match = 0;
	unsigned controller_offset = 0;

	dir = opendir(GPIO_BASE_PATH);
	if (!dir) {
		return 0;
	}

	while(0 != (ent = readdir(dir))) {
		if (1 == sscanf(ent->d_name, "gpiochip%u",
				&controller_offset)) {
			/*
			 * Read the file at gpiochip<O>/label to get the
			 * identifier for this bank of GPIOs.
			 */
			snprintf(filename, sizeof(filename),
				 "%s/gpiochip%u/label",
				 GPIO_BASE_PATH, controller_offset);
			if (ReadFileString(chiplabel, sizeof(chiplabel),
					   filename)) {
				if (!strncasecmp(chiplabel, name,
						 strlen(name))) {
					/*
					 * Store offset when chip label is
					 * matched.
					 */
					*offset = controller_offset;
					match++;
				}
			}
		}
	}

	closedir(dir);
	return (1 == match);
}

static int FindGpioChipOffsetByNumber(unsigned *gpio_num, unsigned *offset,
				      Basemapping *data)
{
	DIR *dir;
	struct dirent *ent;
	int match = 0;

	/* Obtain relative GPIO number.
	 * The assumption here is the Basemapping
	 * table is arranged in decreasing order of
	 * base address and ends with 0.
	 * A UID with value 0 indicates an invalid range
	 * and causes an early return to avoid the directory
	 * opening code below.
	 */
	do {
		if (*gpio_num >= data->base) {
			*gpio_num -= data->base;
			break;
		}
		data++;
	} while(1);

	if (data->uid == 0) {
		return 0;
	}

	dir = opendir(GPIO_BASE_PATH);
	if (!dir) {
		return 0;
	}

	while(0 != (ent = readdir(dir))) {
		/* For every gpiochip entry determine uid. */
		if (1 == sscanf(ent->d_name, "gpiochip%u", offset)) {
			char uid_file[128];
			unsigned uid_value;
			snprintf(uid_file, sizeof(uid_file),
				 "%s/gpiochip%u/device/firmware_node/uid",
				 GPIO_BASE_PATH, *offset);
			if (ReadFileInt(uid_file, &uid_value) < 0)
				continue;
			if (data->uid == uid_value) {
				match++;
				break;
			}
		}
	}

	closedir(dir);
	return (1 == match);
}


/* Braswell has 4 sets of GPIO banks. It is expected the firmware exposes each
 * bank of gpios using a UID in ACPI. Furthermore the gpio number exposed is
 * relative to the bank. e.g. gpio MF_ISH_GPIO_4 in the bank specified by UID 3
 * would be encoded as 0x10016.
 *
 *  UID | Bank Offset
 *  ----+------------
 *   1  | 0x0000
 *   2  | 0x8000
 *   3  | 0x10000
 *   4  | 0x18000
 */
static int BraswellFindGpioChipOffset(unsigned *gpio_num, unsigned *offset,
				      const char *name)
{
	int ret;
	struct utsname host;
	unsigned int maj, min;
	int gpe = 0;
	static Basemapping data[]={
		{0x20000, 0},
		{0x18000, 4},
		{0x10000, 3},
		{0x08000, 2},
		{0x00000, 1}};

	/*
	 * This quirk addresses b:143174998 and is required on kernels >= 4.16
	 * when GPIO numbering has changed with an upstream commit:
	 * 03c4749dd6c7ff948a0ce59a44a1b97c015353c2
	 * "gpio / ACPI: Drop unnecessary ACPI GPIO to Linux GPIO translation".
	 * With that change gpio ACPI/Linux kernel 1:1 mapping was introduced which
	 * made mismatch for gpio number and backward compatibility for user-space.
	 * Details on review commit review
	 * https://chromium-review.googlesource.com/c/chromiumos/platform/vboot_reference/+/2153155
	 */

	/*
	 * Here we are addressing particular wpsw_cur pin which is connected to
	 * East Community GPIO chip (uid == 3, base == 0x10000). In this case there
	 * is only one gap between 11 and 15 (0..11 15..26). For now crosssystem
	 * is not checking pins in other gpio banks, but it is worth to mention that
	 * there are gaps as well.
	 */
	if (*gpio_num >=  0x10000 && *gpio_num < 0x18000)
		gpe = 1;

	ret = FindGpioChipOffsetByNumber(gpio_num, offset, data);
	if (!ret || !gpe)
		return ret;

	if (uname(&host) == 0) {
		if (sscanf(host.release, "%u.%u.", &maj, &min) == 2) {
#if !defined(__FreeBSD__) && !defined(__OpenBSD__)
			if (KERNEL_VERSION(maj, min, 0) >= KERNEL_VERSION(4, 16, 0) &&
			    *offset > 11)
				*offset += 3;
#endif
		} else {
			printf("Couldn't retrieve kernel version!\n");
			ret = 0;
		}
	} else {
		perror("uname");
		ret = 0;
	}

	return ret;
}

/* BayTrail has 3 sets of GPIO banks. It is expected the firmware exposes
 * each bank of gpios using a UID in ACPI. Furthermore the gpio number exposed
 * is relative to the bank. e.g. gpio 6 in the bank specified by UID 3 would
 * be encoded as 0x2006.
 *  UID | Bank Offset
 *  ----+------------
 *   1  | 0x0000
 *   2  | 0x1000
 *   3  | 0x2000
 */
static int BayTrailFindGpioChipOffset(unsigned *gpio_num, unsigned *offset,
				      const char *name)
{
	static Basemapping data[]={
		{0x3000, 0},
		{0x2000, 3},
		{0x1000, 2},
		{0x0000, 1}};

	return FindGpioChipOffsetByNumber(gpio_num, offset, data);
}

struct GpioChipset {
	const char *name;
	int (*ChipOffsetAndGpioNumber)(unsigned *gpio_num,
				       unsigned *chip_offset,
				       const char *name);
};

static const struct GpioChipset chipsets_supported[] = {
	{ "AMD0030", FindGpioChipOffset },
	{ "NM10", FindGpioChipOffset },
	{ "CougarPoint", FindGpioChipOffset },
	{ "PantherPoint", FindGpioChipOffset },
	{ "LynxPoint", FindGpioChipOffset },
	{ "PCH-LP", FindGpioChipOffset },
	{ "INT3437:00", FindGpioChipOffsetByLabel },
	{ "INT344B:00", FindGpioChipOffsetByLabel },
	/* INT3452 are for Apollolake */
	{ "INT3452:00", FindGpioChipOffsetByLabel },
	{ "INT3452:01", FindGpioChipOffsetByLabel },
	{ "INT3452:02", FindGpioChipOffsetByLabel },
	{ "INT3452:03", FindGpioChipOffsetByLabel },
	{ "INT3455:00", FindGpioChipOffsetByLabel },
	{ "INT34BB:00", FindGpioChipOffsetByLabel },
	{ "INT34C8:00", FindGpioChipOffsetByLabel },
	{ "INT34C5:00", FindGpioChipOffsetByLabel },
	/* INTC105x are for Alderlake */
	{ "INTC1055:00", FindGpioChipOffsetByLabel },
	{ "INTC1056:00", FindGpioChipOffsetByLabel },
	/* INT3453 are for GLK */
	{ "INT3453:00", FindGpioChipOffsetByLabel },
	{ "INT3453:01", FindGpioChipOffsetByLabel },
	{ "INT3453:02", FindGpioChipOffsetByLabel },
	{ "INT3453:03", FindGpioChipOffsetByLabel },
	{ "BayTrail", BayTrailFindGpioChipOffset },
	{ "Braswell", BraswellFindGpioChipOffset },
	{ NULL },
};

static const struct GpioChipset *FindChipset(const char *name)
{
	const struct GpioChipset *chipset = &chipsets_supported[0];

	while (chipset->name != NULL) {
		if (!strcmp(name, chipset->name))
			return chipset;
		chipset++;
	}
	return NULL;
}

/* Read a GPIO of the specified signal type (see ACPI GPIO SignalType).
 *
 * Returns 1 if the signal is asserted, 0 if not asserted, or -1 if error. */
static int ReadGpio(unsigned signal_type)
{
	char name[128];
	int index = 0;
	unsigned gpio_type;
	unsigned active_high;
	unsigned controller_num;
	unsigned controller_offset = 0;
	char controller_name[128];
	unsigned value;
	const struct GpioChipset *chipset;

	/* Scan GPIO.* to find a matching signal type */
	for (index = 0; ; index++) {
		snprintf(name, sizeof(name), "%s.%d/GPIO.0", ACPI_GPIO_PATH,
			 index);
		if (ReadFileInt(name, &gpio_type) < 0)
			return -1; /* Ran out of GPIOs before finding a match */
		if (gpio_type == signal_type)
			break;
	}

	/* Read attributes and controller info for the GPIO */
	snprintf(name, sizeof(name), "%s.%d/GPIO.1", ACPI_GPIO_PATH, index);
	if (ReadFileInt(name, &active_high) < 0)
		return -1;
	snprintf(name, sizeof(name), "%s.%d/GPIO.2", ACPI_GPIO_PATH, index);
	if (ReadFileInt(name, &controller_num) < 0)
		return -1;
	/* Do not attempt to read GPIO that is set to -1 in ACPI */
	if (controller_num == 0xFFFFFFFF)
		return -1;

	/* Check for chipsets we recognize. */
	snprintf(name, sizeof(name), "%s.%d/GPIO.3", ACPI_GPIO_PATH, index);
	if (!ReadFileString(controller_name, sizeof(controller_name), name))
		return -1;
	chipset = FindChipset(controller_name);
	if (chipset == NULL)
		return -1;

	/* Modify GPIO number by driver's offset */
	if (!chipset->ChipOffsetAndGpioNumber(&controller_num,
					      &controller_offset,
					      chipset->name))
		return -1;
	controller_offset += controller_num;

	/* Try reading the GPIO value */
	snprintf(name, sizeof(name), "%s/gpio%d/value",
		 GPIO_BASE_PATH, controller_offset);
	if (ReadFileInt(name, &value) < 0) {
		/* Try exporting the GPIO */
		FILE* f = fopen(GPIO_EXPORT_PATH, "wt");
		if (!f)
			return -1;
		fprintf(f, "%u", controller_offset);
		fclose(f);

		/* Try re-reading the GPIO value */
		if (ReadFileInt(name, &value) < 0)
			return -1;
	}

	/* Normalize the value read from the kernel in case it is not always
	 * 1. */
	value = value ? 1 : 0;

	/* Compare the GPIO value with the active value and return 1 if
	 * match. */
	return (value == active_high ? 1 : 0);
}


int VbGetArchPropertyInt(const char* name)
{
	int value = -1;

	/* Switch positions */
	if (!strcasecmp(name,"devsw_cur")) {
		/* Systems with virtual developer switches return at-boot
		 * value */
		value = VbGetSystemPropertyInt("devsw_boot");
	} else if (!strcasecmp(name,"recoverysw_cur")) {
		value = ReadGpio(GPIO_SIGNAL_TYPE_RECOVERY);
	} else if (!strcasecmp(name,"wpsw_cur")) {
		value = ReadGpio(GPIO_SIGNAL_TYPE_WP);
	} else if (!strcasecmp(name,"recoverysw_ec_boot")) {
		value = ReadFileBit(ACPI_CHSW_PATH, CHSW_RECOVERY_EC_BOOT);
	} else if (!strcasecmp(name,"phase_enforcement")) {
		value = ReadGpio(GPIO_SIGNAL_TYPE_PHASE_ENFORCEMENT);
	}

	/* Fields for old systems which don't have VbSharedData */
	if (VbSharedDataVersion() < 2) {
		if (!strcasecmp(name,"recovery_reason")) {
			value = VbGetRecoveryReason();
		} else if (!strcasecmp(name,"devsw_boot")) {
			value = ReadFileBit(ACPI_CHSW_PATH, CHSW_DEV_BOOT);
		} else if (!strcasecmp(name,"recoverysw_boot")) {
			value = ReadFileBit(ACPI_CHSW_PATH, CHSW_RECOVERY_BOOT);
		}
	}

	/* NV storage values.  If unable to get from NV storage, fall back to
	 * the CMOS reboot field used by older BIOS (e.g. Mario). */
	if (!strcasecmp(name,"recovery_request")) {
		value = vb2_get_nv_storage(VB2_NV_RECOVERY_REQUEST);
		if (-1 == value)
			value = VbGetCmosRebootField(CMOSRF_RECOVERY);
	} else if (!strcasecmp(name,"dbg_reset")) {
		value = vb2_get_nv_storage(VB2_NV_DEBUG_RESET_MODE);
		if (-1 == value)
			value = VbGetCmosRebootField(CMOSRF_DEBUG_RESET);
	} else if (!strcasecmp(name,"fwb_tries")) {
		value = vb2_get_nv_storage(VB2_NV_TRY_COUNT);
		if (-1 == value)
			value = VbGetCmosRebootField(CMOSRF_TRY_B);
	}

	/* Firmware update tries is now stored in the kernel field.  On
	 * older systems where it's not, it was stored in a file in the
	 * stateful partition. */
	if (!strcasecmp(name,"fwupdate_tries")) {
		unsigned fwupdate_value;
		if (-1 != vb2_get_nv_storage(VB2_NV_KERNEL_FIELD))
			return -1;  /* NvStorage supported; fail through
				     * arch-specific implementation to normal
				     * implementation. */
		/* Read value from file; missing file means value=0. */
		if (ReadFileInt(NEED_FWUPDATE_PATH, &fwupdate_value) < 0)
			value = 0;
		else
			value = (int)fwupdate_value;
	}

	return value;
}


const char* VbGetArchPropertyString(const char* name, char* dest,
				    size_t size)
{
	unsigned value;

	if (!strcasecmp(name,"arch")) {
		return StrCopy(dest, "x86", size);
	} else if (!strcasecmp(name,"hwid")) {
		return ReadFileString(dest, size, ACPI_BASE_PATH "/HWID");
	} else if (!strcasecmp(name,"fwid")) {
		return ReadFileString(dest, size, ACPI_BASE_PATH "/FWID");
	} else if (!strcasecmp(name,"ro_fwid")) {
		return ReadFileString(dest, size, ACPI_BASE_PATH "/FRID");
	} else if (!strcasecmp(name,"mainfw_act")) {
		if (ReadFileInt(ACPI_BINF_PATH ".1", &value) < 0)
			return NULL;
		switch(value) {
			case 0:
				return StrCopy(dest, "recovery", size);
			case 1:
				return StrCopy(dest, "A", size);
			case 2:
				return StrCopy(dest, "B", size);
			default:
				return NULL;
		}
	} else if (!strcasecmp(name,"mainfw_type")) {
		return VbReadMainFwType(dest, size);
	} else if (!strcasecmp(name,"ecfw_act")) {
		if (ReadFileInt(ACPI_BINF_PATH ".2", &value) < 0)
			return NULL;
		switch(value) {
			case 0:
				return StrCopy(dest, "RO", size);
			case 1:
				return StrCopy(dest, "RW", size);
			default:
				return NULL;
		}
	}

	return NULL;
}


int VbSetArchPropertyInt(const char* name, int value)
{
	/* NV storage values.  If unable to get from NV storage, fall back to
	 * the CMOS reboot field used by older BIOS. */
	if (!strcasecmp(name,"recovery_request")) {
		if (0 == vb2_set_nv_storage(VB2_NV_RECOVERY_REQUEST, value))
			return 0;
		return VbSetCmosRebootField(CMOSRF_RECOVERY, value);
	} else if (!strcasecmp(name,"dbg_reset")) {
		if (0 == vb2_set_nv_storage(VB2_NV_DEBUG_RESET_MODE, value))
			return 0;
		return  VbSetCmosRebootField(CMOSRF_DEBUG_RESET, value);
	} else if (!strcasecmp(name,"fwb_tries")) {
		if (0 == vb2_set_nv_storage(VB2_NV_TRY_COUNT, value))
			return 0;
		return VbSetCmosRebootField(CMOSRF_TRY_B, value);
	}
	/* Firmware update tries is now stored in the kernel field.  On
	 * older systems where it's not, it was stored in a file in the
	 * stateful partition. */
	else if (!strcasecmp(name,"fwupdate_tries")) {
		if (-1 != vb2_get_nv_storage(VB2_NV_KERNEL_FIELD))
			return -1;  /* NvStorage supported; fail through
				     * arch-specific implementation to normal
				     * implementation */

		if (value) {
			char buf[32];
			snprintf(buf, sizeof(buf), "%d", value);
			return WriteFile(NEED_FWUPDATE_PATH, buf, strlen(buf));
		} else {
			/* No update tries, so remove file if it exists. */
			unlink(NEED_FWUPDATE_PATH);
			return 0;
		}
	}

	return -1;
}

int VbSetArchPropertyString(const char* name, const char* value)
{
	/* If there were settable architecture-dependent string properties,
	 * they'd be here. */
	return -1;
}
