/*
 * PCI emulation device which swaps the case of text
 *
 * Copyright (c) 2014 Google, Inc
 * Written by Simon Glass <sjg@chromium.org>
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <common.h>
#include <dm.h>
#include <pci.h>
#include <asm/test.h>
#include <linux/ctype.h>

/**
 * struct swap_case_platdata - platform data for this device
 *
 * @command:	Current PCI command value
 * @bar:	Current base address values
 */
struct swap_case_platdata {
	u16 command;
	u32 bar[2];
};

#define offset_to_barnum(offset)	\
		(((offset) - PCI_BASE_ADDRESS_0) / sizeof(u32))

enum {
	MEM_TEXT_SIZE	= 0x100,
};

enum swap_case_op {
	OP_TO_LOWER,
	OP_TO_UPPER,
	OP_SWAP,
};

static struct pci_bar {
	int type;
	u32 size;
} barinfo[] = {
	{ PCI_BASE_ADDRESS_SPACE_IO, 1 },
	{ PCI_BASE_ADDRESS_MEM_TYPE_32, MEM_TEXT_SIZE },
	{ 0, 0 },
	{ 0, 0 },
	{ 0, 0 },
	{ 0, 0 },
};

struct swap_case_priv {
	enum swap_case_op op;
	char mem_text[MEM_TEXT_SIZE];
};

static int sandbox_swap_case_get_devfn(struct udevice *dev)
{
	struct pci_child_platdata *plat = dev_get_parent_platdata(dev);

	return plat->devfn;
}

static int sandbox_swap_case_read_config(struct udevice *emul, uint offset,
					 ulong *valuep, enum pci_size_t size)
{
	struct swap_case_platdata *plat = dev_get_platdata(emul);

	switch (offset) {
	case PCI_COMMAND:
		*valuep = plat->command;
		break;
	case PCI_HEADER_TYPE:
		*valuep = 0;
		break;
	case PCI_VENDOR_ID:
		*valuep = SANDBOX_PCI_VENDOR_ID;
		break;
	case PCI_DEVICE_ID:
		*valuep = SANDBOX_PCI_DEVICE_ID;
		break;
	case PCI_CLASS_DEVICE:
		if (size == PCI_SIZE_8) {
			*valuep = SANDBOX_PCI_CLASS_SUB_CODE;
		} else {
			*valuep = (SANDBOX_PCI_CLASS_CODE << 8) |
					SANDBOX_PCI_CLASS_SUB_CODE;
		}
		break;
	case PCI_CLASS_CODE:
		*valuep = SANDBOX_PCI_CLASS_CODE;
		break;
	case PCI_BASE_ADDRESS_0:
	case PCI_BASE_ADDRESS_1:
	case PCI_BASE_ADDRESS_2:
	case PCI_BASE_ADDRESS_3:
	case PCI_BASE_ADDRESS_4:
	case PCI_BASE_ADDRESS_5: {
		int barnum;
		u32 *bar, result;

		barnum = offset_to_barnum(offset);
		bar = &plat->bar[barnum];

		result = *bar;
		if (*bar == 0xffffffff) {
			if (barinfo[barnum].type) {
				result = (~(barinfo[barnum].size - 1) &
					PCI_BASE_ADDRESS_IO_MASK) |
					PCI_BASE_ADDRESS_SPACE_IO;
			} else {
				result = (~(barinfo[barnum].size - 1) &
					PCI_BASE_ADDRESS_MEM_MASK) |
					PCI_BASE_ADDRESS_MEM_TYPE_32;
			}
		}
		debug("r bar %d=%x\n", barnum, result);
		*valuep = result;
		break;
	}
	}

	return 0;
}

static int sandbox_swap_case_write_config(struct udevice *emul, uint offset,
					  ulong value, enum pci_size_t size)
{
	struct swap_case_platdata *plat = dev_get_platdata(emul);

	switch (offset) {
	case PCI_COMMAND:
		plat->command = value;
		break;
	case PCI_BASE_ADDRESS_0:
	case PCI_BASE_ADDRESS_1: {
		int barnum;
		u32 *bar;

		barnum = offset_to_barnum(offset);
		bar = &plat->bar[barnum];

		debug("w bar %d=%lx\n", barnum, value);
		*bar = value;
		break;
	}
	}

	return 0;
}

static int sandbox_swap_case_find_bar(struct udevice *emul, unsigned int addr,
				      int *barnump, unsigned int *offsetp)
{
	struct swap_case_platdata *plat = dev_get_platdata(emul);
	int barnum;

	for (barnum = 0; barnum < ARRAY_SIZE(barinfo); barnum++) {
		unsigned int size = barinfo[barnum].size;

		if (addr >= plat->bar[barnum] &&
		    addr < plat->bar[barnum] + size) {
			*barnump = barnum;
			*offsetp = addr - plat->bar[barnum];
			return 0;
		}
	}
	*barnump = -1;

	return -ENOENT;
}

static void sandbox_swap_case_do_op(enum swap_case_op op, char *str, int len)
{
	for (; len > 0; len--, str++) {
		switch (op) {
		case OP_TO_UPPER:
			*str = toupper(*str);
			break;
		case OP_TO_LOWER:
			*str = tolower(*str);
			break;
		case OP_SWAP:
			if (isupper(*str))
				*str = tolower(*str);
			else
				*str = toupper(*str);
			break;
		}
	}
}

int sandbox_swap_case_read_io(struct udevice *dev, unsigned int addr,
			      ulong *valuep, enum pci_size_t size)
{
	struct swap_case_priv *priv = dev_get_priv(dev);
	unsigned int offset;
	int barnum;
	int ret;

	ret = sandbox_swap_case_find_bar(dev, addr, &barnum, &offset);
	if (ret)
		return ret;

	if (barnum == 0 && offset == 0)
		*valuep = (*valuep & ~0xff) | priv->op;

	return 0;
}

int sandbox_swap_case_write_io(struct udevice *dev, unsigned int addr,
			       ulong value, enum pci_size_t size)
{
	struct swap_case_priv *priv = dev_get_priv(dev);
	unsigned int offset;
	int barnum;
	int ret;

	ret = sandbox_swap_case_find_bar(dev, addr, &barnum, &offset);
	if (ret)
		return ret;
	if (barnum == 0 && offset == 0)
		priv->op = value;

	return 0;
}

static int sandbox_swap_case_map_physmem(struct udevice *dev,
		phys_addr_t addr, unsigned long *lenp, void **ptrp)
{
	struct swap_case_priv *priv = dev_get_priv(dev);
	unsigned int offset, avail;
	int barnum;
	int ret;

	ret = sandbox_swap_case_find_bar(dev, addr, &barnum, &offset);
	if (ret)
		return ret;
	if (barnum == 1) {
		*ptrp = priv->mem_text + offset;
		avail = barinfo[1].size - offset;
		if (avail > barinfo[1].size)
			*lenp = 0;
		else
			*lenp = min(*lenp, (ulong)avail);

		return 0;
	}

	return -ENOENT;
}

static int sandbox_swap_case_unmap_physmem(struct udevice *dev,
					   const void *vaddr, unsigned long len)
{
	struct swap_case_priv *priv = dev_get_priv(dev);

	sandbox_swap_case_do_op(priv->op, (void *)vaddr, len);

	return 0;
}

struct dm_pci_emul_ops sandbox_swap_case_emul_ops = {
	.get_devfn = sandbox_swap_case_get_devfn,
	.read_config = sandbox_swap_case_read_config,
	.write_config = sandbox_swap_case_write_config,
	.read_io = sandbox_swap_case_read_io,
	.write_io = sandbox_swap_case_write_io,
	.map_physmem = sandbox_swap_case_map_physmem,
	.unmap_physmem = sandbox_swap_case_unmap_physmem,
};

static const struct udevice_id sandbox_swap_case_ids[] = {
	{ .compatible = "sandbox,swap-case" },
	{ }
};

U_BOOT_DRIVER(sandbox_swap_case_emul) = {
	.name		= "sandbox_swap_case_emul",
	.id		= UCLASS_PCI_EMUL,
	.of_match	= sandbox_swap_case_ids,
	.ops		= &sandbox_swap_case_emul_ops,
	.priv_auto_alloc_size = sizeof(struct swap_case_priv),
	.platdata_auto_alloc_size = sizeof(struct swap_case_platdata),
};
