grub-devel.gnu.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 3/7] Initial support for U-Boot platforms
@ 2013-03-24 17:01 Leif Lindholm
  2013-03-30 16:20 ` Francesco Lavra
  2013-04-01  2:08 ` Vladimir 'φ-coder/phcoder' Serbinenko
  0 siblings, 2 replies; 12+ messages in thread
From: Leif Lindholm @ 2013-03-24 17:01 UTC (permalink / raw)
  To: grub-devel

[-- Attachment #1: Type: text/plain, Size: 1 bytes --]



[-- Attachment #2: 0003-uboot-support.patch --]
[-- Type: application/octet-stream, Size: 47329 bytes --]

=== modified file 'grub-core/Makefile.core.def'
--- grub-core/Makefile.core.def	2013-03-24 12:58:13 +0000
+++ grub-core/Makefile.core.def	2013-03-24 12:58:23 +0000
@@ -114,6 +114,12 @@
   ieee1275 = term/ieee1275/console.c;
   ieee1275 = kern/ieee1275/init.c;
 
+  uboot = disk/uboot/ubootdisk.c;
+  uboot = kern/uboot/uboot.c;
+  uboot = kern/uboot/init.c;
+  uboot = kern/uboot/hw.c;
+  uboot = term/uboot/console.c;
+
   terminfoinkernel = term/terminfo.c;
   terminfoinkernel = term/tparm.c;
   terminfoinkernel = commands/extcmd.c;
@@ -698,6 +704,7 @@
   efi = lib/efi/halt.c;
   ieee1275 = lib/ieee1275/halt.c;
   emu = lib/emu/halt.c;
+  uboot = lib/uboot/halt.c;
 };
 
 module = {
@@ -711,6 +718,7 @@
   mips_arc = lib/mips/arc/reboot.c;
   mips_loongson = lib/mips/loongson/reboot.c;
   mips_qemu_mips = lib/mips/qemu_mips/reboot.c;
+  uboot = lib/uboot/reboot.c;
   common = commands/reboot.c;
 };
 
@@ -1363,6 +1371,7 @@
   name = datetime;
   cmos = lib/cmos_datetime.c;
   efi = lib/efi/datetime.c;
+  uboot = lib/uboot/datetime.c;
   sparc64_ieee1275 = lib/ieee1275/datetime.c;
   powerpc_ieee1275 = lib/ieee1275/datetime.c;
   sparc64_ieee1275 = lib/ieee1275/cmos.c;

=== added directory 'grub-core/disk/uboot'
=== added file 'grub-core/disk/uboot/ubootdisk.c'
--- grub-core/disk/uboot/ubootdisk.c	1970-01-01 00:00:00 +0000
+++ grub-core/disk/uboot/ubootdisk.c	2013-03-24 12:58:23 +0000
@@ -0,0 +1,346 @@
+/* ubootdisk.c - disk subsystem support for U-Boot platforms */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2013  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/disk.h>
+#include <grub/err.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/partition.h>
+#include <grub/term.h>
+#include <grub/types.h>
+#include <grub/uboot/disk.h>
+#include <grub/uboot/uboot.h>
+
+static struct ubootdisk_data *fd_devices;
+static struct ubootdisk_data *hd_devices;
+static struct ubootdisk_data *cd_devices;
+
+/*
+ * grub_ubootdisk_register():
+ *   Called for each disk device enumerated as part of U-Boot initialization
+ *   code.
+ */
+grub_err_t
+grub_ubootdisk_register (struct device_info *newdev, int handle)
+{
+  struct ubootdisk_data *d;
+  enum disktype type;
+
+#define STOR_TYPE(x) ((x) & 0x0ff0)
+  switch (STOR_TYPE (newdev->type))
+    {
+    case DT_STOR_IDE:
+    case DT_STOR_SATA:
+      /* hd */
+      type = hd;
+      break;
+    case DT_STOR_MMC:
+    case DT_STOR_USB:
+      /* fd */
+      type = fd;
+      break;
+    default:
+      return GRUB_ERR_BAD_DEVICE;
+      break;
+    }
+
+  d = (struct ubootdisk_data *) grub_malloc (sizeof (struct ubootdisk_data));
+  if (!d)
+    return GRUB_ERR_OUT_OF_MEMORY;
+  d->handle = handle;
+  d->cookie = newdev->cookie;
+  d->opencount = 0;
+
+  switch (type)
+    {
+    case cd:
+      grub_dprintf ("ubootdisk", "registering cd device\n");
+      d->next = cd_devices;
+      cd_devices = d;
+
+      break;
+    case fd:
+      grub_dprintf ("ubootdisk", "registering fd device\n");
+      d->next = fd_devices;
+      fd_devices = d;
+
+      break;
+    case hd:
+      grub_dprintf ("ubootdisk", "registering hd device\n");
+      d->next = hd_devices;
+      hd_devices = d;
+
+      break;
+    default:
+      grub_free (d);
+      return GRUB_ERR_BAD_DEVICE;
+    }
+
+  return 0;
+}
+
+/*
+ * uboot_disk_iterate():
+ *   Itarator over enumerated disk devices.
+ */
+static int
+uboot_disk_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data,
+		    grub_disk_pull_t pull)
+{
+  struct ubootdisk_data *d;
+  char buf[16];
+  int count;
+
+  switch (pull)
+    {
+    case GRUB_DISK_PULL_NONE:
+      /* "hd" - built-in mass-storage */
+      for (d = hd_devices, count = 0; d; d = d->next, count++)
+	{
+	  grub_snprintf (buf, sizeof (buf) - 1, "hd%d", count);
+	  grub_dprintf ("ubootdisk", "iterating %s\n", buf);
+	  if (hook (buf, hook_data))
+	    return 1;
+	}
+      break;
+    case GRUB_DISK_PULL_REMOVABLE:
+      /* "floppy" - removable mass storage */
+      for (d = fd_devices, count = 0; d; d = d->next, count++)
+	{
+	  grub_snprintf (buf, sizeof (buf) - 1, "fd%d", count);
+	  grub_dprintf ("ubootdisk", "iterating %s\n", buf);
+	  if (hook (buf, hook_data))
+	    return 1;
+	}
+
+      /* "cdrom" - removeable read-only storage */
+      for (d = cd_devices, count = 0; d; d = d->next, count++)
+	{
+	  grub_snprintf (buf, sizeof (buf) - 1, "cd%d", count);
+	  grub_dprintf ("ubootdisk", "iterating %s\n", buf);
+	  if (hook (buf, hook_data))
+	    return 1;
+	}
+      break;
+    default:
+      return 0;
+    }
+
+  return 0;
+}
+
+/* Helper function for uboot_disk_open. */
+static struct ubootdisk_data *
+get_device (struct ubootdisk_data *devices, int num)
+{
+  struct ubootdisk_data *d;
+
+  for (d = devices; d && num; d = d->next, num--)
+    ;
+
+  if (num == 0)
+    return d;
+
+  return NULL;
+}
+
+/*
+ * uboot_disk_open():
+ *   Opens a disk device already enumerated.
+ */
+static grub_err_t
+uboot_disk_open (const char *name, struct grub_disk *disk)
+{
+  struct ubootdisk_data *d;
+  struct device_info *devinfo;
+  int num;
+  int retval;
+
+  grub_dprintf ("ubootdisk", "Opening '%s'\n", name);
+
+  num = grub_strtoul (name + 2, 0, 10);
+  if (grub_errno != GRUB_ERR_NONE)
+    {
+      grub_dprintf ("ubootdisk", "Opening '%s' failed, invalid number\n",
+		    name);
+      goto fail;
+    }
+
+  if (name[1] != 'd')
+    {
+      grub_dprintf ("ubootdisk", "Opening '%s' failed, invalid name\n", name);
+      goto fail;
+    }
+
+  switch (name[0])
+    {
+    case 'f':
+      d = get_device (fd_devices, num);
+      break;
+    case 'c':
+      d = get_device (cd_devices, num);
+      break;
+    case 'h':
+      d = get_device (hd_devices, num);
+      break;
+    default:
+      goto fail;
+    }
+
+  if (!d)
+    goto fail;
+
+  /*
+   * Subsystems may call open on the same device recursively - but U-Boot
+   * does not deal with this. So simply keep track of number of calls and
+   * return success if already open.
+   */
+  if (d->opencount > 0)
+    {
+      grub_dprintf ("ubootdisk", "(%s) already open\n", disk->name);
+      d->opencount++;
+      retval = 0;
+    }
+  else
+    {
+      retval = uboot_dev_open (d->handle);
+      if (retval != 0)
+	goto fail;
+      d->opencount = 1;
+    }
+
+  grub_dprintf ("ubootdisk", "cookie: 0x%08x\n", (grub_addr_t) d->cookie);
+  disk->id = (grub_addr_t) d->cookie;
+
+  /* Device has previously been enumerated, so this should never fail */
+  if ((devinfo = uboot_dev_get (d->handle)) == NULL)
+    goto fail;
+
+  d->block_size = devinfo->di_stor.block_size;
+  if (d->block_size == 0)
+    {
+      grub_printf ("%s: no block size!\n", __FUNCTION__);
+      return GRUB_ERR_IO;
+    }
+
+  for (disk->log_sector_size = 0;
+       (1U << disk->log_sector_size) < d->block_size;
+       disk->log_sector_size++);
+
+  grub_dprintf ("ubootdisk", "(%s) blocksize=%d, log_sector_size=%d\n",
+		disk->name, d->block_size, disk->log_sector_size);
+
+  disk->total_sectors = GRUB_DISK_SIZE_UNKNOWN;
+  disk->data = d;
+
+  return GRUB_ERR_NONE;
+
+fail:
+  return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no such device");
+}
+
+static void
+uboot_disk_close (struct grub_disk *disk)
+{
+  struct ubootdisk_data *d;
+  int retval;
+
+  d = disk->data;
+
+  /*
+   * In mirror of open function, keep track of number of calls to close and
+   * send on to U-Boot only when opencount would decrease to 0.
+   */
+  if (d->opencount > 1)
+    {
+      grub_dprintf ("ubootdisk", "Closed (%s)\n", disk->name);
+
+      d->opencount--;
+    }
+  else if (d->opencount == 1)
+    {
+      retval = uboot_dev_close (d->handle);
+      d->opencount--;
+      grub_dprintf ("ubootdisk", "closed %s (%d)\n", disk->name, retval);
+    }
+  else
+    {
+      grub_dprintf ("ubootdisk", "device %s not open!\n", disk->name);
+    }
+}
+
+/*
+ * uboot_disk_read():
+ *   Called from within disk subsystem to read a sequence of blocks into the
+ *   disk cache. Maps directly on top of U-Boot API, only wrap in some error
+ *   handling.
+ */
+static grub_err_t
+uboot_disk_read (struct grub_disk *disk,
+		 grub_disk_addr_t offset, grub_size_t numblocks, char *buf)
+{
+  struct ubootdisk_data *d;
+  lbasize_t real_size;
+  int retval;
+
+  d = disk->data;
+
+  retval = uboot_dev_read (d->handle, buf, numblocks, offset, &real_size);
+  grub_dprintf ("ubootdisk",
+		"retval=%d, numblocks=%d, real_size=%llu, sector=%llu\n",
+		retval, numblocks, (grub_uint64_t) real_size,
+		(grub_uint64_t) offset);
+  if (retval != 0)
+    return grub_error (GRUB_ERR_IO, "U-Boot disk read error");
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+uboot_disk_write (struct grub_disk *disk __attribute__ ((unused)),
+		  grub_disk_addr_t sector __attribute__ ((unused)),
+		  grub_size_t size __attribute__ ((unused)),
+		  const char *buf __attribute__ ((unused)))
+{
+  grub_dprintf ("ubootdisk", "attempt to write\n");
+  return GRUB_ERR_NOT_IMPLEMENTED_YET;
+}
+
+static struct grub_disk_dev grub_ubootdisk_dev = {
+  .name = "ubootdisk",
+  .id = GRUB_DISK_DEVICE_UBOOTDISK_ID,
+  .iterate = uboot_disk_iterate,
+  .open = uboot_disk_open,
+  .close = uboot_disk_close,
+  .read = uboot_disk_read,
+  .write = uboot_disk_write,
+  .next = 0
+};
+
+void
+grub_ubootdisk_init (void)
+{
+  grub_disk_dev_register (&grub_ubootdisk_dev);
+}
+
+void
+grub_ubootdisk_fini (void)
+{
+  grub_disk_dev_unregister (&grub_ubootdisk_dev);
+}

=== added directory 'grub-core/kern/uboot'
=== added file 'grub-core/kern/uboot/hw.c'
--- grub-core/kern/uboot/hw.c	1970-01-01 00:00:00 +0000
+++ grub-core/kern/uboot/hw.c	2013-03-24 12:58:23 +0000
@@ -0,0 +1,112 @@
+/* hw.c - U-Boot hardware discovery */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2013  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/kernel.h>
+#include <grub/memory.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/offsets.h>
+#include <grub/machine/kernel.h>
+#include <grub/uboot/disk.h>
+#include <grub/uboot/uboot.h>
+
+grub_addr_t start_of_ram;
+
+/*
+ * grub_uboot_probe_memory():
+ *   Queries U-Boot for available memory regions.
+ *
+ *   Sets up heap near the image in memory and sets up "start_of_ram".
+ */
+void
+grub_uboot_mm_init (void)
+{
+  struct sys_info *si = uboot_get_sys_info ();
+
+  grub_mm_init_region ((void *) (grub_modules_get_end ()
+				 + GRUB_KERNEL_MACHINE_STACK_SIZE),
+		       GRUB_KERNEL_MACHINE_HEAP_SIZE);
+
+  if (si && (si->mr_no != 0))
+    {
+      int i;
+      start_of_ram = GRUB_UINT_MAX;
+
+      for (i = 0; i < si->mr_no; i++)
+	if ((si->mr[i].flags & MR_ATTR_MASK) == MR_ATTR_DRAM)
+	  if (si->mr[i].start < start_of_ram)
+	    start_of_ram = si->mr[i].start;
+    }
+}
+
+/*
+ * grub_uboot_probe_hardware():
+ *   
+ */
+grub_err_t
+grub_uboot_probe_hardware (void)
+{
+  int devcount, i;
+
+  devcount = uboot_dev_enum ();
+  grub_dprintf ("init", "%d devices found\n", devcount);
+
+  for (i = 0; i < devcount; i++)
+    {
+      struct device_info *devinfo = uboot_dev_get (i);
+
+      grub_dprintf ("init", "device handle: %d\n", i);
+      grub_dprintf ("init", "  cookie\t= 0x%08x\n",
+		    (grub_uint32_t) devinfo->cookie);
+
+      if (devinfo->type & DEV_TYP_STOR)
+	{
+	  grub_dprintf ("init", "  type\t\t= DISK\n");
+	  grub_ubootdisk_register (devinfo, i);
+	}
+      else if (devinfo->type & DEV_TYP_NET)
+	{
+	  grub_dprintf ("init", "  type\t\t= NET (not supported yet)\n");
+	}
+      else
+	{
+	  grub_dprintf ("init", "%s: unknown device type", __FUNCTION__);
+	}
+    }
+
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_machine_mmap_iterate (grub_memory_hook_t hook, void *hook_data)
+{
+  int i;
+  struct sys_info *si = uboot_get_sys_info ();
+
+  if (!si || (si->mr_no < 1))
+    return GRUB_ERR_BUG;
+
+  /* Iterate and call `hook'.  */
+  for (i = 0; i < si->mr_no; i++)
+    if ((si->mr[i].flags & MR_ATTR_MASK) == MR_ATTR_DRAM)
+      hook (si->mr[i].start, si->mr[i].size, GRUB_MEMORY_AVAILABLE,
+	    hook_data);
+
+  return GRUB_ERR_NONE;
+}

=== added file 'grub-core/kern/uboot/init.c'
--- grub-core/kern/uboot/init.c	1970-01-01 00:00:00 +0000
+++ grub-core/kern/uboot/init.c	2013-03-24 12:58:23 +0000
@@ -0,0 +1,171 @@
+/* init.c - generic U-Boot initialization and finalization */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2013  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/kernel.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/offsets.h>
+#include <grub/term.h>
+#include <grub/time.h>
+#include <grub/machine/kernel.h>
+#include <grub/uboot/console.h>
+#include <grub/uboot/disk.h>
+#include <grub/uboot/uboot.h>
+
+extern char __bss_start[];
+extern char _end[];
+extern grub_size_t grub_total_module_size;
+extern int (*uboot_syscall_ptr) (int, int *, ...);
+
+grub_addr_t grub_modbase;
+
+grub_uint32_t uboot_machine_type;
+grub_addr_t uboot_boot_data;
+
+static unsigned long timer_start;
+
+void
+grub_exit (void)
+{
+  uboot_return (0);
+}
+
+grub_uint32_t
+uboot_get_machine_type (void)
+{
+  return uboot_machine_type;
+}
+
+grub_addr_t
+uboot_get_boot_data (void)
+{
+  return uboot_boot_data;
+}
+
+static grub_uint64_t
+uboot_timer_ms (void)
+{
+  return (grub_uint64_t) uboot_get_timer (timer_start);
+}
+
+void
+grub_machine_init (void)
+{
+  grub_addr_t end, real_bss_start;
+  int ver;
+
+  /* First of all - establish connection with U-Boot */
+  ver = uboot_api_init ();
+  if (!ver)
+    {
+      /* Don't even have a console to log errors to... */
+      grub_exit ();
+    }
+  else if (ver > API_SIG_VERSION)
+    {
+      /* Try to print an error message */
+      uboot_puts ("invalid U-Boot API version\n");
+    }
+
+  /*
+   * Modules were relocated to _end, or __bss_start + grub_total_module_size,
+   * whichever greater. (And __bss_start may not point to actual BSS start...)
+   */
+  real_bss_start = uboot_get_real_bss_start ();
+  end = real_bss_start + grub_total_module_size;
+  if (end < (grub_addr_t) _end)
+    end = (grub_addr_t) _end;
+  grub_modbase = end;
+
+  /* Initialize the console so that GRUB can display messages.  */
+  grub_console_init_early ();
+
+  /* Enumerate memory and initialize the memory management system. */
+  grub_uboot_mm_init ();
+
+  grub_dprintf ("init", "__bss_start: 0x%08x, real_bss_start: 0x%08x\n",
+		(grub_addr_t) __bss_start, real_bss_start);
+  grub_dprintf ("init", "end: 0x%08x, _end: 0x%08x\n",
+		(grub_addr_t) end, (grub_addr_t) _end);
+  grub_dprintf ("init", "grub_modbase: %p\n", (void *) grub_modbase);
+  grub_dprintf ("init", "grub_modules_get_end(): %p\n",
+		(void *) grub_modules_get_end ());
+
+  /* Initialise full terminfo support */
+  grub_console_init_lately ();
+
+  /* Enumerate uboot devices */
+  grub_uboot_probe_hardware ();
+
+  /* Initialise timer */
+  timer_start = uboot_get_timer (0);
+  grub_install_get_time_ms (uboot_timer_ms);
+
+  /* Initialize  */
+  grub_ubootdisk_init ();
+}
+
+
+void
+grub_machine_fini (void)
+{
+}
+
+/*
+ * grub_machine_get_bootlocation():
+ *   Called from kern/main.c, which expects a device name (minus parentheses)
+ *   and a filesystem path back, if any are known.
+ *   Any returned values must be pointers to dynamically allocated strings.
+ */
+void
+grub_machine_get_bootlocation (char **device, char **path)
+{
+  char *tmp;
+
+  tmp = uboot_env_get ("grub_bootdev");
+  if (tmp)
+    {
+      *device = grub_malloc (grub_strlen (tmp) + 1);
+      if (*device == NULL)
+	return;
+      grub_strncpy (*device, tmp, grub_strlen (tmp) + 1);
+    }
+  else
+    *device = NULL;
+
+  tmp = uboot_env_get ("grub_bootpath");
+  if (tmp)
+    {
+      *path = grub_malloc (grub_strlen (tmp) + 1);
+      if (*path == NULL)
+	return;
+      grub_strncpy (*path, tmp, grub_strlen (tmp) + 1);
+    }
+  else
+    *path = NULL;
+}
+
+void
+grub_uboot_fini (void)
+{
+  grub_ubootdisk_fini ();
+  grub_console_fini ();
+}

=== added file 'grub-core/kern/uboot/uboot.c'
--- grub-core/kern/uboot/uboot.c	1970-01-01 00:00:00 +0000
+++ grub-core/kern/uboot/uboot.c	2013-03-24 12:58:23 +0000
@@ -0,0 +1,363 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2013  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/misc.h>
+#include <grub/mm.h>
+#include <grub/uboot/uboot.h>
+
+/*
+ * The main syscall entry point is not reentrant, only one call is
+ * serviced until finished.
+ *
+ * int syscall(int call, int *retval, ...)
+ * e.g. syscall(1, int *, u_int32_t, u_int32_t, u_int32_t, u_int32_t);
+ *
+ * call:	syscall number
+ *
+ * retval:	points to the return value placeholder, this is the place the
+ *		syscall puts its return value, if NULL the caller does not
+ *		expect a return value
+ *
+ * ...		syscall arguments (variable number)
+ *
+ * returns:	0 if the call not found, 1 if serviced
+ */
+
+extern int (*uboot_syscall_ptr) (int, int *, ...);
+extern int uboot_syscall (int, int *, ...);
+extern grub_addr_t uboot_search_hint;
+
+static struct sys_info uboot_sys_info;
+static struct mem_region uboot_mem_info[5];
+static struct device_info uboot_devices[6];
+static int num_devices;
+
+int
+uboot_api_init (void)
+{
+  struct api_signature *start, *end;
+  struct api_signature *p;
+
+  if (uboot_search_hint)
+    {
+      /* Extended search range to work around Trim Slice U-Boot issue */
+      start = (struct api_signature *) ((uboot_search_hint & ~0x000fffff)
+					- 0x00500000);
+      end =
+	(struct api_signature *) ((grub_addr_t) start + UBOOT_API_SEARCH_LEN -
+				  API_SIG_MAGLEN + 0x00500000);
+    }
+  else
+    {
+      start = 0;
+      end = (struct api_signature *) (256 * 1024 * 1024);
+    }
+
+  /* Structure alignment is (at least) 8 bytes */
+  for (p = start; p < end; p = (void *) ((grub_addr_t) p + 8))
+    {
+      if (grub_memcmp (&(p->magic), API_SIG_MAGIC, API_SIG_MAGLEN) == 0)
+	{
+	  uboot_syscall_ptr = p->syscall;
+	  return p->version;
+	}
+    }
+
+  return 0;
+}
+
+/* All functions below are wrappers around the uboot_syscall() function */
+
+/*
+ * int API_getc(int *c)
+ */
+int
+uboot_getc (void)
+{
+  int c;
+  if (!uboot_syscall (API_GETC, NULL, &c))
+    return -1;
+
+  return c;
+}
+
+/*
+ * int API_tstc(int *c)
+ */
+int
+uboot_tstc (void)
+{
+  int c;
+  if (!uboot_syscall (API_TSTC, NULL, &c))
+    return -1;
+
+  return c;
+}
+
+/*
+ * int API_putc(char *ch)
+ */
+void
+uboot_putc (int c)
+{
+  uboot_syscall (API_PUTC, NULL, &c);
+}
+
+/*
+ * int API_puts(const char *s)
+ */
+void
+uboot_puts (const char *s)
+{
+  uboot_syscall (API_PUTS, NULL, s);
+}
+
+/*
+ * int API_reset(void)
+ */
+void
+uboot_reset (void)
+{
+  uboot_syscall (API_RESET, NULL, 0);
+}
+
+/*
+ * int API_get_sys_info(struct sys_info *si)
+ *
+ * fill out the sys_info struct containing selected parameters about the
+ * machine
+ */
+struct sys_info *
+uboot_get_sys_info (void)
+{
+  int retval;
+
+  grub_memset (&uboot_sys_info, 0, sizeof (uboot_sys_info));
+  grub_memset (&uboot_mem_info, 0, sizeof (uboot_mem_info));
+  uboot_sys_info.mr = uboot_mem_info;
+  uboot_sys_info.mr_no = sizeof (uboot_mem_info) / sizeof (struct mem_region);
+
+  if (uboot_syscall (API_GET_SYS_INFO, &retval, &uboot_sys_info))
+    if (retval == 0)
+      return &uboot_sys_info;
+
+  return NULL;
+}
+
+/*
+ * int API_udelay(unsigned long *udelay)
+ */
+void
+uboot_udelay (grub_uint32_t usec)
+{
+  uboot_syscall (API_UDELAY, NULL, &usec);
+}
+
+/*
+ * int API_get_timer(unsigned long *current, unsigned long *base)
+ */
+grub_uint32_t
+uboot_get_timer (grub_uint32_t base)
+{
+  grub_uint32_t current;
+
+  if (!uboot_syscall (API_GET_TIMER, NULL, &current, &base))
+    return 0;
+
+  return current;
+}
+
+/*
+ * int API_dev_enum(struct device_info *)
+ *
+ */
+int
+uboot_dev_enum (void)
+{
+  int max;
+
+  grub_memset (&uboot_devices, 0, sizeof (uboot_devices));
+  max = sizeof (uboot_devices) / sizeof (struct device_info);
+
+  /*
+   * The API_DEV_ENUM call starts a fresh enumeration when passed a
+   * struct device_info with a NULL cookie, and then depends on having
+   * the prevoiusly enumerated device cookie "seeded" into the target
+   * structure.
+   */
+  if (!uboot_syscall (API_DEV_ENUM, NULL, &uboot_devices)
+      || uboot_devices[0].cookie == NULL)
+    return 0;
+
+  for (num_devices = 1; num_devices < max; num_devices++)
+    {
+      uboot_devices[num_devices].cookie =
+	uboot_devices[num_devices - 1].cookie;
+      if (!uboot_syscall (API_DEV_ENUM, NULL, &uboot_devices[num_devices]))
+	return 0;
+
+      /* When no more devices to enumerate, target cookie set to NULL */
+      if (uboot_devices[num_devices].cookie == NULL)
+	break;
+    }
+
+  return num_devices;
+}
+
+#define VALID_DEV(x) (((x) < num_devices) && ((x) >= 0))
+#define OPEN_DEV(x) (VALID_DEV(x) && (uboot_devices[(x)].state == DEV_STA_OPEN))
+
+struct device_info *
+uboot_dev_get (int handle)
+{
+  if (VALID_DEV (handle))
+    return &uboot_devices[handle];
+
+  return NULL;
+}
+
+
+/*
+ * int API_dev_open(struct device_info *)
+ */
+int
+uboot_dev_open (int handle)
+{
+  struct device_info *dev;
+  int retval;
+
+  if (!VALID_DEV (handle))
+    return -1;
+
+  dev = &uboot_devices[handle];
+
+  if (!uboot_syscall (API_DEV_OPEN, &retval, dev))
+    return -1;
+
+  return retval;
+}
+
+/*
+ * int API_dev_close(struct device_info *)
+ */
+int
+uboot_dev_close (int handle)
+{
+  struct device_info *dev;
+  int retval;
+
+  if (!VALID_DEV (handle))
+    return -1;
+
+  dev = &uboot_devices[handle];
+
+  if (!uboot_syscall (API_DEV_CLOSE, &retval, dev))
+    return -1;
+
+  return retval;
+}
+
+
+/*
+ * int API_dev_read(struct device_info *di, void *buf,	size_t *len,
+ *                  unsigned long *start, size_t *act_len)
+ */
+int
+uboot_dev_read (int handle, void *buf, lbasize_t blocks,
+		lbastart_t start, lbasize_t * real_blocks)
+{
+  struct device_info *dev;
+  int retval;
+
+  if (!OPEN_DEV (handle))
+    return -1;
+
+  dev = &uboot_devices[handle];
+
+  if (!uboot_syscall (API_DEV_READ, &retval, dev, buf,
+		      &blocks, &start, real_blocks))
+    return -1;
+
+  return retval;
+}
+
+/*
+ * int API_dev_read(struct device_info *di, void *buf,
+ *                  size_t *len, size_t *act_len)
+ */
+int
+uboot_dev_recv (int handle, void *buf, int size, int *real_size)
+{
+  struct device_info *dev;
+  int retval;
+
+  if (!OPEN_DEV (handle))
+    return -1;
+
+  dev = &uboot_devices[handle];
+  if (!uboot_syscall (API_DEV_READ, &retval, dev, buf, &size, real_size))
+    return -1;
+
+  return retval;
+
+}
+
+/*
+ * Notice: this is for sending network packets only, as U-Boot does not
+ * support writing to storage at the moment (12.2007)
+ *
+ * int API_dev_write(struct device_info *di, void *buf,	int *len)
+ */
+int
+uboot_dev_send (int handle, void *buf, int size)
+{
+  struct device_info *dev;
+  int retval;
+
+  if (!OPEN_DEV (handle))
+    return -1;
+
+  dev = &uboot_devices[handle];
+  if (!uboot_syscall (API_DEV_WRITE, &retval, dev, buf, &size))
+    return -1;
+
+  return retval;
+}
+
+/*
+ * int API_env_get(const char *name, char **value)
+ */
+char *
+uboot_env_get (const char *name)
+{
+  char *value;
+
+  if (!uboot_syscall (API_ENV_GET, NULL, name, &value))
+    return NULL;
+
+  return value;
+}
+
+/*
+ * int API_env_set(const char *name, const char *value)
+ */
+void
+uboot_env_set (const char *name, const char *value)
+{
+  uboot_syscall (API_ENV_SET, NULL, name, value);
+}

=== added directory 'grub-core/lib/uboot'
=== added file 'grub-core/lib/uboot/datetime.c'
--- grub-core/lib/uboot/datetime.c	1970-01-01 00:00:00 +0000
+++ grub-core/lib/uboot/datetime.c	2013-03-24 12:58:23 +0000
@@ -0,0 +1,41 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2013  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/types.h>
+#include <grub/symbol.h>
+#include <grub/uboot/uboot.h>
+#include <grub/datetime.h>
+#include <grub/dl.h>
+
+GRUB_MOD_LICENSE ("GPLv3+");
+
+/* No simple platform-independent RTC access exists in U-Boot. */
+
+grub_err_t
+grub_get_datetime (struct grub_datetime *datetime __attribute__ ((unused)))
+{
+  return grub_error (GRUB_ERR_INVALID_COMMAND,
+		     "can\'t get datetime using U-Boot");
+}
+
+grub_err_t
+grub_set_datetime (struct grub_datetime * datetime __attribute__ ((unused)))
+{
+  return grub_error (GRUB_ERR_INVALID_COMMAND,
+		     "can\'t set datetime using U-Boot");
+}

=== added file 'grub-core/lib/uboot/halt.c'
--- grub-core/lib/uboot/halt.c	1970-01-01 00:00:00 +0000
+++ grub-core/lib/uboot/halt.c	2013-03-24 12:58:23 +0000
@@ -0,0 +1,31 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2013  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/misc.h>
+#include <grub/mm.h>
+#include <grub/kernel.h>
+
+void
+grub_halt (void)
+{
+  grub_machine_fini ();
+
+  /* Just stop here */
+
+  while (1);
+}

=== added file 'grub-core/lib/uboot/reboot.c'
--- grub-core/lib/uboot/reboot.c	1970-01-01 00:00:00 +0000
+++ grub-core/lib/uboot/reboot.c	2013-03-24 12:58:23 +0000
@@ -0,0 +1,30 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2013  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/kernel.h>
+#include <grub/misc.h>
+#include <grub/uboot/uboot.h>
+
+void
+grub_reboot (void)
+{
+  grub_machine_fini ();
+
+  uboot_reset ();
+  while (1);
+}

=== modified file 'grub-core/term/terminfo.c'
--- grub-core/term/terminfo.c	2013-03-05 19:00:51 +0000
+++ grub-core/term/terminfo.c	2013-03-24 12:58:23 +0000
@@ -745,7 +745,9 @@
 
 static grub_extcmd_t cmd;
 
-#if defined (GRUB_MACHINE_IEEE1275) || defined (GRUB_MACHINE_MIPS_LOONGSON) || defined (GRUB_MACHINE_MIPS_QEMU_MIPS) || defined (GRUB_MACHINE_ARC)
+#if defined (GRUB_MACHINE_IEEE1275) || defined (GRUB_MACHINE_MIPS_LOONGSON) \
+  || defined (GRUB_MACHINE_MIPS_QEMU_MIPS) || defined (GRUB_MACHINE_ARC) \
+  || defined (GRUB_MACHINE_UBOOT)
 void grub_terminfo_init (void)
 #else
 GRUB_MOD_INIT(terminfo)

=== added directory 'grub-core/term/uboot'
=== added file 'grub-core/term/uboot/console.c'
--- grub-core/term/uboot/console.c	1970-01-01 00:00:00 +0000
+++ grub-core/term/uboot/console.c	2013-03-24 12:58:23 +0000
@@ -0,0 +1,141 @@
+/* console.c - console interface layer for U-Boot platforms */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2013  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/term.h>
+#include <grub/misc.h>
+#include <grub/types.h>
+#include <grub/err.h>
+#include <grub/terminfo.h>
+#include <grub/uboot/uboot.h>
+#include <grub/uboot/console.h>
+
+static void
+put (struct grub_term_output *term __attribute__ ((unused)), const int c)
+{
+  uboot_putc (c);
+}
+
+static int
+readkey (struct grub_term_input *term __attribute__ ((unused)))
+{
+  if (uboot_tstc () > 0)
+    return uboot_getc ();
+
+  return -1;
+}
+
+static void
+uboot_console_setcursor (struct grub_term_output *term
+			 __attribute__ ((unused)), int on
+			 __attribute__ ((unused)))
+{
+  grub_terminfo_setcursor (term, on);
+}
+
+static grub_err_t
+uboot_console_init_input (struct grub_term_input *term)
+{
+  return grub_terminfo_input_init (term);
+}
+
+extern struct grub_terminfo_output_state uboot_console_terminfo_output;
+
+static void
+uboot_console_dimensions (void)
+{
+  /* Use a small console by default.  */
+  if (!uboot_console_terminfo_output.width)
+    uboot_console_terminfo_output.width = 80;
+  if (!uboot_console_terminfo_output.height)
+    uboot_console_terminfo_output.height = 24;
+}
+
+static grub_err_t
+uboot_console_init_output (struct grub_term_output *term)
+{
+  uboot_console_dimensions ();
+
+  grub_terminfo_output_init (term);
+
+  return 0;
+}
+
+struct grub_terminfo_input_state uboot_console_terminfo_input = {
+  .readkey = readkey
+};
+
+struct grub_terminfo_output_state uboot_console_terminfo_output = {
+  .put = put,
+  .width = 80,
+  .height = 24
+};
+
+static struct grub_term_input uboot_console_term_input = {
+  .name = "console",
+  .init = uboot_console_init_input,
+  .getkey = grub_terminfo_getkey,
+  .data = &uboot_console_terminfo_input
+};
+
+static struct grub_term_output uboot_console_term_output = {
+  .name = "console",
+  .init = uboot_console_init_output,
+  .putchar = grub_terminfo_putchar,
+  .getwh = grub_terminfo_getwh,
+  .getxy = grub_terminfo_getxy,
+  .gotoxy = grub_terminfo_gotoxy,
+  .cls = grub_terminfo_cls,
+  .setcolorstate = grub_terminfo_setcolorstate,
+  .setcursor = uboot_console_setcursor,
+  .flags = GRUB_TERM_CODE_TYPE_ASCII,
+  .data = &uboot_console_terminfo_output,
+};
+
+void
+grub_console_init_early (void)
+{
+  grub_term_register_input ("console", &uboot_console_term_input);
+  grub_term_register_output ("console", &uboot_console_term_output);
+}
+
+
+/*
+ * grub_console_init_lately():
+ *   Initializes terminfo formatting by registering terminal type.
+ *   Called after heap has been configured.
+ *   
+ */
+void
+grub_console_init_lately (void)
+{
+  const char *type;
+
+  /* See if explicitly set by U-Boot environment */
+  type = uboot_env_get ("grub_term");
+  if (!type)
+    type = "vt100";
+
+  grub_terminfo_init ();
+  grub_terminfo_output_register (&uboot_console_term_output, type);
+}
+
+void
+grub_console_fini (void)
+{
+}

=== modified file 'include/grub/disk.h'
--- include/grub/disk.h	2013-02-27 16:19:15 +0000
+++ include/grub/disk.h	2013-03-24 12:58:23 +0000
@@ -43,6 +43,7 @@
     GRUB_DISK_DEVICE_CRYPTODISK_ID,
     GRUB_DISK_DEVICE_ARCDISK_ID,
     GRUB_DISK_DEVICE_HOSTDISK_ID,
+    GRUB_DISK_DEVICE_UBOOTDISK_ID,
   };
 
 struct grub_disk;

=== modified file 'include/grub/kernel.h'
--- include/grub/kernel.h	2013-03-07 07:17:24 +0000
+++ include/grub/kernel.h	2013-03-24 12:58:23 +0000
@@ -78,7 +78,7 @@
 #if defined (GRUB_MACHINE_PCBIOS) || defined (GRUB_MACHINE_COREBOOT) \
   || defined (GRUB_MACHINE_MULTIBOOT) || defined (GRUB_MACHINE_MIPS_QEMU_MIPS) \
   || defined (GRUB_MACHINE_MIPS_LOONGSON) || defined (GRUB_MACHINE_ARC) \
-  || defined (__sparc__)
+  || defined (__sparc__) || defined (GRUB_MACHINE_UBOOT)
 /* FIXME: stack is between 2 heap regions. Move it.  */
 #define GRUB_KERNEL_PRELOAD_SPACE_REUSABLE 1
 #endif

=== added directory 'include/grub/uboot'
=== added file 'include/grub/uboot/api_public.h'
--- include/grub/uboot/api_public.h	1970-01-01 00:00:00 +0000
+++ include/grub/uboot/api_public.h	2013-03-24 12:58:23 +0000
@@ -0,0 +1,184 @@
+/*
+ * (C) Copyright 2007-2008 Semihalf
+ *
+ * Written by: Rafal Jaworowski <raj@semihalf.com>
+ *
+ * This file is dual licensed; you can use it under the terms of
+ * either the GPL, or the BSD license, at your option.
+ *
+ * I. GPL:
+ *
+ * This file 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 file 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., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ * Alternatively,
+ *
+ * II. BSD license:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _API_PUBLIC_H_
+#define _API_PUBLIC_H_
+
+#define API_EINVAL		1	/* invalid argument(s)  */
+#define API_ENODEV		2	/* no device            */
+#define API_ENOMEM		3	/* no memory            */
+#define API_EBUSY		4	/* busy, occupied etc.  */
+#define API_EIO			5	/* I/O error            */
+#define API_ESYSC		6	/* syscall error        */
+
+typedef int (*scp_t) (int, int *, ...);
+
+typedef grub_uint16_t uint16_t;
+typedef grub_uint32_t uint32_t;
+
+#define API_SIG_VERSION	1
+#define API_SIG_MAGIC	"UBootAPI"
+#define API_SIG_MAGLEN	8
+
+struct api_signature
+{
+  char magic[API_SIG_MAGLEN];	/* magic string */
+  uint16_t version;		/* API version */
+  uint32_t checksum;		/* checksum of this sig struct */
+  scp_t syscall;		/* entry point to the API */
+};
+
+enum
+{
+  API_RSVD = 0,
+  API_GETC,
+  API_PUTC,
+  API_TSTC,
+  API_PUTS,
+  API_RESET,
+  API_GET_SYS_INFO,
+  API_UDELAY,
+  API_GET_TIMER,
+  API_DEV_ENUM,
+  API_DEV_OPEN,
+  API_DEV_CLOSE,
+  API_DEV_READ,
+  API_DEV_WRITE,
+  API_ENV_ENUM,
+  API_ENV_GET,
+  API_ENV_SET,
+  API_DISPLAY_GET_INFO,
+  API_DISPLAY_DRAW_BITMAP,
+  API_DISPLAY_CLEAR,
+  API_MAXCALL
+};
+
+#define MR_ATTR_FLASH	0x0001
+#define MR_ATTR_DRAM	0x0002
+#define MR_ATTR_SRAM	0x0003
+#define MR_ATTR_MASK	0x000f
+
+struct mem_region
+{
+  unsigned long start;
+  unsigned long size;
+  int flags;
+};
+
+struct sys_info
+{
+  unsigned long clk_bus;
+  unsigned long clk_cpu;
+  unsigned long bar;
+  struct mem_region *mr;
+  int mr_no;			/* number of memory regions */
+};
+
+#undef CONFIG_SYS_64BIT_LBA
+#ifdef CONFIG_SYS_64BIT_LBA
+typedef u_int64_t lbasize_t;
+#else
+typedef unsigned long lbasize_t;
+#endif
+typedef unsigned long lbastart_t;
+
+#define DEV_TYP_NONE	0x0000
+#define DEV_TYP_NET	0x0001
+
+#define DEV_TYP_STOR	0x0002
+#define DT_STOR_IDE	0x0010
+#define DT_STOR_SCSI	0x0020
+#define DT_STOR_USB	0x0040
+#define DT_STOR_MMC	0x0080
+#define DT_STOR_SATA	0x0100
+
+#define DEV_STA_CLOSED	0x0000	/* invalid, closed */
+#define DEV_STA_OPEN	0x0001	/* open i.e. active */
+
+struct device_info
+{
+  int type;
+  void *cookie;
+
+  union
+  {
+    struct
+    {
+      lbasize_t block_count;	/* no of blocks */
+      unsigned long block_size;	/* size of one block */
+    } storage;
+
+    struct
+    {
+      unsigned char hwaddr[6];
+    } net;
+  } info;
+#define di_stor info.storage
+#define di_net info.net
+
+  int state;
+};
+
+#define DISPLAY_TYPE_LCD	0x0001
+#define DISPLAY_TYPE_VIDEO	0x0002
+
+struct display_info
+{
+  int type;
+  /* screen size in pixels */
+  int pixel_width;
+  int pixel_height;
+  /* screen size in rows and columns of text */
+  int screen_rows;
+  int screen_cols;
+};
+
+#endif /* _API_PUBLIC_H_ */

=== added file 'include/grub/uboot/console.h'
--- include/grub/uboot/console.h	1970-01-01 00:00:00 +0000
+++ include/grub/uboot/console.h	2013-03-24 12:58:23 +0000
@@ -0,0 +1,29 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2013  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/>.
+ */
+
+#ifndef GRUB_CONSOLE_MACHINE_HEADER
+#define GRUB_CONSOLE_MACHINE_HEADER 1
+
+/* Initialize the console system.  */
+void grub_console_init_early (void);
+void grub_console_init_lately (void);
+
+/* Exit the console system.  */
+void grub_console_fini (void);
+
+#endif /* ! GRUB_CONSOLE_MACHINE_HEADER */

=== added file 'include/grub/uboot/disk.h'
--- include/grub/uboot/disk.h	1970-01-01 00:00:00 +0000
+++ include/grub/uboot/disk.h	2013-03-24 12:58:23 +0000
@@ -0,0 +1,44 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2013  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/>.
+ */
+
+#ifndef GRUB_UBOOT_DISK_HEADER
+#define GRUB_UBOOT_DISK_HEADER	1
+
+#include <grub/symbol.h>
+#include <grub/disk.h>
+#include <grub/uboot/uboot.h>
+
+void grub_ubootdisk_init (void);
+void grub_ubootdisk_fini (void);
+
+enum disktype
+{ cd, fd, hd };
+
+struct ubootdisk_data
+{
+  struct ubootdisk_data *next;
+  void *cookie;
+  int handle;
+  int opencount;
+  enum disktype type;
+  grub_uint32_t block_size;
+};
+
+grub_err_t grub_ubootdisk_register (struct device_info *newdev, int handle);
+
+#endif /* ! GRUB_UBOOT_DISK_HEADER */

=== added file 'include/grub/uboot/uboot.h'
--- include/grub/uboot/uboot.h	1970-01-01 00:00:00 +0000
+++ include/grub/uboot/uboot.h	2013-03-24 12:58:23 +0000
@@ -0,0 +1,150 @@
+/* uboot.h - declare variables and functions for U-Boot support */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2013 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/>.
+ */
+
+#ifndef GRUB_UBOOT_UBOOT_HEADER
+#define GRUB_UBOOT_UBOOT_HEADER	1
+
+#include <grub/types.h>
+#include <grub/dl.h>
+
+/* Functions.  */
+void grub_uboot_mm_init (void);
+void grub_uboot_init (void);
+void grub_uboot_fini (void);
+
+void uboot_return (int) __attribute__ ((noreturn));
+
+grub_addr_t uboot_get_real_bss_start (void);
+
+grub_err_t grub_uboot_probe_hardware (void);
+
+extern grub_addr_t EXPORT_VAR (start_of_ram);
+
+grub_uint32_t EXPORT_FUNC (uboot_get_machine_type) (void);
+grub_addr_t EXPORT_FUNC (uboot_get_boot_data) (void);
+
+
+/*
+ * The U-Boot API operates through a "syscall" interface, consisting of an
+ * entry point address and a set of syscall numbers. The location of this
+ * entry point is described in a structure allocated on the U-Boot heap.
+ * We scan through a defined region around the hint address passed to us
+ * from U-Boot.
+ */
+#include <grub/uboot/api_public.h>
+
+#define UBOOT_API_SEARCH_LEN (3 * 1024 * 1024)
+int uboot_api_init (void);
+
+/* All functions below are wrappers around the uboot_syscall() function */
+
+/*
+ * int API_getc(int *c)
+ */
+int uboot_getc (void);
+
+/*
+ * int API_tstc(int *c)
+ */
+int uboot_tstc (void);
+
+/*
+ * int API_putc(char *ch)
+ */
+void uboot_putc (int c);
+
+/*
+ * int API_puts(const char *s)
+ */
+void uboot_puts (const char *s);
+
+/*
+ * int API_reset(void)
+ */
+void EXPORT_FUNC (uboot_reset) (void);
+
+/*
+ * int API_get_sys_info(struct sys_info *si)
+ *
+ * fill out the sys_info struct containing selected parameters about the
+ * machine
+ */
+struct sys_info *uboot_get_sys_info (void);
+
+/*
+ * int API_udelay(unsigned long *udelay)
+ */
+void uboot_udelay (grub_uint32_t usec);
+
+/*
+ * int API_get_timer(unsigned long *current, unsigned long *base)
+ */
+grub_uint32_t uboot_get_timer (grub_uint32_t base);
+
+/*
+ * int API_dev_enum(struct device_info *)
+ */
+int uboot_dev_enum (void);
+
+struct device_info *uboot_dev_get (int handle);
+
+/*
+ * int API_dev_open(struct device_info *)
+ */
+int uboot_dev_open (int handle);
+
+/*
+ * int API_dev_close(struct device_info *)
+ */
+int uboot_dev_close (int handle);
+
+/*
+ * Notice: this is for sending network packets only, as U-Boot does not
+ * support writing to storage at the moment (12.2007)
+ *
+ * int API_dev_write(struct device_info *di, void *buf,	int *len)
+ */
+int uboot_dev_write (int handle, void *buf, int *len);
+
+/*
+ * int API_dev_read(
+ *	struct device_info *di,
+ *	void *buf,
+ *	size_t *len,
+ *	unsigned long *start
+ *	size_t *act_len
+ * )
+ */
+int uboot_dev_read (int handle, void *buf, lbasize_t blocks,
+		    lbastart_t start, lbasize_t * real_blocks);
+
+int uboot_dev_recv (int handle, void *buf, int size, int *real_size);
+int uboot_dev_send (int handle, void *buf, int size);
+
+/*
+ * int API_env_get(const char *name, char **value)
+ */
+char *uboot_env_get (const char *name);
+
+/*
+ * int API_env_set(const char *name, const char *value)
+ */
+void uboot_env_set (const char *name, const char *value);
+
+#endif /* ! GRUB_UBOOT_UBOOT_HEADER */


^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2013-05-02 19:25 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-03-24 17:01 [PATCH 3/7] Initial support for U-Boot platforms Leif Lindholm
2013-03-30 16:20 ` Francesco Lavra
2013-03-30 16:43   ` Vladimir 'φ-coder/phcoder' Serbinenko
2013-04-03 16:24   ` Leif Lindholm
2013-04-03 18:05     ` Lennart Sorensen
2013-04-03 19:59       ` Vladimir 'φ-coder/phcoder' Serbinenko
2013-04-01  2:08 ` Vladimir 'φ-coder/phcoder' Serbinenko
2013-04-03 16:17   ` Leif Lindholm
2013-04-08 10:49     ` Vladimir 'φ-coder/phcoder' Serbinenko
2013-04-09 10:37       ` Leif Lindholm
2013-04-09 11:29         ` Vladimir 'φ-coder/phcoder' Serbinenko
2013-05-02 19:25   ` Vladimir 'φ-coder/phcoder' Serbinenko

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).