/*
 * Copyright (C) 2008 Daniel Verkamp <daniel@drv.nu>.
 *
 * 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
 *
 * SYSLINUX COM32 image format
 *
 */

FILE_LICENCE ( GPL2_OR_LATER );

#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <errno.h>
#include <assert.h>
#include <realmode.h>
#include <basemem.h>
#include <comboot.h>
#include <ipxe/uaccess.h>
#include <ipxe/image.h>
#include <ipxe/segment.h>
#include <ipxe/init.h>
#include <ipxe/io.h>
#include <ipxe/console.h>

/**
 * Execute COMBOOT image
 *
 * @v image		COM32 image
 * @ret rc		Return status code
 */
static int com32_exec_loop ( struct image *image ) {
	struct memory_map memmap;
	unsigned int i;
	int state;
	uint32_t avail_mem_top;

	state = rmsetjmp ( comboot_return );

	switch ( state ) {
	case 0: /* First time through; invoke COM32 program */

		/* Get memory map */
		get_memmap ( &memmap );

		/* Find end of block covering COM32 image loading area */
		for ( i = 0, avail_mem_top = 0 ; i < memmap.count ; i++ ) {
			if ( (memmap.regions[i].start <= COM32_START_PHYS) &&
			     (memmap.regions[i].end > COM32_START_PHYS + image->len) ) {
				avail_mem_top = memmap.regions[i].end;
				break;
			}
		}

		DBGC ( image, "COM32 %p: available memory top = 0x%x\n",
		       image, avail_mem_top );

		assert ( avail_mem_top != 0 );

		/* Hook COMBOOT API interrupts */
		hook_comboot_interrupts();

		/* Unregister image, so that a "boot" command doesn't
		 * throw us into an execution loop.  We never
		 * reregister ourselves; COMBOOT images expect to be
		 * removed on exit.
		 */
		unregister_image ( image );

		__asm__ __volatile__ ( PHYS_CODE (
			/* Preserve registers */
			"pushal\n\t"
			/* Preserve stack pointer */
			"subl $4, %k0\n\t"
			"movl %%esp, (%k0)\n\t"
			/* Switch to COM32 stack */
			"movl %k0, %%esp\n\t"
			/* Enable interrupts */
			"sti\n\t"
			/* Construct stack frame */
			"pushl %k1\n\t"
			"pushl %k2\n\t"
			"pushl %k3\n\t"
			"pushl %k4\n\t"
			"pushl %k5\n\t"
			"pushl %k6\n\t"
			"pushl $6\n\t"
			/* Call COM32 entry point */
			"movl %k7, %k0\n\t"
			"call *%k0\n\t"
			/* Disable interrupts */
			"cli\n\t"
			/* Restore stack pointer */
			"movl 28(%%esp), %%esp\n\t"
			/* Restore registers */
			"popal\n\t" )
			:
			: "r" ( avail_mem_top ),
			  "r" ( virt_to_phys ( com32_cfarcall_wrapper ) ),
			  "r" ( virt_to_phys ( com32_farcall_wrapper ) ),
			  "r" ( get_fbms() * 1024 - ( COM32_BOUNCE_SEG << 4 ) ),
			  "i" ( COM32_BOUNCE_SEG << 4 ),
			  "r" ( virt_to_phys ( com32_intcall_wrapper ) ),
			  "r" ( virt_to_phys ( image->cmdline ?
					       image->cmdline : "" ) ),
			  "i" ( COM32_START_PHYS )
			: "memory" );
		DBGC ( image, "COM32 %p: returned\n", image );
		break;

	case COMBOOT_EXIT:
		DBGC ( image, "COM32 %p: exited\n", image );
		break;

	case COMBOOT_EXIT_RUN_KERNEL:
		assert ( image->replacement );
		DBGC ( image, "COM32 %p: exited to run kernel %s\n",
		       image, image->replacement->name );
		break;

	case COMBOOT_EXIT_COMMAND:
		DBGC ( image, "COM32 %p: exited after executing command\n",
		       image );
		break;

	default:
		assert ( 0 );
		break;
	}

	unhook_comboot_interrupts();
	comboot_force_text_mode();

	return 0;
}

/**
 * Check image name extension
 *
 * @v image		COM32 image
 * @ret rc		Return status code
 */
static int com32_identify ( struct image *image ) {
	const char *ext;
	static const uint8_t magic[] = { 0xB8, 0xFF, 0x4C, 0xCD, 0x21 };
	uint8_t buf[5];

	if ( image->len >= 5 ) {
		/* Check for magic number
		 * mov eax,21cd4cffh
		 * B8 FF 4C CD 21
		 */
		copy_from_user ( buf, image->data, 0, sizeof(buf) );
		if ( ! memcmp ( buf, magic, sizeof(buf) ) ) {
			DBGC ( image, "COM32 %p: found magic number\n",
			       image );
			return 0;
		}
	}

	/* Magic number not found; check filename extension */

	ext = strrchr( image->name, '.' );

	if ( ! ext ) {
		DBGC ( image, "COM32 %p: no extension\n",
		       image );
		return -ENOEXEC;
	}

	++ext;

	if ( strcasecmp( ext, "c32" ) ) {
		DBGC ( image, "COM32 %p: unrecognized extension %s\n",
		       image, ext );
		return -ENOEXEC;
	}

	return 0;
}


/**
 * Load COM32 image into memory
 * @v image		COM32 image
 * @ret rc		Return status code
 */
static int com32_load_image ( struct image *image ) {
	size_t filesz, memsz;
	userptr_t buffer;
	int rc;

	filesz = image->len;
	memsz = filesz;
	buffer = phys_to_user ( COM32_START_PHYS );
	if ( ( rc = prep_segment ( buffer, filesz, memsz ) ) != 0 ) {
		DBGC ( image, "COM32 %p: could not prepare segment: %s\n",
		       image, strerror ( rc ) );
		return rc;
	}

	/* Copy image to segment */
	memcpy_user ( buffer, 0, image->data, 0, filesz );

	return 0;
}

/**
 * Prepare COM32 low memory bounce buffer
 * @v image		COM32 image
 * @ret rc		Return status code
 */
static int com32_prepare_bounce_buffer ( struct image * image ) {
	unsigned int seg;
	userptr_t seg_userptr;
	size_t filesz, memsz;
	int rc;

	seg = COM32_BOUNCE_SEG;
	seg_userptr = real_to_user ( seg, 0 );

	/* Ensure the entire 64k segment is free */
	memsz = 0xFFFF;
	filesz = 0;

	/* Prepare, verify, and load the real-mode segment */
	if ( ( rc = prep_segment ( seg_userptr, filesz, memsz ) ) != 0 ) {
		DBGC ( image, "COM32 %p: could not prepare bounce buffer segment: %s\n",
		       image, strerror ( rc ) );
		return rc;
	}

	return 0;
}

/**
 * Probe COM32 image
 *
 * @v image		COM32 image
 * @ret rc		Return status code
 */
static int com32_probe ( struct image *image ) {
	int rc;

	DBGC ( image, "COM32 %p: name '%s'\n", image, image->name );

	/* Check if this is a COMBOOT image */
	if ( ( rc = com32_identify ( image ) ) != 0 ) {
		return rc;
	}

	return 0;
}

/**
 * Execute COMBOOT image
 *
 * @v image		COM32 image
 * @ret rc		Return status code
 */
static int com32_exec ( struct image *image ) {
	int rc;

	/* Load image */
	if ( ( rc = com32_load_image ( image ) ) != 0 ) {
		return rc;
	}

	/* Prepare bounce buffer segment */
	if ( ( rc = com32_prepare_bounce_buffer ( image ) ) != 0 ) {
		return rc;
	}

	/* Reset console */
	console_reset();

	return com32_exec_loop ( image );
}

/** SYSLINUX COM32 image type */
struct image_type com32_image_type __image_type ( PROBE_NORMAL ) = {
	.name = "COM32",
	.probe = com32_probe,
	.exec = com32_exec,
};
