/*
 *  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/env.h>
#include <grub/file.h>
#include <grub/disk.h>
#include <grub/xnu.h>
#include <grub/cpu/xnu.h>
#include <grub/mm.h>
#include <grub/loader.h>
#include <grub/autoefi.h>
#include <grub/i386/tsc.h>
#include <grub/i386/cpuid.h>
#include <grub/efi/api.h>
#include <grub/i386/pit.h>
#include <grub/misc.h>
#include <grub/charset.h>
#include <grub/term.h>
#include <grub/command.h>
#include <grub/i18n.h>
#include <grub/bitmap_scale.h>
#include <grub/cpu/io.h>
#include <grub/random.h>

#define min(a,b) (((a) < (b)) ? (a) : (b))
#define max(a,b) (((a) > (b)) ? (a) : (b))

#define DEFAULT_VIDEO_MODE "auto"

char grub_xnu_cmdline[1024];
grub_uint32_t grub_xnu_entry_point, grub_xnu_arg1, grub_xnu_stack;

/* Aliases set for some tables. */
struct tbl_alias
{
  grub_efi_guid_t guid;
  const char *name;
};

static struct tbl_alias table_aliases[] =
  {
    {GRUB_EFI_ACPI_20_TABLE_GUID, "ACPI_20"},
    {GRUB_EFI_ACPI_TABLE_GUID, "ACPI"},
  };

struct grub_xnu_devprop_device_descriptor
{
  struct grub_xnu_devprop_device_descriptor *next;
  struct grub_xnu_devprop_device_descriptor **prev;
  struct property_descriptor *properties;
  struct grub_efi_device_path *path;
  int pathlen;
};

static int
utf16_strlen (grub_uint16_t *in)
{
  int i;
  for (i = 0; in[i]; i++);
  return i;
}

/* Read frequency from a string in MHz and return it in Hz. */
static grub_uint64_t
readfrequency (const char *str)
{
  grub_uint64_t num = 0;
  int mul = 1000000;
  int found = 0;

  while (*str)
    {
      unsigned long digit;

      digit = grub_tolower (*str) - '0';
      if (digit > 9)
	break;

      found = 1;

      num = num * 10 + digit;
      str++;
    }
  num *= 1000000;
  if (*str == '.')
    {
      str++;
      while (*str)
	{
	  unsigned long digit;

	  digit = grub_tolower (*str) - '0';
	  if (digit > 9)
	    break;

	  found = 1;

	  mul /= 10;
	  num = num + mul * digit;
	  str++;
	}
    }
  if (! found)
    return 0;

  return num;
}

/* Thanks to Kabyl for precious information about Intel architecture. */
static grub_uint64_t
guessfsb (void)
{
  const grub_uint64_t sane_value = 100000000;
  grub_uint32_t manufacturer[3], max_cpuid, capabilities, msrlow;
  grub_uint32_t a, b, d, divisor;

  if (! grub_cpu_is_cpuid_supported ())
    return sane_value;

  grub_cpuid (0, max_cpuid, manufacturer[0], manufacturer[2], manufacturer[1]);

  /* Only Intel for now is done. */
  if (grub_memcmp (manufacturer, "GenuineIntel", 12) != 0)
    return sane_value;

  /* Check Speedstep. */
  if (max_cpuid < 1)
    return sane_value;

  grub_cpuid (1, a, b, capabilities, d);

  if (! (capabilities & (1 << 7)))
    return sane_value;

  /* Read the multiplier. */
  asm volatile ("movl $0x198, %%ecx\n"
		"rdmsr"
		: "=d" (msrlow)
		:
		: "%ecx", "%eax");

  grub_uint64_t v;
  grub_uint32_t r;

  /* (2000ULL << 32) / grub_tsc_rate  */
  /* Assumption: TSC frequency is over 2 MHz.  */
  v = 0xffffffff / grub_tsc_rate;
  v *= 2000;
  /* v is at most 2000 off from (2000ULL << 32) / grub_tsc_rate.
     Since grub_tsc_rate < 2^32/2^11=2^21, so no overflow.
   */
  r = (2000ULL << 32) - v * grub_tsc_rate;
  v += r / grub_tsc_rate;

  divisor = ((msrlow >> 7) & 0x3e) | ((msrlow >> 14) & 1);
  if (divisor == 0)
    return sane_value;
  return grub_divmod64 (v, divisor, 0);
}

struct property_descriptor
{
  struct property_descriptor *next;
  struct property_descriptor **prev;
  grub_uint8_t *name;
  grub_uint16_t *name16;
  int name16len;
  int length;
  void *data;
};

static struct grub_xnu_devprop_device_descriptor *devices = 0;

grub_err_t
grub_xnu_devprop_remove_property (struct grub_xnu_devprop_device_descriptor *dev,
				  char *name)
{
  struct property_descriptor *prop;
  prop = grub_named_list_find (GRUB_AS_NAMED_LIST (dev->properties), name);
  if (!prop)
    return GRUB_ERR_NONE;

  grub_free (prop->name);
  grub_free (prop->name16);
  grub_free (prop->data);

  grub_list_remove (GRUB_AS_LIST (prop));

  return GRUB_ERR_NONE;
}

grub_err_t
grub_xnu_devprop_remove_device (struct grub_xnu_devprop_device_descriptor *dev)
{
  void *t;
  struct property_descriptor *prop;

  grub_list_remove (GRUB_AS_LIST (dev));

  for (prop = dev->properties; prop; )
    {
      grub_free (prop->name);
      grub_free (prop->name16);
      grub_free (prop->data);
      t = prop;
      prop = prop->next;
      grub_free (t);
    }

  grub_free (dev->path);
  grub_free (dev);

  return GRUB_ERR_NONE;
}

struct grub_xnu_devprop_device_descriptor *
grub_xnu_devprop_add_device (struct grub_efi_device_path *path, int length)
{
  struct grub_xnu_devprop_device_descriptor *ret;

  ret = grub_zalloc (sizeof (*ret));
  if (!ret)
    return 0;

  ret->path = grub_malloc (length);
  if (!ret->path)
    {
      grub_free (ret);
      return 0;
    }
  ret->pathlen = length;
  grub_memcpy (ret->path, path, length);

  grub_list_push (GRUB_AS_LIST_P (&devices), GRUB_AS_LIST (ret));

  return ret;
}

static grub_err_t
grub_xnu_devprop_add_property (struct grub_xnu_devprop_device_descriptor *dev,
			       grub_uint8_t *utf8, grub_uint16_t *utf16,
			       int utf16len, void *data, int datalen)
{
  struct property_descriptor *prop;

  prop = grub_malloc (sizeof (*prop));
  if (!prop)
    return grub_errno;

  prop->name = utf8;
  prop->name16 = utf16;
  prop->name16len = utf16len;

  prop->length = datalen;
  prop->data = grub_malloc (prop->length);
  if (!prop->data)
    {
      grub_free (prop->name);
      grub_free (prop->name16);
      grub_free (prop);
      return grub_errno;
    }
  grub_memcpy (prop->data, data, prop->length);
  grub_list_push (GRUB_AS_LIST_P (&dev->properties),
		  GRUB_AS_LIST (prop));
  return GRUB_ERR_NONE;
}

grub_err_t
grub_xnu_devprop_add_property_utf8 (struct grub_xnu_devprop_device_descriptor *dev,
				    char *name, void *data, int datalen)
{
  grub_uint8_t *utf8;
  grub_uint16_t *utf16;
  int len, utf16len;
  grub_err_t err;

  utf8 = (grub_uint8_t *) grub_strdup (name);
  if (!utf8)
    return grub_errno;

  len = grub_strlen (name);
  utf16 = grub_malloc (sizeof (grub_uint16_t) * len);
  if (!utf16)
    {
      grub_free (utf8);
      return grub_errno;
    }

  utf16len = grub_utf8_to_utf16 (utf16, len, utf8, len, NULL);
  if (utf16len < 0)
    {
      grub_free (utf8);
      grub_free (utf16);
      return grub_errno;
    }

  err = grub_xnu_devprop_add_property (dev, utf8, utf16,
				       utf16len, data, datalen);
  if (err)
    {
      grub_free (utf8);
      grub_free (utf16);
      return err;
    }

  return GRUB_ERR_NONE;
}

grub_err_t
grub_xnu_devprop_add_property_utf16 (struct grub_xnu_devprop_device_descriptor *dev,
				     grub_uint16_t *name, int namelen,
				     void *data, int datalen)
{
  grub_uint8_t *utf8;
  grub_uint16_t *utf16;
  grub_err_t err;

  utf16 = grub_malloc (sizeof (grub_uint16_t) * namelen);
  if (!utf16)
    return grub_errno;
  grub_memcpy (utf16, name, sizeof (grub_uint16_t) * namelen);

  utf8 = grub_malloc (namelen * 4 + 1);
  if (!utf8)
    {
      grub_free (utf16);
      return grub_errno;
    }

  *grub_utf16_to_utf8 ((grub_uint8_t *) utf8, name, namelen) = '\0';

  err = grub_xnu_devprop_add_property (dev, utf8, utf16,
				       namelen, data, datalen);
  if (err)
    {
      grub_free (utf8);
      grub_free (utf16);
      return err;
    }

  return GRUB_ERR_NONE;
}

void
grub_cpu_xnu_unload (void)
{
  struct grub_xnu_devprop_device_descriptor *dev1, *dev2;

  for (dev1 = devices; dev1; )
    {
      dev2 = dev1->next;
      grub_xnu_devprop_remove_device (dev1);
      dev1 = dev2;
    }
}

static grub_err_t
grub_cpu_xnu_fill_devprop (void)
{
  struct grub_xnu_devtree_key *efikey;
  int total_length = sizeof (struct grub_xnu_devprop_header);
  struct grub_xnu_devtree_key *devprop;
  struct grub_xnu_devprop_device_descriptor *device;
  void *ptr;
  struct grub_xnu_devprop_header *head;
  void *t;
  int numdevs = 0;

  /* The key "efi". */
  efikey = grub_xnu_create_key (&grub_xnu_devtree_root, "efi");
  if (! efikey)
    return grub_errno;

  for (device = devices; device; device = device->next)
    {
      struct property_descriptor *propdesc;
      total_length += sizeof (struct grub_xnu_devprop_device_header);
      total_length += device->pathlen;

      for (propdesc = device->properties; propdesc; propdesc = propdesc->next)
	{
	  total_length += sizeof (grub_uint32_t);
	  total_length += sizeof (grub_uint16_t)
	    * (propdesc->name16len + 1);
	  total_length += sizeof (grub_uint32_t);
	  total_length += propdesc->length;
	}
      numdevs++;
    }

  devprop = grub_xnu_create_value (&(efikey->first_child), "device-properties");
  if (!devprop)
    return grub_errno;

  devprop->data = grub_malloc (total_length);
  devprop->datasize = total_length;

  ptr = devprop->data;
  head = ptr;
  ptr = head + 1;
  head->length = total_length;
  head->alwaysone = 1;
  head->num_devices = numdevs;
  for (device = devices; device; )
    {
      struct grub_xnu_devprop_device_header *devhead;
      struct property_descriptor *propdesc;
      devhead = ptr;
      devhead->num_values = 0;
      ptr = devhead + 1;

      grub_memcpy (ptr, device->path, device->pathlen);
      ptr = (char *) ptr + device->pathlen;

      for (propdesc = device->properties; propdesc; )
	{
	  grub_uint32_t *len;
	  grub_uint16_t *name;
	  void *data;

	  len = ptr;
	  *len = 2 * propdesc->name16len + sizeof (grub_uint16_t)
	    + sizeof (grub_uint32_t);
	  ptr = len + 1;

	  name = ptr;
	  grub_memcpy (name, propdesc->name16, 2 * propdesc->name16len);
	  name += propdesc->name16len;

	  /* NUL terminator.  */
	  *name = 0;
	  ptr = name + 1;

	  len = ptr;
	  *len = propdesc->length + sizeof (grub_uint32_t);
	  data = len + 1;
	  ptr = data;
	  grub_memcpy (ptr, propdesc->data, propdesc->length);
	  ptr = (char *) ptr + propdesc->length;

	  grub_free (propdesc->name);
	  grub_free (propdesc->name16);
	  grub_free (propdesc->data);
	  t = propdesc;
	  propdesc = propdesc->next;
	  grub_free (t);
	  devhead->num_values++;
	}

      devhead->length = (char *) ptr - (char *) devhead;
      t = device;
      device = device->next;
      grub_free (t);
    }

  devices = 0;

  return GRUB_ERR_NONE;
}

static grub_err_t
grub_cmd_devprop_load (grub_command_t cmd __attribute__ ((unused)),
		       int argc, char *args[])
{
  grub_file_t file;
  void *buf, *bufstart, *bufend;
  struct grub_xnu_devprop_header *head;
  grub_size_t size;
  unsigned i, j;

  if (argc != 1)
    return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));

  file = grub_file_open (args[0], GRUB_FILE_XNU_DEVPROP);
  if (! file)
    return grub_errno;
  size = grub_file_size (file);
  buf = grub_malloc (size);
  if (!buf)
    {
      grub_file_close (file);
      return grub_errno;
    }
  if (grub_file_read (file, buf, size) != (grub_ssize_t) size)
    {
      grub_file_close (file);
      return grub_errno;
    }
  grub_file_close (file);

  bufstart = buf;
  bufend = (char *) buf + size;
  head = buf;
  buf = head + 1;
  for (i = 0; i < grub_le_to_cpu32 (head->num_devices) && buf < bufend; i++)
    {
      struct grub_efi_device_path *dp, *dpstart;
      struct grub_xnu_devprop_device_descriptor *dev;
      struct grub_xnu_devprop_device_header *devhead;

      devhead = buf;
      buf = devhead + 1;
      dpstart = buf;

      do
	{
	  dp = buf;
	  buf = (char *) buf + GRUB_EFI_DEVICE_PATH_LENGTH (dp);
	}
      while (!GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp) && buf < bufend);

      dev = grub_xnu_devprop_add_device (dpstart, (char *) buf
					 - (char *) dpstart);

      for (j = 0; j < grub_le_to_cpu32 (devhead->num_values) && buf < bufend;
	   j++)
	{
	  grub_uint32_t *namelen;
	  grub_uint32_t *datalen;
	  grub_uint16_t *utf16;
	  void *data;
	  grub_err_t err;

	  namelen = buf;
	  buf = namelen + 1;
	  if (buf >= bufend)
	    break;

	  utf16 = buf;
	  buf = (char *) buf + *namelen - sizeof (grub_uint32_t);
	  if (buf >= bufend)
	    break;

	  datalen = buf;
	  buf = datalen + 1;
	  if (buf >= bufend)
	    break;

	  data = buf;
	  buf = (char *) buf + *datalen - sizeof (grub_uint32_t);
	  if (buf >= bufend)
	    break;
	  err = grub_xnu_devprop_add_property_utf16
	    (dev, utf16, (*namelen - sizeof (grub_uint32_t)
			  - sizeof (grub_uint16_t)) / sizeof (grub_uint16_t),
	     data, *datalen - sizeof (grub_uint32_t));
	  if (err)
	    {
	      grub_free (bufstart);
	      return err;
	    }
	}
    }

  grub_free (bufstart);
  return GRUB_ERR_NONE;
}

/* Fill device tree. */
/* FIXME: some entries may be platform-agnostic. Move them to loader/xnu.c. */
static grub_err_t
grub_cpu_xnu_fill_devicetree (grub_uint64_t *fsbfreq_out)
{
  struct grub_xnu_devtree_key *efikey;
  struct grub_xnu_devtree_key *chosenkey;
  struct grub_xnu_devtree_key *cfgtablekey;
  struct grub_xnu_devtree_key *curval;
  struct grub_xnu_devtree_key *runtimesrvkey;
  struct grub_xnu_devtree_key *platformkey;
  unsigned i, j;
  grub_err_t err;

  chosenkey = grub_xnu_create_key (&grub_xnu_devtree_root, "chosen");
  if (! chosenkey)
    return grub_errno;

  /* Random seed. */
  curval = grub_xnu_create_value (&(chosenkey->first_child), "random-seed");
  if (! curval)
    return grub_errno;
  curval->datasize = 64;
  curval->data = grub_malloc (curval->datasize);
  if (! curval->data)
    return grub_errno;
  /* Our random is not peer-reviewed but xnu uses this seed only for
     ASLR in kernel.  */
  err = grub_crypto_get_random (curval->data, curval->datasize);
  if (err)
    return err;

  /* The value "model". */
  /* FIXME: may this value be sometimes different? */
  curval = grub_xnu_create_value (&grub_xnu_devtree_root, "model");
  if (! curval)
    return grub_errno;
  curval->datasize = sizeof ("ACPI");
  curval->data = grub_strdup ("ACPI");
  curval = grub_xnu_create_value (&grub_xnu_devtree_root, "compatible");
  if (! curval)
    return grub_errno;
  curval->datasize = sizeof ("ACPI");
  curval->data = grub_strdup ("ACPI");

  /* The key "efi". */
  efikey = grub_xnu_create_key (&grub_xnu_devtree_root, "efi");
  if (! efikey)
    return grub_errno;

  /* Information about firmware. */
  curval = grub_xnu_create_value (&(efikey->first_child), "firmware-revision");
  if (! curval)
    return grub_errno;
  curval->datasize = (SYSTEM_TABLE_SIZEOF (firmware_revision));
  curval->data = grub_malloc (curval->datasize);
  if (! curval->data)
    return grub_errno;
  grub_memcpy (curval->data, (SYSTEM_TABLE_VAR(firmware_revision)),
	       curval->datasize);

  curval = grub_xnu_create_value (&(efikey->first_child), "firmware-vendor");
  if (! curval)
    return grub_errno;
  curval->datasize =
    2 * (utf16_strlen (SYSTEM_TABLE_PTR (firmware_vendor)) + 1);
  curval->data = grub_malloc (curval->datasize);
  if (! curval->data)
    return grub_errno;
  grub_memcpy (curval->data, SYSTEM_TABLE_PTR (firmware_vendor),
	       curval->datasize);

  curval = grub_xnu_create_value (&(efikey->first_child), "firmware-abi");
  if (! curval)
    return grub_errno;
  curval->datasize = sizeof ("EFI32");
  curval->data = grub_malloc (curval->datasize);
  if (! curval->data)
    return grub_errno;
  if (SIZEOF_OF_UINTN == 4)
    grub_memcpy (curval->data, "EFI32", curval->datasize);
  else
    grub_memcpy (curval->data, "EFI64", curval->datasize);

  /* The key "platform". */
  platformkey = grub_xnu_create_key (&(efikey->first_child),
				     "platform");
  if (! platformkey)
    return grub_errno;

  /* Pass FSB frequency to the kernel. */
  curval = grub_xnu_create_value (&(platformkey->first_child), "FSBFrequency");
  if (! curval)
    return grub_errno;
  curval->datasize = sizeof (grub_uint64_t);
  curval->data = grub_malloc (curval->datasize);
  if (!curval->data)
    return grub_errno;

  /* First see if user supplies the value. */
  const char *fsbvar = grub_env_get ("fsb");
  grub_uint64_t fsbfreq = 0;
  if (fsbvar)
    fsbfreq = readfrequency (fsbvar);
  /* Try autodetect. */
  if (! fsbfreq)
    fsbfreq = guessfsb ();
  *((grub_uint64_t *) curval->data) = fsbfreq;
  *fsbfreq_out = fsbfreq;
  grub_dprintf ("xnu", "fsb autodetected as %llu\n",
		(unsigned long long) *((grub_uint64_t *) curval->data));

  cfgtablekey = grub_xnu_create_key (&(efikey->first_child),
				     "configuration-table");
  if (!cfgtablekey)
    return grub_errno;

  /* Fill "configuration-table" key. */
  for (i = 0; i < SYSTEM_TABLE (num_table_entries); i++)
    {
      void *ptr;
      struct grub_xnu_devtree_key *curkey;
      grub_efi_packed_guid_t guid;
      char guidbuf[64];

      /* Retrieve current key. */
#ifdef GRUB_MACHINE_EFI
      {
	ptr = (void *)
	  grub_efi_system_table->configuration_table[i].vendor_table;
	guid = grub_efi_system_table->configuration_table[i].vendor_guid;
      }
#else
      if (SIZEOF_OF_UINTN == 4)
	{
	  ptr = (void *) (grub_addr_t) ((grub_efiemu_configuration_table32_t *)
					SYSTEM_TABLE_PTR (configuration_table))[i]
	    .vendor_table;
	  guid =
	    ((grub_efiemu_configuration_table32_t *)
	     SYSTEM_TABLE_PTR (configuration_table))[i].vendor_guid;
	}
      else
	{
	  ptr = (void *) (grub_addr_t) ((grub_efiemu_configuration_table64_t *)
					SYSTEM_TABLE_PTR (configuration_table))[i]
	    .vendor_table;
	  guid =
	    ((grub_efiemu_configuration_table64_t *)
	     SYSTEM_TABLE_PTR (configuration_table))[i].vendor_guid;
	}
#endif

      /* The name of key for new table. */
      grub_snprintf (guidbuf, sizeof (guidbuf), "%08x-%04x-%04x-%02x%02x-",
		     guid.data1, guid.data2, guid.data3, guid.data4[0],
		     guid.data4[1]);
      for (j = 2; j < 8; j++)
	grub_snprintf (guidbuf + grub_strlen (guidbuf),
		       sizeof (guidbuf) - grub_strlen (guidbuf),
		       "%02x", guid.data4[j]);
      /* For some reason GUID has to be in uppercase. */
      for (j = 0; guidbuf[j] ; j++)
	if (guidbuf[j] >= 'a' && guidbuf[j] <= 'f')
	  guidbuf[j] += 'A' - 'a';
      curkey = grub_xnu_create_key (&(cfgtablekey->first_child), guidbuf);
      if (! curkey)
	return grub_errno;

      curval = grub_xnu_create_value (&(curkey->first_child), "guid");
      if (! curval)
	return grub_errno;
      curval->datasize = sizeof (guid);
      curval->data = grub_malloc (curval->datasize);
      if (! curval->data)
	return grub_errno;
      grub_memcpy (curval->data, &guid, curval->datasize);

      /* The value "table". */
      curval = grub_xnu_create_value (&(curkey->first_child), "table");
      if (! curval)
	return grub_errno;
      curval->datasize = SIZEOF_OF_UINTN;
      curval->data = grub_malloc (curval->datasize);
      if (! curval->data)
	return grub_errno;
      if (SIZEOF_OF_UINTN == 4)
	*((grub_uint32_t *) curval->data) = (grub_addr_t) ptr;
      else
	*((grub_uint64_t *) curval->data) = (grub_addr_t) ptr;

      /* Create alias. */
      for (j = 0; j < ARRAY_SIZE(table_aliases); j++)
	if (grub_memcmp (&table_aliases[j].guid, &guid, sizeof (guid)) == 0)
	  break;
      if (j != ARRAY_SIZE(table_aliases))
	{
	  curval = grub_xnu_create_value (&(curkey->first_child), "alias");
	  if (!curval)
	    return grub_errno;
	  curval->datasize = grub_strlen (table_aliases[j].name) + 1;
	  curval->data = grub_malloc (curval->datasize);
	  if (!curval->data)
	    return grub_errno;
	  grub_memcpy (curval->data, table_aliases[j].name, curval->datasize);
	}
    }

  /* Create and fill "runtime-services" key. */
  runtimesrvkey = grub_xnu_create_key (&(efikey->first_child),
				       "runtime-services");
  if (! runtimesrvkey)
    return grub_errno;
  curval = grub_xnu_create_value (&(runtimesrvkey->first_child), "table");
  if (! curval)
    return grub_errno;
  curval->datasize = SIZEOF_OF_UINTN;
  curval->data = grub_malloc (curval->datasize);
  if (! curval->data)
    return grub_errno;
  if (SIZEOF_OF_UINTN == 4)
    *((grub_uint32_t *) curval->data)
      = (grub_addr_t) SYSTEM_TABLE_PTR (runtime_services);
  else
    *((grub_uint64_t *) curval->data)
      = (grub_addr_t) SYSTEM_TABLE_PTR (runtime_services);

  return GRUB_ERR_NONE;
}

grub_err_t
grub_xnu_boot_resume (void)
{
  struct grub_relocator32_state state;

  state.esp = grub_xnu_stack;
  state.ebp = grub_xnu_stack;
  state.eip = grub_xnu_entry_point;
  state.eax = grub_xnu_arg1;

  return grub_relocator32_boot (grub_xnu_relocator, state, 0); 
}

/* Setup video for xnu. */
static grub_err_t
grub_xnu_set_video (struct grub_xnu_boot_params_common *params)
{
  struct grub_video_mode_info mode_info;
  char *tmp;
  const char *modevar;
  void *framebuffer;
  grub_err_t err;
  struct grub_video_bitmap *bitmap = NULL;

  modevar = grub_env_get ("gfxpayload");
  /* Consider only graphical 32-bit deep modes.  */
  if (! modevar || *modevar == 0)
    err = grub_video_set_mode (DEFAULT_VIDEO_MODE,
			       GRUB_VIDEO_MODE_TYPE_PURE_TEXT
			       | GRUB_VIDEO_MODE_TYPE_DEPTH_MASK,
			       32 << GRUB_VIDEO_MODE_TYPE_DEPTH_POS);
  else
    {
      tmp = grub_xasprintf ("%s;" DEFAULT_VIDEO_MODE, modevar);
      if (! tmp)
	return grub_errno;
      err = grub_video_set_mode (tmp,
				 GRUB_VIDEO_MODE_TYPE_PURE_TEXT
				 | GRUB_VIDEO_MODE_TYPE_DEPTH_MASK,
				 32 << GRUB_VIDEO_MODE_TYPE_DEPTH_POS);
      grub_free (tmp);
    }

  if (err)
    return err;

  err = grub_video_get_info (&mode_info);
  if (err)
    return err;

  if (grub_xnu_bitmap)
     {
       if (grub_xnu_bitmap_mode == GRUB_XNU_BITMAP_STRETCH)
	 err = grub_video_bitmap_create_scaled (&bitmap,
						mode_info.width,
						mode_info.height,
						grub_xnu_bitmap,
						GRUB_VIDEO_BITMAP_SCALE_METHOD_BEST);
       else
	 bitmap = grub_xnu_bitmap;
     }

  if (bitmap)
    {
      if (grub_xnu_bitmap_mode == GRUB_XNU_BITMAP_STRETCH)
	err = grub_video_bitmap_create_scaled (&bitmap,
					       mode_info.width,
					       mode_info.height,
					       grub_xnu_bitmap,
					       GRUB_VIDEO_BITMAP_SCALE_METHOD_BEST);
      else
	bitmap = grub_xnu_bitmap;
    }

  if (bitmap)
    {
      int x, y;

      x = mode_info.width - bitmap->mode_info.width;
      x /= 2;
      y = mode_info.height - bitmap->mode_info.height;
      y /= 2;
      err = grub_video_blit_bitmap (bitmap,
				    GRUB_VIDEO_BLIT_REPLACE,
				    x > 0 ? x : 0,
				    y > 0 ? y : 0,
				    x < 0 ? -x : 0,
				    y < 0 ? -y : 0,
				    min (bitmap->mode_info.width,
					 mode_info.width),
				    min (bitmap->mode_info.height,
					 mode_info.height));
    }
  if (err)
    {
      grub_print_error ();
      grub_errno = GRUB_ERR_NONE;
      bitmap = 0;
    }

  err = grub_video_get_info_and_fini (&mode_info, &framebuffer);
  if (err)
    return err;

  params->lfb_width = mode_info.width;
  params->lfb_height = mode_info.height;
  params->lfb_depth = mode_info.bpp;
  params->lfb_line_len = mode_info.pitch;

  params->lfb_base = (grub_addr_t) framebuffer;
  params->lfb_mode = bitmap ? GRUB_XNU_VIDEO_SPLASH 
    : GRUB_XNU_VIDEO_TEXT_IN_VIDEO;

  return GRUB_ERR_NONE;
}

static int
total_ram_hook (grub_uint64_t addr __attribute__ ((unused)), grub_uint64_t size,
		grub_memory_type_t type,
		void *data)
{
  grub_uint64_t *result = data;

  if (type != GRUB_MEMORY_AVAILABLE)
    return 0;
  *result += size;
  return 0;
}

static grub_uint64_t
get_total_ram (void)
{
  grub_uint64_t result = 0;

  grub_mmap_iterate (total_ram_hook, &result);
  return result;
}

/* Boot xnu. */
grub_err_t
grub_xnu_boot (void)
{
  union grub_xnu_boot_params_any *bootparams;
  struct grub_xnu_boot_params_common *bootparams_common;
  void *bp_in;
  grub_addr_t bootparams_target;
  grub_err_t err;
  grub_efi_uintn_t memory_map_size = 0;
  void *memory_map;
  grub_addr_t memory_map_target;
  grub_efi_uintn_t map_key = 0;
  grub_efi_uintn_t descriptor_size = 0;
  grub_efi_uint32_t descriptor_version = 0;
  grub_uint64_t firstruntimepage, lastruntimepage;
  grub_uint64_t curruntimepage;
  grub_addr_t devtree_target;
  grub_size_t devtreelen;
  int i;
  struct grub_relocator32_state state;
  grub_uint64_t fsbfreq = 100000000;
  int v2 = (grub_xnu_darwin_version >= 11);
  grub_uint32_t efi_system_table = 0;

  err = grub_autoefi_prepare ();
  if (err)
    return err;

  err = grub_cpu_xnu_fill_devprop ();
  if (err)
    return err;

  err = grub_cpu_xnu_fill_devicetree (&fsbfreq);
  if (err)
    return err;

  err = grub_xnu_fill_devicetree ();
  if (err)
    return err;

  /* Page-align to avoid following parts to be inadvertently freed. */
  err = grub_xnu_align_heap (GRUB_XNU_PAGESIZE);
  if (err)
    return err;

  /* Pass memory map to kernel. */
  memory_map_size = 0;
  memory_map = 0;
  map_key = 0;
  descriptor_size = 0;
  descriptor_version = 0;

  grub_dprintf ("xnu", "eip=%x, efi=%p\n", grub_xnu_entry_point,
		grub_autoefi_system_table);

  const char *debug = grub_env_get ("debug");

  if (debug && (grub_strword (debug, "all") || grub_strword (debug, "xnu")))
    {
      grub_puts_ (N_("Press any key to launch xnu"));
      grub_getkey ();
    }

  /* Relocate the boot parameters to heap. */
  err = grub_xnu_heap_malloc (sizeof (*bootparams),
			      &bp_in, &bootparams_target);
  if (err)
    return err;
  bootparams = bp_in;

  grub_memset (bootparams, 0, sizeof (*bootparams));
  if (v2)
    {
      bootparams_common = &bootparams->v2.common;
      bootparams->v2.fsbfreq = fsbfreq;
      bootparams->v2.ram_size = get_total_ram();
    }
  else
    bootparams_common = &bootparams->v1.common;

  /* Set video. */
  err = grub_xnu_set_video (bootparams_common);
  if (err != GRUB_ERR_NONE)
    {
      grub_print_error ();
      grub_errno = GRUB_ERR_NONE;
      grub_puts_ (N_("Booting in blind mode"));

      bootparams_common->lfb_mode = 0;
      bootparams_common->lfb_width = 0;
      bootparams_common->lfb_height = 0;
      bootparams_common->lfb_depth = 0;
      bootparams_common->lfb_line_len = 0;
      bootparams_common->lfb_base = 0;
    }

  if (grub_autoefi_get_memory_map (&memory_map_size, memory_map,
				   &map_key, &descriptor_size,
				   &descriptor_version) < 0)
    return grub_errno;

  /* We will do few allocations later. Reserve some space for possible
     memory map growth.  */
  memory_map_size += 20 * descriptor_size;
  err = grub_xnu_heap_malloc (memory_map_size,
			      &memory_map, &memory_map_target);
  if (err)
    return err;

  err = grub_xnu_writetree_toheap (&devtree_target, &devtreelen);
  if (err)
    return err;

  grub_memcpy (bootparams_common->cmdline, grub_xnu_cmdline,
	       sizeof (bootparams_common->cmdline));

  bootparams_common->devtree = devtree_target;
  bootparams_common->devtreelen = devtreelen;

  err = grub_autoefi_finish_boot_services (&memory_map_size, memory_map,
					   &map_key, &descriptor_size,
					   &descriptor_version);
  if (err)
    return err;

  if (v2)
    bootparams->v2.efi_system_table = (grub_addr_t) grub_autoefi_system_table;
  else
    bootparams->v1.efi_system_table = (grub_addr_t) grub_autoefi_system_table;  

  firstruntimepage = (((grub_addr_t) grub_xnu_heap_target_start
		       + grub_xnu_heap_size + GRUB_XNU_PAGESIZE - 1)
		      / GRUB_XNU_PAGESIZE) + 20;
  curruntimepage = firstruntimepage;

  for (i = 0; (unsigned) i < memory_map_size / descriptor_size; i++)
    {
      grub_efi_memory_descriptor_t *curdesc = (grub_efi_memory_descriptor_t *)
	((char *) memory_map + descriptor_size * i);

      curdesc->virtual_start = curdesc->physical_start;

      if (curdesc->type == GRUB_EFI_RUNTIME_SERVICES_DATA
	  || curdesc->type == GRUB_EFI_RUNTIME_SERVICES_CODE)
	{
	  curdesc->virtual_start = curruntimepage << 12;
	  curruntimepage += curdesc->num_pages;
	  if (curdesc->physical_start
	      <= (grub_addr_t) grub_autoefi_system_table
	      && curdesc->physical_start + (curdesc->num_pages << 12)
	      > (grub_addr_t) grub_autoefi_system_table)
	    efi_system_table
	      = (grub_addr_t) grub_autoefi_system_table
	      - curdesc->physical_start + curdesc->virtual_start;
	  if (SIZEOF_OF_UINTN == 8 && grub_xnu_is_64bit)
	    curdesc->virtual_start |= 0xffffff8000000000ULL;
	}
    }

  lastruntimepage = curruntimepage;

  if (v2)
    {
      bootparams->v2.efi_uintnbits = SIZEOF_OF_UINTN * 8;
      bootparams->v2.verminor = GRUB_XNU_BOOTARGSV2_VERMINOR;
      bootparams->v2.vermajor = GRUB_XNU_BOOTARGSV2_VERMAJOR;
      bootparams->v2.efi_system_table = efi_system_table;
    }
  else
    {
      bootparams->v1.efi_uintnbits = SIZEOF_OF_UINTN * 8;
      bootparams->v1.verminor = GRUB_XNU_BOOTARGSV1_VERMINOR;
      bootparams->v1.vermajor = GRUB_XNU_BOOTARGSV1_VERMAJOR;
      bootparams->v1.efi_system_table = efi_system_table;
    }

  bootparams_common->efi_runtime_first_page = firstruntimepage;
  bootparams_common->efi_runtime_npages = lastruntimepage - firstruntimepage;
  bootparams_common->efi_mem_desc_size = descriptor_size;
  bootparams_common->efi_mem_desc_version = descriptor_version;
  bootparams_common->efi_mmap = memory_map_target;
  bootparams_common->efi_mmap_size = memory_map_size;
  bootparams_common->heap_start = grub_xnu_heap_target_start;
  bootparams_common->heap_size = curruntimepage * GRUB_XNU_PAGESIZE - grub_xnu_heap_target_start;

  /* Parameters for asm helper. */
  grub_xnu_stack = bootparams_common->heap_start
    + bootparams_common->heap_size + GRUB_XNU_PAGESIZE;
  grub_xnu_arg1 = bootparams_target;

  grub_autoefi_set_virtual_address_map (memory_map_size, descriptor_size,
					descriptor_version, memory_map);

  state.eip = grub_xnu_entry_point;
  state.eax = grub_xnu_arg1;
  state.esp = grub_xnu_stack;
  state.ebp = grub_xnu_stack;

  /* XNU uses only APIC. Disable PIC.  */
  grub_outb (0xff, 0x21);
  grub_outb (0xff, 0xa1);

  return grub_relocator32_boot (grub_xnu_relocator, state, 0);
}

static grub_command_t cmd_devprop_load;

void
grub_cpu_xnu_init (void)
{
  cmd_devprop_load = grub_register_command ("xnu_devprop_load",
					    grub_cmd_devprop_load,
					    /* TRANSLATORS: `device-properties'
					       is a variable name,
					       not a program.  */
					    0, N_("Load `device-properties' dump."));
}

void
grub_cpu_xnu_fini (void)
{
  grub_unregister_command (cmd_devprop_load);
}
