/*
 * Copyright (C) 2022 Michael Brown <mbrown@fensystems.co.uk>.
 *
 * 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 Street, Fifth Floor, Boston, MA
 * 02110-1301, USA.
 *
 * You can also choose to distribute this program under the terms of
 * the Unmodified Binary Distribution Licence (as given in the file
 * COPYING.UBDL), provided that you have satisfied its requirements.
 */

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );

#include <errno.h>
#include <ipxe/uaccess.h>
#include <ipxe/ecam.h>

/** @file
 *
 * PCI Enhanced Configuration Access Mechanism (ECAM)
 *
 */

/** Cached mapped ECAM allocation */
static struct ecam_mapping ecam;

/**
 * Find lowest ECAM allocation not below a given PCI bus:dev.fn address
 *
 * @v busdevfn		PCI bus:dev.fn address
 * @v range		PCI device address range to fill in
 * @v alloc		ECAM allocation to fill in, or NULL
 * @ret rc		Return status code
 */
static int ecam_find ( uint32_t busdevfn, struct pci_range *range,
		       struct ecam_allocation *alloc ) {
	struct ecam_allocation tmp;
	unsigned int best = 0;
	unsigned int offset;
	unsigned int count;
	unsigned int index;
	userptr_t mcfg;
	uint32_t length;
	uint32_t start;

	/* Return empty range on error */
	range->count = 0;

	/* Locate MCFG table */
	mcfg = acpi_table ( ECAM_SIGNATURE, 0 );
	if ( ! mcfg ) {
		DBGC ( &ecam, "ECAM found no MCFG table\n" );
		return -ENOTSUP;
	}

	/* Get length of table */
	copy_from_user ( &length, mcfg,
			 offsetof ( struct ecam_table, acpi.length ),
			 sizeof ( length ) );

	/* Iterate over allocations */
	for ( offset = offsetof ( struct ecam_table, alloc ) ;
	      ( offset + sizeof ( tmp ) ) <= le32_to_cpu ( length ) ;
	      offset += sizeof ( tmp ) ) {

		/* Read allocation */
		copy_from_user ( &tmp, mcfg, offset, sizeof ( tmp ) );
		DBGC2 ( &ecam, "ECAM %04x:[%02x-%02x] has base %08llx\n",
			le16_to_cpu ( tmp.segment ), tmp.start, tmp.end,
			( ( unsigned long long ) le64_to_cpu ( tmp.base ) ) );
		start = PCI_BUSDEVFN ( le16_to_cpu ( tmp.segment ),
				       tmp.start, 0, 0 );
		count = PCI_BUSDEVFN ( 0, ( tmp.end - tmp.start + 1 ), 0, 0 );

		/* Check for a matching or new closest allocation */
		index = ( busdevfn - start );
		if ( ( index < count ) || ( index > best ) ) {
			if ( alloc )
				memcpy ( alloc, &tmp, sizeof ( *alloc ) );
			range->start = start;
			range->count = count;
			best = index;
		}

		/* Stop if this range contains the target bus:dev.fn address */
		if ( index < count )
			return 0;
	}

	return ( best ? 0 : -ENOENT );
}

/**
 * Find next PCI bus:dev.fn address range in system
 *
 * @v busdevfn		Starting PCI bus:dev.fn address
 * @v range		PCI bus:dev.fn address range to fill in
 */
static void ecam_discover ( uint32_t busdevfn, struct pci_range *range ) {

	/* Find new range, if any */
	ecam_find ( busdevfn, range, NULL );
}

/**
 * Access configuration space for PCI device
 *
 * @v pci		PCI device
 * @ret rc		Return status code
 */
static int ecam_access ( struct pci_device *pci ) {
	uint64_t base;
	size_t len;
	int rc;

	/* Reuse mapping if possible */
	if ( ( pci->busdevfn - ecam.range.start ) < ecam.range.count )
		return 0;

	/* Clear any existing mapping */
	if ( ecam.regs ) {
		iounmap ( ecam.regs );
		ecam.regs = NULL;
	}

	/* Find allocation for this PCI device */
	if ( ( rc = ecam_find ( pci->busdevfn, &ecam.range,
				&ecam.alloc ) ) != 0 ) {
		DBGC ( &ecam, "ECAM found no allocation for " PCI_FMT ": %s\n",
		       PCI_ARGS ( pci ), strerror ( rc ) );
		goto err_find;
	}
	if ( ecam.range.start > pci->busdevfn ) {
		DBGC ( &ecam, "ECAM found no allocation for " PCI_FMT "\n",
		       PCI_ARGS ( pci ) );
		goto err_find;
	}

	/* Map configuration space for this allocation */
	base = le64_to_cpu ( ecam.alloc.base );
	len = ( ecam.range.count * ECAM_SIZE );
	ecam.regs = ioremap ( base, len );
	if ( ! ecam.regs ) {
		DBGC ( &ecam, "ECAM %04x:[%02x-%02x] could not map "
		       "[%08llx,%08llx)\n", le16_to_cpu ( ecam.alloc.segment ),
		       ecam.alloc.start, ecam.alloc.end, base, ( base + len ) );
		rc = -ENODEV;
		goto err_ioremap;
	}

	/* Populate cached mapping */
	DBGC ( &ecam, "ECAM %04x:[%02x-%02x] mapped [%08llx,%08llx) -> %p\n",
	       le16_to_cpu ( ecam.alloc.segment ), ecam.alloc.start,
	       ecam.alloc.end, base, ( base + len ), ecam.regs );
	return 0;

	iounmap ( ecam.regs );
 err_ioremap:
 err_find:
	ecam.range.count = 0;
	return rc;
}

/**
 * Read from PCI configuration space
 *
 * @v pci	PCI device
 * @v location	Offset and length within PCI configuration space
 * @v value	Value read
 * @ret rc	Return status code
 */
int ecam_read ( struct pci_device *pci, unsigned int location, void *value ) {
	unsigned int where = ECAM_WHERE ( location );
	unsigned int len = ECAM_LEN ( location );
	unsigned int index;
	void *addr;
	int rc;

	/* Return all-ones on error */
	memset ( value, 0xff, len );

	/* Access configuration space */
	if ( ( rc = ecam_access ( pci ) ) != 0 )
		return rc;

	/* Read from address */
	index = ( pci->busdevfn - ecam.range.start );
	addr = ( ecam.regs + ( index * ECAM_SIZE ) + where );
	switch ( len ) {
	case 4:
		*( ( uint32_t *) value ) = readl ( addr );
		break;
	case 2:
		*( ( uint16_t *) value ) = readw ( addr );
		break;
	case 1:
		*( ( uint8_t *) value ) = readb ( addr );
		break;
	default:
		assert ( 0 );
	}

	return 0;
}

/**
 * Write to PCI configuration space
 *
 * @v pci	PCI device
 * @v location	Offset and length within PCI configuration space
 * @v value	Value to write
 * @ret rc	Return status code
 */
int ecam_write ( struct pci_device *pci, unsigned int location,
		 unsigned long value ) {
	unsigned int where = ECAM_WHERE ( location );
	unsigned int len = ECAM_LEN ( location );
	unsigned int index;
	void *addr;
	int rc;

	/* Access configuration space */
	if ( ( rc = ecam_access ( pci ) ) != 0 )
		return rc;

	/* Read from address */
	index = ( pci->busdevfn - ecam.range.start );
	addr = ( ecam.regs + ( index * ECAM_SIZE ) + where );
	switch ( len ) {
	case 4:
		writel ( value, addr );
		break;
	case 2:
		writew ( value, addr );
		break;
	case 1:
		writeb ( value, addr );
		break;
	default:
		assert ( 0 );
	}

	return 0;
}

PROVIDE_PCIAPI ( ecam, pci_discover, ecam_discover );
PROVIDE_PCIAPI_INLINE ( ecam, pci_read_config_byte );
PROVIDE_PCIAPI_INLINE ( ecam, pci_read_config_word );
PROVIDE_PCIAPI_INLINE ( ecam, pci_read_config_dword );
PROVIDE_PCIAPI_INLINE ( ecam, pci_write_config_byte );
PROVIDE_PCIAPI_INLINE ( ecam, pci_write_config_word );
PROVIDE_PCIAPI_INLINE ( ecam, pci_write_config_dword );
PROVIDE_PCIAPI_INLINE ( ecam, pci_ioremap );

struct pci_api ecam_api = PCIAPI_RUNTIME ( ecam );
