/*
 * Copyright (C) 2007 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 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.
 */

FILE_LICENCE ( GPL2_OR_LATER );

#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <pxe.h>
#include <realmode.h>
#include <undirom.h>

/** @file
 *
 * UNDI expansion ROMs
 *
 */

/** List of all UNDI ROMs */
static LIST_HEAD ( undiroms );

/**
 * Parse PXE ROM ID structure
 *
 * @v undirom		UNDI ROM
 * @v pxeromid		Offset within ROM to PXE ROM ID structure
 * @ret rc		Return status code
 */
static int undirom_parse_pxeromid ( struct undi_rom *undirom,
				   unsigned int pxeromid ) {
	struct undi_rom_id undi_rom_id;
	unsigned int undiloader;

	DBGC ( undirom, "UNDIROM %p has PXE ROM ID at %04x:%04x\n", undirom,
	       undirom->rom_segment, pxeromid );

	/* Read PXE ROM ID structure and verify */
	copy_from_real ( &undi_rom_id, undirom->rom_segment, pxeromid,
			 sizeof ( undi_rom_id ) );
	if ( undi_rom_id.Signature != UNDI_ROM_ID_SIGNATURE ) {
		DBGC ( undirom, "UNDIROM %p has bad PXE ROM ID signature "
		       "%08x\n", undirom, undi_rom_id.Signature );
		return -EINVAL;
	}

	/* Check for UNDI loader */
	undiloader = undi_rom_id.UNDILoader;
	if ( ! undiloader ) {
		DBGC ( undirom, "UNDIROM %p has no UNDI loader\n", undirom );
		return -EINVAL;
	}

	/* Fill in UNDI ROM loader fields */
	undirom->loader_entry.segment = undirom->rom_segment;
	undirom->loader_entry.offset = undiloader;
	undirom->code_size = undi_rom_id.CodeSize;
	undirom->data_size = undi_rom_id.DataSize;

	DBGC ( undirom, "UNDIROM %p has UNDI loader at %04x:%04x "
	       "(code %04zx data %04zx)\n", undirom,
	       undirom->loader_entry.segment, undirom->loader_entry.offset,
	       undirom->code_size, undirom->data_size );
	return 0;
}

/**
 * Parse PCI expansion header
 *
 * @v undirom		UNDI ROM
 * @v pcirheader	Offset within ROM to PCI expansion header
 */
static int undirom_parse_pcirheader ( struct undi_rom *undirom,
				     unsigned int pcirheader ) {
	struct pcir_header pcir_header;

	DBGC ( undirom, "UNDIROM %p has PCI expansion header at %04x:%04x\n",
	       undirom, undirom->rom_segment, pcirheader );

	/* Read PCI expansion header and verify */
	copy_from_real ( &pcir_header, undirom->rom_segment, pcirheader,
			 sizeof ( pcir_header ) );
	if ( pcir_header.signature != PCIR_SIGNATURE ) {
		DBGC ( undirom, "UNDIROM %p has bad PCI expansion header "
		       "signature %08x\n", undirom, pcir_header.signature );
		return -EINVAL;
	}

	/* Fill in UNDI ROM PCI device fields */
	undirom->bus_type = PCI_NIC;
	undirom->bus_id.pci.vendor_id = pcir_header.vendor_id;
	undirom->bus_id.pci.device_id = pcir_header.device_id;

	DBGC ( undirom, "UNDIROM %p is for PCI devices %04x:%04x\n", undirom,
	       undirom->bus_id.pci.vendor_id, undirom->bus_id.pci.device_id );
	return 0;
	
}

/**
 * Probe UNDI ROM
 *
 * @v rom_segment	ROM segment address
 * @ret rc		Return status code
 */
static int undirom_probe ( unsigned int rom_segment ) {
	struct undi_rom *undirom = NULL;
	struct undi_rom_header romheader;
	size_t rom_len;
	unsigned int pxeromid;
	unsigned int pcirheader;
	int rc;

	/* Read expansion ROM header and verify */
	copy_from_real ( &romheader, rom_segment, 0, sizeof ( romheader ) );
	if ( romheader.Signature != ROM_SIGNATURE ) {
		rc = -EINVAL;
		goto err;
	}
	rom_len = ( romheader.ROMLength * 512 );

	/* Allocate memory for UNDI ROM */
	undirom = zalloc ( sizeof ( *undirom ) );
	if ( ! undirom ) {
		DBG ( "Could not allocate UNDI ROM structure\n" );
		rc = -ENOMEM;
		goto err;
	}
	DBGC ( undirom, "UNDIROM %p trying expansion ROM at %04x:0000 "
	       "(%zdkB)\n", undirom, rom_segment, ( rom_len / 1024 ) );
	undirom->rom_segment = rom_segment;

	/* Check for and parse PXE ROM ID */
	pxeromid = romheader.PXEROMID;
	if ( ! pxeromid ) {
		DBGC ( undirom, "UNDIROM %p has no PXE ROM ID\n", undirom );
		rc = -EINVAL;
		goto err;
	}
	if ( pxeromid > rom_len ) {
		DBGC ( undirom, "UNDIROM %p PXE ROM ID outside ROM\n",
		       undirom );
		rc = -EINVAL;
		goto err;
	}
	if ( ( rc = undirom_parse_pxeromid ( undirom, pxeromid ) ) != 0 )
		goto err;

	/* Parse PCIR header, if present */
	pcirheader = romheader.PCIRHeader;
	if ( pcirheader )
		undirom_parse_pcirheader ( undirom, pcirheader );

	/* Add to UNDI ROM list and return */
	DBGC ( undirom, "UNDIROM %p registered\n", undirom );
	list_add_tail ( &undirom->list, &undiroms );
	return 0;

 err:
	free ( undirom );
	return rc;
}

/**
 * Create UNDI ROMs for all possible expansion ROMs
 *
 * @ret 
 */
static void undirom_probe_all_roms ( void ) {
	static int probed = 0;
	unsigned int rom_segment;

	/* Perform probe only once */
	if ( probed )
		return;

	DBG ( "Scanning for PXE expansion ROMs\n" );

	/* Scan through expansion ROM region at 512 byte intervals */
	for ( rom_segment = 0xc000 ; rom_segment < 0x10000 ;
	      rom_segment += 0x20 ) {
		undirom_probe ( rom_segment );
	}

	probed = 1;
}

/**
 * Find UNDI ROM for PCI device
 *
 * @v vendor_id		PCI vendor ID
 * @v device_id		PCI device ID
 * @v rombase		ROM base address, or 0 for any
 * @ret undirom		UNDI ROM, or NULL
 */
struct undi_rom * undirom_find_pci ( unsigned int vendor_id,
				     unsigned int device_id,
				     unsigned int rombase ) {
	struct undi_rom *undirom;

	undirom_probe_all_roms();

	list_for_each_entry ( undirom, &undiroms, list ) {
		if ( undirom->bus_type != PCI_NIC )
			continue;
		if ( undirom->bus_id.pci.vendor_id != vendor_id )
			continue;
		if ( undirom->bus_id.pci.device_id != device_id )
			continue;
		if ( rombase && ( ( undirom->rom_segment << 4 ) != rombase ) )
			continue;
		DBGC ( undirom, "UNDIROM %p matched PCI %04x:%04x (%08x)\n",
		       undirom, vendor_id, device_id, rombase );
		return undirom;
	}

	DBG ( "No UNDI ROM matched PCI %04x:%04x (%08x)\n",
	      vendor_id, device_id, rombase );
	return NULL;
}
