/*
 * Copyright (C) 2013 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 <errno.h>
#include <ipxe/linux_api.h>
#include <ipxe/linux.h>
#include <ipxe/smbios.h>

/** SMBIOS filename */
static const char smbios_filename[] = "/dev/mem";

/** SMBIOS entry point scan region start address */
#define SMBIOS_ENTRY_START 0xf0000

/** SMBIOS entry point scan region length */
#define SMBIOS_ENTRY_LEN 0x10000

/** SMBIOS mapping alignment */
#define SMBIOS_ALIGN 0x1000

/**
 * Find SMBIOS
 *
 * @v smbios		SMBIOS entry point descriptor structure to fill in
 * @ret rc		Return status code
 */
static int linux_find_smbios ( struct smbios *smbios ) {
	struct smbios_entry entry;
	void *entry_mem;
	void *smbios_mem;
	size_t smbios_offset;
	size_t smbios_indent;
	size_t smbios_len;
	int fd;
	int rc;

	/* Open SMBIOS file */
	fd = linux_open ( smbios_filename, O_RDONLY );
	if ( fd < 0 ) {
		rc = -ELINUX ( linux_errno );
		DBGC ( smbios, "SMBIOS could not open %s: %s\n",
		       smbios_filename, linux_strerror ( linux_errno ) );
		goto err_open;
	}

	/* Map the region potentially containing the SMBIOS entry point */
	entry_mem = linux_mmap ( NULL, SMBIOS_ENTRY_LEN, PROT_READ, MAP_SHARED,
				 fd, SMBIOS_ENTRY_START );
	if ( entry_mem == MAP_FAILED ) {
		rc = -ELINUX ( linux_errno );
		DBGC ( smbios, "SMBIOS could not mmap %s (%#x+%#x): %s\n",
		       smbios_filename, SMBIOS_ENTRY_START, SMBIOS_ENTRY_LEN,
		       linux_strerror ( linux_errno ) );
		goto err_mmap_entry;
	}

	/* Scan for the SMBIOS entry point */
	if ( ( rc = find_smbios_entry ( virt_to_user ( entry_mem ),
					SMBIOS_ENTRY_LEN, &entry ) ) != 0 )
		goto err_find_entry;

	/* Map the region containing the SMBIOS structures */
	smbios_indent = ( entry.smbios_address & ( SMBIOS_ALIGN - 1 ) );
	smbios_offset = ( entry.smbios_address - smbios_indent );
	smbios_len = ( entry.smbios_len + smbios_indent );
	smbios_mem = linux_mmap ( NULL, smbios_len, PROT_READ, MAP_SHARED,
				  fd, smbios_offset );
	if ( smbios_mem == MAP_FAILED ) {
		rc = -ELINUX ( linux_errno );
		DBGC ( smbios, "SMBIOS could not mmap %s (%#zx+%#zx): %s\n",
		       smbios_filename, smbios_offset, smbios_len,
		       linux_strerror ( linux_errno ) );
		goto err_mmap_smbios;
	}

	/* Fill in entry point descriptor structure */
	smbios->address = virt_to_user ( smbios_mem + smbios_indent );
	smbios->len = entry.smbios_len;
	smbios->count = entry.smbios_count;
	smbios->version = SMBIOS_VERSION ( entry.major, entry.minor );

	/* Unmap the entry point region (no longer required) */
	linux_munmap ( entry_mem, SMBIOS_ENTRY_LEN );

	return 0;

	linux_munmap ( smbios_mem, smbios_len );
 err_mmap_smbios:
 err_find_entry:
	linux_munmap ( entry_mem, SMBIOS_ENTRY_LEN );
 err_mmap_entry:
	linux_close ( fd );
 err_open:
	return rc;
}

PROVIDE_SMBIOS ( linux, find_smbios, linux_find_smbios );
