summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
f843e29)
OS has. These capabilities result in different modes which the device-tree is
configured in, as well as what processor capabilities are presented. So, if
the capabilities are different from what was previously booted, firmware has to
reboot to reconfigure the device-tree. The second boot will have the updated
device-tree and we can boot as normal.
When this firmware initiated reboot occurs yaboot will now boot the same kernel
as the previous boot attempt with no action by the user needed. I have
successfully booted on POWER5 and POWER6 machines using various levels of the
kernel.
Patch from: Mike Wolf <mjw@linux.vnet.ibm.com>
#define BOOTDEVSZ (2048) /* iscsi args can be in excess of 1040 bytes */
#define TOK_ISCSI "iscsi"
#define PROM_CLAIM_MAX_ADDR 0x8000000
#define BOOTDEVSZ (2048) /* iscsi args can be in excess of 1040 bytes */
#define TOK_ISCSI "iscsi"
#define PROM_CLAIM_MAX_ADDR 0x8000000
+#define BOOTLASTSZ 1024
+#define FW_NBR_REBOOTSZ 4
struct prom_args;
typedef int (*prom_entry)(struct prom_args *);
struct prom_args;
typedef int (*prom_entry)(struct prom_args *);
char bootdevice[BOOTDEVSZ];
char bootoncelabel[1024];
char bootargs[1024];
char bootdevice[BOOTDEVSZ];
char bootoncelabel[1024];
char bootargs[1024];
+char bootlastlabel[BOOTLASTSZ] = {0};
+char fw_nbr_reboots[FW_NBR_REBOOTSZ] = {0};
+long fw_reboot_cnt = 0;
char *password = NULL;
struct boot_fspec_t boot;
int _machine = _MACH_Pmac;
char *password = NULL;
struct boot_fspec_t boot;
int _machine = _MACH_Pmac;
+ if (first && !fw_reboot_cnt) {
first = 0;
imagename = bootargs;
word_split(&imagename, ¶ms->args);
first = 0;
imagename = bootargs;
word_split(&imagename, ¶ms->args);
timeout = simple_strtol(q, NULL, 0);
}
timeout = simple_strtol(q, NULL, 0);
}
+ /* If this is a reboot due to FW detecting CAS changes then
+ * set timeout to 1. The last kernel booted will be booted
+ * again automatically. It should seem seamless to the user
+ */
+ if (fw_reboot_cnt)
+ timeout = 1;
+
prom_printf("boot: ");
c = -1;
if (timeout != -1) {
prom_printf("boot: ");
c = -1;
if (timeout != -1) {
if (!imagename) {
if (bootoncelabel[0] != 0)
imagename = bootoncelabel;
if (!imagename) {
if (bootoncelabel[0] != 0)
imagename = bootoncelabel;
+ else if (bootlastlabel[0] != 0)
+ imagename = bootlastlabel;
+ else
imagename = cfg_get_default();
}
if (imagename)
imagename = cfg_get_default();
}
if (imagename)
if ( useconf && (!imagename || imagename[0] == 0 ))
imagename = cfg_get_default();
if ( useconf && (!imagename || imagename[0] == 0 ))
imagename = cfg_get_default();
+ /* write the imagename out so it can be reused on reboot if necessary */
+ prom_set_options("boot-last-label", imagename, strlen(imagename));
+
label = 0;
defdevice = boot.dev;
label = 0;
defdevice = boot.dev;
yaboot_main(void)
{
char *ptype;
yaboot_main(void)
{
char *ptype;
int conf_given = 0;
char conf_path[1024];
int conf_given = 0;
char conf_path[1024];
DEBUG_F("/chosen/bootargs = %s\n", bootargs);
prom_get_chosen("bootpath", bootdevice, BOOTDEVSZ);
DEBUG_F("/chosen/bootpath = %s\n", bootdevice);
DEBUG_F("/chosen/bootargs = %s\n", bootargs);
prom_get_chosen("bootpath", bootdevice, BOOTDEVSZ);
DEBUG_F("/chosen/bootpath = %s\n", bootdevice);
+ prom_get_options("ibm,fw-nbr-reboots",fw_nbr_reboots, FW_NBR_REBOOTSZ);
+ fw_reboot_cnt = simple_strtol(fw_nbr_reboots,&endp,10);
+ if (fw_reboot_cnt > 0L)
+ prom_get_options("boot-last-label", bootlastlabel, BOOTLASTSZ);
/* If conf= specified on command line, it overrides
Usage: conf=device:partition,/path/to/conffile
/* If conf= specified on command line, it overrides
Usage: conf=device:partition,/path/to/conffile