Blame SOURCES/0096-IBM-client-architecture-CAS-reboot-support.patch

f725e3
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
f725e3
From: Paulo Flabiano Smorigo <pfsmorigo@br.ibm.com>
f725e3
Date: Thu, 20 Sep 2012 18:07:39 -0300
f725e3
Subject: [PATCH] IBM client architecture (CAS) reboot support
f725e3
f725e3
This is an implementation of IBM client architecture (CAS) reboot for GRUB.
f725e3
f725e3
There are cases where the POWER firmware must reboot in order to support
f725e3
specific features requested by a kernel. The kernel calls
f725e3
ibm,client-architecture-support and it may either return or reboot with the new
f725e3
feature set. eg:
f725e3
f725e3
Calling ibm,client-architecture-support.../
f725e3
Elapsed time since release of system processors: 70959 mins 50 secs
f725e3
Welcome to GRUB!
f725e3
f725e3
Instead of return to the GRUB menu, it will check if the flag for CAS reboot is
f725e3
set. If so, grub will automatically boot the last booted kernel using the same
f725e3
parameters
f725e3
---
f725e3
 grub-core/kern/ieee1275/openfw.c | 62 ++++++++++++++++++++++++++++++++++++++++
f725e3
 grub-core/normal/main.c          | 19 ++++++++++++
f725e3
 grub-core/script/execute.c       |  7 +++++
f725e3
 include/grub/ieee1275/ieee1275.h |  2 ++
f725e3
 4 files changed, 90 insertions(+)
f725e3
f725e3
diff --git a/grub-core/kern/ieee1275/openfw.c b/grub-core/kern/ieee1275/openfw.c
f725e3
index ddb778340e4..6db8b986551 100644
f725e3
--- a/grub-core/kern/ieee1275/openfw.c
f725e3
+++ b/grub-core/kern/ieee1275/openfw.c
f725e3
@@ -561,3 +561,65 @@ grub_ieee1275_canonicalise_devname (const char *path)
f725e3
   return NULL;
f725e3
 }
f725e3
 
f725e3
+/* Check if it's a CAS reboot. If so, set the script to be executed.  */
f725e3
+int
f725e3
+grub_ieee1275_cas_reboot (char *script)
f725e3
+{
f725e3
+  grub_uint32_t ibm_ca_support_reboot;
f725e3
+  grub_uint32_t ibm_fw_nbr_reboots;
f725e3
+  char property_value[10];
f725e3
+  grub_ssize_t actual;
f725e3
+  grub_ieee1275_ihandle_t options;
f725e3
+
f725e3
+  if (grub_ieee1275_finddevice ("/options", &options) < 0)
f725e3
+    return -1;
f725e3
+
f725e3
+  /* Check two properties, one is enough to get cas reboot value */
f725e3
+  ibm_ca_support_reboot = 0;
f725e3
+  if (grub_ieee1275_get_integer_property (grub_ieee1275_chosen,
f725e3
+                                          "ibm,client-architecture-support-reboot",
f725e3
+                                          &ibm_ca_support_reboot,
f725e3
+                                          sizeof (ibm_ca_support_reboot),
f725e3
+                                          &actual) >= 0)
f725e3
+    grub_dprintf("ieee1275", "ibm,client-architecture-support-reboot: %u\n",
f725e3
+                 ibm_ca_support_reboot);
f725e3
+
f725e3
+  ibm_fw_nbr_reboots = 0;
f725e3
+  if (grub_ieee1275_get_property (options, "ibm,fw-nbr-reboots",
f725e3
+                                  property_value, sizeof (property_value),
f725e3
+                                  &actual) >= 0)
f725e3
+    {
f725e3
+      property_value[sizeof (property_value) - 1] = 0;
f725e3
+      ibm_fw_nbr_reboots = (grub_uint8_t) grub_strtoul (property_value, 0, 10);
f725e3
+      grub_dprintf("ieee1275", "ibm,fw-nbr-reboots: %u\n", ibm_fw_nbr_reboots);
f725e3
+    }
f725e3
+
f725e3
+  if (ibm_ca_support_reboot || ibm_fw_nbr_reboots)
f725e3
+    {
f725e3
+      if (! grub_ieee1275_get_property_length (options, "boot-last-label", &actual))
f725e3
+        {
f725e3
+          if (actual > 1024)
f725e3
+            script = grub_realloc (script, actual + 1);
f725e3
+          grub_ieee1275_get_property (options, "boot-last-label", script, actual,
f725e3
+                                      &actual);
f725e3
+          return 0;
f725e3
+        }
f725e3
+    }
f725e3
+
f725e3
+  grub_ieee1275_set_boot_last_label ("");
f725e3
+
f725e3
+  return -1;
f725e3
+}
f725e3
+
f725e3
+int grub_ieee1275_set_boot_last_label (const char *text)
f725e3
+{
f725e3
+  grub_ieee1275_ihandle_t options;
f725e3
+  grub_ssize_t actual;
f725e3
+
f725e3
+  grub_dprintf("ieee1275", "set boot_last_label (size: %u)\n", grub_strlen(text));
f725e3
+  if (! grub_ieee1275_finddevice ("/options", &options) &&
f725e3
+      options != (grub_ieee1275_ihandle_t) -1)
f725e3
+    grub_ieee1275_set_property (options, "boot-last-label", text,
f725e3
+                                grub_strlen (text), &actual);
f725e3
+  return 0;
f725e3
+}
f725e3
diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c
f725e3
index 6f4970f71c1..f72844c9f37 100644
f725e3
--- a/grub-core/normal/main.c
f725e3
+++ b/grub-core/normal/main.c
f725e3
@@ -33,6 +33,9 @@
f725e3
 #include <grub/charset.h>
f725e3
 #include <grub/script_sh.h>
f725e3
 #include <grub/bufio.h>
f725e3
+#ifdef GRUB_MACHINE_IEEE1275
f725e3
+#include <grub/ieee1275/ieee1275.h>
f725e3
+#endif
f725e3
 
f725e3
 GRUB_MOD_LICENSE ("GPLv3+");
f725e3
 
f725e3
@@ -275,6 +278,22 @@ grub_normal_execute (const char *config, int nested, int batch)
f725e3
     {
f725e3
       menu = read_config_file (config);
f725e3
 
f725e3
+#ifdef GRUB_MACHINE_IEEE1275
f725e3
+      int boot;
f725e3
+      boot = 0;
f725e3
+      char *script;
f725e3
+      script = grub_malloc (1024);
f725e3
+      if (! grub_ieee1275_cas_reboot (script))
f725e3
+        {
f725e3
+          char *dummy[1] = { NULL };
f725e3
+          if (! grub_script_execute_sourcecode (script, 0, dummy))
f725e3
+            boot = 1;
f725e3
+        }
f725e3
+      grub_free (script);
f725e3
+      if (boot)
f725e3
+        grub_command_execute ("boot", 0, 0);
f725e3
+#endif
f725e3
+
f725e3
       /* Ignore any error.  */
f725e3
       grub_errno = GRUB_ERR_NONE;
f725e3
     }
f725e3
diff --git a/grub-core/script/execute.c b/grub-core/script/execute.c
f725e3
index 8f01c1bbfa2..cec9539a47c 100644
f725e3
--- a/grub-core/script/execute.c
f725e3
+++ b/grub-core/script/execute.c
f725e3
@@ -27,6 +27,9 @@
f725e3
 #include <grub/normal.h>
f725e3
 #include <grub/extcmd.h>
f725e3
 #include <grub/i18n.h>
f725e3
+#ifdef GRUB_MACHINE_IEEE1275
f725e3
+#include <grub/ieee1275/ieee1275.h>
f725e3
+#endif
f725e3
 
f725e3
 /* Max digits for a char is 3 (0xFF is 255), similarly for an int it
f725e3
    is sizeof (int) * 3, and one extra for a possible -ve sign.  */
f725e3
@@ -892,6 +895,10 @@ grub_script_execute_sourcecode (const char *source)
f725e3
   grub_err_t ret = 0;
f725e3
   struct grub_script *parsed_script;
f725e3
 
f725e3
+#ifdef GRUB_MACHINE_IEEE1275
f725e3
+  grub_ieee1275_set_boot_last_label (source);
f725e3
+#endif
f725e3
+
f725e3
   while (source)
f725e3
     {
f725e3
       char *line;
f725e3
diff --git a/include/grub/ieee1275/ieee1275.h b/include/grub/ieee1275/ieee1275.h
f725e3
index 8e425130327..9f26c69a2df 100644
f725e3
--- a/include/grub/ieee1275/ieee1275.h
f725e3
+++ b/include/grub/ieee1275/ieee1275.h
f725e3
@@ -234,6 +234,8 @@ int EXPORT_FUNC(grub_ieee1275_devalias_next) (struct grub_ieee1275_devalias *ali
f725e3
 void EXPORT_FUNC(grub_ieee1275_children_peer) (struct grub_ieee1275_devalias *alias);
f725e3
 void EXPORT_FUNC(grub_ieee1275_children_first) (const char *devpath,
f725e3
 						struct grub_ieee1275_devalias *alias);
f725e3
+int EXPORT_FUNC(grub_ieee1275_cas_reboot) (char *script);
f725e3
+int EXPORT_FUNC(grub_ieee1275_set_boot_last_label) (const char *text);
f725e3
 
f725e3
 #define FOR_IEEE1275_DEVALIASES(alias) for (grub_ieee1275_devalias_init_iterator (&(alias)); grub_ieee1275_devalias_next (&(alias));)
f725e3