/* Copyright 2014-2015 IBM Corp.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *	http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 * implied.
 * See the License for the specific language governing permissions and
 * imitations under the License.
 */

#define _GNU_SOURCE

#include <assert.h>
#include <stdio.h>
#include <unistd.h>
#include <getopt.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <sys/stat.h>
#include <errno.h>
#include <stdbool.h>
#include <stdarg.h>
#include <time.h>
#include <poll.h>
#include <dirent.h>

#include <endian.h>

#include <sys/ioctl.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <sys/un.h>

#include <linux/ipmi.h>
#include <linux/limits.h>

#include <asm/opal-prd.h>

#include <opal-api.h>
#include <types.h>

#include <ccan/list/list.h>

#include "opal-prd.h"
#include "hostboot-interface.h"
#include "module.h"
#include "pnor.h"
#include "i2c.h"

struct prd_range {
	const char		*name;
	uint64_t		physaddr;
	uint64_t		size;
	void			*buf;
	bool			multiple;
	uint32_t		instance;
};

struct prd_msgq_item {
	struct list_node	list;
	struct opal_prd_msg	msg;
};

struct opal_prd_ctx {
	int			fd;
	int			socket;
	struct opal_prd_info	info;
	struct prd_range	*ranges;
	int			n_ranges;
	bool			fw_range_instances;
	long			page_size;
	void			*code_addr;
	size_t			code_size;
	bool			debug;
	struct pnor		pnor;
	char			*hbrt_file_name;
	bool			use_syslog;
	bool			expert_mode;
	struct list_head	msgq;
	struct opal_prd_msg	*msg;
	size_t			msg_alloc_len;
	void			(*vlog)(int, const char *, va_list);
};

enum control_msg_type {
	CONTROL_MSG_ENABLE_OCCS		= 0x00,
	CONTROL_MSG_DISABLE_OCCS	= 0x01,
	CONTROL_MSG_TEMP_OCC_RESET	= 0x02,
	CONTROL_MSG_TEMP_OCC_ERROR	= 0x03,
	CONTROL_MSG_ATTR_OVERRIDE	= 0x04,
	CONTROL_MSG_HTMGT_PASSTHRU	= 0x05,
	CONTROL_MSG_RUN_CMD		= 0x30,
};

struct control_msg {
	enum control_msg_type	type;
	int			response;
	union {
		struct {
			unsigned int	argc;
		} run_cmd;
		struct {
			uint64_t	chip;
		} occ_reset;
		struct {
			uint64_t	chip;
		} occ_error;
	};
	unsigned int		data_len;
	unsigned char		data[];

};

#define MAX_CONTROL_MSG_BUF	4096

static struct opal_prd_ctx *ctx;

static const char *opal_prd_devnode = "/dev/opal-prd";
static const char *opal_prd_socket = "/run/opal-prd-control";
static const char *hbrt_code_region_name = "ibm,hbrt-code-image";
static const int opal_prd_version = 1;
static uint64_t opal_prd_ipoll = 0xf000000000000000;

static const int max_msgq_len = 16;

static const char *ipmi_devnode = "/dev/ipmi0";
static const int ipmi_timeout_ms = 5000;

static const char *devicetree_base =
		"/sys/firmware/devicetree/base";

/* Memory error handling */
static const char *mem_offline_soft =
		"/sys/devices/system/memory/soft_offline_page";
static const char *mem_offline_hard =
		"/sys/devices/system/memory/hard_offline_page";

#define ADDR_STRING_SZ 20 /* Hold %16lx */

/* This is the "real" HBRT call table for calling into HBRT as
 * provided by it. It will be used by the assembly thunk
 */
struct runtime_interfaces *hservice_runtime;
struct runtime_interfaces hservice_runtime_fixed;

/* This is the callback table provided by assembly code */
extern struct host_interfaces hinterface;

/* Create opd to call hostservice init */
struct func_desc {
	void *addr;
	void *toc;
} hbrt_entry;

static int nr_chips;
static u64 chips[256];

static int read_prd_msg(struct opal_prd_ctx *ctx);

static struct prd_range *find_range(const char *name, uint32_t instance)
{
	struct prd_range *range;
	unsigned int i;

	for (i = 0; i < ctx->n_ranges; i++) {
		range = &ctx->ranges[i];

		if (strcmp(range->name, name))
			continue;

		if (range->multiple && range->instance != instance)
			continue;

		return range;
	}

	return NULL;
}

static void pr_log_stdio(int priority, const char *fmt, va_list ap)
{
	if (!ctx->debug && priority >= LOG_DEBUG)
		return;

	vprintf(fmt, ap);
	printf("\n");

	if (ctx->debug)
		fflush(stdout);
}

/* standard logging prefixes:
 * HBRT:  Messages from hostboot runtime code
 * FW:    Interactions with OPAL firmware
 * IMAGE: HBRT image loading
 * MEM:   Memory failure interface
 * SCOM:  Chip SCOM interface
 * IPMI:  IPMI interface
 * PNOR:  PNOR interface
 * I2C:   i2c interface
 * PM:    PM/OCC interface
 * CTRL:  User-triggered control events
 * KMOD:   Kernel module functions
 */

void pr_log(int priority, const char *fmt, ...)
{
	va_list ap;

	va_start(ap, fmt);
	ctx->vlog(priority, fmt, ap);
	va_end(ap);
}

static void pr_log_nocall(const char *name)
{
	pr_log(LOG_WARNING, "HBRT: Call %s not provided", name);
}

static void hexdump(const uint8_t *data, uint32_t len)
{
	int i;

	for (i = 0; i < len; i++) {
		if (i % 16 == 0)
			printf("\n");
		else if(i % 4 == 0)
			printf(" ");

		printf("%02x", data[i]);
	}

	printf("\n");
}

static void pr_log_daemon_init(void)
{
	if (ctx->use_syslog) {
		openlog("opal-prd", LOG_NDELAY, LOG_DAEMON);
		ctx->vlog = vsyslog;
	}
}

/* Check service processor type */
static bool is_fsp_system(void)
{
	char *path;
	int rc;

	rc = asprintf(&path, "%s/fsps", devicetree_base);
	if (rc < 0) {
		pr_log(LOG_ERR, "FW: error creating '/fsps' path %m");
		return false;
	}

	return access(path, F_OK) ? false : true;
}

/**
 * ABI check that we can't perform at build-time: we want to ensure that the
 * layout of struct host_interfaces matches that defined in the thunk.
 */
static void check_abi(void)
{
	extern unsigned char __hinterface_start, __hinterface_pad,
	       __hinterface_end;

	/* ensure our struct size matches the thunk definition */
	assert((&__hinterface_end - &__hinterface_start)
			== sizeof(struct host_interfaces));

	/* ensure the padding layout is as expected */
	assert((void *)&__hinterface_start == (void *)&hinterface);
	assert((void *)&__hinterface_pad == (void *)&hinterface.reserved);
}

/* HBRT init wrappers */
extern struct runtime_interfaces *call_hbrt_init(struct host_interfaces *);

/* hservice Call wrappers */

extern void call_cxxtestExecute(void *);
extern int call_handle_attns(uint64_t i_proc,
			uint64_t i_ipollStatus,
			uint64_t i_ipollMask);
extern void call_process_occ_error (uint64_t i_chipId);
extern int call_enable_attns(void);
extern int call_enable_occ_actuation(bool i_occActivation);
extern void call_process_occ_reset(uint64_t i_chipId);
extern int call_mfg_htmgt_pass_thru(uint16_t i_cmdLength, uint8_t *i_cmdData,
				uint16_t *o_rspLength, uint8_t *o_rspData);
extern int call_apply_attr_override(uint8_t *i_data, size_t size);
extern int call_run_command(int argc, const char **argv, char **o_outString);
extern int call_sbe_message_passing(uint32_t i_chipId);
extern uint64_t call_get_ipoll_events(void);
extern int call_firmware_notify(uint64_t len, void *data);
extern int call_reset_pm_complex(uint64_t chip);
extern int call_load_pm_complex(u64 chip, u64 homer, u64 occ_common, u32 mode);
extern int call_start_pm_complex(u64 chip);

void hservice_puts(const char *str)
{
	int priority = LOG_INFO;

	/* Interpret the 2-character ERR_MRK/FAIL_MRK/WARN_MRK prefixes that
	 * may be present on HBRT log messages, and bump the log priority as
	 * appropriate.
	 */
	if (strlen(str) >= 2 && str[1] == '>') {
		switch (str[0]) {
		case 'E':
		case 'F':
			priority = LOG_ERR;
			break;
		case 'W':
			priority = LOG_WARNING;
			break;
		}
	}

	pr_log(priority, "HBRT: %s", str);
}

void hservice_assert(void)
{
	pr_log(LOG_ERR, "HBRT: Failed assertion! exiting.");
	exit(EXIT_FAILURE);
}

void *hservice_malloc(size_t size)
{
	return malloc(size);
}

void hservice_free(void *ptr)
{
	free(ptr);
}

void *hservice_realloc(void *ptr, size_t size)
{
	return realloc(ptr, size);
}

int hservice_scom_read(uint64_t chip_id, uint64_t addr, void *buf)
{
	int rc;
	struct opal_prd_scom scom;

	scom.chip = chip_id;
	scom.addr = addr;

	rc = ioctl(ctx->fd, OPAL_PRD_SCOM_READ, &scom);
	if (rc) {
		pr_log(LOG_ERR, "SCOM: ioctl read(chip 0x%lx, addr 0x%lx) "
				"failed: %m", chip_id, addr);
		return 0;
	}
	rc = (int)scom.rc;

	pr_debug("SCOM: read: chip 0x%lx, addr 0x%lx, val 0x%lx, rc %d",
		 chip_id, addr, scom.data, rc);

	*(uint64_t *)buf = htobe64(scom.data);

	return rc;
}

int hservice_scom_write(uint64_t chip_id, uint64_t addr,
                               const void *buf)
{
	int rc;
	struct opal_prd_scom scom;

	scom.chip = chip_id;
	scom.addr = addr;
	scom.data = be64toh(*(uint64_t *)buf);

	rc = ioctl(ctx->fd, OPAL_PRD_SCOM_WRITE, &scom);
	if (rc) {
		pr_log(LOG_ERR, "SCOM: ioctl write(chip 0x%lx, addr 0x%lx) "
				"failed: %m", chip_id, addr);
		return 0;
	}
	rc = (int)scom.rc;

	pr_debug("SCOM: write: chip 0x%lx, addr 0x%lx, val 0x%lx, rc %d",
		 chip_id, addr, scom.data, rc);

	return rc;
}

uint64_t hservice_get_reserved_mem(const char *name, uint32_t instance)
{
	struct prd_range *range;

	pr_debug("IMAGE: hservice_get_reserved_mem: %s, %d", name, instance);

	range = find_range(name, instance);
	if (!range) {
		pr_log(LOG_WARNING, "IMAGE: get_reserved_mem: "
				"no such range %s", name);
		return 0;
	}

	if (!range->buf) {
		uint64_t align_physaddr, offset;

		pr_debug("IMAGE: Mapping 0x%016lx 0x%08lx %s[%d]",
				range->physaddr, range->size,
				range->name, range->instance);

		align_physaddr = range->physaddr & ~(ctx->page_size-1);
		offset = range->physaddr & (ctx->page_size-1);
		range->buf = mmap(NULL, range->size, PROT_WRITE | PROT_READ,
					MAP_SHARED, ctx->fd, align_physaddr);

		if (range->buf == MAP_FAILED)
			pr_log(LOG_ERR,
				"IMAGE: mmap of %s[%d](0x%016lx) failed: %m",
				name, instance, range->physaddr);
		else
			range->buf += offset;
	}

	if (range->buf == MAP_FAILED) {
		pr_log(LOG_WARNING,
				"IMAGE: get_reserved_mem: %s[%d] has no vaddr",
				name, instance);
		return 0;
	}

	pr_debug(
		"IMAGE: hservice_get_reserved_mem: %s[%d](0x%016lx) address %p",
			name, range->instance, range->physaddr,
			range->buf);

	return (uint64_t)range->buf;
}

void hservice_nanosleep(uint64_t i_seconds, uint64_t i_nano_seconds)
{
	const struct timespec ns = {
		.tv_sec = i_seconds,
		.tv_nsec = i_nano_seconds
	};

	nanosleep(&ns, NULL);
}

int hservice_set_page_execute(void *addr)
{
	/* HBRT calls this on the pages that are already being executed,
	 * nothing to do here */
	return -1;
}

int hservice_clock_gettime(clockid_t i_clkId, struct timespec *o_tp)
{
	struct timespec tmp;
	int rc;

	rc = clock_gettime(i_clkId, &tmp);
	if (rc)
		return rc;

	o_tp->tv_sec = htobe64(tmp.tv_sec);
	o_tp->tv_nsec = htobe64(tmp.tv_nsec);

	return 0;
}

int hservice_pnor_read(uint32_t i_proc, const char* i_partitionName,
		uint64_t i_offset, void* o_data, size_t i_sizeBytes)
{
	return pnor_operation(&ctx->pnor, i_partitionName, i_offset, o_data,
			      i_sizeBytes, PNOR_OP_READ);
}

int hservice_pnor_write(uint32_t i_proc, const char* i_partitionName,
		uint64_t i_offset, void* o_data, size_t i_sizeBytes)
{
	return pnor_operation(&ctx->pnor, i_partitionName, i_offset, o_data,
			      i_sizeBytes, PNOR_OP_WRITE);
}

int hservice_i2c_read(uint64_t i_master, uint16_t i_devAddr,
		uint32_t i_offsetSize, uint32_t i_offset,
		uint32_t i_length, void* o_data)
{
	uint32_t chip_id;
	uint8_t engine, port;

	chip_id = (i_master & HBRT_I2C_MASTER_CHIP_MASK) >>
		HBRT_I2C_MASTER_CHIP_SHIFT;
	engine = (i_master & HBRT_I2C_MASTER_ENGINE_MASK) >>
		HBRT_I2C_MASTER_ENGINE_SHIFT;
	port = (i_master & HBRT_I2C_MASTER_PORT_MASK) >>
		HBRT_I2C_MASTER_PORT_SHIFT;
	return i2c_read(chip_id, engine, port, i_devAddr, i_offsetSize,
			i_offset, i_length, o_data);
}

int hservice_i2c_write(uint64_t i_master, uint16_t i_devAddr,
		uint32_t i_offsetSize, uint32_t i_offset,
		uint32_t i_length, void* i_data)
{
	uint32_t chip_id;
	uint8_t engine, port;

	chip_id = (i_master & HBRT_I2C_MASTER_CHIP_MASK) >>
		HBRT_I2C_MASTER_CHIP_SHIFT;
	engine = (i_master & HBRT_I2C_MASTER_ENGINE_MASK) >>
		HBRT_I2C_MASTER_ENGINE_SHIFT;
	port = (i_master & HBRT_I2C_MASTER_PORT_MASK) >>
		HBRT_I2C_MASTER_PORT_SHIFT;
	return i2c_write(chip_id, engine, port, i_devAddr, i_offsetSize,
			 i_offset, i_length, i_data);
}

int hservice_wakeup(u32 core, u32 mode)
{
	struct opal_prd_msg msg;

	msg.hdr.type = OPAL_PRD_MSG_TYPE_CORE_SPECIAL_WAKEUP;
	msg.hdr.size = htobe16(sizeof(msg));
	msg.spl_wakeup.core = htobe32(core);
	msg.spl_wakeup.mode = htobe32(mode);

	if (write(ctx->fd, &msg, sizeof(msg)) != sizeof(msg)) {
		pr_log(LOG_ERR, "FW: Failed to send CORE_SPECIAL_WAKEUP msg %x : %m\n",
		       core);
		return -1;
	}

	return 0;
}

static void pnor_load_module(struct opal_prd_ctx *ctx)
{
	insert_module("powernv_flash");
}

static void ipmi_init(struct opal_prd_ctx *ctx)
{
	insert_module("ipmi_devintf");
}

static int ipmi_send(int fd, uint8_t netfn, uint8_t cmd, long seq,
		uint8_t *buf, size_t len)
{
	struct ipmi_system_interface_addr addr;
	struct ipmi_req req;
	int rc;

	memset(&addr, 0, sizeof(addr));
	addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
	addr.channel = IPMI_BMC_CHANNEL;

	memset(&req, 0, sizeof(req));
	req.addr = (unsigned char *)&addr;
	req.addr_len = sizeof(addr);

	req.msgid = seq;
	req.msg.netfn = netfn;
	req.msg.cmd = cmd;
	req.msg.data = buf;
	req.msg.data_len = len;

	rc = ioctl(fd, IPMICTL_SEND_COMMAND, &req);
	if (rc < 0)
		return -1;

	return 0;
}

static int ipmi_recv(int fd, uint8_t *netfn, uint8_t *cmd, long *seq,
		uint8_t *buf, size_t *len)
{
	struct ipmi_recv recv;
	struct ipmi_addr addr;
	int rc;

	recv.addr = (unsigned char *)&addr;
	recv.addr_len = sizeof(addr);
	recv.msg.data = buf;
	recv.msg.data_len = *len;

	rc = ioctl(fd, IPMICTL_RECEIVE_MSG_TRUNC, &recv);
	if (rc < 0 && errno != EMSGSIZE) {
		pr_log(LOG_WARNING, "IPMI: recv (%zd bytes) failed: %m", *len);
		return -1;
	} else if (rc < 0 && errno == EMSGSIZE) {
		pr_log(LOG_NOTICE, "IPMI: truncated message (netfn %d, cmd %d, "
				"size %zd), continuing anyway",
				recv.msg.netfn, recv.msg.cmd, *len);
	}

	*netfn = recv.msg.netfn;
	*cmd = recv.msg.cmd;
	*seq = recv.msgid;
	*len = recv.msg.data_len;

	return 0;
}

int hservice_ipmi_msg(uint8_t netfn, uint8_t cmd,
		void *tx_buf, size_t tx_size,
		void *rx_buf, size_t *rx_size)
{
	struct timeval start, now, delta;
	struct pollfd pollfds[1];
	static long seq;
	size_t size;
	int rc, fd;

	size = be64toh(*rx_size);

	fd = open(ipmi_devnode, O_RDWR);
	if (fd < 0) {
		pr_log(LOG_WARNING, "IPMI: Failed to open IPMI device %s: %m",
				ipmi_devnode);
		return -1;
	}

	seq++;
	pr_debug("IPMI: sending %zd bytes (netfn 0x%02x, cmd 0x%02x)",
			tx_size, netfn, cmd);

	rc = ipmi_send(fd, netfn, cmd, seq, tx_buf, tx_size);
	if (rc) {
		pr_log(LOG_WARNING, "IPMI: send failed");
		goto out;
	}

	gettimeofday(&start, NULL);

	pollfds[0].fd = fd;
	pollfds[0].events = POLLIN;

	for (;;) {
		long rx_seq;
		int timeout;

		gettimeofday(&now, NULL);
		timersub(&now, &start, &delta);
		timeout = ipmi_timeout_ms - ((delta.tv_sec * 1000) +
				(delta.tv_usec / 1000));
		if (timeout < 0)
			timeout = 0;

		rc = poll(pollfds, 1, timeout);
		if (rc < 0) {
			pr_log(LOG_ERR, "IPMI: poll(%s) failed: %m",
					ipmi_devnode);
			break;
		}

		if (rc == 0) {
			pr_log(LOG_WARNING, "IPMI: response timeout (>%dms)",
					ipmi_timeout_ms);
			rc = -1;
			break;
		}

		rc = ipmi_recv(fd, &netfn, &cmd, &rx_seq, rx_buf, &size);
		if (rc)
			break;

		if (seq != rx_seq) {
			pr_log(LOG_NOTICE, "IPMI: out-of-sequence reply: %ld, "
					"expected %ld. Dropping message.",
					rx_seq, seq);
			continue;
		}

		pr_debug("IPMI: received %zd bytes", tx_size);
		*rx_size = be64toh(size);
		rc = 0;
		break;
	}

out:
	close(fd);
	return rc;
}

int hservice_memory_error(uint64_t i_start_addr, uint64_t i_endAddr,
		enum MemoryError_t i_errorType)
{
	const char *sysfsfile, *typestr;
	char buf[ADDR_STRING_SZ];
	int memfd, rc, n, ret = 0;
	uint64_t addr;

	switch(i_errorType) {
	case MEMORY_ERROR_CE:
		sysfsfile = mem_offline_soft;
		typestr = "correctable";
		break;
	case MEMORY_ERROR_UE:
		sysfsfile = mem_offline_hard;
		typestr = "uncorrectable";
		break;
	default:
		pr_log(LOG_WARNING, "MEM: Invalid memory error type %d",
				i_errorType);
		return -1;
	}

	pr_log(LOG_ERR, "MEM: Memory error: range %016lx-%016lx, type: %s",
			i_start_addr, i_endAddr, typestr);


	memfd = open(sysfsfile, O_WRONLY);
	if (memfd < 0) {
		pr_log(LOG_CRIT, "MEM: Failed to offline memory! "
				"Unable to open sysfs node %s: %m", sysfsfile);
		return -1;
	}

	for (addr = i_start_addr; addr <= i_endAddr; addr += ctx->page_size) {
		n = snprintf(buf, ADDR_STRING_SZ, "0x%lx", addr);
		rc = write(memfd, buf, n);
		if (rc != n) {
			pr_log(LOG_CRIT, "MEM: Failed to offline memory! "
					"page addr: %016lx type: %d: %m",
				addr, i_errorType);
			ret = rc;
		}
	}

	return ret;
}

uint64_t hservice_get_interface_capabilities(uint64_t set)
{
	if (set == HBRT_CAPS_SET1_OPAL)
		return HBRT_CAPS_OPAL_HAS_XSCOM_RC ||
			HBRT_CAPS_OPAL_HAS_WAKEUP_SUPPORT;

	return 0;
}

uint64_t hservice_firmware_request(uint64_t req_len, void *req,
		uint64_t *resp_lenp, void *resp)
{
	struct opal_prd_msg *msg = ctx->msg;
	uint64_t resp_len;
	size_t size;
	int rc, n;

	resp_len = be64_to_cpu(*resp_lenp);

	pr_log(LOG_DEBUG,
			"HBRT: firmware request: %lu bytes req, %lu bytes resp",
			req_len, resp_len);

	/* sanity check for potential overflows */
	if (req_len > 0xffff || resp_len > 0xffff)
		return -1;

	size = sizeof(msg->hdr) + sizeof(msg->token) +
		sizeof(msg->fw_req) + req_len;

	/* we need the entire message to fit within the 2-byte size field */
	if (size > 0xffff)
		return -1;

	/* variable sized message, so we may need to expand our buffer */
	if (size > ctx->msg_alloc_len) {
		msg = realloc(ctx->msg, size);
		if (!msg) {
			pr_log(LOG_ERR,
				"FW: failed to expand message buffer: %m");
			return -1;
		}
		ctx->msg = msg;
		ctx->msg_alloc_len = size;
	}

	memset(msg, 0, size);

	/* construct request message... */
	msg->hdr.type = OPAL_PRD_MSG_TYPE_FIRMWARE_REQUEST;
	msg->hdr.size = htobe16(size);
	msg->fw_req.req_len = htobe64(req_len);
	msg->fw_req.resp_len = htobe64(resp_len);
	memcpy(msg->fw_req.data, req, req_len);

	hexdump((void *)msg, size);

	/* ... and send to firmware */
	rc = write(ctx->fd, msg, size);
	if (rc != size) {
		pr_log(LOG_WARNING,
			"FW: Failed to send FIRMWARE_REQUEST message: %m");
		return -1;
	}

	/* We have an "inner" poll loop here, as we want to ensure that the
	 * next entry into HBRT is the return from this function. So, only
	 * read from the prd fd, and queue anything that isn't a response
	 * to this request
	 */
	n = 0;
	for (;;) {
		struct prd_msgq_item *item;

		rc = read_prd_msg(ctx);
		if (rc)
			return -1;

		msg = ctx->msg;
		if (msg->hdr.type == OPAL_PRD_MSG_TYPE_FIRMWARE_RESPONSE) {
			size = be64toh(msg->fw_resp.len);
			if (size > resp_len)
				return -1;

			/* success! a valid response that fits into HBRT's
			 * resp buffer */
			memcpy(resp, msg->fw_resp.data, size);
			*resp_lenp = htobe64(size);
			return 0;
		}

		/* not a response? queue up for later consumption */
		if (++n > max_msgq_len) {
			pr_log(LOG_ERR,
				"FW: too many messages queued (%d) while "
				"waiting for FIRMWARE_RESPONSE", n);
			return -1;
		}
		size = be16toh(msg->hdr.size);
		item = malloc(sizeof(*item) + size);
		memcpy(&item->msg, msg, size);
		list_add_tail(&ctx->msgq, &item->list);
	}
}

int hservices_init(struct opal_prd_ctx *ctx, void *code)
{
	uint64_t *s, *d;
	int i, sz;

	pr_debug("IMAGE: code address: %p", code);

	/* We enter at 0x100 into the image. */
	/* Load func desc in BE since we reverse it in thunk */

	hbrt_entry.addr = (void *)htobe64((unsigned long)code + 0x100);
	hbrt_entry.toc = 0; /* No toc for init entry point */

	if (memcmp(code, "HBRTVERS", 8) != 0) {
		pr_log(LOG_ERR, "IMAGE: Bad signature for "
				"ibm,hbrt-code-image! exiting");
		return -1;
	}

	pr_debug("IMAGE: calling ibm,hbrt_init()");
	hservice_runtime = call_hbrt_init(&hinterface);
	if (!hservice_runtime) {
		pr_log(LOG_ERR, "IMAGE: hbrt_init failed, exiting");
		return -1;
	}

	pr_log(LOG_NOTICE, "IMAGE: hbrt_init complete, version %016lx",
			hservice_runtime->interface_version);

	sz = sizeof(struct runtime_interfaces)/sizeof(uint64_t);
	s = (uint64_t *)hservice_runtime;
	d = (uint64_t *)&hservice_runtime_fixed;
	/* Byte swap the function pointers */
	for (i = 0; i < sz; i++)
		d[i] = be64toh(s[i]);

	return 0;
}

static void fixup_hinterface_table(void)
{
	uint64_t *t64;
	unsigned int i, sz;

	/* Swap interface version */
	hinterface.interface_version =
		htobe64(hinterface.interface_version);

	/* Swap OPDs */
	sz = sizeof(struct host_interfaces) / sizeof(uint64_t);
	t64 = (uint64_t *)&hinterface;
	for (i = 1; i < sz; i++) {
		uint64_t *opd = (uint64_t *)t64[i];
		if (!opd)
			continue;
		t64[i] = htobe64(t64[i]);
		opd[0] = htobe64(opd[0]);
		opd[1] = htobe64(opd[1]);
		opd[2] = htobe64(opd[2]);
	}
}

static int map_hbrt_file(struct opal_prd_ctx *ctx, const char *name)
{
	struct stat statbuf;
	int fd, rc;
	void *buf;

	fd = open(name, O_RDONLY);
	if (fd < 0) {
		pr_log(LOG_ERR, "IMAGE: HBRT file open(%s) failed: %m", name);
		return -1;
	}

	rc = fstat(fd, &statbuf);
	if (rc < 0) {
		pr_log(LOG_ERR, "IMAGE: HBRT file fstat(%s) failed: %m", name);
		close(fd);
		return -1;
	}

	buf = mmap(NULL, statbuf.st_size, PROT_READ | PROT_WRITE | PROT_EXEC,
			MAP_PRIVATE, fd, 0);
	close(fd);

	if (buf == MAP_FAILED) {
		pr_log(LOG_ERR, "IMAGE: HBRT file mmap(%s, 0x%zx) failed: %m",
				name, statbuf.st_size);
		return -1;
	}

	ctx->code_addr = buf;
	ctx->code_size = statbuf.st_size;
	return -0;
}

static int map_hbrt_physmem(struct opal_prd_ctx *ctx, const char *name)
{
	struct prd_range *range;
	void *buf;

	range = find_range(name, 0);
	if (!range) {
		pr_log(LOG_ERR, "IMAGE: can't find code region %s", name);
		return -1;
	}

	buf = mmap(NULL, range->size, PROT_READ | PROT_WRITE | PROT_EXEC,
			MAP_PRIVATE, ctx->fd, range->physaddr);
	if (buf == MAP_FAILED) {
		pr_log(LOG_ERR, "IMAGE: mmap(range:%s, "
				"phys:0x%016lx, size:0x%016lx) failed: %m",
				name, range->physaddr, range->size);
		return -1;
	}

	ctx->code_addr = buf;
	ctx->code_size = range->size;
	return 0;
}

static void dump_hbrt_map(struct opal_prd_ctx *ctx)
{
	const char *dump_name = "hbrt.bin";
	int fd, rc;

	if (!ctx->debug)
		return;

	fd = open(dump_name, O_WRONLY | O_CREAT, 0644);
	if (fd < 0) {
		pr_log(LOG_NOTICE, "IMAGE: couldn't debug image %s for writing",
				dump_name);
		return;
	}

	rc = ftruncate(fd, 0);
	if (rc < 0) {
		pr_log(LOG_NOTICE, "IMAGE: couldn't truncate image %s for writing",
				dump_name);
		return;
	}
	rc = write(fd, ctx->code_addr, ctx->code_size);
	close(fd);

	if (rc != ctx->code_size)
		pr_log(LOG_NOTICE, "IMAGE: write to %s failed: %m", dump_name);
	else
		pr_debug("IMAGE: dumped HBRT binary to %s", dump_name);
}

static int open_and_read(const char *path, void **bufp, int *lenp)
{
	struct stat statbuf;
	int fd, rc, bytes;
	void *buf;

	fd = open(path, O_RDONLY);
	if (fd < 0)
		return -1;

	rc = fstat(fd, &statbuf);
	if (rc) {
		close(fd);
		return -1;
	}

	buf = malloc(statbuf.st_size);

	for (rc = bytes = 0; bytes < statbuf.st_size; bytes += rc) {
		rc = read(fd, buf + bytes, statbuf.st_size - bytes);
		if (rc < 0) {
			if (errno == EINTR)
				continue;
			break;
		} else if (rc == 0)
			break;
	}

	if (bytes == statbuf.st_size)
		rc = 0;

	if (rc == 0) {
		if (lenp)
			*lenp = bytes;
		if (bufp)
			*bufp = buf;
	} else {
		free(buf);
	}

	close(fd);

	return rc == 0 ? 0 : -1;
}

static int prd_init_one_range(struct opal_prd_ctx *ctx, const char *path,
		struct dirent *dirent)
{
	char *label_path, *reg_path, *instance_path;
	struct prd_range *range;
	int label_len, len, rc;
	__be64 *reg;
	char *label;
	void *buf;

	rc = asprintf(&label_path, "%s/%s/ibm,prd-label", path, dirent->d_name);
	if (rc < 0) {
		pr_log(LOG_ERR, "FW: error creating 'ibm,prd-label' path "
				"node: %m");
		return -1;
	}
	rc = asprintf(&instance_path, "%s/%s/ibm,prd-instance",
			path, dirent->d_name);
	if (rc < 0) {
		pr_log(LOG_ERR, "FW: error creating 'ibm,prd-instance' path "
				"node: %m");
		return -1;
	}
	rc = asprintf(&reg_path, "%s/%s/reg", path, dirent->d_name);
	if (rc < 0) {
		pr_log(LOG_ERR, "FW: error creating 'reg' path "
				" node: %m");
		return -1;
	}

	reg = NULL;
	label = NULL;
	rc = -1;

	rc = open_and_read(label_path, &buf, &label_len);
	if (rc)
		goto out_free;

	label = buf;

	if (label[label_len-1] != '\0')
		pr_log(LOG_INFO, "FW: node %s has invalid ibm,prd-label - "
				"not nul-terminated",
				dirent->d_name);

	rc = open_and_read(reg_path, &buf, &len);
	if (rc)
		goto out_free;

	reg = buf;

	if (len != 2 * sizeof(*reg)) {
		pr_log(LOG_ERR, "FW: node %s has invalid 'reg' size: %d",
				dirent->d_name, len);
		goto out_free;
	}


	ctx->ranges = realloc(ctx->ranges, ++ctx->n_ranges * sizeof(*range));
	range = &ctx->ranges[ctx->n_ranges - 1];
	range->name = strndup(label, label_len);
	range->physaddr = be64toh(reg[0]);
	range->size = be64toh(reg[1]);
	range->buf = NULL;
	range->multiple = false;
	range->instance = 0;

	/* optional instance */
	rc = open_and_read(instance_path, &buf, &len);
	if (!rc && len == sizeof(uint32_t)) {
		range->multiple = true;
		range->instance = be32toh(*(uint32_t *)buf);
		ctx->fw_range_instances = true;
	}
	rc = 0;

out_free:
	free(reg);
	free(label);
	free(instance_path);
	free(reg_path);
	free(label_path);
	return rc;
}

static int compare_ranges(const void *ap, const void *bp)
{
	const struct prd_range *a = ap, *b = bp;
	int rc;

	rc = strcmp(a->name, b->name);
	if (rc)
		return rc;

	if (a->physaddr < b->physaddr)
		return -1;
	else if (a->physaddr > b->physaddr)
		return 1;

	return 0;
}

static void assign_range_instances(struct opal_prd_ctx *ctx)
{
	int i;

	if (!ctx->n_ranges)
		return;

	ctx->ranges[0].multiple = false;
	ctx->ranges[0].instance = 0;

	for (i = 1; i < ctx->n_ranges; i++) {
		struct prd_range *cur, *prev;

		cur = &ctx->ranges[i];
		prev = &ctx->ranges[i-1];

		if (!strcmp(cur->name, prev->name)) {
			prev->multiple = true;
			cur->multiple = true;
			cur->instance = prev->instance + 1;
		} else {
			cur->multiple = false;
			cur->instance = 0;
		}
	}
}

static void print_ranges(struct opal_prd_ctx *ctx)
{
	int i;

	if (ctx->n_ranges == 0)
		pr_log(LOG_INFO, "FW: No PRD ranges");

	pr_log(LOG_DEBUG, "FW: %d PRD ranges, instances assigned by %s",
			ctx->n_ranges,
			ctx->fw_range_instances ? "firmware" : "userspace");

	for (i = 0; i < ctx->n_ranges; i++) {
		struct prd_range *range = &ctx->ranges[i];
		char instance_str[20];

		if (range->multiple)
			snprintf(instance_str, sizeof(instance_str),
					" [%d]", range->instance);
		else
			instance_str[0] = '\0';

		pr_log(LOG_DEBUG, "FW:  %016lx-%016lx %s%s", range->physaddr,
				range->physaddr + range->size - 1,
				range->name,
				instance_str);
	}
}

static int chip_init(void)
{
	struct dirent *dirent;
	char *path;
	DIR *dir;
	__be32 *chipid;
	void *buf;
	int rc, len, i;

	dir = opendir(devicetree_base);
	if (!dir) {
		pr_log(LOG_ERR, "FW: Can't open %s", devicetree_base);
		return  -1;
	}

	for (;;) {
		dirent = readdir(dir);
		if (!dirent)
			break;

		if (strncmp("xscom", dirent->d_name, 5))
			continue;

		rc = asprintf(&path, "%s/%s/ibm,chip-id", devicetree_base,
			      dirent->d_name);
		if (rc < 0) {
			pr_log(LOG_ERR, "FW: Failed to create chip-id path");
			return -1;
		}

		rc = open_and_read(path, &buf, &len);
		if (rc) {
			pr_log(LOG_ERR, "FW; Failed to read chipid");
			return -1;
		}
		chipid = buf;
		chips[nr_chips++] = be32toh(*chipid);
	}

	pr_log(LOG_DEBUG, "FW: Chip init");
	for (i = 0; i < nr_chips; i++)
		pr_log(LOG_DEBUG, "FW: Chip 0x%lx", chips[i]);

	return 0;
}

static int prd_init_ranges(struct opal_prd_ctx *ctx)
{
	struct dirent *dirent;
	char *path;
	DIR *dir;
	int rc;

	rc = asprintf(&path, "%s/reserved-memory", devicetree_base);
	if (rc < 0) {
		pr_log(LOG_ERR, "FW: error creating 'reserved-memory' path "
				"node: %m");
		return -1;
	}

	rc = -1;

	dir = opendir(path);
	if (!dir) {
		pr_log(LOG_ERR, "FW: can't open reserved-memory device-tree "
				"node: %m");
		goto out_free;
	}

	for (;;) {
		dirent = readdir(dir);
		if (!dirent)
			break;

		prd_init_one_range(ctx, path, dirent);
	}

	rc = 0;
	/* sort ranges and assign instance numbers for duplicates (if the
	 * firmware doesn't number instances for us) */
	qsort(ctx->ranges, ctx->n_ranges, sizeof(struct prd_range),
			compare_ranges);

	if (!ctx->fw_range_instances)
		assign_range_instances(ctx);

	print_ranges(ctx);

out_free:
	free(path);
	closedir(dir);
	return rc;
}

bool find_string(const char *buffer, size_t len, const char *s)
{
	const char *c, *end;

	if (!buffer)
		return false;
	c = buffer;
	end = c + len;

	while (c < end) {
		if (!strcasecmp(s, c))
			return true;
		c += strlen(c) + 1;
	}
	return false;
}

static int is_prd_supported(void)
{
	char *path;
	int rc;
	int len;
	char *buf;

	rc = asprintf(&path, "%s/ibm,opal/diagnostics/compatible",
		      devicetree_base);
	if (rc < 0) {
		pr_log(LOG_ERR, "FW: error creating 'compatible' node path: %m");
		return -1;
	}

	rc = open_and_read(path, (void *) &buf, &len);
	if (rc)
		goto out_free;

	if (buf[len - 1] != '\0')
		pr_log(LOG_INFO, "FW: node %s is not nul-terminated", path);

	rc = find_string(buf, len, "ibm,opal-prd") ? 0 : -1;

	free(buf);
out_free:
	free(path);
	return rc;
}

static int prd_init(struct opal_prd_ctx *ctx)
{
	int rc;

	ctx->page_size = sysconf(_SC_PAGE_SIZE);

	/* set up the device, and do our get_info ioctl */
	ctx->fd = open(opal_prd_devnode, O_RDWR);
	if (ctx->fd < 0) {
		pr_log(LOG_ERR, "FW: Can't open PRD device %s: %m",
				opal_prd_devnode);
		return -1;
	}

	rc = ioctl(ctx->fd, OPAL_PRD_GET_INFO, &ctx->info);
	if (rc) {
		pr_log(LOG_ERR, "FW: Can't query PRD information: %m");
		return -1;
	}

	rc = prd_init_ranges(ctx);
	if (rc) {
		pr_log(LOG_ERR, "FW: can't parse PRD memory information");
		return -1;
	}

	rc = chip_init();
	if (rc)
		pr_log(LOG_ERR, "FW: Failed to initialize chip IDs");

	return 0;
}

static int handle_msg_attn(struct opal_prd_ctx *ctx, struct opal_prd_msg *msg)
{
	uint64_t proc, ipoll_mask, ipoll_status;
	int rc;

	proc = be64toh(msg->attn.proc);
	ipoll_status = be64toh(msg->attn.ipoll_status);
	ipoll_mask = be64toh(msg->attn.ipoll_mask);

	if (!hservice_runtime->handle_attns) {
		pr_log_nocall("handle_attns");
		return -1;
	}

	rc = call_handle_attns(proc, ipoll_status, ipoll_mask);
	if (rc) {
		pr_log(LOG_ERR, "HBRT: handle_attns(%lx,%lx,%lx) failed, rc %d",
				proc, ipoll_status, ipoll_mask, rc);
		return -1;
	}

	/* send the response */
	msg->hdr.type = OPAL_PRD_MSG_TYPE_ATTN_ACK;
	msg->hdr.size = htobe16(sizeof(*msg));
	msg->attn_ack.proc = htobe64(proc);
	msg->attn_ack.ipoll_ack = htobe64(ipoll_status);
	rc = write(ctx->fd, msg, sizeof(*msg));

	if (rc != sizeof(*msg)) {
		pr_log(LOG_WARNING, "FW: Failed to send ATTN_ACK message: %m");
		return -1;
	}

	return 0;
}

static int handle_msg_occ_error(struct opal_prd_ctx *ctx,
		struct opal_prd_msg *msg)
{
	uint32_t proc;

	proc = be64toh(msg->occ_error.chip);

	pr_debug("FW: firmware signaled OCC error for proc 0x%x", proc);

	if (!hservice_runtime->process_occ_error) {
		pr_log_nocall("process_occ_error");
		return -1;
	}

	call_process_occ_error(proc);
	return 0;
}

static int pm_complex_load_start(void)
{
	struct prd_range *range;
	u64 homer, occ_common;
	int rc = -1, i;

	if (!hservice_runtime->load_pm_complex) {
		pr_log_nocall("load_pm_complex");
		return rc;
	}

	if (!hservice_runtime->start_pm_complex) {
		pr_log_nocall("start_pm_complex");
		return rc;
	}

	range = find_range("ibm,occ-common-area", 0);
	if (!range) {
		pr_log(LOG_ERR, "PM: ibm,occ-common-area not found");
		return rc;
	}
	occ_common = range->physaddr;

	for (i = 0; i < nr_chips; i++) {
		range = find_range("ibm,homer-image", chips[i]);
		if (!range) {
			pr_log(LOG_ERR, "PM: ibm,homer-image not found 0x%lx",
			       chips[i]);
			return -1;
		}
		homer = range->physaddr;

		pr_debug("PM: calling load_pm_complex(0x%lx, 0x%lx, 0x%lx, LOAD)",
			 chips[i], homer, occ_common);
		rc = call_load_pm_complex(chips[i], homer, occ_common, 0);
		if (rc) {
			pr_log(LOG_ERR, "PM: Failed load_pm_complex(0x%lx) %m",
			       chips[i]);
			return rc;
		}
	}

	for (i = 0; i < nr_chips; i++) {
		pr_debug("PM: calling start_pm_complex(0x%lx)", chips[i]);
		rc = call_start_pm_complex(chips[i]);
		if (rc) {
			pr_log(LOG_ERR, "PM: Failed start_pm_complex(0x%lx): %m",
			       chips[i]);
			return rc;
		}
	}

	return rc;
}

static int pm_complex_reset(uint64_t chip)
{
	int rc;

	/*
	 * FSP system -> reset_pm_complex
	 * BMC system -> process_occ_reset
	 */
	if (is_fsp_system()) {
		int i;

		if (!hservice_runtime->reset_pm_complex) {
			pr_log_nocall("reset_pm_complex");
			return -1;
		}

		for (i = 0; i < nr_chips; i++) {
			pr_debug("PM: calling pm_complex_reset(%ld)", chips[i]);
			rc = call_reset_pm_complex(chip);
			if (rc) {
				pr_log(LOG_ERR, "PM: Failed pm_complex_reset(%ld): %m",
				       chips[i]);
				return rc;
			}
		}

		rc = pm_complex_load_start();
	} else {
		if (!hservice_runtime->process_occ_reset) {
			pr_log_nocall("process_occ_reset");
			return -1;
		}

		pr_debug("PM: calling process_occ_reset(%ld)", chip);
		call_process_occ_reset(chip);
		rc = 0;
	}

	return rc;
}

static int handle_msg_occ_reset(struct opal_prd_ctx *ctx,
		struct opal_prd_msg *msg)
{
	uint32_t proc;
	int rc;

	proc = be64toh(msg->occ_reset.chip);

	pr_debug("FW: firmware requested OCC reset for proc 0x%x", proc);

	rc = pm_complex_reset(proc);

	return rc;
}

static int handle_msg_firmware_notify(struct opal_prd_ctx *ctx,
		struct opal_prd_msg *msg)
{
	uint64_t len;
	void *buf;

	len = be64toh(msg->fw_notify.len);
	buf = msg->fw_notify.data;

	pr_debug("FW: firmware notification, %ld bytes", len);

	if (!hservice_runtime->firmware_notify) {
		pr_log_nocall("firmware_notify");
		return -1;
	}

	call_firmware_notify(len, buf);

	return 0;
}

static int handle_msg_sbe_passthrough(struct opal_prd_ctx *ctx,
				      struct opal_prd_msg *msg)
{
	uint32_t proc;
	int rc;

	proc = be64toh(msg->sbe_passthrough.chip);

	pr_debug("FW: firmware sent SBE pass through command for proc 0x%x\n",
		 proc);

	if (!hservice_runtime->sbe_message_passing) {
		pr_log_nocall("sbe_message_passing");
		return -1;
	}

	rc = call_sbe_message_passing(proc);
	return rc;
}

static int handle_msg_fsp_occ_reset(struct opal_prd_msg *msg)
{
	struct opal_prd_msg omsg;
	int rc = -1, i;

	pr_debug("FW: FSP requested OCC reset");

	if (!hservice_runtime->reset_pm_complex) {
		pr_log_nocall("reset_pm_complex");
		return rc;
	}

	for (i = 0; i < nr_chips; i++) {
		pr_debug("PM: calling pm_complex_reset(0x%lx)", chips[i]);
		rc = call_reset_pm_complex(chips[i]);
		if (rc) {
			pr_log(LOG_ERR, "PM: Failed pm_complex_reset(0x%lx) %m",
			       chips[i]);
			break;
		}
	}

	omsg.hdr.type = OPAL_PRD_MSG_TYPE_FSP_OCC_RESET_STATUS;
	omsg.hdr.size = htobe16(sizeof(omsg));
	omsg.fsp_occ_reset_status.chip = msg->occ_reset.chip;
	omsg.fsp_occ_reset_status.status = htobe64(rc);

	if (write(ctx->fd, &omsg, sizeof(omsg)) != sizeof(omsg)) {
		pr_log(LOG_ERR, "FW: Failed to send FSP_OCC_RESET_STATUS msg: %m");
		return -1;
	}

	return rc;
}

static int handle_msg_fsp_occ_load_start(struct opal_prd_msg *msg)
{
	struct opal_prd_msg omsg;
	int rc;

	pr_debug("FW: FSP requested OCC load/start");
	rc = pm_complex_load_start();

	omsg.hdr.type = OPAL_PRD_MSG_TYPE_FSP_OCC_LOAD_START_STATUS;
	omsg.hdr.size = htobe16(sizeof(omsg));
	omsg.fsp_occ_reset_status.chip = msg->occ_reset.chip;
	omsg.fsp_occ_reset_status.status = htobe64(rc);

	if (write(ctx->fd, &omsg, sizeof(omsg)) != sizeof(omsg)) {
		pr_log(LOG_ERR, "FW: Failed to send FSP_OCC_LOAD_START_STATUS msg: %m");
		return -1;
	}

	return rc;
}

static int handle_prd_msg(struct opal_prd_ctx *ctx, struct opal_prd_msg *msg)
{
	int rc = -1;

	switch (msg->hdr.type) {
	case OPAL_PRD_MSG_TYPE_ATTN:
		rc = handle_msg_attn(ctx, msg);
		break;
	case OPAL_PRD_MSG_TYPE_OCC_RESET:
		rc = handle_msg_occ_reset(ctx, msg);
		break;
	case OPAL_PRD_MSG_TYPE_OCC_ERROR:
		rc = handle_msg_occ_error(ctx, msg);
		break;
	case OPAL_PRD_MSG_TYPE_FIRMWARE_NOTIFY:
		rc = handle_msg_firmware_notify(ctx, msg);
		break;
	case OPAL_PRD_MSG_TYPE_SBE_PASSTHROUGH:
		rc = handle_msg_sbe_passthrough(ctx, msg);
		break;
	case OPAL_PRD_MSG_TYPE_FSP_OCC_RESET:
		rc = handle_msg_fsp_occ_reset(msg);
		break;
	case OPAL_PRD_MSG_TYPE_FSP_OCC_LOAD_START:
		rc = handle_msg_fsp_occ_load_start(msg);
		break;
	default:
		pr_log(LOG_WARNING, "Invalid incoming message type 0x%x",
				msg->hdr.type);
	}

	return rc;
}

#define list_for_each_pop(h, i, type, member) \
	for (i = list_pop((h), type, member); \
		i; \
		i = list_pop((h), type, member))


static int process_msgq(struct opal_prd_ctx *ctx)
{
	struct prd_msgq_item *item;

	list_for_each_pop(&ctx->msgq, item, struct prd_msgq_item, list) {
		handle_prd_msg(ctx, &item->msg);
		free(item);
	}

	return 0;
}

static int read_prd_msg(struct opal_prd_ctx *ctx)
{
	struct opal_prd_msg *msg;
	int size;
	int rc;

	msg = ctx->msg;

	rc = read(ctx->fd, msg, ctx->msg_alloc_len);
	if (rc < 0 && errno == EAGAIN)
		return -1;

	/* we need at least enough for the message header... */
	if (rc < 0) {
		pr_log(LOG_WARNING, "FW: error reading from firmware: %m");
		return -1;
	}

	if (rc < sizeof(msg->hdr)) {
		pr_log(LOG_WARNING, "FW: short message read from firmware");
		return -1;
	}

	/* ... and for the reported message size to be sane */
	size = htobe16(msg->hdr.size);
	if (size < sizeof(msg->hdr)) {
		pr_log(LOG_ERR, "FW: Mismatched message size "
				"between opal-prd and firmware "
				"(%d from FW, %zd expected)",
				size, sizeof(msg->hdr));
		return -1;
	}

	/* expand our message buffer if necessary... */
	if (size > ctx->msg_alloc_len) {
		msg = realloc(ctx->msg, size);
		if (!msg) {
			pr_log(LOG_ERR,
				"FW: Can't expand PRD message buffer: %m");
			return -1;
		}
		ctx->msg = msg;
		ctx->msg_alloc_len = size;
	}

	/* ... and complete the read */
	if (size > rc) {
		size_t pos;

		for (pos = rc; pos < size;) {
			rc = read(ctx->fd, msg + pos, size - pos);

			if (rc < 0 && errno == EAGAIN)
				continue;

			if (rc <= 0) {
				pr_log(LOG_WARNING,
					"FW: error reading from firmware: %m");
				return -1;
			}

			pos += rc;
		}
	}

	return 0;
}

static void handle_prd_control_occ_error(struct control_msg *send_msg,
		struct control_msg *recv_msg)
{
	uint64_t chip;

	if (!hservice_runtime->process_occ_error) {
		pr_log_nocall("process_occ_error");
		return;
	}

	chip = recv_msg->occ_error.chip;

	pr_debug("CTRL: calling process_occ_error(%lu)", chip);
	call_process_occ_error(chip);

	send_msg->data_len = 0;
	send_msg->response = 0;
}

static void handle_prd_control_occ_reset(struct control_msg *send_msg,
		struct control_msg *msg)
{
	struct opal_prd_msg omsg;
	uint64_t chip;
	int rc;

	/* notify OPAL of the impending reset */
	memset(&omsg, 0, sizeof(omsg));
	omsg.hdr.type = OPAL_PRD_MSG_TYPE_OCC_RESET_NOTIFY;
	omsg.hdr.size = htobe16(sizeof(omsg));
	rc = write(ctx->fd, &omsg, sizeof(omsg));
	if (rc != sizeof(omsg))
		pr_log(LOG_WARNING, "FW: Failed to send OCC_RESET message: %m");

	chip = msg->occ_reset.chip;

	/* do reset */
	pr_debug("CTRL: Calling OCC reset on chip %ld", chip);
	pm_complex_reset(chip);

	send_msg->data_len = 0;
	send_msg->response = 0;
}

static void handle_prd_control_occ_actuation(struct control_msg *msg,
					     bool enable)
{
	if (!hservice_runtime->enable_occ_actuation) {
		pr_log_nocall("enable_occ_actuation");
		return;
	}

	pr_debug("CTRL: calling enable_occ_actuation(%s)",
			enable ? "true" : "false");
	msg->data_len = 0;
	msg->response = call_enable_occ_actuation(enable);
}

static void handle_prd_control_attr_override(struct control_msg *send_msg,
					     struct control_msg *recv_msg)
{
	if (!hservice_runtime->apply_attr_override) {
		pr_log_nocall("apply_attr_override");
		return;
	}

	pr_debug("CTRL: calling apply_attr_override");
	send_msg->response = call_apply_attr_override(
			recv_msg->data, recv_msg->data_len);
	send_msg->data_len = 0;
}

static void handle_prd_control_htmgt_passthru(struct control_msg *send_msg,
					      struct control_msg *recv_msg)
{
	uint16_t rsp_len;

	if (!hservice_runtime->mfg_htmgt_pass_thru) {
		pr_log_nocall("mfg_htmgt_pass_thru");
		return;
	}

	pr_debug("CTRL: calling mfg_htmgt_pass_thru");
	send_msg->response = call_mfg_htmgt_pass_thru(recv_msg->data_len,
						      recv_msg->data, &rsp_len,
						      send_msg->data);
	send_msg->data_len = be16toh(rsp_len);
	if (send_msg->data_len > MAX_CONTROL_MSG_BUF) {
		pr_log(LOG_ERR, "CTRL: response buffer overrun, data len: %d",
				send_msg->data_len);
		send_msg->data_len = MAX_CONTROL_MSG_BUF;
	}
}

static void handle_prd_control_run_cmd(struct control_msg *send_msg,
				       struct control_msg *recv_msg)
{
	char *runcmd_output, *s;
	const char **argv;
	int i, argc;
	size_t size;

	if (!hservice_runtime->run_command) {
		pr_log_nocall("run_command");
		return;
	}

	argc = recv_msg->run_cmd.argc;
	pr_debug("CTRL: run_command, argc:%d\n", argc);

	argv = malloc(argc * sizeof(*argv));
	if (!argv) {
		pr_log(LOG_ERR, "CTRL: argv buffer malloc failed: %m");
		return;
	}

	s = (char *)recv_msg->data;
	size = 0;
	for (i = 0; i < argc; i++) {
		argv[i] = (char *)htobe64((uint64_t)&s[size]);
		size += (strlen(&s[size]) + 1);
	}

	/* Call HBRT */
	send_msg->response = call_run_command(argc, argv, &runcmd_output);
	runcmd_output = (char *)be64toh((uint64_t)runcmd_output);
	free(argv);

	s = (char *)send_msg->data;
	if (runcmd_output) {
		size = strlen(runcmd_output);
		if (size >= MAX_CONTROL_MSG_BUF) {
			pr_log(LOG_WARNING, "CTRL: output message truncated");
			runcmd_output[MAX_CONTROL_MSG_BUF] = '\0';
			size = MAX_CONTROL_MSG_BUF;
		}

		strcpy(s, runcmd_output);
		send_msg->data_len = size + 1;
		free(runcmd_output);
	} else {
		strcpy(s, "Null");
		send_msg->data_len = strlen("Null") + 1;
	}
}

static void handle_prd_control(struct opal_prd_ctx *ctx, int fd)
{
	struct control_msg msg, *recv_msg, *send_msg;
	bool enabled = false;
	int rc, size;

	/* Default reply, in the error path */
	send_msg = &msg;

	/* Peek into the socket to ascertain the size of the available data */
	rc = recv(fd, &msg, sizeof(msg), MSG_PEEK);
	if (rc != sizeof(msg)) {
		pr_log(LOG_WARNING, "CTRL: failed to receive control "
				"message: %m");
		msg.response = -1;
		msg.data_len = 0;
		goto out_send;
	}

	size = sizeof(*recv_msg) + msg.data_len;

	/* Default reply, in the error path */
	msg.data_len = 0;
	msg.response = -1;

	recv_msg = malloc(size);
	if (!recv_msg) {
		pr_log(LOG_ERR, "CTRL: message buffer malloc failed: %m");
		goto out_send;
	}

	rc = recv(fd, recv_msg, size, MSG_TRUNC);
	if (rc != size) {
		pr_log(LOG_WARNING, "CTRL: failed to receive control "
				"message: %m");
		goto out_free_recv;
	}

	send_msg = malloc(sizeof(*send_msg) + MAX_CONTROL_MSG_BUF);
	if (!send_msg) {
		pr_log(LOG_ERR, "CTRL: message buffer malloc failed: %m");
		send_msg = &msg;
		goto out_free_recv;
	}

	send_msg->type = recv_msg->type;
	send_msg->response = -1;
	switch (recv_msg->type) {
	case CONTROL_MSG_ENABLE_OCCS:
		enabled = true;
		/* fall through */
	case CONTROL_MSG_DISABLE_OCCS:
		handle_prd_control_occ_actuation(send_msg, enabled);
		break;
	case CONTROL_MSG_TEMP_OCC_RESET:
		handle_prd_control_occ_reset(send_msg, recv_msg);
		break;
	case CONTROL_MSG_TEMP_OCC_ERROR:
		handle_prd_control_occ_error(send_msg, recv_msg);
		break;
	case CONTROL_MSG_ATTR_OVERRIDE:
		handle_prd_control_attr_override(send_msg, recv_msg);
		break;
	case CONTROL_MSG_HTMGT_PASSTHRU:
		handle_prd_control_htmgt_passthru(send_msg, recv_msg);
		break;
	case CONTROL_MSG_RUN_CMD:
		handle_prd_control_run_cmd(send_msg, recv_msg);
		break;
	default:
		pr_log(LOG_WARNING, "CTRL: Unknown control message action %d",
				recv_msg->type);
		send_msg->data_len = 0;
		break;
	}

out_free_recv:
	free(recv_msg);
out_send:
	size = sizeof(*send_msg) + send_msg->data_len;
	rc = send(fd, send_msg, size, MSG_DONTWAIT | MSG_NOSIGNAL);
	if (rc && (errno == EAGAIN || errno == EWOULDBLOCK || errno == EPIPE))
		pr_debug("CTRL: control send() returned %d, ignoring failure",
				rc);
	else if (rc != size)
		pr_log(LOG_NOTICE, "CTRL: Failed to send control response: %m");

	if (send_msg != &msg)
		free(send_msg);
}

static int run_attn_loop(struct opal_prd_ctx *ctx)
{
	struct pollfd pollfds[2];
	struct opal_prd_msg msg;
	int rc, fd;

	if (hservice_runtime->enable_attns) {
		pr_debug("HBRT: calling enable_attns");
		rc = call_enable_attns();
		if (rc) {
			pr_log(LOG_ERR, "HBRT: enable_attns() failed, "
					"aborting");
			return -1;
		}
	}

	if (hservice_runtime->get_ipoll_events) {
		pr_debug("HBRT: calling get_ipoll_events");
		opal_prd_ipoll = call_get_ipoll_events();
	}

	pr_debug("HBRT: enabling IPOLL events 0x%016lx", opal_prd_ipoll);

	/* send init message, to unmask interrupts */
	msg.hdr.type = OPAL_PRD_MSG_TYPE_INIT;
	msg.hdr.size = htobe16(sizeof(msg));
	msg.init.version = htobe64(opal_prd_version);
	msg.init.ipoll = htobe64(opal_prd_ipoll);

	pr_debug("FW: writing init message");
	rc = write(ctx->fd, &msg, sizeof(msg));
	if (rc != sizeof(msg)) {
		pr_log(LOG_ERR, "FW: Init message failed: %m. Aborting.");
		return -1;
	}

	pollfds[0].fd = ctx->fd;
	pollfds[0].events = POLLIN | POLLERR;
	pollfds[1].fd = ctx->socket;
	pollfds[1].events = POLLIN | POLLERR;

	for (;;) {
		/* run through any pending messages */
		process_msgq(ctx);

		rc = poll(pollfds, 2, -1);
		if (rc < 0) {
			pr_log(LOG_ERR, "FW: event poll failed: %m");
			exit(EXIT_FAILURE);
		}

		if (!rc)
			continue;

		if (pollfds[0].revents & POLLIN) {
			rc = read_prd_msg(ctx);
			if (!rc)
				handle_prd_msg(ctx, ctx->msg);
		}

		if (pollfds[1].revents & POLLIN) {
			fd = accept(ctx->socket, NULL, NULL);
			if (fd < 0) {
				pr_log(LOG_NOTICE, "CTRL: accept failed: %m");
				continue;
			}
			handle_prd_control(ctx, fd);
			close(fd);
		}
	}

	return 0;
}

static int init_control_socket(struct opal_prd_ctx *ctx)
{
	struct sockaddr_un addr;
	int fd, rc;

	unlink(opal_prd_socket);

	addr.sun_family = AF_UNIX;
	strcpy(addr.sun_path, opal_prd_socket);

	fd = socket(AF_LOCAL, SOCK_STREAM, 0);
	if (fd < 0) {
		pr_log(LOG_WARNING, "CTRL: Can't open control socket %s: %m",
				opal_prd_socket);
		return -1;
	}

	rc = bind(fd, (struct sockaddr *)&addr, sizeof(addr));
	if (rc) {
		pr_log(LOG_WARNING, "CTRL: Can't bind control socket %s: %m",
				opal_prd_socket);
		close(fd);
		return -1;
	}

	rc = listen(fd, 0);
	if (rc) {
		pr_log(LOG_WARNING, "CTRL: Can't listen on "
				"control socket %s: %m", opal_prd_socket);
		close(fd);
		return -1;
	}

	pr_log(LOG_INFO, "CTRL: Listening on control socket %s",
			opal_prd_socket);

	ctx->socket = fd;
	return 0;
}


static int run_prd_daemon(struct opal_prd_ctx *ctx)
{
	int rc;

	/* log to syslog */
	pr_log_daemon_init();

	pr_debug("CTRL: Starting PRD daemon\n");

	ctx->fd = -1;
	ctx->socket = -1;

	/* set up our message buffer */
	ctx->msg_alloc_len = sizeof(*ctx->msg);
	ctx->msg = malloc(ctx->msg_alloc_len);
	if (!ctx->msg) {
		pr_log(LOG_ERR, "FW: Can't allocate PRD message buffer: %m");
		return -1;
	}


	list_head_init(&ctx->msgq);

	i2c_init();

#ifdef DEBUG_I2C
	{
		uint8_t foo[128];
		int i;

		rc = i2c_read(0, 1, 2, 0x50, 2, 0x10, 128, foo);
		pr_debug("I2C: read rc: %d", rc);
		for (i = 0; i < sizeof(foo); i += 8) {
			pr_debug("I2C: %02x %02x %02x %02x %02x %02x %02x %02x",
			       foo[i + 0], foo[i + 1], foo[i + 2], foo[i + 3],
			       foo[i + 4], foo[i + 5], foo[i + 6], foo[i + 7]);
		}
	}
#endif
	rc = init_control_socket(ctx);
	if (rc) {
		pr_log(LOG_WARNING, "CTRL: Error initialising PRD control: %m");
		goto out_close;
	}


	rc = prd_init(ctx);
	if (rc) {
		pr_log(LOG_ERR, "FW: Error initialising PRD channel");
		goto out_close;
	}

	if (ctx->hbrt_file_name) {
		rc = map_hbrt_file(ctx, ctx->hbrt_file_name);
		if (rc) {
			pr_log(LOG_ERR, "IMAGE: Can't access hbrt file %s",
					ctx->hbrt_file_name);
			goto out_close;
		}
	} else {
		rc = map_hbrt_physmem(ctx, hbrt_code_region_name);
		if (rc) {
			pr_log(LOG_ERR, "IMAGE: Can't access hbrt "
					"physical memory");
			goto out_close;
		}
		dump_hbrt_map(ctx);
	}

	pr_debug("IMAGE: hbrt map at %p, size 0x%zx",
			ctx->code_addr, ctx->code_size);

	fixup_hinterface_table();

	if (!is_fsp_system()) {
		pnor_load_module(ctx);

		rc = pnor_init(&ctx->pnor);
		if (rc) {
			pr_log(LOG_ERR, "PNOR: Failed to open pnor: %m");
			goto out_close;
		}
	} else {
		/* Disable PNOR function pointers */
		hinterface.pnor_read = NULL;
		hinterface.pnor_write = NULL;
	}

	ipmi_init(ctx);

	pr_debug("HBRT: calling hservices_init");
	rc = hservices_init(ctx, ctx->code_addr);
	if (rc) {
		pr_log(LOG_ERR, "HBRT: Can't initialise HBRT");
		goto out_close;
	}
	pr_debug("HBRT: hservices_init done");

	/* Test a scom */
	if (ctx->debug) {
		uint64_t val;
		pr_debug("SCOM: trying scom read");
		fflush(stdout);
		hservice_scom_read(0x00, 0xf000f, &val);
		pr_debug("SCOM:  f00f: %lx", be64toh(val));
	}

	run_attn_loop(ctx);
	rc = 0;

out_close:
	pr_debug("CTRL: stopping PRD daemon\n");
	pnor_close(&ctx->pnor);
	if (ctx->fd != -1)
		close(ctx->fd);
	if (ctx->socket != -1)
		close(ctx->socket);
	if (ctx->msg)
		free(ctx->msg);
	return rc;
}

static int send_prd_control(struct control_msg *send_msg,
			    struct control_msg **recv_msg)
{
	struct sockaddr_un addr;
	struct control_msg *msg;
	int sd, rc, size;

	sd = socket(AF_UNIX, SOCK_STREAM, 0);
	if (!sd) {
		pr_log(LOG_ERR, "CTRL: Failed to create control socket: %m");
		return -1;
	}

	addr.sun_family = AF_UNIX;
	strcpy(addr.sun_path, opal_prd_socket);

	rc = connect(sd, (struct sockaddr *)&addr, sizeof(addr));
	if (rc) {
		pr_log(LOG_ERR, "CTRL: Failed to connect to prd daemon: %m");
		goto out_close;
	}

	size = sizeof(*send_msg) + send_msg->data_len;
	rc = send(sd, send_msg, size, 0);
	if (rc != size) {
		pr_log(LOG_ERR, "CTRL: Failed to send control message: %m");
		rc = -1;
		goto out_close;
	}

	size = sizeof(*msg) + MAX_CONTROL_MSG_BUF;
	msg = malloc(size);
	if (!msg) {
		pr_log(LOG_ERR, "CTRL: msg buffer malloc failed: %m");
		rc = -1;
		goto out_close;
	}

	*recv_msg = msg;

	/* wait for our reply */
	rc = recv(sd, msg, size, 0);
	if (rc < 0) {
		pr_log(LOG_ERR, "CTRL: Failed to receive control message: %m");
		goto out_close;

	} else if (rc != (sizeof(*msg) + msg->data_len)) {
		pr_log(LOG_WARNING, "CTRL: Short read from control socket");
		rc = -1;
		goto out_close;
	}

	rc = msg->response;

out_close:
	close(sd);
	return rc;
}

static int send_occ_control(struct opal_prd_ctx *ctx, int argc, char *argv[])
{
	struct control_msg send_msg, *recv_msg = NULL;
	unsigned long chip = 0;
	const char *op;
	int rc;

	assert(argc >= 1);
	op = argv[0];

	/* some commands accept a 'chip' argument, so parse it here */
	if (argc > 1) {
		char *arg, *end;
		arg = argv[1];
		chip = strtoul(arg, &end, 0);
		if (end == arg) {
			pr_log(LOG_ERR, "CTRL: invalid argument %s", arg);
			return -1;
		}
	}

	memset(&send_msg, 0, sizeof(send_msg));

	if (!strcmp(op, "enable"))
		send_msg.type = CONTROL_MSG_ENABLE_OCCS;
	else if (!strcmp(op, "disable"))
		send_msg.type = CONTROL_MSG_DISABLE_OCCS;

	else if (!strcmp(op, "reset")) {
		send_msg.type = CONTROL_MSG_TEMP_OCC_RESET;
		send_msg.occ_reset.chip = (uint64_t)chip;

	} else if (!strcmp(op, "process-error")) {
		send_msg.type = CONTROL_MSG_TEMP_OCC_ERROR;
		send_msg.occ_error.chip = (uint64_t)chip;
	} else {
		pr_log(LOG_ERR, "CTRL: Invalid OCC action '%s'", op);
		return -1;
	}

	rc = send_prd_control(&send_msg, &recv_msg);
	if (recv_msg) {
		if (recv_msg->response || ctx->debug)
			pr_debug("CTRL: OCC action %s returned status %d", op,
					recv_msg->response);
		free(recv_msg);
	}

	return rc;
}

static int send_attr_override(struct opal_prd_ctx *ctx, uint32_t argc,
			      char *argv[])
{
	struct control_msg *send_msg, *recv_msg = NULL;
	struct stat statbuf;
	size_t sz;
	FILE *fd;
	int rc;

	rc = stat(argv[0], &statbuf);
	if (rc) {
		pr_log(LOG_ERR, "CTRL: stat() failed on the file: %m");
		return -1;
	}

	send_msg = malloc(sizeof(*send_msg) + statbuf.st_size);
	if (!send_msg) {
		pr_log(LOG_ERR, "CTRL: msg buffer malloc failed: %m");
		return -1;
	}

	send_msg->type = CONTROL_MSG_ATTR_OVERRIDE;
	send_msg->data_len = statbuf.st_size;

	fd = fopen(argv[0], "r");
	if (!fd) {
		pr_log(LOG_NOTICE, "CTRL: can't open %s: %m", argv[0]);
		rc = -1;
		goto out_free;
	}

	sz = fread(send_msg->data, 1, send_msg->data_len, fd);
	fclose(fd);
	if (sz != statbuf.st_size) {
		pr_log(LOG_ERR, "CTRL: short read from the file");
		rc = -1;
		goto out_free;
	}

	rc = send_prd_control(send_msg, &recv_msg);
	if (recv_msg) {
		if (recv_msg->response || ctx->debug)
			pr_debug("CTRL: attribute override returned status %d",
					recv_msg->response);
		free(recv_msg);
	}

out_free:
	free(send_msg);
	return rc;
}

static int send_htmgt_passthru(struct opal_prd_ctx *ctx, int argc, char *argv[])
{
	struct control_msg *send_msg, *recv_msg = NULL;
	int rc, i;

	if (!ctx->expert_mode) {
		pr_log(LOG_WARNING, "CTRL: need to be in expert mode");
		return -1;
	}

	send_msg = malloc(sizeof(*send_msg) + argc);
	if (!send_msg) {
		pr_log(LOG_ERR, "CTRL: message buffer malloc failed: %m");
		return -1;
	}

	send_msg->type = CONTROL_MSG_HTMGT_PASSTHRU;
	send_msg->data_len = argc;

	if (ctx->debug)
		pr_debug("CTRL: HTMGT passthru arguments:");

	for (i = 0; i < argc; i++) {
		if (ctx->debug)
			pr_debug("argv[%d] = %s", i, argv[i]);

		sscanf(argv[i], "%hhx", &send_msg->data[i]);
	}

	rc = send_prd_control(send_msg, &recv_msg);
	free(send_msg);

	if (recv_msg) {
		if (recv_msg->response || ctx->debug)
			pr_debug("CTRL: HTMGT passthru returned status %d",
					recv_msg->response);
		if (recv_msg->response == 0 && recv_msg->data_len)
			hexdump(recv_msg->data, recv_msg->data_len);

		free(recv_msg);
	}

	return rc;
}

static int send_run_command(struct opal_prd_ctx *ctx, int argc, char *argv[])
{
	struct control_msg *send_msg, *recv_msg = NULL;
	uint32_t size = 0;
	int rc, i;
	char *s;

	if (!ctx->expert_mode) {
		pr_log(LOG_WARNING, "CTRL: need to be in expert mode");
		return -1;
	}

	if (ctx->debug) {
		pr_debug("CTRL: run command arguments:");
		for (i=0; i < argc; i++)
			pr_debug("argv[%d] = %s", i, argv[i]);
	}

	for (i = 0; i < argc; i++)
		size += (strlen(argv[i]) + 1);

	send_msg = malloc(sizeof(*send_msg) + size);
	if (!send_msg) {
		pr_log(LOG_ERR, "CTRL: msg buffer malloc failed: %m");
		return -1;
	}

	/* Setup message */
	send_msg->type = CONTROL_MSG_RUN_CMD;
	send_msg->run_cmd.argc = argc;
	send_msg->data_len = size;
	s = (char *)send_msg->data;
	for (i = 0; i < argc; i++) {
		strcpy(s, argv[i]);
		s = s + strlen(argv[i]) + 1;
	}

	rc = send_prd_control(send_msg, &recv_msg);
	free(send_msg);
	if (recv_msg) {
		if (!rc)
			pr_log(LOG_INFO, "Received: %s", recv_msg->data);

		if (recv_msg->response || ctx->debug)
			pr_debug("CTRL: run command returned status %d",
					recv_msg->response);
		free(recv_msg);
	}

	return rc;
}

static void usage(const char *progname)
{
	printf("Usage:\n");
	printf("\t%s [--debug] [--file <hbrt-image>] [--pnor <device>]\n",
			progname);
	printf("\t%s occ <enable|disable|reset [chip]>\n", progname);
	printf("\t%s pm-complex reset [chip]>\n", progname);
	printf("\t%s htmgt-passthru <bytes...>\n", progname);
	printf("\t%s override <FILE>\n", progname);
	printf("\t%s run [arg 0] [arg 1]..[arg n]\n", progname);
	printf("\n");
	printf("Options:\n"
"\t--debug            verbose logging for debug information\n"
"\t--pnor DEVICE      use PNOR MTD device\n"
"\t--file FILE        use FILE for hostboot runtime code (instead of code\n"
"\t                     exported by firmware)\n"
"\t--stdio            log to stdio, instead of syslog\n");
}

static void print_version(void)
{
	extern const char version[];
	printf("opal-prd %s\n", version);
}

static struct option opal_diag_options[] = {
	{"file", required_argument, NULL, 'f'},
	{"pnor", required_argument, NULL, 'p'},
	{"debug", no_argument, NULL, 'd'},
	{"help", no_argument, NULL, 'h'},
	{"version", no_argument, NULL, 'v'},
	{"stdio", no_argument, NULL, 's'},
	{"expert-mode", no_argument, NULL, 'e'},
	{ 0 },
};

enum action {
	ACTION_RUN_DAEMON,
	ACTION_OCC_CONTROL,
	ACTION_ATTR_OVERRIDE,
	ACTION_HTMGT_PASSTHRU,
	ACTION_RUN_COMMAND,
};

static int parse_action(const char *str, enum action *action)
{
	int rc;

	if (!strcmp(str, "occ")) {
		*action = ACTION_OCC_CONTROL;
		rc = 0;

		if (is_fsp_system()) {
			pr_log(LOG_ERR, "CTRL: occ commands are not "
			       "supported on this system");
			rc = -1;
		}
	} else if (!strcmp(str, "pm-complex")) {
		*action = ACTION_OCC_CONTROL;
		rc = 0;

		if (!is_fsp_system()) {
			pr_log(LOG_ERR, "CTRL: pm-complex commands are not "
			       "supported on this system");
			rc = -1;
		}
	} else if (!strcmp(str, "daemon")) {
		*action = ACTION_RUN_DAEMON;
		rc = 0;
	} else if (!strcmp(str, "override")) {
		*action = ACTION_ATTR_OVERRIDE;
		rc = 0;
	} else if (!strcmp(str, "htmgt-passthru")) {
		*action = ACTION_HTMGT_PASSTHRU;
		rc = 0;
	} else if (!strcmp(str, "run")) {
		*action = ACTION_RUN_COMMAND;
		return 0;
	} else {
		pr_log(LOG_ERR, "CTRL: unknown argument '%s'", str);
		rc = -1;
	}

	return rc;
}

int main(int argc, char *argv[])
{
	struct opal_prd_ctx _ctx;
	enum action action;
	int rc;

	check_abi();

	ctx = &_ctx;
	memset(ctx, 0, sizeof(*ctx));
	ctx->vlog = pr_log_stdio;
	ctx->use_syslog = true;

	/* Parse options */
	for (;;) {
		int c;

		c = getopt_long(argc, argv, "f:p:dhse", opal_diag_options, NULL);
		if (c == -1)
			break;

		switch (c) {
		case 'f':
			ctx->hbrt_file_name = optarg;
			break;
		case 'd':
			ctx->debug = true;
			break;
		case 'p':
			ctx->pnor.path = strndup(optarg, PATH_MAX);
			break;
		case 's':
			ctx->use_syslog = false;
			break;
		case 'h':
			usage(argv[0]);
			return EXIT_SUCCESS;
		case 'e':
			ctx->expert_mode = true;
			break;
		case 'v':
			print_version();
			return EXIT_SUCCESS;
		case '?':
		default:
			usage(argv[0]);
			return EXIT_FAILURE;
		}
	}

	if (optind < argc) {
		rc = parse_action(argv[optind], &action);
		if (rc)
			return EXIT_FAILURE;
		optind++;
	} else {
		action = ACTION_RUN_DAEMON;
	}

	if (is_prd_supported() < 0) {
		pr_log(LOG_ERR, "CTRL: PowerNV OPAL runtime diagnostic "
				"is not supported on this system");
		return -1;
	}

	switch (action) {
	case ACTION_RUN_DAEMON:
		rc = run_prd_daemon(ctx);
		break;
	case ACTION_OCC_CONTROL:
		if (optind >= argc) {
			pr_log(LOG_ERR, "CTRL: occ command requires "
					"an argument");
			return EXIT_FAILURE;
		}

		rc = send_occ_control(ctx, argc - optind, &argv[optind]);
		break;
	case ACTION_ATTR_OVERRIDE:
		if (optind >= argc) {
			pr_log(LOG_ERR, "CTRL: attribute override command "
					"requires an argument");
			return EXIT_FAILURE;
		}

		rc = send_attr_override(ctx, argc - optind, &argv[optind]);
		break;
	case ACTION_HTMGT_PASSTHRU:
		if (optind >= argc) {
			pr_log(LOG_ERR, "CTRL: htmgt passthru requires at least "
					"one argument");
			return EXIT_FAILURE;
		}

		rc = send_htmgt_passthru(ctx, argc - optind, &argv[optind]);
		break;
	case ACTION_RUN_COMMAND:
		if (optind >= argc) {
			pr_log(LOG_ERR, "CTRL: run command requires "
					"argument(s)");
			return EXIT_FAILURE;
		}

		rc = send_run_command(ctx, argc - optind, &argv[optind]);
		break;
	default:
		break;
	}

	return rc == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
}
