#include "bios.h"
#include "ioport.h"
#include "pci.h"
#include <string.h>

static uint16_t addend;
static uint8_t bus, bridge_head;
static bool use_i440fx_routing;
static int bridge_count;
uint8_t max_bus;

static void do_setup_pci_bus(void);

static void pci_foreach(void(*fn)(uint32_t bdf, uint32_t id, uint8_t type))
{
	int d, f;
	for (d = 0; d < 32; d++) {
		for (f = 0; f < 8; f++) {
			uint32_t bdf = (bus * 256) + (d * 8) + f;
			uint32_t id = pci_config_readl(bdf, PCI_VENDOR_ID);
			uint16_t vendor;
			uint8_t type;

			/* 0x0000 or 0xFFFF?  Skip.  */
			vendor = id & 0xFFFF;
			if ((uint16_t)(vendor + 1) <= 1) {
				if (f == 0)
					break;
				else
					continue;
			}

			type = pci_config_readb(bdf, PCI_HEADER_TYPE);
			fn(bdf, id, type);

			if (f == 0 && !(type & PCI_HEADER_TYPE_MULTI_FUNCTION))
				break;
		}
	}
}

static void do_setup_pci_irq(uint32_t bdf, int pin)
{
	int dev = (bdf >> 3) & 0x1f;
	int lnk, irq;

	irq = pci_config_readb(bdf, PCI_INTERRUPT_LINE);
	if (irq != 0)
		return;

	lnk = addend + pin;
	if (use_i440fx_routing)
		lnk += dev - 1;
	else {
		/* Q35 devices 25-31 all use LNKA.  Devices 0-24 have
		 * a slightly different mapping.
		 */
		if (dev <= 24)
			lnk += dev;
	}
	lnk &= 3;

	irq = lnk & 2 ? 11 : 10;
	pci_config_writeb(bdf, PCI_INTERRUPT_LINE, irq);
}

static void do_setup_pci(uint32_t bdf, uint32_t id, uint8_t type)
{
	uint16_t class;
	uint8_t pin;

	pin = pci_config_readb(bdf, PCI_INTERRUPT_PIN);
	if (pin != 0)
		do_setup_pci_irq(bdf, pin);

	if (type & PCI_HEADER_TYPE_BRIDGE) {
		uint32_t ctl;

		ctl = pci_config_readw(bdf, PCI_BRIDGE_CONTROL);
		pci_config_writew(bdf, PCI_BRIDGE_CONTROL,
				  ctl | PCI_BRIDGE_CTL_SERR);
	}

	class = pci_config_readw(bdf, PCI_CLASS_DEVICE);
	switch (class) {
	case PCI_CLASS_STORAGE_IDE:
		pci_config_writel(bdf, 0x10, 0x1f0);
		pci_config_writel(bdf, 0x14, 0x3f4);
		pci_config_writel(bdf, 0x18, 0x170);
		pci_config_writel(bdf, 0x1c, 0x374);
		if (id == (PCI_VENDOR_ID_INTEL | (PCI_DEVICE_ID_INTEL_82371SB_1 << 16))
		    || id == (PCI_VENDOR_ID_INTEL | (PCI_DEVICE_ID_INTEL_82371AB << 16))) {
			/* Enable IDE0 and IDE1.  */
			pci_config_writew(bdf, 0x40, 0x8000);
			pci_config_writew(bdf, 0x42, 0x8000);
		}
		break;

	case PCI_CLASS_BRIDGE_PCI:
		pci_config_writeb(bdf, PCI_PRIMARY_BUS, bus);
		/* prevent accidental access to unintended devices */
		pci_config_writeb(bdf, PCI_SUBORDINATE_BUS, 0);
		/*
		 * Insert at the head of a linked list of bridges.
		 * do_setup_pci_bus will use it later to initialize secondary
		 * buses with a recursive call.
		 */
		pci_config_writeb(bdf, PCI_SECONDARY_BUS, bridge_head);
		bridge_head = (uint8_t)(bdf & 0xFF);
		bridge_count++;
		break;
	}
}

static void do_setup_pci_bus(void)
{
	uint8_t save_bus, next_head;
	int i;

	bridge_head = 0xFF;
	bridge_count = 0;

	/* Discover all PCI devices and block bridges */
	pci_foreach(do_setup_pci);

	next_head = bridge_head;
	save_bus = bus;

	/* Configure bridges on this bus and recursively setup new busses */
	for (i = bridge_count; i > 0; i--) {
		uint32_t bdf = (save_bus * 256) + next_head;

		next_head = pci_config_readb(bdf, PCI_SECONDARY_BUS);

		bus = ++max_bus;
		pci_config_writeb(bdf, PCI_SECONDARY_BUS, bus);
		pci_config_writeb(bdf, PCI_SUBORDINATE_BUS, 255);

		/* Add PCI bridge device id for the recursive call.  */
		addend += (bdf >> 3) & 0x1f;
		do_setup_pci_bus();
		addend -= (bdf >> 3) & 0x1f;

		pci_config_writeb(bdf, PCI_SUBORDINATE_BUS, max_bus);
	}
}

void setup_bios32(void)
{
	char *bios32 = malloc_fseg_align(16, 16);
	void *bios32_entry_ = &bios32_entry;
	int i;

	memcpy(bios32, "_32_", 4);
	memcpy(bios32 + 4, &bios32_entry_, 4);
	bios32[8] = 0;
	bios32[9] = 1;
	memset(bios32 + 10, 0, 6);
	for (i = 0; i <= 9; i++)
		bios32[10] -= bios32[i];
}

void setup_pci(void)
{
	const int bdf = 0;

	uint32_t id = pci_config_readl(bdf, 0);
	if (id == (PCI_VENDOR_ID_INTEL | (PCI_DEVICE_ID_INTEL_82441 << 16)))
		use_i440fx_routing = true;
	else if (id == (PCI_VENDOR_ID_INTEL | (PCI_DEVICE_ID_INTEL_Q35_MCH << 16)))
		use_i440fx_routing = false;
	else
		panic();

	do_setup_pci_bus();
	setup_bios32();
}
