/* 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>
#include <linux/nvram.h>
#include <linux/version.h>
#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_FMAP_PATH ACPI_BASE_PATH "/FMAP"
#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)
{
	int fd = fileno(file);
	ioctl(fd, NVRAM_SETCKS);
}


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 (KERNEL_VERSION(maj, min, 0) >= KERNEL_VERSION(4, 16, 0) &&
			    *offset > 11)
				*offset += 3;
		} 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;

	/* Values from ACPI */
	if (!strcasecmp(name,"fmap_base")) {
		unsigned fmap_base;
		if (ReadFileInt(ACPI_FMAP_PATH, &fmap_base) < 0)
			return -1;
		else
			value = (int)fmap_base;
	}

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