// SPDX-License-Identifier: GPL-2.0+
/*
 * Compaq Hot Plug Controller Driver
 *
 * Copyright (C) 1995,2001 Compaq Computer Corporation
 * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
 * Copyright (C) 2001 IBM Corp.
 *
 * All rights reserved.
 *
 * Send feedback to <greg@kroah.com>
 *
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/proc_fs.h>
#include <linux/slab.h>
#include <linux/workqueue.h>
#include <linux/pci.h>
#include <linux/pci_hotplug.h>
#include <linux/uaccess.h>
#include "cpqphp.h"
#include "cpqphp_nvram.h"


#define ROM_INT15_PHY_ADDR		0x0FF859
#define READ_EV				0xD8A4
#define WRITE_EV			0xD8A5

struct register_foo {
	union {
		unsigned long lword;		/* eax */
		unsigned short word;		/* ax */

		struct {
			unsigned char low;	/* al */
			unsigned char high;	/* ah */
		} byte;
	} data;

	unsigned char opcode;	/* see below */
	unsigned long length;	/* if the reg. is a pointer, how much data */
} __attribute__ ((packed));

struct all_reg {
	struct register_foo eax_reg;
	struct register_foo ebx_reg;
	struct register_foo ecx_reg;
	struct register_foo edx_reg;
	struct register_foo edi_reg;
	struct register_foo esi_reg;
	struct register_foo eflags_reg;
} __attribute__ ((packed));


struct ev_hrt_header {
	u8 Version;
	u8 num_of_ctrl;
	u8 next;
};

struct ev_hrt_ctrl {
	u8 bus;
	u8 device;
	u8 function;
	u8 mem_avail;
	u8 p_mem_avail;
	u8 io_avail;
	u8 bus_avail;
	u8 next;
};


static u8 evbuffer_init;
static u8 evbuffer_length;
static u8 evbuffer[1024];

static void __iomem *compaq_int15_entry_point;

/* lock for ordering int15_bios_call() */
static DEFINE_SPINLOCK(int15_lock);


/* This is a series of function that deals with
 * setting & getting the hotplug resource table in some environment variable.
 */

/*
 * We really shouldn't be doing this unless there is a _very_ good reason to!!!
 * greg k-h
 */


static u32 add_byte(u32 **p_buffer, u8 value, u32 *used, u32 *avail)
{
	u8 **tByte;

	if ((*used + 1) > *avail)
		return(1);

	*((u8 *)*p_buffer) = value;
	tByte = (u8 **)p_buffer;
	(*tByte)++;
	*used += 1;
	return(0);
}


static u32 add_dword(u32 **p_buffer, u32 value, u32 *used, u32 *avail)
{
	if ((*used + 4) > *avail)
		return(1);

	**p_buffer = value;
	(*p_buffer)++;
	*used += 4;
	return(0);
}


/*
 * check_for_compaq_ROM
 *
 * this routine verifies that the ROM OEM string is 'COMPAQ'
 *
 * returns 0 for non-Compaq ROM, 1 for Compaq ROM
 */
static int check_for_compaq_ROM(void __iomem *rom_start)
{
	u8 temp1, temp2, temp3, temp4, temp5, temp6;
	int result = 0;

	temp1 = readb(rom_start + 0xffea + 0);
	temp2 = readb(rom_start + 0xffea + 1);
	temp3 = readb(rom_start + 0xffea + 2);
	temp4 = readb(rom_start + 0xffea + 3);
	temp5 = readb(rom_start + 0xffea + 4);
	temp6 = readb(rom_start + 0xffea + 5);
	if ((temp1 == 'C') &&
	    (temp2 == 'O') &&
	    (temp3 == 'M') &&
	    (temp4 == 'P') &&
	    (temp5 == 'A') &&
	    (temp6 == 'Q')) {
		result = 1;
	}
	dbg("%s - returned %d\n", __func__, result);
	return result;
}


static u32 access_EV(u16 operation, u8 *ev_name, u8 *buffer, u32 *buf_size)
{
	unsigned long flags;
	int op = operation;
	int ret_val;

	if (!compaq_int15_entry_point)
		return -ENODEV;

	spin_lock_irqsave(&int15_lock, flags);
	__asm__ (
		"xorl   %%ebx,%%ebx\n" \
		"xorl    %%edx,%%edx\n" \
		"pushf\n" \
		"push %%cs\n" \
		"cli\n" \
		"call *%6\n"
		: "=c" (*buf_size), "=a" (ret_val)
		: "a" (op), "c" (*buf_size), "S" (ev_name),
		"D" (buffer), "m" (compaq_int15_entry_point)
		: "%ebx", "%edx");
	spin_unlock_irqrestore(&int15_lock, flags);

	return((ret_val & 0xFF00) >> 8);
}


/*
 * load_HRT
 *
 * Read the hot plug Resource Table from NVRAM
 */
static int load_HRT(void __iomem *rom_start)
{
	u32 available;
	u32 temp_dword;
	u8 temp_byte = 0xFF;
	u32 rc;

	if (!check_for_compaq_ROM(rom_start))
		return -ENODEV;

	available = 1024;

	/* Now load the EV */
	temp_dword = available;

	rc = access_EV(READ_EV, "CQTHPS", evbuffer, &temp_dword);

	evbuffer_length = temp_dword;

	/* We're maintaining the resource lists so write FF to invalidate old
	 * info
	 */
	temp_dword = 1;

	rc = access_EV(WRITE_EV, "CQTHPS", &temp_byte, &temp_dword);

	return rc;
}


/*
 * store_HRT
 *
 * Save the hot plug Resource Table in NVRAM
 */
static u32 store_HRT(void __iomem *rom_start)
{
	u32 *buffer;
	u32 *pFill;
	u32 usedbytes;
	u32 available;
	u32 temp_dword;
	u32 rc;
	u8 loop;
	u8 numCtrl = 0;
	struct controller *ctrl;
	struct pci_resource *resNode;
	struct ev_hrt_header *p_EV_header;
	struct ev_hrt_ctrl *p_ev_ctrl;

	available = 1024;

	if (!check_for_compaq_ROM(rom_start))
		return(1);

	buffer = (u32 *) evbuffer;

	if (!buffer)
		return(1);

	pFill = buffer;
	usedbytes = 0;

	p_EV_header = (struct ev_hrt_header *) pFill;

	ctrl = cpqhp_ctrl_list;

	/* The revision of this structure */
	rc = add_byte(&pFill, 1 + ctrl->push_flag, &usedbytes, &available);
	if (rc)
		return(rc);

	/* The number of controllers */
	rc = add_byte(&pFill, 1, &usedbytes, &available);
	if (rc)
		return(rc);

	while (ctrl) {
		p_ev_ctrl = (struct ev_hrt_ctrl *) pFill;

		numCtrl++;

		/* The bus number */
		rc = add_byte(&pFill, ctrl->bus, &usedbytes, &available);
		if (rc)
			return(rc);

		/* The device Number */
		rc = add_byte(&pFill, PCI_SLOT(ctrl->pci_dev->devfn), &usedbytes, &available);
		if (rc)
			return(rc);

		/* The function Number */
		rc = add_byte(&pFill, PCI_FUNC(ctrl->pci_dev->devfn), &usedbytes, &available);
		if (rc)
			return(rc);

		/* Skip the number of available entries */
		rc = add_dword(&pFill, 0, &usedbytes, &available);
		if (rc)
			return(rc);

		/* Figure out memory Available */

		resNode = ctrl->mem_head;

		loop = 0;

		while (resNode) {
			loop++;

			/* base */
			rc = add_dword(&pFill, resNode->base, &usedbytes, &available);
			if (rc)
				return(rc);

			/* length */
			rc = add_dword(&pFill, resNode->length, &usedbytes, &available);
			if (rc)
				return(rc);

			resNode = resNode->next;
		}

		/* Fill in the number of entries */
		p_ev_ctrl->mem_avail = loop;

		/* Figure out prefetchable memory Available */

		resNode = ctrl->p_mem_head;

		loop = 0;

		while (resNode) {
			loop++;

			/* base */
			rc = add_dword(&pFill, resNode->base, &usedbytes, &available);
			if (rc)
				return(rc);

			/* length */
			rc = add_dword(&pFill, resNode->length, &usedbytes, &available);
			if (rc)
				return(rc);

			resNode = resNode->next;
		}

		/* Fill in the number of entries */
		p_ev_ctrl->p_mem_avail = loop;

		/* Figure out IO Available */

		resNode = ctrl->io_head;

		loop = 0;

		while (resNode) {
			loop++;

			/* base */
			rc = add_dword(&pFill, resNode->base, &usedbytes, &available);
			if (rc)
				return(rc);

			/* length */
			rc = add_dword(&pFill, resNode->length, &usedbytes, &available);
			if (rc)
				return(rc);

			resNode = resNode->next;
		}

		/* Fill in the number of entries */
		p_ev_ctrl->io_avail = loop;

		/* Figure out bus Available */

		resNode = ctrl->bus_head;

		loop = 0;

		while (resNode) {
			loop++;

			/* base */
			rc = add_dword(&pFill, resNode->base, &usedbytes, &available);
			if (rc)
				return(rc);

			/* length */
			rc = add_dword(&pFill, resNode->length, &usedbytes, &available);
			if (rc)
				return(rc);

			resNode = resNode->next;
		}

		/* Fill in the number of entries */
		p_ev_ctrl->bus_avail = loop;

		ctrl = ctrl->next;
	}

	p_EV_header->num_of_ctrl = numCtrl;

	/* Now store the EV */

	temp_dword = usedbytes;

	rc = access_EV(WRITE_EV, "CQTHPS", (u8 *) buffer, &temp_dword);

	dbg("usedbytes = 0x%x, length = 0x%x\n", usedbytes, temp_dword);

	evbuffer_length = temp_dword;

	if (rc) {
		err(msg_unable_to_save);
		return(1);
	}

	return(0);
}


void compaq_nvram_init(void __iomem *rom_start)
{
	if (rom_start)
		compaq_int15_entry_point = (rom_start + ROM_INT15_PHY_ADDR - ROM_PHY_ADDR);

	dbg("int15 entry  = %p\n", compaq_int15_entry_point);
}


int compaq_nvram_load(void __iomem *rom_start, struct controller *ctrl)
{
	u8 bus, device, function;
	u8 nummem, numpmem, numio, numbus;
	u32 rc;
	u8 *p_byte;
	struct pci_resource *mem_node;
	struct pci_resource *p_mem_node;
	struct pci_resource *io_node;
	struct pci_resource *bus_node;
	struct ev_hrt_ctrl *p_ev_ctrl;
	struct ev_hrt_header *p_EV_header;

	if (!evbuffer_init) {
		/* Read the resource list information in from NVRAM */
		if (load_HRT(rom_start))
			memset(evbuffer, 0, 1024);

		evbuffer_init = 1;
	}

	/* If we saved information in NVRAM, use it now */
	p_EV_header = (struct ev_hrt_header *) evbuffer;

	/* The following code is for systems where version 1.0 of this
	 * driver has been loaded, but doesn't support the hardware.
	 * In that case, the driver would incorrectly store something
	 * in NVRAM.
	 */
	if ((p_EV_header->Version == 2) ||
	    ((p_EV_header->Version == 1) && !ctrl->push_flag)) {
		p_byte = &(p_EV_header->next);

		p_ev_ctrl = (struct ev_hrt_ctrl *) &(p_EV_header->next);

		p_byte += 3;

		if (p_byte > ((u8 *)p_EV_header + evbuffer_length))
			return 2;

		bus = p_ev_ctrl->bus;
		device = p_ev_ctrl->device;
		function = p_ev_ctrl->function;

		while ((bus != ctrl->bus) ||
		       (device != PCI_SLOT(ctrl->pci_dev->devfn)) ||
		       (function != PCI_FUNC(ctrl->pci_dev->devfn))) {
			nummem = p_ev_ctrl->mem_avail;
			numpmem = p_ev_ctrl->p_mem_avail;
			numio = p_ev_ctrl->io_avail;
			numbus = p_ev_ctrl->bus_avail;

			p_byte += 4;

			if (p_byte > ((u8 *)p_EV_header + evbuffer_length))
				return 2;

			/* Skip forward to the next entry */
			p_byte += (nummem + numpmem + numio + numbus) * 8;

			if (p_byte > ((u8 *)p_EV_header + evbuffer_length))
				return 2;

			p_ev_ctrl = (struct ev_hrt_ctrl *) p_byte;

			p_byte += 3;

			if (p_byte > ((u8 *)p_EV_header + evbuffer_length))
				return 2;

			bus = p_ev_ctrl->bus;
			device = p_ev_ctrl->device;
			function = p_ev_ctrl->function;
		}

		nummem = p_ev_ctrl->mem_avail;
		numpmem = p_ev_ctrl->p_mem_avail;
		numio = p_ev_ctrl->io_avail;
		numbus = p_ev_ctrl->bus_avail;

		p_byte += 4;

		if (p_byte > ((u8 *)p_EV_header + evbuffer_length))
			return 2;

		while (nummem--) {
			mem_node = kmalloc(sizeof(struct pci_resource), GFP_KERNEL);

			if (!mem_node)
				break;

			mem_node->base = *(u32 *)p_byte;
			dbg("mem base = %8.8x\n", mem_node->base);
			p_byte += 4;

			if (p_byte > ((u8 *)p_EV_header + evbuffer_length)) {
				kfree(mem_node);
				return 2;
			}

			mem_node->length = *(u32 *)p_byte;
			dbg("mem length = %8.8x\n", mem_node->length);
			p_byte += 4;

			if (p_byte > ((u8 *)p_EV_header + evbuffer_length)) {
				kfree(mem_node);
				return 2;
			}

			mem_node->next = ctrl->mem_head;
			ctrl->mem_head = mem_node;
		}

		while (numpmem--) {
			p_mem_node = kmalloc(sizeof(struct pci_resource), GFP_KERNEL);

			if (!p_mem_node)
				break;

			p_mem_node->base = *(u32 *)p_byte;
			dbg("pre-mem base = %8.8x\n", p_mem_node->base);
			p_byte += 4;

			if (p_byte > ((u8 *)p_EV_header + evbuffer_length)) {
				kfree(p_mem_node);
				return 2;
			}

			p_mem_node->length = *(u32 *)p_byte;
			dbg("pre-mem length = %8.8x\n", p_mem_node->length);
			p_byte += 4;

			if (p_byte > ((u8 *)p_EV_header + evbuffer_length)) {
				kfree(p_mem_node);
				return 2;
			}

			p_mem_node->next = ctrl->p_mem_head;
			ctrl->p_mem_head = p_mem_node;
		}

		while (numio--) {
			io_node = kmalloc(sizeof(struct pci_resource), GFP_KERNEL);

			if (!io_node)
				break;

			io_node->base = *(u32 *)p_byte;
			dbg("io base = %8.8x\n", io_node->base);
			p_byte += 4;

			if (p_byte > ((u8 *)p_EV_header + evbuffer_length)) {
				kfree(io_node);
				return 2;
			}

			io_node->length = *(u32 *)p_byte;
			dbg("io length = %8.8x\n", io_node->length);
			p_byte += 4;

			if (p_byte > ((u8 *)p_EV_header + evbuffer_length)) {
				kfree(io_node);
				return 2;
			}

			io_node->next = ctrl->io_head;
			ctrl->io_head = io_node;
		}

		while (numbus--) {
			bus_node = kmalloc(sizeof(struct pci_resource), GFP_KERNEL);

			if (!bus_node)
				break;

			bus_node->base = *(u32 *)p_byte;
			p_byte += 4;

			if (p_byte > ((u8 *)p_EV_header + evbuffer_length)) {
				kfree(bus_node);
				return 2;
			}

			bus_node->length = *(u32 *)p_byte;
			p_byte += 4;

			if (p_byte > ((u8 *)p_EV_header + evbuffer_length)) {
				kfree(bus_node);
				return 2;
			}

			bus_node->next = ctrl->bus_head;
			ctrl->bus_head = bus_node;
		}

		/* If all of the following fail, we don't have any resources for
		 * hot plug add
		 */
		rc = 1;
		rc &= cpqhp_resource_sort_and_combine(&(ctrl->mem_head));
		rc &= cpqhp_resource_sort_and_combine(&(ctrl->p_mem_head));
		rc &= cpqhp_resource_sort_and_combine(&(ctrl->io_head));
		rc &= cpqhp_resource_sort_and_combine(&(ctrl->bus_head));

		if (rc)
			return(rc);
	} else {
		if ((evbuffer[0] != 0) && (!ctrl->push_flag))
			return 1;
	}

	return 0;
}


int compaq_nvram_store(void __iomem *rom_start)
{
	int rc = 1;

	if (rom_start == NULL)
		return -ENODEV;

	if (evbuffer_init) {
		rc = store_HRT(rom_start);
		if (rc)
			err(msg_unable_to_save);
	}
	return rc;
}

