/* Prepare efiemu. E.g. allocate memory, load the runtime
   to appropriate place, etc */
/*
 *  GRUB  --  GRand Unified Bootloader
 *  Copyright (C) 2009  Free Software Foundation, Inc.
 *
 *  GRUB 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 3 of the License, or
 *  (at your option) any later version.
 *
 *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <grub/err.h>
#include <grub/mm.h>
#include <grub/types.h>
#include <grub/misc.h>
#include <grub/efiemu/efiemu.h>
#include <grub/crypto.h>

grub_err_t
SUFFIX (grub_efiemu_prepare) (struct grub_efiemu_prepare_hook *prepare_hooks,
			      struct grub_efiemu_configuration_table
			      *config_tables)
{
  grub_err_t err;
  int conftable_handle;
  struct grub_efiemu_configuration_table *cur;
  struct grub_efiemu_prepare_hook *curhook;

  int cntconftables = 0;
  struct SUFFIX (grub_efiemu_configuration_table) *conftables = 0;
  int i;
  int handle;
  grub_off_t off;

  grub_dprintf ("efiemu", "Preparing EfiEmu\n");

  /* Request space for the list of configuration tables */
  for (cur = config_tables; cur; cur = cur->next)
    cntconftables++;
  conftable_handle
    = grub_efiemu_request_memalign (GRUB_EFIEMU_PAGESIZE,
				    cntconftables * sizeof (*conftables),
				    GRUB_EFI_RUNTIME_SERVICES_DATA);

  /* Switch from phase 1 (counting) to phase 2 (real job) */
  grub_efiemu_alloc_syms ();
  grub_efiemu_mm_do_alloc ();
  grub_efiemu_write_sym_markers ();

  grub_efiemu_system_table32 = 0;
  grub_efiemu_system_table64 = 0;

  /* Execute hooks */
  for (curhook = prepare_hooks; curhook; curhook = curhook->next)
    curhook->hook (curhook->data);

  /* Move runtime to its due place */
  err = grub_efiemu_loadcore_load ();
  if (err)
    {
      grub_efiemu_unload ();
      return err;
    }

  err = grub_efiemu_resolve_symbol ("efiemu_system_table", &handle, &off);
  if (err)
    {
      grub_efiemu_unload ();
      return err;
    }

  SUFFIX (grub_efiemu_system_table)
    = (struct SUFFIX (grub_efi_system_table) *)
    ((grub_uint8_t *) grub_efiemu_mm_obtain_request (handle) + off);

  /* Put pointer to the list of configuration tables in system table */
  err = grub_efiemu_write_value
	(&(SUFFIX (grub_efiemu_system_table)->configuration_table), 0,
	 conftable_handle, 0, 1,
	 sizeof (SUFFIX (grub_efiemu_system_table)->configuration_table));
  if (err)
    {
      grub_efiemu_unload ();
      return err;
    }

  SUFFIX(grub_efiemu_system_table)->num_table_entries = cntconftables;

  /* Fill the list of configuration tables */
  conftables = (struct SUFFIX (grub_efiemu_configuration_table) *)
    grub_efiemu_mm_obtain_request (conftable_handle);
  i = 0;
  for (cur = config_tables; cur; cur = cur->next, i++)
    {
      grub_memcpy (&(conftables[i].vendor_guid), &(cur->guid),
		       sizeof (cur->guid));
      if (cur->get_table)
	conftables[i].vendor_table = (grub_addr_t) cur->get_table (cur->data);
      else
	conftables[i].vendor_table = (grub_addr_t) cur->data;
    }

  err = SUFFIX (grub_efiemu_crc) ();
  if (err)
    {
      grub_efiemu_unload ();
      return err;
    }

  grub_dprintf ("efiemu","system_table = %p, conftables = %p (%d entries)\n",
		SUFFIX (grub_efiemu_system_table), conftables, cntconftables);

  return GRUB_ERR_NONE;
}

grub_err_t
SUFFIX (grub_efiemu_crc) (void)
{
  grub_err_t err;
  int handle;
  grub_off_t off;
  struct SUFFIX (grub_efiemu_runtime_services) *runtime_services;
  grub_uint32_t crc32_val;

  if (GRUB_MD_CRC32->mdlen != 4)
    return grub_error (GRUB_ERR_BUG, "incorrect mdlen");

  /* compute CRC32 of runtime_services */
  err = grub_efiemu_resolve_symbol ("efiemu_runtime_services",
				    &handle, &off);
  if (err)
    return err;

  runtime_services = (struct SUFFIX (grub_efiemu_runtime_services) *)
	((grub_uint8_t *) grub_efiemu_mm_obtain_request (handle) + off);

  runtime_services->hdr.crc32 = 0;

  grub_crypto_hash (GRUB_MD_CRC32, &crc32_val,
		    runtime_services, runtime_services->hdr.header_size);
  runtime_services->hdr.crc32 =
      grub_be_to_cpu32(crc32_val);

  err = grub_efiemu_resolve_symbol ("efiemu_system_table", &handle, &off);
  if (err)
    return err;

  /* compute CRC32 of system table */
  SUFFIX (grub_efiemu_system_table)->hdr.crc32 = 0;
  grub_crypto_hash (GRUB_MD_CRC32, &crc32_val,
		    SUFFIX (grub_efiemu_system_table),
		    SUFFIX (grub_efiemu_system_table)->hdr.header_size);
  SUFFIX (grub_efiemu_system_table)->hdr.crc32 =
      grub_be_to_cpu32(crc32_val);

  grub_dprintf ("efiemu","system_table = %p, runtime_services = %p\n",
		SUFFIX (grub_efiemu_system_table), runtime_services);

  return GRUB_ERR_NONE;
}
