grub_ieee1275_phandle_t grub_ieee1275_chosen;
static grub_uint32_t grub_ieee1275_flags;
-
\f
+
int
grub_ieee1275_test_flag (enum grub_ieee1275_flag flag)
{
grub_ieee1275_phandle_t openprom;
int rc;
int realmode = 0;
+ char tmp[32];
+ int is_smartfirmware = 0;
grub_ieee1275_finddevice ("/options", &options);
rc = grub_ieee1275_get_property (options, "real-mode?", &realmode,
grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_REAL_MODE);
grub_ieee1275_finddevice ("/openprom", &openprom);
- rc = grub_ieee1275_get_property (openprom, "SmartFirmware-version", 0, 0, 0);
- if (rc >= 0)
+
+ rc = grub_ieee1275_get_property (openprom, "CodeGen-copyright",
+ tmp, sizeof (tmp), 0);
+#define SF "SmartFirmware(tm)"
+ if (rc >= 0 && !grub_strncmp (tmp, SF, sizeof (SF) - 1))
+ is_smartfirmware = 1;
+
+ if (is_smartfirmware)
{
- grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_NO_PARTITION_0);
- grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_0_BASED_PARTITIONS);
+ /* Broken in all versions */
grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_BROKEN_OUTPUT);
+
+ /* There are two incompatible ways of checking the version number. Try
+ both. */
+ rc = grub_ieee1275_get_property (openprom, "SmartFirmware-version",
+ tmp, sizeof (tmp), 0);
+ if (rc < 0)
+ rc = grub_ieee1275_get_property (openprom, "firmware-version",
+ tmp, sizeof (tmp), 0);
+ if (rc >= 0)
+ {
+ /* It is tempting to implement a version parser to set the flags for
+ e.g. 1.3 and below. However, there's a special situation here.
+ 3rd party updates which fix the partition bugs are common, and for
+ some reason their fixes aren't being merged into trunk. So for
+ example we know that 1.2 and 1.3 are broken, but there's 1.2.99
+ and 1.3.99 which are known good (and appliing this workaround
+ would cause breakage). */
+ if (!grub_strcmp (tmp, "1.0")
+ || !grub_strcmp (tmp, "1.1")
+ || !grub_strcmp (tmp, "1.2")
+ || !grub_strcmp (tmp, "1.3"))
+ {
+ grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_NO_PARTITION_0);
+ grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_0_BASED_PARTITIONS);
+ }
+ }
}
}