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;
cmdinit();
- if (first) {
+ if (first && !fw_reboot_cnt) {
first = 0;
imagename = bootargs;
word_split(&imagename, ¶ms->args);
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) {
if (!imagename) {
if (bootoncelabel[0] != 0)
imagename = bootoncelabel;
- else
+ else if (bootlastlabel[0] != 0)
+ imagename = bootlastlabel;
+ else
imagename = cfg_get_default();
}
if (imagename)
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;
void *sysmap_base;
unsigned long sysmap_size;
kernel_entry_t kernel_entry;
- struct bi_record* birec;
char* loc=NULL;
loadinfo_t loadinfo;
void *initrd_more,*initrd_want;
flush_icache_range ((long)loadinfo.base, (long)loadinfo.base+loadinfo.memsize);
DEBUG_F(" done\n");
- if (flat_vmlinux) {
- /*
- * Fill new boot infos (only if booting a vmlinux).
- *
- * The birec is low on memory, probably inside the malloc pool,
- * so we don't write it earlier. At this point, we should not
- * use anything coming from the malloc pool.
- */
- birec = (struct bi_record *)_ALIGN(loadinfo.filesize+(1<<20)-1,(1<<20));
-
- /* We make sure it's mapped. We map only 64k for now, it's
- * plenty enough we don't claim since this precise memory
- * range may already be claimed by the malloc pool.
- */
- prom_map (birec, birec, 0x10000);
- DEBUG_F("birec at %p\n", birec);
- DEBUG_SLEEP;
-
- birec->tag = BI_FIRST;
- birec->size = sizeof(struct bi_record);
- birec = (struct bi_record *)((ulong)birec + birec->size);
-
- birec->tag = BI_BOOTLOADER_ID;
- sprintf( (char *)birec->data, "yaboot");
- birec->size = sizeof(struct bi_record) + strlen("yaboot") + 1;
- birec = (struct bi_record *)((ulong)birec + birec->size);
-
- birec->tag = BI_MACHTYPE;
- birec->data[0] = _machine;
- birec->size = sizeof(struct bi_record) + sizeof(ulong);
- birec = (struct bi_record *)((ulong)birec + birec->size);
-
- if (sysmap_base) {
- birec->tag = BI_SYSMAP;
- birec->data[0] = (ulong)sysmap_base;
- birec->data[1] = sysmap_size;
- birec->size = sizeof(struct bi_record) + sizeof(ulong)*2;
- birec = (struct bi_record *)((ulong)birec + birec->size);
- }
- birec->tag = BI_LAST;
- birec->size = sizeof(struct bi_record);
- birec = (struct bi_record *)((ulong)birec + birec->size);
- }
-
/* compute the kernel's entry point. */
kernel_entry = loadinfo.base + loadinfo.entry - loadinfo.load_loc;
goto bail;
}
- /* leave some room (1Mb) for boot infos */
- loadinfo->memsize = _ALIGN(loadinfo->memsize,(1<<20)) + 0x100000;
+ loadinfo->memsize = _ALIGN(loadinfo->memsize,(1<<20));
/* Claim OF memory */
DEBUG_F("Before prom_claim, mem_sz: 0x%08lx\n", loadinfo->memsize);
e->e_ident[EI_MAG3] == ELFMAG3 &&
e->e_ident[EI_CLASS] == ELFCLASS64 &&
e->e_ident[EI_DATA] == ELFDATA2MSB &&
- e->e_type == ET_EXEC &&
+ (e->e_type == ET_EXEC || e->e_type == ET_DYN) &&
e->e_machine == EM_PPC64);
}
yaboot_main(void)
{
char *ptype;
+ char *endp;
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);
+ if (prom_get_options("ibm,client-architecture-support-reboot",fw_nbr_reboots, FW_NBR_REBOOTSZ) == -1 )
+ 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
prom_printf("%s: Unable to parse\n", bootdevice);
return -1;
}
- if (_machine == _MACH_bplan)
+ if (_machine == _MACH_bplan && !conf_given)
boot.part++;
DEBUG_F("After parse_device_path: dev=%s, part=%d, file=%s\n",
boot.dev, boot.part, boot.file);
if (!conf_given) {
- if (_machine == _MACH_chrp || machine == _MACH_bplan)
+ if (_machine == _MACH_chrp || _machine == _MACH_bplan)
boot.file = "/etc/";
else if (strlen(boot.file)) {
if (!strncmp(boot.file, "\\\\", 2))