/*
 * Copyright (c) 2013, ARM Limited. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 *
 * Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * Neither the name of ARM nor the names of its contributors may be used
 * to endorse or promote products derived from this software without specific
 * prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <semihosting.h>

#ifndef SEMIHOSTING_SUPPORTED
#define SEMIHOSTING_SUPPORTED  1
#endif

extern int semihosting_call(unsigned int operation,
			    void *system_block_address);

typedef struct {
	const char *file_name;
	unsigned int mode;
	unsigned int name_length;
} smh_file_open_block;

typedef struct {
	int handle;
	void *buffer;
	unsigned int length;
} smh_file_read_write_block;

typedef struct {
	int handle;
	unsigned int location;
} smh_file_seek_block;

typedef struct {
	char *command_line;
	unsigned int command_length;
} smh_system_block;

int semihosting_connection_supported(void)
{
	return SEMIHOSTING_SUPPORTED;
}

int semihosting_file_open(const char *file_name, unsigned int mode)
{
	smh_file_open_block open_block;

	open_block.file_name = file_name;
	open_block.mode = mode;
	open_block.name_length = strlen(file_name);

	return semihosting_call(SEMIHOSTING_SYS_OPEN,
				(void *) &open_block);
}

int semihosting_file_seek(int file_handle, unsigned int offset)
{
	smh_file_seek_block seek_block;
	int result;

	seek_block.handle = file_handle;
	seek_block.location = offset;

	result = semihosting_call(SEMIHOSTING_SYS_SEEK,
				  (void *) &seek_block);

	if (result)
		result = semihosting_call(SEMIHOSTING_SYS_ERRNO, 0);

	return result;
}

int semihosting_file_read(int file_handle, int *length, void *buffer)
{
	smh_file_read_write_block read_block;
	int result = -EINVAL;

	if ((length == NULL) || (buffer == NULL))
		return result;

	read_block.handle = file_handle;
	read_block.buffer = buffer;
	read_block.length = *length;

	result = semihosting_call(SEMIHOSTING_SYS_READ,
				  (void *) &read_block);

	if (result == *length) {
		return -EINVAL;
	} else if (result < *length) {
		*length -= result;
		return 0;
	} else
		return result;
}

int semihosting_file_write(int file_handle, int *length, void *buffer)
{
	smh_file_read_write_block write_block;

	if ((length == NULL) || (buffer == NULL))
		return -EINVAL;

	write_block.handle = file_handle;
	write_block.buffer = buffer;
	write_block.length = *length;

	*length = semihosting_call(SEMIHOSTING_SYS_WRITE,
				   (void *) &write_block);

	return *length;
}

int semihosting_file_close(int file_handle)
{
	return semihosting_call(SEMIHOSTING_SYS_CLOSE,
				(void *) &file_handle);
}

int semihosting_file_length(int file_handle)
{
	return semihosting_call(SEMIHOSTING_SYS_FLEN,
				(void *) &file_handle);
}

char semihosting_read_char(void)
{
	return semihosting_call(SEMIHOSTING_SYS_READC, NULL);
}

void semihosting_write_char(char character)
{
	semihosting_call(SEMIHOSTING_SYS_WRITEC, (void *) &character);
}

void semihosting_write_string(char *string)
{
	semihosting_call(SEMIHOSTING_SYS_WRITE0, (void *) string);
}

int semihosting_system(char *command_line)
{
	smh_system_block system_block;

	system_block.command_line = command_line;
	system_block.command_length = strlen(command_line);

	return semihosting_call(SEMIHOSTING_SYS_SYSTEM,
				(void *) &system_block);
}

int semihosting_get_flen(const char *file_name)
{
	int file_handle, length;

	assert(semihosting_connection_supported());

	file_handle = semihosting_file_open(file_name, FOPEN_MODE_RB);
	if (file_handle == -1)
		return file_handle;

	/* Find the length of the file */
	length = semihosting_file_length(file_handle);

	return semihosting_file_close(file_handle) ? -1 : length;
}

int semihosting_download_file(const char *file_name,
			      int buf_size,
			      void *buf)
{
	int ret = -EINVAL, file_handle, length;

	/* Null pointer check */
	if (!buf)
		return ret;

	assert(semihosting_connection_supported());

	file_handle = semihosting_file_open(file_name, FOPEN_MODE_RB);
	if (file_handle == -1)
		return ret;

	/* Find the actual length of the file */
	length = semihosting_file_length(file_handle);
	if (length == -1)
		goto semihosting_fail;

	/* Signal error if we do not have enough space for the file */
	if (length > buf_size)
		goto semihosting_fail;

	/*
	 * A successful read will return 0 in which case we pass back
	 * the actual number of bytes read. Else we pass a negative
	 * value indicating an error.
	 */
	ret = semihosting_file_read(file_handle, &length, buf);
	if (ret)
		goto semihosting_fail;
	else
		ret = length;

semihosting_fail:
	semihosting_file_close(file_handle);
	return ret;
}
