/*
 * This file is part of the coreboot project.
 *
 * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering
 * Copyright (C) 2007 Advanced Micro Devices, Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 2 of the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */


#define RES_DEBUG 0

static void setup_resource_map(const u32 *register_values, u32 max)
{
	u32 i;
//	printk(BIOS_DEBUG, "setting up resource map....");

	for(i = 0; i < max; i += 3) {
		device_t dev;
		u32 where;
		u32 reg;

		dev = register_values[i] & ~0xff;
		where = register_values[i] & 0xff;
		reg = pci_read_config32(dev, where);
		reg &= register_values[i+1];
		reg |= register_values[i+2];
		pci_write_config32(dev, where, reg);
	}
//	printk(BIOS_DEBUG, "done.\n");
}


void setup_resource_map_offset(const u32 *register_values, u32 max, u32 offset_pci_dev, u32 offset_io_base)
{
	u32 i;
//	printk(BIOS_DEBUG, "setting up resource map offset....");
	for(i = 0; i < max; i += 3) {
		device_t dev;
		u32 where;
		unsigned long reg;
		dev = (register_values[i] & ~0xfff) + offset_pci_dev;
		where = register_values[i] & 0xfff;
		reg = pci_read_config32(dev, where);
		reg &= register_values[i+1];
		reg |= register_values[i+2] + offset_io_base;
		pci_write_config32(dev, where, reg);
	}
//	printk(BIOS_DEBUG, "done.\n");
}

#define RES_PCI_IO 0x10
#define RES_PORT_IO_8 0x22
#define RES_PORT_IO_32 0x20
#define RES_MEM_IO 0x40

void setup_resource_map_x_offset(const u32 *register_values, u32 max, u32 offset_pci_dev, u32 offset_io_base)
{
	u32 i;

	if (IS_ENABLED(RES_DEBUG))
		printk(BIOS_DEBUG, "setting up resource map ex offset....\n");

	for(i = 0; i < max; i += 4) {
		if (IS_ENABLED(RES_DEBUG))
			printk(BIOS_DEBUG, "%04x: %02x %08x <- & %08x | %08x\n",
				i/4, register_values[i],
				register_values[i+1] + ( (register_values[i]==RES_PCI_IO) ? offset_pci_dev : 0),
				register_values[i+2],
				register_values[i+3] + ( ( (register_values[i] & RES_PORT_IO_32) == RES_PORT_IO_32) ? offset_io_base : 0)
				);
		switch (register_values[i]) {
		case RES_PCI_IO: //PCI
			{
			device_t dev;
			u32 where;
			u32 reg;
			dev = (register_values[i+1] & ~0xfff) + offset_pci_dev;
			where = register_values[i+1] & 0xfff;
			reg = pci_read_config32(dev, where);
			if (IS_ENABLED(RES_DEBUG))
				printk(BIOS_SPEW, "WAS: %08x\n", reg);
			reg &= register_values[i+2];
			reg |= register_values[i+3];
			pci_write_config32(dev, where, reg);
			if (IS_ENABLED(RES_DEBUG))
				printk(BIOS_SPEW, "NOW: %08x\n", reg);
			}
			break;
		case RES_PORT_IO_8: // io 8
			{
			u32 where;
			u32 reg;
			where = register_values[i+1] + offset_io_base;
			reg = inb(where);
			if (IS_ENABLED(RES_DEBUG))
				printk(BIOS_SPEW, "WAS: %08x\n", reg);
			reg &= register_values[i+2];
			reg |= register_values[i+3];
			outb(reg, where);
			if (IS_ENABLED(RES_DEBUG))
				printk(BIOS_SPEW, "NOW: %08x\n", reg);
			}
			break;
		case RES_PORT_IO_32:  //io32
			{
			u32 where;
			u32 reg;
			where = register_values[i+1] + offset_io_base;
			reg = inl(where);
			if (IS_ENABLED(RES_DEBUG))
				printk(BIOS_SPEW, "WAS: %08x\n", reg);
			reg &= register_values[i+2];
			reg |= register_values[i+3];
			outl(reg, where);
			if (IS_ENABLED(RES_DEBUG))
				printk(BIOS_SPEW, "NOW: %08x\n", reg);
			}
			break;
		} // switch


	}

	if (IS_ENABLED(RES_DEBUG))
		printk(BIOS_DEBUG, "done.\n");
}

void setup_resource_map_x(const u32 *register_values, u32 max)
{
	u32 i;

	if (IS_ENABLED(RES_DEBUG))
		printk(BIOS_DEBUG, "setting up resource map ex offset....\n");

	for(i = 0; i < max; i += 4) {
		if (IS_ENABLED(RES_DEBUG))
			printk(BIOS_DEBUG, "%04x: %02x %08x <- & %08x | %08x\n",
				i/4, register_values[i],register_values[i+1], register_values[i+2], register_values[i+3]);
		switch (register_values[i]) {
		case RES_PCI_IO: //PCI
			{
			device_t dev;
			u32 where;
			u32 reg;
			dev = register_values[i+1] & ~0xff;
			where = register_values[i+1] & 0xff;
			reg = pci_read_config32(dev, where);
			reg &= register_values[i+2];
			reg |= register_values[i+3];
			pci_write_config32(dev, where, reg);
			}
			break;
		case RES_PORT_IO_8: // io 8
			{
			u32 where;
			u32 reg;
			where = register_values[i+1];
			reg = inb(where);
			reg &= register_values[i+2];
			reg |= register_values[i+3];
			outb(reg, where);
			}
			break;
		case RES_PORT_IO_32:  //io32
			{
			u32 where;
			u32 reg;
			where = register_values[i+1];
			reg = inl(where);
			reg &= register_values[i+2];
			reg |= register_values[i+3];
			outl(reg, where);
			}
			break;
		} // switch


	}

	if (IS_ENABLED(RES_DEBUG))
		printk(BIOS_DEBUG, "done.\n");
}

#if 0
static void setup_iob_resource_map(const u32 *register_values, u32 max)
{
	u32 i;

	for(i = 0; i < max; i += 3) {
		u32 where;
		u32 reg;

		where = register_values[i];
		reg = inb(where);
		reg &= register_values[i+1];
		reg |= register_values[i+2];
		outb(reg, where);
	}
}

static void setup_io_resource_map(const u32 *register_values, u32 max)
{
	u32 i;

	for(i = 0; i < max; i += 3) {
		u32 where;
		u32 reg;

		where = register_values[i];
		reg = inl(where);
		reg &= register_values[i+1];
		reg |= register_values[i+2];

		outl(reg, where);
	}
}
#endif
