// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (C) 2022 Sean Anderson <sean.anderson@seco.com>
 * Copyright 2014 Broadcom Corporation
 */

#include <common.h>
#include <log.h>
#include <semihosting.h>

#define SYSOPEN		0x01
#define SYSCLOSE	0x02
#define SYSWRITEC	0x03
#define SYSWRITE0	0x04
#define SYSWRITE	0x05
#define SYSREAD		0x06
#define SYSREADC	0x07
#define SYSISERROR	0x08
#define SYSSEEK		0x0A
#define SYSFLEN		0x0C
#define SYSERRNO	0x13

#if CONFIG_IS_ENABLED(SEMIHOSTING_FALLBACK)
static bool _semihosting_enabled = true;
static bool try_semihosting = true;

bool semihosting_enabled(void)
{
	if (try_semihosting) {
		smh_trap(SYSERRNO, NULL);
		try_semihosting = false;
	}

	return _semihosting_enabled;
}

void disable_semihosting(void)
{
	_semihosting_enabled = false;
}
#endif

/**
 * smh_errno() - Read the host's errno
 *
 * This gets the value of the host's errno and negates it. The host's errno may
 * or may not be set, so only call this function if a previous semihosting call
 * has failed.
 *
 * Return: a negative error value
 */
static int smh_errno(void)
{
	long ret = smh_trap(SYSERRNO, NULL);

	if (ret > 0 && ret < INT_MAX)
		return -ret;
	return -EIO;
}

long smh_open(const char *fname, enum smh_open_mode mode)
{
	long fd;
	struct smh_open_s {
		const char *fname;
		unsigned long mode;
		size_t len;
	} open;

	debug("%s: file \'%s\', mode \'%u\'\n", __func__, fname, mode);

	open.fname = fname;
	open.len = strlen(fname);
	open.mode = mode;

	/* Open the file on the host */
	fd = smh_trap(SYSOPEN, &open);
	if (fd == -1)
		return smh_errno();
	return fd;
}

/**
 * struct smg_rdwr_s - Arguments for read and write
 * @fd: A file descriptor returned from smh_open()
 * @memp: Pointer to a buffer of memory of at least @len bytes
 * @len: The number of bytes to read or write
 */
struct smh_rdwr_s {
	long fd;
	void *memp;
	size_t len;
};

long smh_read(long fd, void *memp, size_t len)
{
	long ret;
	struct smh_rdwr_s read;

	debug("%s: fd %ld, memp %p, len %zu\n", __func__, fd, memp, len);

	read.fd = fd;
	read.memp = memp;
	read.len = len;

	ret = smh_trap(SYSREAD, &read);
	if (ret < 0)
		return smh_errno();
	return len - ret;
}

long smh_write(long fd, const void *memp, size_t len, ulong *written)
{
	long ret;
	struct smh_rdwr_s write;

	debug("%s: fd %ld, memp %p, len %zu\n", __func__, fd, memp, len);

	write.fd = fd;
	write.memp = (void *)memp;
	write.len = len;

	ret = smh_trap(SYSWRITE, &write);
	*written = len - ret;
	if (ret)
		return smh_errno();
	return 0;
}

long smh_close(long fd)
{
	long ret;

	debug("%s: fd %ld\n", __func__, fd);

	ret = smh_trap(SYSCLOSE, &fd);
	if (ret == -1)
		return smh_errno();
	return 0;
}

long smh_flen(long fd)
{
	long ret;

	debug("%s: fd %ld\n", __func__, fd);

	ret = smh_trap(SYSFLEN, &fd);
	if (ret == -1)
		return smh_errno();
	return ret;
}

long smh_seek(long fd, long pos)
{
	long ret;
	struct smh_seek_s {
		long fd;
		long pos;
	} seek;

	debug("%s: fd %ld pos %ld\n", __func__, fd, pos);

	seek.fd = fd;
	seek.pos = pos;

	ret = smh_trap(SYSSEEK, &seek);
	if (ret)
		return smh_errno();
	return 0;
}

int smh_getc(void)
{
	return smh_trap(SYSREADC, NULL);
}

void smh_putc(char ch)
{
	smh_trap(SYSWRITEC, &ch);
}

void smh_puts(const char *s)
{
	smh_trap(SYSWRITE0, (char *)s);
}
