Hi all,

This is an implementation of IBM client architecture (CAS) reboot for GRUB.

There are cases where the POWER firmware must reboot in order to support specific features requested by a kernel. The kernel calls ibm,client-architecture-support and it may either return or reboot with the new feature set. eg:

Calling ibm,client-architecture-support.../
Elapsed time since release of system processors: 70959 mins 50 secs
Welcome to GRUB!

Instead of return to the GRUB menu, it will check if the flag for CAS reboot is set. If so, grub will automatically boot the last booted kernel using the same parameters

--
Paulo Flabiano Smorigo
Software Engineer
Linux Technology Center - IBM Systems & Technology Group

=== modified file 'ChangeLog'
--- ChangeLog	2012-09-10 07:34:29 +0000
+++ ChangeLog	2012-09-10 20:35:05 +0000
@@ -1,3 +1,17 @@
+2012-09-10  Paulo Flabiano Smorigo <[email protected]>
+
+	IBM client architecture (CAS) reboot support added.
+
+	* grub-core/kern/ieee1275/openfw.c (grub_ieee1275_cas_reboot): New
+	function.
+	(grub_ieee1275_set_boot_last_label): Likewise.
+	* include/grub/ieee1275/ieee1275.h (grub_ieee1275_cas_reboot): New
+	proto.
+	(grub_ieee1275_set_boot_last_label): Likewise.
+	* grub-core/normal/main.c (grub_normal_execute): CAS reboot check added.
+	* grub-core/script/execute.c (grub_script_execute_sourcecode): Store
+	the meny entry for CAS reboot.
+
 2012-09-10  Benoit Gschwind <gschwind>
 
 	* grub-core/loader/efi/appleloader.c (devpath_8): New var.

=== modified file 'grub-core/kern/ieee1275/openfw.c'
--- grub-core/kern/ieee1275/openfw.c	2012-06-20 21:31:59 +0000
+++ grub-core/kern/ieee1275/openfw.c	2012-09-05 21:17:35 +0000
@@ -523,3 +523,66 @@
   return NULL;
 }
 
+/* Check if it's a CAS reboot. If so, set the script to be executed.  */
+int
+grub_ieee1275_cas_reboot (char *script)
+{
+  grub_uint32_t ibm_ca_support_reboot;
+  grub_uint32_t ibm_fw_nbr_reboots;
+  char property_value[10];
+  grub_ssize_t actual;
+  grub_ieee1275_ihandle_t options;
+
+  if (grub_ieee1275_finddevice ("/options", &options) < 0)
+    return -1;
+
+  /* Check two properties, one is enough to get cas reboot value */
+  ibm_ca_support_reboot = 0;
+  if (grub_ieee1275_get_integer_property (grub_ieee1275_chosen,
+                                          "ibm,client-architecture-support-reboot",
+                                          &ibm_ca_support_reboot,
+                                          sizeof (ibm_ca_support_reboot),
+                                          &actual) >= 0)
+    grub_dprintf("ieee1275", "ibm,client-architecture-support-reboot: %u\n",
+                 ibm_ca_support_reboot);
+
+  ibm_fw_nbr_reboots = 0;
+  if (grub_ieee1275_get_property (options, "ibm,fw-nbr-reboots",
+                                  property_value, sizeof (property_value),
+                                  &actual) >= 0)
+    {
+      property_value[sizeof (property_value) - 1] = 0;
+      ibm_fw_nbr_reboots = (grub_uint8_t) grub_strtoul (property_value, 0, 10);
+      grub_dprintf("ieee1275", "ibm,fw-nbr-reboots: %u\n", ibm_fw_nbr_reboots);
+    }
+
+  if (ibm_ca_support_reboot || ibm_fw_nbr_reboots)
+    {
+      if (! grub_ieee1275_get_property_length (options, "boot-last-label", &actual))
+        {
+          if (actual > 1024)
+            script = grub_realloc (script, actual + 1);
+          grub_ieee1275_get_property (options, "boot-last-label", script, actual,
+                                      &actual);
+          return 0;
+        }
+    }
+
+  grub_ieee1275_set_boot_last_label ("");
+
+  return -1;
+}
+
+int grub_ieee1275_set_boot_last_label (const char *text)
+{
+  grub_ieee1275_ihandle_t options;
+  grub_ssize_t actual;
+
+  grub_dprintf("ieee1275", "set boot_last_label (size: %u)\n", grub_strlen(text));
+  if (! grub_ieee1275_finddevice ("/options", &options) &&
+      options != (grub_ieee1275_ihandle_t) -1)
+    grub_ieee1275_set_property (options, "boot-last-label", text,
+                                grub_strlen (text), &actual);
+  return 0;
+}
+

=== modified file 'grub-core/normal/main.c'
--- grub-core/normal/main.c	2012-06-28 00:06:36 +0000
+++ grub-core/normal/main.c	2012-09-05 21:17:41 +0000
@@ -32,6 +32,9 @@
 #include <grub/i18n.h>
 #include <grub/charset.h>
 #include <grub/script_sh.h>
+#ifdef GRUB_MACHINE_IEEE1275
+#include <grub/ieee1275/ieee1275.h>
+#endif
 
 GRUB_MOD_LICENSE ("GPLv3+");
 
@@ -296,6 +299,22 @@
     {
       menu = read_config_file (config);
 
+#ifdef GRUB_MACHINE_IEEE1275
+      int boot;
+      boot = 0;
+      char *script;
+      script = grub_malloc (1024);
+      if (! grub_ieee1275_cas_reboot (script))
+        {
+          char *dummy[1] = { NULL };
+          if (! grub_script_execute_sourcecode (script, 0, dummy))
+            boot = 1;
+        }
+      grub_free (script);
+      if (boot)
+        grub_command_execute ("boot", 0, 0);
+#endif
+
       /* Ignore any error.  */
       grub_errno = GRUB_ERR_NONE;
     }

=== modified file 'grub-core/script/execute.c'
--- grub-core/script/execute.c	2012-06-21 20:02:09 +0000
+++ grub-core/script/execute.c	2012-09-05 21:13:34 +0000
@@ -27,6 +27,9 @@
 #include <grub/normal.h>
 #include <grub/extcmd.h>
 #include <grub/i18n.h>
+#ifdef GRUB_MACHINE_IEEE1275
+#include <grub/ieee1275/ieee1275.h>
+#endif
 
 /* Max digits for a char is 3 (0xFF is 255), similarly for an int it
    is sizeof (int) * 3, and one extra for a possible -ve sign.  */
@@ -820,6 +823,10 @@
   old_scope = scope;
   scope = &new_scope;
 
+#ifdef GRUB_MACHINE_IEEE1275
+  grub_ieee1275_set_boot_last_label (source);
+#endif
+
   while (source)
     {
       char *line;

=== modified file 'include/grub/ieee1275/ieee1275.h'
--- include/grub/ieee1275/ieee1275.h	2012-06-20 20:19:26 +0000
+++ include/grub/ieee1275/ieee1275.h	2012-09-01 00:32:03 +0000
@@ -208,5 +208,7 @@
 char *EXPORT_FUNC(grub_ieee1275_get_aliasdevname) (const char *path);
 char *EXPORT_FUNC(grub_ieee1275_canonicalise_devname) (const char *path);
 char *EXPORT_FUNC(grub_ieee1275_get_device_type) (const char *path);
+int EXPORT_FUNC(grub_ieee1275_cas_reboot) (char *script);
+int EXPORT_FUNC(grub_ieee1275_set_boot_last_label) (const char *text);
 
 #endif /* ! GRUB_IEEE1275_HEADER */

_______________________________________________
Grub-devel mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to