/*
 * Copyright (C) 2015 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 <stdint.h>
#include <string.h>
#include <errno.h>
#include <ipxe/console.h>
#include <ipxe/init.h>
#include <realmode.h>
#include <int13.h>
#include <config/console.h>

/** @file
 *
 * INT13 disk log console
 *
 */

/* Set default console usage if applicable */
#if ! ( defined ( CONSOLE_INT13 ) && CONSOLE_EXPLICIT ( CONSOLE_INT13 ) )
#undef CONSOLE_INT13
#define CONSOLE_INT13 ( CONSOLE_USAGE_ALL & ~CONSOLE_USAGE_LOG )
#endif

/** Disk drive number */
#define INT13CON_DRIVE 0x80

/** Log partition type */
#define INT13CON_PARTITION_TYPE 0xe0

/** Maximum number of outstanding unwritten characters */
#define INT13CON_MAX_UNWRITTEN 64

/** Log partition header */
struct int13con_header {
	/** Magic signature */
	char magic[10];
} __attribute__ (( packed ));

/** Log partition magic signature */
#define INT13CON_MAGIC "iPXE LOG\n\n"

/** Original INT13 vector */
static struct segoff __bss16 ( int13con_vector );
#define int13con_vector __use_data16 ( int13con_vector )

/** Sector buffer */
static uint8_t __bss16_array ( int13con_buffer, [INT13_BLKSIZE] );
#define int13con_buffer __use_data16 ( int13con_buffer )

/** Disk address packet */
static struct int13_disk_address __bss16 ( int13con_address );
#define int13con_address __use_data16 ( int13con_address )

/** Current LBA */
static uint64_t int13con_lba;

/** Maximum LBA */
static uint64_t int13con_max_lba;

/** Current offset within sector */
static size_t int13con_offset;

/** Number of unwritten characters */
static size_t int13con_unwritten;

struct console_driver int13con __console_driver;

/**
 * Read/write disk sector
 *
 * @v op		Operation
 * @v lba		Logical block address
 * @ret rc		Return status code
 */
static int int13con_rw ( unsigned int op, uint64_t lba ) {
	uint8_t error;

	/* Construct disk address packet */
	int13con_address.bufsize = sizeof ( int13con_address );
	int13con_address.count = 1;
	int13con_address.buffer.segment = rm_ds;
	int13con_address.buffer.offset = __from_data16 ( int13con_buffer );
	int13con_address.lba = lba;

	/* Emulate INT13 via original vector.  We do this since iPXE
	 * (or another subsequent bootloader) may hook INT13 and remap
	 * drive numbers.
	 */
	__asm__ ( REAL_CODE ( "pushfw\n\t"
			      "cli\n\t"
			      "lcall *int13con_vector\n\t" )
		  : "=a" ( error )
		  : "0" ( op << 8 ), "d" ( INT13CON_DRIVE ),
		    "S" ( __from_data16 ( &int13con_address ) ) );
	if ( error ) {
		DBG ( "INT13CON operation %04x failed: %02x\n",
		      op, error );
		return -EIO;
	}

	return 0;
}

/**
 * Write character to console
 *
 * @v character		Character
 */
static void int13con_putchar ( int character ) {
	static int busy;
	int rc;

	/* Ignore if we are already mid-logging */
	if ( busy )
		return;
	busy = 1;

	/* Write character to buffer */
	int13con_buffer[int13con_offset++] = character;
	int13con_unwritten++;

	/* Write sector to disk, if applicable */
	if ( ( int13con_offset == INT13_BLKSIZE ) ||
	     ( int13con_unwritten == INT13CON_MAX_UNWRITTEN ) ||
	     ( character == '\n' ) ) {

		/* Write sector to disk */
		if ( ( rc = int13con_rw ( INT13_EXTENDED_WRITE,
					  int13con_lba ) ) != 0 ) {
			DBG ( "INT13CON could not write log\n" );
			/* Ignore and continue; there's nothing we can do */
		}

		/* Reset count of unwritten characters */
		int13con_unwritten = 0;
	}

	/* Move to next sector, if applicable */
	if ( int13con_offset == INT13_BLKSIZE ) {

		/* Disable console if we have run out of space */
		if ( int13con_lba >= int13con_max_lba )
			int13con.disabled = 1;

		/* Clear log buffer */
		memset ( int13con_buffer, 0, sizeof ( int13con_buffer ) );
		int13con_offset = 0;

		/* Move to next sector */
		int13con_lba++;
	}

	/* Clear busy flag */
	busy = 0;
}

/**
 * Find log partition
 *
 * @ret rc		Return status code
 */
static int int13con_find ( void ) {
	struct master_boot_record *mbr =
		( ( struct master_boot_record * ) int13con_buffer );
	struct int13con_header *hdr =
		( ( struct int13con_header * ) int13con_buffer );
	struct partition_table_entry part[4];
	unsigned int i;
	int rc;

	/* Read MBR */
	if ( ( rc = int13con_rw ( INT13_EXTENDED_READ, 0 ) ) != 0 ) {
		DBG ( "INT13CON could not read MBR: %s\n", strerror ( rc ) );
		return rc;
	}

	/* Check MBR magic */
	if ( mbr->magic != INT13_MBR_MAGIC ) {
		DBG ( "INT13CON incorrect MBR magic\n" );
		DBG2_HDA ( 0, mbr, sizeof ( *mbr ) );
		return -EINVAL;
	}

	/* Look for magic partition */
	memcpy ( part, mbr->partitions, sizeof ( part ) );
	for ( i = 0 ; i < ( sizeof ( part ) / sizeof ( part[0] ) ) ; i++ ) {

		/* Skip partitions of the wrong type */
		if ( part[i].type != INT13CON_PARTITION_TYPE )
			continue;

		/* Read partition header */
		if ( ( rc = int13con_rw ( INT13_EXTENDED_READ,
					  part[i].start ) ) != 0 ) {
			DBG ( "INT13CON partition %d could not read header: "
			      "%s\n", ( i + 1 ), strerror ( rc ) );
			continue;
		}

		/* Check partition header */
		if ( memcmp ( hdr->magic, INT13CON_MAGIC,
			      sizeof ( hdr->magic ) ) != 0 ) {
			DBG ( "INT13CON partition %d bad magic\n", ( i + 1 ) );
			DBG2_HDA ( 0, hdr, sizeof ( *hdr ) );
			continue;
		}

		/* Found log partition */
		DBG ( "INT13CON partition %d at [%08x,%08x)\n", ( i + 1 ),
		      part[i].start, ( part[i].start + part[i].length ) );
		int13con_lba = part[i].start;
		int13con_max_lba = ( part[i].start + part[i].length - 1 );

		/* Initialise log buffer */
		memset ( &int13con_buffer[ sizeof ( *hdr ) ], 0,
			 ( sizeof ( int13con_buffer ) - sizeof ( *hdr ) ) );
		int13con_offset = sizeof ( hdr->magic );

		return 0;
	}

	DBG ( "INT13CON found no log partition\n" );
	return -ENOENT;
}

/**
 * Initialise INT13 console
 *
 */
static void int13con_init ( void ) {
	uint8_t error;
	uint16_t check;
	unsigned int discard_c;
	unsigned int discard_d;
	int rc;

	/* Check for INT13 extensions */
	__asm__ __volatile__ ( REAL_CODE ( "int $0x13\n\t"
					   "setc %%al\n\t" )
			       : "=a" ( error ), "=b" ( check ),
				 "=c" ( discard_c ), "=d" ( discard_d )
			       : "0" ( INT13_EXTENSION_CHECK << 8 ),
				 "1" ( 0x55aa ), "3" ( INT13CON_DRIVE ) );
	if ( error || ( check != 0xaa55 ) ) {
		DBG ( "INT13CON missing extensions (%02x,%04x)\n",
		      error, check );
		return;
	}

	/* Store original INT13 vector */
	copy_from_real ( &int13con_vector, 0, ( 0x13 * 4 ),
			 sizeof ( int13con_vector ) );
	DBG ( "INT13CON using original INT13 vector %04x:%04x\n",
	      int13con_vector.segment, int13con_vector.offset );

	/* Locate log partition */
	if ( ( rc = int13con_find() ) != 0)
		return;

	/* Enable console */
	int13con.disabled = 0;
}

/**
 * INT13 console initialisation function
 */
struct init_fn int13con_init_fn __init_fn ( INIT_CONSOLE ) = {
	.initialise = int13con_init,
};

/** INT13 console driver */
struct console_driver int13con __console_driver = {
	.putchar = int13con_putchar,
	.disabled = CONSOLE_DISABLED,
	.usage = CONSOLE_INT13,
};
