/*
 * From Coreboot
 *
 * Copyright (C) 2001 Ronald G. Minnich
 * Copyright (C) 2005 Nick.Barker9@btinternet.com
 * Copyright (C) 2007-2009 coresystems GmbH
 *
 * SPDX-License-Identifier:	GPL-2.0
 */

#include <common.h>
#include <asm/pci.h>
#include "bios_emul.h"

/* errors go in AH. Just set these up so that word assigns will work */
enum {
	PCIBIOS_SUCCESSFUL = 0x0000,
	PCIBIOS_UNSUPPORTED = 0x8100,
	PCIBIOS_BADVENDOR = 0x8300,
	PCIBIOS_NODEV = 0x8600,
	PCIBIOS_BADREG = 0x8700
};

int int10_handler(void)
{
	static u8 cursor_row, cursor_col;
	int res = 0;

	switch ((M.x86.R_EAX & 0xff00) >> 8) {
	case 0x01: /* Set cursor shape */
		res = 1;
		break;
	case 0x02: /* Set cursor position */
		if (cursor_row != ((M.x86.R_EDX >> 8) & 0xff) ||
		    cursor_col >= (M.x86.R_EDX & 0xff)) {
			debug("\n");
		}
		cursor_row = (M.x86.R_EDX >> 8) & 0xff;
		cursor_col = M.x86.R_EDX & 0xff;
		res = 1;
		break;
	case 0x03: /* Get cursor position */
		M.x86.R_EAX &= 0x00ff;
		M.x86.R_ECX = 0x0607;
		M.x86.R_EDX = (cursor_row << 8) | cursor_col;
		res = 1;
		break;
	case 0x06: /* Scroll up */
		debug("\n");
		res = 1;
		break;
	case 0x08: /* Get Character and Mode at Cursor Position */
		M.x86.R_EAX = 0x0f00 | 'A'; /* White on black 'A' */
		res = 1;
		break;
	case 0x09: /* Write Character and attribute */
	case 0x0e: /* Write Character */
		debug("%c", M.x86.R_EAX & 0xff);
		res = 1;
		break;
	case 0x0f: /* Get video mode */
		M.x86.R_EAX = 0x5002; /*80 x 25 */
		M.x86.R_EBX &= 0x00ff;
		res = 1;
		break;
	default:
		printf("Unknown INT10 function %04x\n", M.x86.R_EAX & 0xffff);
		break;
	}
	return res;
}

int int12_handler(void)
{
	M.x86.R_EAX = 64 * 1024;
	return 1;
}

int int16_handler(void)
{
	int res = 0;

	switch ((M.x86.R_EAX & 0xff00) >> 8) {
	case 0x00: /* Check for Keystroke */
		M.x86.R_EAX = 0x6120; /* Space Bar, Space */
		res = 1;
		break;
	case 0x01: /* Check for Keystroke */
		M.x86.R_EFLG |= 1 << 6; /* Zero Flag set (no key available) */
		res = 1;
		break;
	default:
		printf("Unknown INT16 function %04x\n", M.x86.R_EAX & 0xffff);

break;
	}
	return res;
}

#define PCI_CONFIG_SPACE_TYPE1	(1 << 0)
#define PCI_SPECIAL_CYCLE_TYPE1	(1 << 4)

int int1a_handler(void)
{
	unsigned short func = (unsigned short)M.x86.R_EAX;
	int retval = 1;
	unsigned short devid, vendorid, devfn;
	/* Use short to get rid of gabage in upper half of 32-bit register */
	short devindex;
	unsigned char bus;
	pci_dev_t dev;
	u32 dword;
	u16 word;
	u8 byte, reg;

	switch (func) {
	case 0xb101: /* PCIBIOS Check */
		M.x86.R_EDX = 0x20494350;	/* ' ICP' */
		M.x86.R_EAX &= 0xffff0000; /* Clear AH / AL */
		M.x86.R_EAX |= PCI_CONFIG_SPACE_TYPE1 |
				PCI_SPECIAL_CYCLE_TYPE1;
		/*
		 * last bus in the system. Hard code to 255 for now.
		 * dev_enumerate() does not seem to tell us (publically)
		 */
		M.x86.R_ECX = 0xff;
		M.x86.R_EDI = 0x00000000;	/* protected mode entry */
		retval = 1;
		break;
	case 0xb102: /* Find Device */
		devid = M.x86.R_ECX;
		vendorid = M.x86.R_EDX;
		devindex = M.x86.R_ESI;
		dev = pci_find_device(vendorid, devid, devindex);
		if (dev != -1) {
			unsigned short busdevfn;
			M.x86.R_EAX &= 0xffff00ff; /* Clear AH */
			M.x86.R_EAX |= PCIBIOS_SUCCESSFUL;
			/*
			 * busnum is an unsigned char;
			 * devfn is an int, so we mask it off.
			 */
			busdevfn = (PCI_BUS(dev) << 8) | PCI_DEV(dev) << 3 |
				PCI_FUNC(dev);
			debug("0x%x: return 0x%x\n", func, busdevfn);
			M.x86.R_EBX = busdevfn;
			retval = 1;
		} else {
			M.x86.R_EAX &= 0xffff00ff; /* Clear AH */
			M.x86.R_EAX |= PCIBIOS_NODEV;
			retval = 0;
		}
		break;
	case 0xb10a: /* Read Config Dword */
	case 0xb109: /* Read Config Word */
	case 0xb108: /* Read Config Byte */
	case 0xb10d: /* Write Config Dword */
	case 0xb10c: /* Write Config Word */
	case 0xb10b: /* Write Config Byte */
		devfn = M.x86.R_EBX & 0xff;
		bus = M.x86.R_EBX >> 8;
		reg = M.x86.R_EDI;
		dev = PCI_BDF(bus, devfn >> 3, devfn & 7);
		if (!dev) {
			debug("0x%x: BAD DEVICE bus %d devfn 0x%x\n", func,
			      bus, devfn);
			/* Or are we supposed to return PCIBIOS_NODEV? */
			M.x86.R_EAX &= 0xffff00ff; /* Clear AH */
			M.x86.R_EAX |= PCIBIOS_BADREG;
			retval = 0;
			return retval;
		}
		switch (func) {
		case 0xb108: /* Read Config Byte */
			byte = x86_pci_read_config8(dev, reg);
			M.x86.R_ECX = byte;
			break;
		case 0xb109: /* Read Config Word */
			word = x86_pci_read_config16(dev, reg);
			M.x86.R_ECX = word;
			break;
		case 0xb10a: /* Read Config Dword */
			dword = x86_pci_read_config32(dev, reg);
			M.x86.R_ECX = dword;
			break;
		case 0xb10b: /* Write Config Byte */
			byte = M.x86.R_ECX;
			x86_pci_write_config8(dev, reg, byte);
			break;
		case 0xb10c: /* Write Config Word */
			word = M.x86.R_ECX;
			x86_pci_write_config16(dev, reg, word);
			break;
		case 0xb10d: /* Write Config Dword */
			dword = M.x86.R_ECX;
			x86_pci_write_config32(dev, reg, dword);
			break;
		}

#ifdef CONFIG_REALMODE_DEBUG
		debug("0x%x: bus %d devfn 0x%x reg 0x%x val 0x%x\n", func,
		      bus, devfn, reg, M.x86.R_ECX);
#endif
		M.x86.R_EAX &= 0xffff00ff; /* Clear AH */
		M.x86.R_EAX |= PCIBIOS_SUCCESSFUL;
		retval = 1;
		break;
	default:
		printf("UNSUPPORTED PCIBIOS FUNCTION 0x%x\n", func);
		M.x86.R_EAX &= 0xffff00ff; /* Clear AH */
		M.x86.R_EAX |= PCIBIOS_UNSUPPORTED;
		retval = 0;
		break;
	}

	return retval;
}
