/*
 * Copyright (C) 2014 Michael Brown <mbrown@fensystems.co.uk>.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301, USA.
 *
 * You can also choose to distribute this program under the terms of
 * the Unmodified Binary Distribution Licence (as given in the file
 * COPYING.UBDL), provided that you have satisfied its requirements.
 */

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );

#include <stdint.h>
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ipxe/io.h>
#include <ipxe/nap.h>
#include <ipxe/malloc.h>
#include <ipxe/xen.h>
#include <ipxe/xenevent.h>
#include <ipxe/xenstore.h>

/*
 * xs_wire.h attempts to define a static error table xsd_errors, which
 * interacts badly with the dynamically generated error numbers used
 * by iPXE.  Prevent this table from being constructed by including
 * errno.h only after including xs_wire.h.
 *
 */
#include <xen/io/xs_wire.h>
#include <errno.h>

/** @file
 *
 * XenStore interface
 *
 */

/** Request identifier */
static uint32_t xenstore_req_id;

/**
 * Send XenStore request raw data
 *
 * @v xen		Xen hypervisor
 * @v data		Data buffer
 * @v len		Length of data
 */
static void xenstore_send ( struct xen_hypervisor *xen, const void *data,
			    size_t len ) {
	struct xenstore_domain_interface *intf = xen->store.intf;
	XENSTORE_RING_IDX prod = readl ( &intf->req_prod );
	XENSTORE_RING_IDX cons;
	XENSTORE_RING_IDX idx;
	const char *bytes = data;
	size_t offset;
	size_t fill;

	DBGCP ( intf, "XENSTORE raw request:\n" );
	DBGCP_HDA ( intf, MASK_XENSTORE_IDX ( prod ), data, len );

	/* Write one byte at a time */
	for ( offset = 0 ; offset < len ; offset++ ) {

		/* Wait for space to become available */
		while ( 1 ) {
			cons = readl ( &intf->req_cons );
			fill = ( prod - cons );
			if ( fill < XENSTORE_RING_SIZE )
				break;
			DBGC2 ( xen, "." );
			cpu_nap();
			rmb();
		}

		/* Write byte */
		idx = MASK_XENSTORE_IDX ( prod++ );
		writeb ( bytes[offset], &intf->req[idx] );
	}

	/* Update producer counter */
	wmb();
	writel ( prod, &intf->req_prod );
	wmb();
}

/**
 * Send XenStore request string (excluding terminating NUL)
 *
 * @v xen		Xen hypervisor
 * @v string		String
 */
static void xenstore_send_string ( struct xen_hypervisor *xen,
				   const char *string ) {

	xenstore_send ( xen, string, strlen ( string ) );
}

/**
 * Receive XenStore response raw data
 *
 * @v xen		Xen hypervisor
 * @v data		Data buffer, or NULL to discard data
 * @v len		Length of data
 */
static void xenstore_recv ( struct xen_hypervisor *xen, void *data,
			    size_t len ) {
	struct xenstore_domain_interface *intf = xen->store.intf;
	XENSTORE_RING_IDX cons = readl ( &intf->rsp_cons );
	XENSTORE_RING_IDX prod;
	XENSTORE_RING_IDX idx;
	char *bytes = data;
	size_t offset;
	size_t fill;

	DBGCP ( intf, "XENSTORE raw response:\n" );

	/* Read one byte at a time */
	for ( offset = 0 ; offset < len ; offset++ ) {

		/* Wait for data to be ready */
		while ( 1 ) {
			prod = readl ( &intf->rsp_prod );
			fill = ( prod - cons );
			if ( fill > 0 )
				break;
			DBGC2 ( xen, "." );
			cpu_nap();
			rmb();
		}

		/* Read byte */
		idx = MASK_XENSTORE_IDX ( cons++ );
		if ( data )
			bytes[offset] = readb ( &intf->rsp[idx] );
	}
	if ( data )
		DBGCP_HDA ( intf, MASK_XENSTORE_IDX ( cons - len ), data, len );

	/* Update consumer counter */
	writel ( cons, &intf->rsp_cons );
	wmb();
}

/**
 * Send XenStore request
 *
 * @v xen		Xen hypervisor
 * @v type		Message type
 * @v req_id		Request ID
 * @v value		Value, or NULL to omit
 * @v key		Key path components
 * @ret rc		Return status code
 */
static int xenstore_request ( struct xen_hypervisor *xen,
			      enum xsd_sockmsg_type type, uint32_t req_id,
			      const char *value, va_list key ) {
	struct xsd_sockmsg msg;
	struct evtchn_send event;
	const char *string;
	va_list tmp;
	int xenrc;
	int rc;

	/* Construct message header */
	msg.type = type;
	msg.req_id = req_id;
	msg.tx_id = 0;
	msg.len = 0;
	DBGC2 ( xen, "XENSTORE request ID %d type %d ", req_id, type );

	/* Calculate total length */
	va_copy ( tmp, key );
	while ( ( string = va_arg ( tmp, const char * ) ) != NULL ) {
		DBGC2 ( xen, "%s%s", ( msg.len ? "/" : "" ), string );
		msg.len += ( strlen ( string ) + 1 /* '/' or NUL */ );
	}
	va_end ( tmp );
	if ( value ) {
		DBGC2 ( xen, " = \"%s\"", value );
		msg.len += strlen ( value );
	}
	DBGC2 ( xen, "\n" );

	/* Send message */
	xenstore_send ( xen, &msg, sizeof ( msg ) );
	string = va_arg ( key, const char * );
	assert ( string != NULL );
	xenstore_send_string ( xen, string );
	while ( ( string = va_arg ( key, const char * ) ) != NULL ) {
		xenstore_send_string ( xen, "/" );
		xenstore_send_string ( xen, string );
	}
	xenstore_send ( xen, "", 1 ); /* Separating NUL */
	if ( value )
		xenstore_send_string ( xen, value );

	/* Notify the back end */
	event.port = xen->store.port;
	if ( ( xenrc = xenevent_send ( xen, &event ) ) != 0 ) {
		rc = -EXEN ( xenrc );
		DBGC ( xen, "XENSTORE could not notify back end: %s\n",
		       strerror ( rc ) );
		return rc;
	}

	return 0;
}

/**
 * Receive XenStore response
 *
 * @v xen		Xen hypervisor
 * @v req_id		Request ID
 * @v value		Value to fill in
 * @v len		Length to fill in
 * @ret rc		Return status code
 *
 * The caller is responsible for eventually calling free() on the
 * returned value.  Note that the value may comprise multiple
 * NUL-terminated strings concatenated together.  A terminating NUL
 * will always be appended to the returned value.
 */
static int xenstore_response ( struct xen_hypervisor *xen, uint32_t req_id,
			       char **value, size_t *len ) {
	struct xsd_sockmsg msg;
	char *string;
	int rc;

	/* Wait for response to become available */
	while ( ! xenevent_pending ( xen, xen->store.port ) )
		cpu_nap();

	/* Receive message header */
	xenstore_recv ( xen, &msg, sizeof ( msg ) );
	*len = msg.len;

	/* Allocate space for response */
	*value = zalloc ( msg.len + 1 /* terminating NUL */ );

	/* Receive data.  Do this even if allocation failed, or if the
	 * request ID was incorrect, to avoid leaving data in the
	 * ring.
	 */
	xenstore_recv ( xen, *value, msg.len );

	/* Validate request ID */
	if ( msg.req_id != req_id ) {
		DBGC ( xen, "XENSTORE response ID mismatch (got %d, expected "
		       "%d)\n", msg.req_id, req_id );
		rc = -EPROTO;
		goto err_req_id;
	}

	/* Check for allocation failure */
	if ( ! *value ) {
		DBGC ( xen, "XENSTORE could not allocate %d bytes for "
		       "response\n", msg.len );
		rc = -ENOMEM;
		goto err_alloc;
	}

	/* Check for explicit errors */
	if ( msg.type == XS_ERROR ) {
		DBGC ( xen, "XENSTORE response error \"%s\"\n", *value );
		rc = -EIO;
		goto err_explicit;
	}

	DBGC2 ( xen, "XENSTORE response ID %d\n", req_id );
	if ( DBG_EXTRA ) {
		for ( string = *value ; string < ( *value + msg.len ) ;
		      string += ( strlen ( string ) + 1 /* NUL */ ) ) {
			DBGC2 ( xen, " - \"%s\"\n", string );
		}
	}
	return 0;

 err_explicit:
 err_alloc:
 err_req_id:
	free ( *value );
	*value = NULL;
	return rc;
}

/**
 * Issue a XenStore message
 *
 * @v xen		Xen hypervisor
 * @v type		Message type
 * @v response		Response value to fill in, or NULL to discard
 * @v len		Response length to fill in, or NULL to ignore
 * @v request		Request value, or NULL to omit
 * @v key		Key path components
 * @ret rc		Return status code
 */
static int xenstore_message ( struct xen_hypervisor *xen,
			      enum xsd_sockmsg_type type, char **response,
			      size_t *len, const char *request, va_list key ) {
	char *response_value;
	size_t response_len;
	int rc;

	/* Send request */
	if ( ( rc = xenstore_request ( xen, type, ++xenstore_req_id,
				       request, key ) ) != 0 )
		return rc;

	/* Receive response */
	if ( ( rc = xenstore_response ( xen, xenstore_req_id, &response_value,
					&response_len ) ) != 0 )
		return rc;

	/* Return response, if applicable */
	if ( response ) {
		*response = response_value;
	} else {
		free ( response_value );
	}
	if ( len )
		*len = response_len;

	return 0;
}

/**
 * Read XenStore value
 *
 * @v xen		Xen hypervisor
 * @v value		Value to fill in
 * @v key		Key path components
 * @ret rc		Return status code
 *
 * On a successful return, the caller is responsible for calling
 * free() on the returned value.
 */
static int xenstore_vread ( struct xen_hypervisor *xen, char **value,
			    va_list key ) {

	return xenstore_message ( xen, XS_READ, value, NULL, NULL, key );
}

/**
 * Read XenStore value
 *
 * @v xen		Xen hypervisor
 * @v value		Value to fill in
 * @v ...		Key path components
 * @ret rc		Return status code
 *
 * On a successful return, the caller is responsible for calling
 * free() on the returned value.
 */
__attribute__ (( sentinel )) int
xenstore_read ( struct xen_hypervisor *xen, char **value, ... ) {
	va_list key;
	int rc;

	va_start ( key, value );
	rc = xenstore_vread ( xen, value, key );
	va_end ( key );
	return rc;
}

/**
 * Read XenStore numeric value
 *
 * @v xen		Xen hypervisor
 * @v num		Numeric value to fill in
 * @v ...		Key path components
 * @ret rc		Return status code
 */
__attribute__ (( sentinel )) int
xenstore_read_num ( struct xen_hypervisor *xen, unsigned long *num, ... ) {
	va_list key;
	char *value;
	char *endp;
	int rc;

	/* Try to read text value */
	va_start ( key, num );
	rc = xenstore_vread ( xen, &value, key );
	va_end ( key );
	if ( rc != 0 )
		goto err_read;

	/* Try to parse as numeric value */
	*num = strtoul ( value, &endp, 10 );
	if ( ( *value == '\0' ) || ( *endp != '\0' ) ) {
		DBGC ( xen, "XENSTORE found invalid numeric value \"%s\"\n",
		       value );
		rc = -EINVAL;
		goto err_strtoul;
	}

 err_strtoul:
	free ( value );
 err_read:
	return rc;
}

/**
 * Write XenStore value
 *
 * @v xen		Xen hypervisor
 * @v value		Value
 * @v key		Key path components
 * @ret rc		Return status code
 */
static int xenstore_vwrite ( struct xen_hypervisor *xen, const char *value,
			     va_list key ) {

	return xenstore_message ( xen, XS_WRITE, NULL, NULL, value, key );
}

/**
 * Write XenStore value
 *
 * @v xen		Xen hypervisor
 * @v value		Value
 * @v ...		Key path components
 * @ret rc		Return status code
 */
__attribute__ (( sentinel )) int
xenstore_write ( struct xen_hypervisor *xen, const char *value, ... ) {
	va_list key;
	int rc;

	va_start ( key, value );
	rc = xenstore_vwrite ( xen, value, key );
	va_end ( key );
	return rc;
}

/**
 * Write XenStore numeric value
 *
 * @v xen		Xen hypervisor
 * @v num		Numeric value
 * @v ...		Key path components
 * @ret rc		Return status code
 */
__attribute__ (( sentinel )) int
xenstore_write_num ( struct xen_hypervisor *xen, unsigned long num, ... ) {
	char value[ 21 /* "18446744073709551615" + NUL */ ];
	va_list key;
	int rc;

	/* Construct value */
	snprintf ( value, sizeof ( value ), "%ld", num );

	/* Write value */
	va_start ( key, num );
	rc = xenstore_vwrite ( xen, value, key );
	va_end ( key );
	return rc;
}

/**
 * Delete XenStore value
 *
 * @v xen		Xen hypervisor
 * @v ...		Key path components
 * @ret rc		Return status code
 */
__attribute__ (( sentinel )) int
xenstore_rm ( struct xen_hypervisor *xen, ... ) {
	va_list key;
	int rc;

	va_start ( key, xen );
	rc = xenstore_message ( xen, XS_RM, NULL, NULL, NULL, key );
	va_end ( key );
	return rc;
}

/**
 * Read XenStore directory
 *
 * @v xen		Xen hypervisor
 * @v children		Child key names to fill in
 * @v len		Length of child key names to fill in
 * @v ...		Key path components
 * @ret rc		Return status code
 */
__attribute__ (( sentinel )) int
xenstore_directory ( struct xen_hypervisor *xen, char **children, size_t *len,
		     ... ) {
	va_list key;
	int rc;

	va_start ( key, len );
	rc = xenstore_message ( xen, XS_DIRECTORY, children, len, NULL, key );
	va_end ( key );
	return rc;
}

/**
 * Dump XenStore directory contents (for debugging)
 *
 * @v xen		Xen hypervisor
 * @v key		Key
 */
void xenstore_dump ( struct xen_hypervisor *xen, const char *key ) {
	char *value;
	char *children;
	char *child;
	char *child_key;
	size_t len;
	int rc;

	/* Try to dump current key as a value */
	if ( ( rc = xenstore_read ( xen, &value, key, NULL ) ) == 0 ) {
		DBGC ( xen, "%s = \"%s\"\n", key, value );
		free ( value );
	}

	/* Try to recurse into each child in turn */
	if ( ( rc = xenstore_directory ( xen, &children, &len, key,
					 NULL ) ) == 0 ) {
		for ( child = children ; child < ( children + len ) ;
		      child += ( strlen ( child ) + 1 /* NUL */ ) ) {

			/* Construct child key */
			if ( asprintf ( &child_key, "%s/%s", key, child ) < 0 ){
				DBGC ( xen, "XENSTORE could not allocate child "
				       "key \"%s/%s\"\n", key, child );
				rc = -ENOMEM;
				break;
			}

			/* Recurse into child key, continuing on error */
			xenstore_dump ( xen, child_key );
			free ( child_key );
		}
		free ( children );
	}
}
