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

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