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

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

#include "glue.h"

#define errf(fmt, args...) do { printf("ERROR @ %s(): ", __func__); printf(fmt, ##args); } while (0)

#define BUF_SZ		2048
#define WAIT_SECS	5

void	test_dump_buf(void *, int);
void	test_dump_di(int);
void	test_dump_si(struct sys_info *);
void	test_dump_sig(struct api_signature *);

static char buf[BUF_SZ];

int main(int argc, char *const argv[])
{
	int rv = 0, h, i, j, devs_no;
	struct api_signature *sig = NULL;
	ulong start, now;
	struct device_info *di;
	lbasize_t rlen;
	struct display_info disinfo;

	if (!api_search_sig(&sig))
		return -1;

	syscall_ptr = sig->syscall;
	if (syscall_ptr == NULL)
		return -2;

	if (sig->version > API_SIG_VERSION)
		return -3;

	printf("API signature found @%p\n", sig);
	test_dump_sig(sig);

	printf("\n*** Consumer API test ***\n");
	printf("syscall ptr 0x%p@%p\n", syscall_ptr, &syscall_ptr);

	/* console activities */
	ub_putc('B');

	printf("*** Press any key to continue ***\n");
	printf("got char 0x%x\n", ub_getc());

	/* system info */
	test_dump_si(ub_get_sys_info());

	/* timing */
	printf("\n*** Timing - wait a couple of secs ***\n");
	start = ub_get_timer(0);
	printf("\ntime: start %lu\n\n", start);
	for (i = 0; i < WAIT_SECS; i++)
		for (j = 0; j < 1000; j++)
			ub_udelay(1000);	/* wait 1 ms */

	/* this is the number of milliseconds that passed from ub_get_timer(0) */
	now = ub_get_timer(start);
	printf("\ntime: now %lu\n\n", now);

	/* enumerate devices */
	printf("\n*** Enumerate devices ***\n");
	devs_no = ub_dev_enum();

	printf("Number of devices found: %d\n", devs_no);
	if (devs_no == 0)
		return -1;

	printf("\n*** Show devices ***\n");
	for (i = 0; i < devs_no; i++) {
		test_dump_di(i);
		printf("\n");
	}

	printf("\n*** Operations on devices ***\n");

	/* test opening a device already opened */
	h = 0;
	if ((rv = ub_dev_open(h)) != 0) {
		errf("open device %d error %d\n", h, rv);
		return -1;
	}
	if ((rv = ub_dev_open(h)) != 0)
		errf("open device %d error %d\n", h, rv);

	ub_dev_close(h);

	/* test storage */
	printf("Trying storage devices...\n");
	for (i = 0; i < devs_no; i++) {
		di = ub_dev_get(i);

		if (di->type & DEV_TYP_STOR)
			break;

	}
	if (i == devs_no)
		printf("No storage devices available\n");
	else {
		memset(buf, 0, BUF_SZ);

		if ((rv = ub_dev_open(i)) != 0)
			errf("open device %d error %d\n", i, rv);

		else if ((rv = ub_dev_read(i, buf, 1, 0, &rlen)) != 0)
			errf("could not read from device %d, error %d\n", i, rv);
		else {
			printf("Sector 0 dump (512B):\n");
			test_dump_buf(buf, 512);
		}

		ub_dev_close(i);
	}

	/* test networking */
	printf("Trying network devices...\n");
	for (i = 0; i < devs_no; i++) {
		di = ub_dev_get(i);

		if (di->type == DEV_TYP_NET)
			break;

	}
	if (i == devs_no)
		printf("No network devices available\n");
	else {
		if ((rv = ub_dev_open(i)) != 0)
			errf("open device %d error %d\n", i, rv);
		else if ((rv = ub_dev_send(i, &buf, 2048)) != 0)
			errf("could not send to device %d, error %d\n", i, rv);

		ub_dev_close(i);
	}

	if (ub_dev_close(h) != 0)
		errf("could not close device %d\n", h);

	printf("\n*** Env vars ***\n");

	printf("ethact = %s\n", ub_env_get("ethact"));
	printf("old fileaddr = %s\n", ub_env_get("fileaddr"));
	ub_env_set("fileaddr", "deadbeef");
	printf("new fileaddr = %s\n", ub_env_get("fileaddr"));

	const char *env = NULL;

	while ((env = ub_env_enum(env)) != NULL)
		printf("%s = %s\n", env, ub_env_get(env));

	printf("\n*** Display ***\n");

	if (ub_display_get_info(DISPLAY_TYPE_LCD, &disinfo)) {
		printf("LCD info: failed\n");
	} else {
		printf("LCD info:\n");
		printf("  pixel width:  %d\n", disinfo.pixel_width);
		printf("  pixel height: %d\n", disinfo.pixel_height);
		printf("  screen rows:  %d\n", disinfo.screen_rows);
		printf("  screen cols:  %d\n", disinfo.screen_cols);
	}
	if (ub_display_get_info(DISPLAY_TYPE_VIDEO, &disinfo)) {
		printf("video info: failed\n");
	} else {
		printf("video info:\n");
		printf("  pixel width:  %d\n", disinfo.pixel_width);
		printf("  pixel height: %d\n", disinfo.pixel_height);
		printf("  screen rows:  %d\n", disinfo.screen_rows);
		printf("  screen cols:  %d\n", disinfo.screen_cols);
	}

	printf("*** Press any key to continue ***\n");
	printf("got char 0x%x\n", ub_getc());

	/*
	 * This only clears messages on screen, not on serial port. It is
	 * equivalent to a no-op if no display is available.
	 */
	ub_display_clear();

	/* reset */
	printf("\n*** Resetting board ***\n");
	ub_reset();
	printf("\nHmm, reset returned...?!\n");

	return rv;
}

void test_dump_sig(struct api_signature *sig)
{
	printf("signature:\n");
	printf("  version\t= %d\n", sig->version);
	printf("  checksum\t= 0x%08x\n", sig->checksum);
	printf("  sc entry\t= 0x%p\n", sig->syscall);
}

void test_dump_si(struct sys_info *si)
{
	int i;

	printf("sys info:\n");
	printf("  clkbus\t= 0x%08x\n", (unsigned int)si->clk_bus);
	printf("  clkcpu\t= 0x%08x\n", (unsigned int)si->clk_cpu);
	printf("  bar\t\t= 0x%08x\n", (unsigned int)si->bar);

	printf("---\n");
	for (i = 0; i < si->mr_no; i++) {
		if (si->mr[i].flags == 0)
			break;

		printf("  start\t= 0x%08lx\n", si->mr[i].start);
		printf("  size\t= 0x%08lx\n", si->mr[i].size);

		switch(si->mr[i].flags & 0x000F) {
			case MR_ATTR_FLASH:
				printf("  type FLASH\n");
				break;
			case MR_ATTR_DRAM:
				printf("  type DRAM\n");
				break;
			case MR_ATTR_SRAM:
				printf("  type SRAM\n");
				break;
			default:
				printf("  type UNKNOWN\n");
		}
		printf("---\n");
	}
}

static char *test_stor_typ(int type)
{
	if (type & DT_STOR_IDE)
		return "IDE";

	if (type & DT_STOR_MMC)
		return "MMC";

	if (type & DT_STOR_SATA)
		return "SATA";

	if (type & DT_STOR_SCSI)
		return "SCSI";

	if (type & DT_STOR_USB)
		return "USB";

	return "Unknown";
}

void test_dump_buf(void *buf, int len)
{
	int i;
	int line_counter = 0;
	int sep_flag = 0;
	int addr = 0;

	printf("%07x:\t", addr);

	for (i = 0; i < len; i++) {
		if (line_counter++ > 15) {
			line_counter = 0;
			sep_flag = 0;
			addr += 16;
			i--;
			printf("\n%07x:\t", addr);
			continue;
		}

		if (sep_flag++ > 1) {
			sep_flag = 1;
			printf(" ");
		}

		printf("%02x", *((char *)buf++));
	}

	printf("\n");
}

void test_dump_di(int handle)
{
	int i;
	struct device_info *di = ub_dev_get(handle);

	printf("device info (%d):\n", handle);
	printf("  cookie\t= 0x%p\n", di->cookie);
	printf("  type\t\t= 0x%08x\n", di->type);

	if (di->type == DEV_TYP_NET) {
		printf("  hwaddr\t= ");
		for (i = 0; i < 6; i++)
			printf("%02x ", di->di_net.hwaddr[i]);

		printf("\n");

	} else if (di->type & DEV_TYP_STOR) {
		printf("  type\t\t= %s\n", test_stor_typ(di->type));
		printf("  blk size\t\t= %d\n", (unsigned int)di->di_stor.block_size);
		printf("  blk count\t\t= %d\n", (unsigned int)di->di_stor.block_count);
	}
}
