// SPDX-License-Identifier: GPL-2.0+
/*
 * (C) Copyright 2007-2008 Semihalf, Rafal Jaworowski <raj@semihalf.com>
 */

#include <common.h>
#include <env.h>
#include <linux/types.h>
#include <api_public.h>

#include "glue.h"

static int valid_sig(struct api_signature *sig)
{
	uint32_t checksum;
	struct api_signature s;

	if (sig == NULL)
		return 0;
	/*
	 * Clear the checksum field (in the local copy) so as to calculate the
	 * CRC with the same initial contents as at the time when the sig was
	 * produced
	 */
	s = *sig;
	s.checksum = 0;

	checksum = crc32(0, (unsigned char *)&s, sizeof(struct api_signature));

	if (checksum != sig->checksum)
		return 0;

	return 1;
}

/*
 * Searches for the U-Boot API signature
 *
 * returns 1/0 depending on found/not found result
 */
int api_search_sig(struct api_signature **sig)
{
	unsigned char *sp;
	uint32_t search_start = 0;
	uint32_t search_end = 0;

	if (sig == NULL)
		return 0;

	if (search_hint == 0)
		search_hint = 255 * 1024 * 1024;

	search_start = search_hint & ~0x000fffff;
	search_end = search_start + API_SEARCH_LEN - API_SIG_MAGLEN;

	sp = (unsigned char *)search_start;
	while ((sp + API_SIG_MAGLEN) < (unsigned char *)search_end) {
		if (!memcmp(sp, API_SIG_MAGIC, API_SIG_MAGLEN)) {
			*sig = (struct api_signature *)sp;
			if (valid_sig(*sig))
				return 1;
		}
		sp += API_SIG_MAGLEN;
	}

	*sig = NULL;
	return 0;
}

/****************************************
 *
 * console
 *
 ****************************************/

int ub_getc(void)
{
	int c;

	if (!syscall(API_GETC, NULL, &c))
		return -1;

	return c;
}

int ub_tstc(void)
{
	int t;

	if (!syscall(API_TSTC, NULL, &t))
		return -1;

	return t;
}

void ub_putc(char c)
{
	syscall(API_PUTC, NULL, &c);
}

void ub_puts(const char *s)
{
	syscall(API_PUTS, NULL, s);
}

/****************************************
 *
 * system
 *
 ****************************************/

void ub_reset(void)
{
	syscall(API_RESET, NULL);
}

static struct mem_region mr[UB_MAX_MR];
static struct sys_info si;

struct sys_info * ub_get_sys_info(void)
{
	int err = 0;

	memset(&si, 0, sizeof(struct sys_info));
	si.mr = mr;
	si.mr_no = UB_MAX_MR;
	memset(&mr, 0, sizeof(mr));

	if (!syscall(API_GET_SYS_INFO, &err, &si))
		return NULL;

	return ((err) ? NULL : &si);
}

/****************************************
 *
 * timing
 *
 ****************************************/

void ub_udelay(unsigned long usec)
{
	syscall(API_UDELAY, NULL, &usec);
}

unsigned long ub_get_timer(unsigned long base)
{
	unsigned long cur;

	if (!syscall(API_GET_TIMER, NULL, &cur, &base))
		return 0;

	return cur;
}


/****************************************************************************
 *
 * devices
 *
 * Devices are identified by handles: numbers 0, 1, 2, ..., UB_MAX_DEV-1
 *
 ***************************************************************************/

static struct device_info devices[UB_MAX_DEV];

struct device_info * ub_dev_get(int i)
{
	return ((i < 0 || i >= UB_MAX_DEV) ? NULL : &devices[i]);
}

/*
 * Enumerates the devices: fills out device_info elements in the devices[]
 * array.
 *
 * returns:		number of devices found
 */
int ub_dev_enum(void)
{
	struct device_info *di;
	int n = 0;

	memset(&devices, 0, sizeof(struct device_info) * UB_MAX_DEV);
	di = &devices[0];

	if (!syscall(API_DEV_ENUM, NULL, di))
		return 0;

	while (di->cookie != NULL) {

		if (++n >= UB_MAX_DEV)
			break;

		/* take another device_info */
		di++;

		/* pass on the previous cookie */
		di->cookie = devices[n - 1].cookie;

		if (!syscall(API_DEV_ENUM, NULL, di))
			return 0;
	}

	return n;
}

/*
 * handle:	0-based id of the device
 *
 * returns:	0 when OK, err otherwise
 */
int ub_dev_open(int handle)
{
	struct device_info *di;
	int err = 0;

	if (handle < 0 || handle >= UB_MAX_DEV)
		return API_EINVAL;

	di = &devices[handle];

	if (!syscall(API_DEV_OPEN, &err, di))
		return -1;

	return err;
}

int ub_dev_close(int handle)
{
	struct device_info *di;

	if (handle < 0 || handle >= UB_MAX_DEV)
		return API_EINVAL;

	di = &devices[handle];
	if (!syscall(API_DEV_CLOSE, NULL, di))
		return -1;

	return 0;
}

/*
 *
 * Validates device for read/write, it has to:
 *
 * - have sane handle
 * - be opened
 *
 * returns:	0/1 accordingly
 */
static int dev_valid(int handle)
{
	if (handle < 0 || handle >= UB_MAX_DEV)
		return 0;

	if (devices[handle].state != DEV_STA_OPEN)
		return 0;

	return 1;
}

static int dev_stor_valid(int handle)
{
	if (!dev_valid(handle))
		return 0;

	if (!(devices[handle].type & DEV_TYP_STOR))
		return 0;

	return 1;
}

int ub_dev_read(int handle, void *buf, lbasize_t len, lbastart_t start,
		lbasize_t *rlen)
{
	struct device_info *di;
	lbasize_t act_len;
	int err = 0;

	if (!dev_stor_valid(handle))
		return API_ENODEV;

	di = &devices[handle];
	if (!syscall(API_DEV_READ, &err, di, buf, &len, &start, &act_len))
		return API_ESYSC;

	if (!err && rlen)
		*rlen = act_len;

	return err;
}

static int dev_net_valid(int handle)
{
	if (!dev_valid(handle))
		return 0;

	if (devices[handle].type != DEV_TYP_NET)
		return 0;

	return 1;
}

int ub_dev_recv(int handle, void *buf, int len, int *rlen)
{
	struct device_info *di;
	int err = 0, act_len;

	if (!dev_net_valid(handle))
		return API_ENODEV;

	di = &devices[handle];
	if (!syscall(API_DEV_READ, &err, di, buf, &len, &act_len))
		return API_ESYSC;

	if (!err && rlen)
		*rlen = act_len;

	 return (err);
}

int ub_dev_send(int handle, void *buf, int len)
{
	struct device_info *di;
	int err = 0;

	if (!dev_net_valid(handle))
		return API_ENODEV;

	di = &devices[handle];
	if (!syscall(API_DEV_WRITE, &err, di, buf, &len))
		return API_ESYSC;

	return err;
}

/****************************************
 *
 * env vars
 *
 ****************************************/

char * ub_env_get(const char *name)
{
	char *value;

	if (!syscall(API_ENV_GET, NULL, name, &value))
		return NULL;

	return value;
}

void ub_env_set(const char *name, char *value)
{
	syscall(API_ENV_SET, NULL, name, value);
}

static char env_name[256];

const char * ub_env_enum(const char *last)
{
	const char *env, *str;
	int i;

	env = NULL;

	/*
	 * It's OK to pass only the name piece as last (and not the whole
	 * 'name=val' string), since the API_ENUM_ENV call uses env_match()
	 * internally, which handles such case
	 */
	if (!syscall(API_ENV_ENUM, NULL, last, &env))
		return NULL;

	if (!env)
		/* no more env. variables to enumerate */
		return NULL;

	/* next enumerated env var */
	memset(env_name, 0, 256);
	for (i = 0, str = env; *str != '=' && *str != '\0';)
		env_name[i++] = *str++;

	env_name[i] = '\0';

	return env_name;
}

/****************************************
 *
 * display
 *
 ****************************************/

int ub_display_get_info(int type, struct display_info *di)
{
	int err = 0;

	if (!syscall(API_DISPLAY_GET_INFO, &err, type, di))
		return API_ESYSC;

	return err;
}

int ub_display_draw_bitmap(ulong bitmap, int x, int y)
{
	int err = 0;

	if (!syscall(API_DISPLAY_DRAW_BITMAP, &err, bitmap, x, y))
		return API_ESYSC;

	return err;
}

void ub_display_clear(void)
{
	syscall(API_DISPLAY_CLEAR, NULL);
}

__weak void *memcpy(void *dest, const void *src, size_t size)
{
	unsigned char *dptr = dest;
	const unsigned char *ptr = src;
	const unsigned char *end = src + size;

	while (ptr < end)
		*dptr++ = *ptr++;

	return dest;
}
