/*
 * Copyright (C) 2009 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., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <stdint.h>
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
#include <assert.h>
#include <getopt.h>
#include <gpxe/efi/efi.h>
#include <gpxe/efi/IndustryStandard/PeImage.h>
#include <gpxe/efi/IndustryStandard/Pci22.h>

#define eprintf(...) fprintf ( stderr, __VA_ARGS__ )

/** Command-line options */
struct options {
	uint16_t vendor;
	uint16_t device;
};

/**
 * Allocate memory
 *
 * @v len		Length of memory to allocate
 * @ret ptr		Pointer to allocated memory
 */
static void * xmalloc ( size_t len ) {
	void *ptr;

	ptr = malloc ( len );
	if ( ! ptr ) {
		eprintf ( "Could not allocate %zd bytes\n", len );
		exit ( 1 );
	}

	return ptr;
}

/**
 * Get file size
 *
 * @v file		File
 * @v len		File size
 */
static size_t file_size ( FILE *file ) {
	ssize_t len;

	return len;
}

/**
 * Read information from PE headers
 *
 * @v pe		PE file
 * @ret machine		Machine type
 * @ret subsystem	EFI subsystem
 */
static void read_pe_info ( void *pe, uint16_t *machine,
			   uint16_t *subsystem ) {
	EFI_IMAGE_DOS_HEADER *dos;
	union {
		EFI_IMAGE_NT_HEADERS32 nt32;
		EFI_IMAGE_NT_HEADERS64 nt64;
	} *nt;

	/* Locate NT header */
	dos = pe;
	nt = ( pe + dos->e_lfanew );

	/* Parse out PE information */
	*machine = nt->nt32.FileHeader.Machine;
	switch ( *machine ) {
	case EFI_IMAGE_MACHINE_IA32:
		*subsystem = nt->nt32.OptionalHeader.Subsystem;
		break;
	case EFI_IMAGE_MACHINE_X64:
		*subsystem = nt->nt64.OptionalHeader.Subsystem;
		break;
	default:
		eprintf ( "Unrecognised machine type %04x\n", *machine );
		exit ( 1 );
	}
}

/**
 * Convert EFI image to ROM image
 *
 * @v pe		EFI file
 * @v rom		ROM file
 */
static void make_efi_rom ( FILE *pe, FILE *rom, struct options *opts ) {
	struct {
		EFI_PCI_EXPANSION_ROM_HEADER rom;
		PCI_DATA_STRUCTURE pci __attribute__ (( aligned ( 4 ) ));
		uint8_t checksum;
	} *headers;
	struct stat pe_stat;
	size_t pe_size;
	size_t rom_size;
	void *buf;
	void *payload;
	unsigned int i;
	uint8_t checksum;

	/* Determine PE file size */
	if ( fstat ( fileno ( pe ), &pe_stat ) != 0 ) {
		eprintf ( "Could not stat PE file: %s\n",
			  strerror ( errno ) );
		exit ( 1 );
	}
	pe_size = pe_stat.st_size;

	/* Determine ROM file size */
	rom_size = ( ( pe_size + sizeof ( *headers ) + 511 ) & ~511 );

	/* Allocate ROM buffer and read in PE file */
	buf = xmalloc ( rom_size );
	memset ( buf, 0, rom_size );
	headers = buf;
	payload = ( buf + sizeof ( *headers ) );
	if ( fread ( payload, pe_size, 1, pe ) != 1 ) {
		eprintf ( "Could not read PE file: %s\n",
			  strerror ( errno ) );
		exit ( 1 );
	}

	/* Construct ROM header */
	headers->rom.Signature = PCI_EXPANSION_ROM_HEADER_SIGNATURE;
	headers->rom.InitializationSize = ( rom_size / 512 );
	headers->rom.EfiSignature = EFI_PCI_EXPANSION_ROM_HEADER_EFISIGNATURE;
	read_pe_info ( payload, &headers->rom.EfiMachineType,
		       &headers->rom.EfiSubsystem );
	headers->rom.EfiImageHeaderOffset = sizeof ( *headers );
	headers->rom.PcirOffset =
		offsetof ( typeof ( *headers ), pci );
	headers->pci.Signature = PCI_DATA_STRUCTURE_SIGNATURE;
	headers->pci.VendorId = opts->vendor;
	headers->pci.DeviceId = opts->device;
	headers->pci.Length = sizeof ( headers->pci );
	headers->pci.ClassCode[0] = PCI_CLASS_NETWORK;
	headers->pci.ImageLength = ( rom_size / 512 );
	headers->pci.CodeType = 0x03; /* No constant in EFI headers? */
	headers->pci.Indicator = 0x80; /* No constant in EFI headers? */

	/* Fix image checksum */
	for ( i = 0, checksum = 0 ; i < rom_size ; i++ )
		checksum += *( ( uint8_t * ) buf + i );
	headers->checksum -= checksum;

	/* Write out ROM */
	if ( fwrite ( buf, rom_size, 1, rom ) != 1 ) {
		eprintf ( "Could not write ROM file: %s\n",
			  strerror ( errno ) );
		exit ( 1 );
	}
}

/**
 * Print help
 *
 * @v program_name	Program name
 */
static void print_help ( const char *program_name ) {
	eprintf ( "Syntax: %s [--vendor=VVVV] [--device=DDDD] "
		  "infile outfile\n", program_name );
}

/**
 * Parse command-line options
 *
 * @v argc		Argument count
 * @v argv		Argument list
 * @v opts		Options structure to populate
 */
static int parse_options ( const int argc, char **argv,
			   struct options *opts ) {
	char *end;
	int c;

	while (1) {
		int option_index = 0;
		static struct option long_options[] = {
			{ "vendor", required_argument, NULL, 'v' },
			{ "device", required_argument, NULL, 'd' },
			{ "help", 0, NULL, 'h' },
			{ 0, 0, 0, 0 }
		};

		if ( ( c = getopt_long ( argc, argv, "v:d:h",
					 long_options,
					 &option_index ) ) == -1 ) {
			break;
		}

		switch ( c ) {
		case 'v':
			opts->vendor = strtoul ( optarg, &end, 16 );
			if ( *end ) {
				eprintf ( "Invalid vendor \"%s\"\n", optarg );
				exit ( 2 );
			}
			break;
		case 'd':
			opts->device = strtoul ( optarg, &end, 16 );
			if ( *end ) {
				eprintf ( "Invalid device \"%s\"\n", optarg );
				exit ( 2 );
			}
			break;
		case 'h':
			print_help ( argv[0] );
			exit ( 0 );
		case '?':
		default:
			exit ( 2 );
		}
	}
	return optind;
}

int main ( int argc, char **argv ) {
	struct options opts = {
	};
	unsigned int infile_index;
	const char *infile_name;
	const char *outfile_name;
	FILE *infile;
	FILE *outfile;

	/* Parse command-line arguments */
	infile_index = parse_options ( argc, argv, &opts );
	if ( argc != ( infile_index + 2 ) ) {
		print_help ( argv[0] );
		exit ( 2 );
	}
	infile_name = argv[infile_index];
	outfile_name = argv[infile_index + 1];

	/* Open input and output files */
	infile = fopen ( infile_name, "r" );
	if ( ! infile ) {
		eprintf ( "Could not open %s for reading: %s\n",
			  infile_name, strerror ( errno ) );
		exit ( 1 );
	}
	outfile = fopen ( outfile_name, "w" );
	if ( ! outfile ) {
		eprintf ( "Could not open %s for writing: %s\n",
			  outfile_name, strerror ( errno ) );
		exit ( 1 );
	}

	/* Convert file */
	make_efi_rom ( infile, outfile, &opts );

	fclose ( outfile );
	fclose ( infile );

	return 0;
}
