/*
 * This file is part of the flashrom project.
 *
 * Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
 * Copyright (C) 2010, 2011 Carl-Daniel Hailfinger
 *
 * 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; either version 2 of the License, or
 * (at your option) any later version.
 *
 * 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.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
 */

#include <stdlib.h>
#include <string.h>
#include "flash.h"
#include "programmer.h"

uint32_t io_base_addr;
struct pci_access *pacc;
struct pci_dev *pcidev_dev = NULL;

enum pci_bartype {
	TYPE_MEMBAR,
	TYPE_IOBAR,
	TYPE_ROMBAR,
	TYPE_UNKNOWN
};

uintptr_t pcidev_validate(struct pci_dev *dev, int bar,
			 const struct pcidev_status *devs)
{
	int i;
	uint64_t addr;
	uint32_t upperaddr;
	uint8_t headertype;
	uint16_t supported_cycles;
	enum pci_bartype bartype = TYPE_UNKNOWN;

	for (i = 0; devs[i].device_name != NULL; i++) {
		if (dev->device_id != devs[i].device_id)
			continue;

		msg_pinfo("Found \"%s %s\" (%04x:%04x, BDF %02x:%02x.%x).\n",
		       devs[i].vendor_name, devs[i].device_name,
		       dev->vendor_id, dev->device_id, dev->bus, dev->dev,
		       dev->func);

		headertype = pci_read_byte(dev, PCI_HEADER_TYPE) & 0x7f;
		msg_pspew("PCI header type 0x%02x\n", headertype);

		/*
		 * Don't use dev->base_addr[x] (as value for 'bar'), won't
		 * work on older libpci.
		 */
		addr = pci_read_long(dev, bar);

		/* Sanity checks. */
		switch (headertype) {
		case PCI_HEADER_TYPE_NORMAL:
			switch (bar) {
			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:
				if ((addr & PCI_BASE_ADDRESS_SPACE) ==
				    PCI_BASE_ADDRESS_SPACE_IO)
					bartype = TYPE_IOBAR;
				else
					bartype = TYPE_MEMBAR;
				break;
			case PCI_ROM_ADDRESS:
				bartype = TYPE_ROMBAR;
				break;
			}
			break;
		case PCI_HEADER_TYPE_BRIDGE:
			switch (bar) {
			case PCI_BASE_ADDRESS_0:
			case PCI_BASE_ADDRESS_1:
				if ((addr & PCI_BASE_ADDRESS_SPACE) ==
				    PCI_BASE_ADDRESS_SPACE_IO)
					bartype = TYPE_IOBAR;
				else
					bartype = TYPE_MEMBAR;
				break;
			case PCI_ROM_ADDRESS1:
				bartype = TYPE_ROMBAR;
				break;
			}
			break;
		case PCI_HEADER_TYPE_CARDBUS:
			break;
		default:
			msg_perr("Unknown PCI header type 0x%02x, BAR type "
				 "cannot be determined reliably.\n", headertype);
			break;
		}

		supported_cycles = pci_read_word(dev, PCI_COMMAND);

		msg_pdbg("Requested BAR is ");
		switch (bartype) {
		case TYPE_MEMBAR:
			msg_pdbg("MEM");
			if (!(supported_cycles & PCI_COMMAND_MEMORY)) {
				msg_perr("MEM BAR access requested, but device "
					 "has MEM space accesses disabled.\n");
				/* TODO: Abort here? */
			}
			msg_pdbg(", %sbit, %sprefetchable\n",
				 ((addr & 0x6) == 0x0) ? "32" :
				 (((addr & 0x6) == 0x4) ? "64" : "reserved"),
				 (addr & 0x8) ? "" : "not ");
			if ((addr & 0x6) == 0x4) {
				/* The spec says that a 64-bit register consumes
				 * two subsequent dword locations.
				 */
				upperaddr = pci_read_long(dev, bar + 4);
				if (upperaddr != 0x00000000) {
					/* Fun! A real 64-bit resource. */
					if (sizeof(uintptr_t) != sizeof(uint64_t)) {
						msg_perr("BAR unreachable!");
						/* TODO: Really abort here? If
						 * multiple PCI devices match,
						 * we might never tell the user
						 * about the other devices.
						 */
						return 0;
					}
					addr |= (uint64_t)upperaddr << 32;
				}
			}
			addr &= PCI_BASE_ADDRESS_MEM_MASK;
			break;
		case TYPE_IOBAR:
			msg_pdbg("I/O\n");
#if __FLASHROM_HAVE_OUTB__
			if (!(supported_cycles & PCI_COMMAND_IO)) {
				msg_perr("I/O BAR access requested, but device "
					 "has I/O space accesses disabled.\n");
				/* TODO: Abort here? */
			}
#else
			msg_perr("I/O BAR access requested, but flashrom does "
				 "not support I/O BAR access on this platform "
				 "(yet).\n");
#endif
			addr &= PCI_BASE_ADDRESS_IO_MASK;
			break;
		case TYPE_ROMBAR:
			msg_pdbg("ROM\n");
			/* Not sure if this check is needed. */
			if (!(supported_cycles & PCI_COMMAND_MEMORY)) {
				msg_perr("MEM BAR access requested, but device "
					 "has MEM space accesses disabled.\n");
				/* TODO: Abort here? */
			}
			addr &= PCI_ROM_ADDRESS_MASK;
			break;
		case TYPE_UNKNOWN:
			msg_perr("BAR type unknown, please report a bug at "
				 "flashrom@flashrom.org\n");
		}
		
		if (devs[i].status == NT) {
			msg_pinfo("===\nThis PCI device is UNTESTED. Please "
				  "report the 'flashrom -p xxxx' output \n"
				  "to flashrom@flashrom.org if it works "
				  "for you. Please add the name of your\n"
				  "PCI device to the subject. Thank you for "
				  "your help!\n===\n");
		}

		return (uintptr_t)addr;
	}

	return 0;
}

uintptr_t pcidev_init(uint16_t vendor_id, int bar,
		     const struct pcidev_status *devs)
{
	struct pci_dev *dev;
	struct pci_filter filter;
	char *pcidev_bdf;
	char *msg = NULL;
	int found = 0;
	uintptr_t addr = 0, curaddr = 0;

	pacc = pci_alloc();     /* Get the pci_access structure */
	pci_init(pacc);         /* Initialize the PCI library */
	pci_scan_bus(pacc);     /* We want to get the list of devices */
	pci_filter_init(pacc, &filter);

	/* Filter by vendor and also bb:dd.f (if supplied by the user). */
	filter.vendor = vendor_id;
	pcidev_bdf = extract_programmer_param("pci");
	if (pcidev_bdf != NULL) {
		if ((msg = pci_filter_parse_slot(&filter, pcidev_bdf))) {
			msg_perr("Error: %s\n", msg);
			exit(1);
		}
	}
	free(pcidev_bdf);

	for (dev = pacc->devices; dev; dev = dev->next) {
		if (pci_filter_match(&filter, dev)) {
			if ((addr = pcidev_validate(dev, bar, devs)) != 0) {
				curaddr = addr;
				pcidev_dev = dev;
				found++;
			}
		}
	}

	/* Only continue if exactly one supported PCI dev has been found. */
	if (found == 0) {
		msg_perr("Error: No supported PCI device found.\n");
		exit(1);
	} else if (found > 1) {
		msg_perr("Error: Multiple supported PCI devices found. "
			"Use 'flashrom -p xxxx:pci=bb:dd.f' \n"
			"to explicitly select the card with the given BDF "
			"(PCI bus, device, function).\n");
		exit(1);
	}

	return curaddr;
}

void print_supported_pcidevs(const struct pcidev_status *devs)
{
	int i;

	msg_pinfo("PCI devices:\n");
	for (i = 0; devs[i].vendor_name != NULL; i++) {
		msg_pinfo("%s %s [%04x:%04x]%s\n", devs[i].vendor_name,
		       devs[i].device_name, devs[i].vendor_id,
		       devs[i].device_id,
		       (devs[i].status == NT) ? " (untested)" : "");
	}
}

enum pci_write_type {
	pci_write_type_byte,
	pci_write_type_word,
	pci_write_type_long,
};

struct undo_pci_write_data {
	struct pci_dev dev;
	int reg;
	enum pci_write_type type;
	union {
		uint8_t bytedata;
		uint16_t worddata;
		uint32_t longdata;
	};
};

void undo_pci_write(void *p)
{
	struct undo_pci_write_data *data = p;
	msg_pdbg("Restoring PCI config space for %02x:%02x:%01x reg 0x%02x\n",
		 data->dev.bus, data->dev.dev, data->dev.func, data->reg);
	switch (data->type) {
	case pci_write_type_byte:
		pci_write_byte(&data->dev, data->reg, data->bytedata);
		break;
	case pci_write_type_word:
		pci_write_word(&data->dev, data->reg, data->worddata);
		break;
	case pci_write_type_long:
		pci_write_long(&data->dev, data->reg, data->longdata);
		break;
	}
	/* p was allocated in register_undo_pci_write. */
	free(p);
}

#define register_undo_pci_write(a, b, c) 				\
{									\
	struct undo_pci_write_data *undo_pci_write_data;		\
	undo_pci_write_data = malloc(sizeof(struct undo_pci_write_data)); \
	undo_pci_write_data->dev = *a;					\
	undo_pci_write_data->reg = b;					\
	undo_pci_write_data->type = pci_write_type_##c;			\
	undo_pci_write_data->c##data = pci_read_##c(dev, reg);		\
	register_shutdown(undo_pci_write, undo_pci_write_data);		\
}

#define register_undo_pci_write_byte(a, b) register_undo_pci_write(a, b, byte)
#define register_undo_pci_write_word(a, b) register_undo_pci_write(a, b, word)
#define register_undo_pci_write_long(a, b) register_undo_pci_write(a, b, long)

int rpci_write_byte(struct pci_dev *dev, int reg, uint8_t data)
{
	register_undo_pci_write_byte(dev, reg);
	return pci_write_byte(dev, reg, data);
}
 
int rpci_write_word(struct pci_dev *dev, int reg, uint16_t data)
{
	register_undo_pci_write_word(dev, reg);
	return pci_write_word(dev, reg, data);
}
 
int rpci_write_long(struct pci_dev *dev, int reg, uint32_t data)
{
	register_undo_pci_write_long(dev, reg);
	return pci_write_long(dev, reg, data);
}
