From patchwork Wed Jan 2 20:12:34 2008 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Wolf X-Patchwork-Id: 22963 Return-Path: X-Original-To: yaboot-devel@ozlabs.org Delivered-To: yaboot-devel@ozlabs.org Received: from e33.co.us.ibm.com (e33.co.us.ibm.com [32.97.110.151]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "e33.co.us.ibm.com", Issuer "Equifax" (verified OK)) by ozlabs.org (Postfix) with ESMTP id 668B7DDDDB for ; Thu, 3 Jan 2008 07:12:37 +1100 (EST) Received: from d03relay04.boulder.ibm.com (d03relay04.boulder.ibm.com [9.17.195.106]) by e33.co.us.ibm.com (8.13.8/8.13.8) with ESMTP id m02KCZYB025057 for ; Wed, 2 Jan 2008 15:12:35 -0500 Received: from d03av02.boulder.ibm.com (d03av02.boulder.ibm.com [9.17.195.168]) by d03relay04.boulder.ibm.com (8.13.8/8.13.8/NCO v8.7) with ESMTP id m02KCYIP126466 for ; Wed, 2 Jan 2008 13:12:34 -0700 Received: from d03av02.boulder.ibm.com (loopback [127.0.0.1]) by d03av02.boulder.ibm.com (8.12.11.20060308/8.13.3) with ESMTP id m02KCYoO004054 for ; Wed, 2 Jan 2008 13:12:34 -0700 Received: from [9.10.86.71] (9-10-86-71.rchland.ibm.com [9.10.86.71]) by d03av02.boulder.ibm.com (8.12.11.20060308/8.12.11) with ESMTP id m02KCXdL003980 for ; Wed, 2 Jan 2008 13:12:34 -0700 Message-ID: <477BF032.20308@linux.vnet.ibm.com> Date: Wed, 02 Jan 2008 14:12:34 -0600 From: Mike Wolf User-Agent: Thunderbird 2.0.0.6 (X11/20071022) MIME-Version: 1.0 To: yaboot-devel@ozlabs.org Subject: [PATCH] support firmware reboot when CAS changes are detected. X-BeenThere: yaboot-devel@ozlabs.org X-Mailman-Version: 2.1.9 Precedence: list Reply-To: mjw@linux.vnet.ibm.com List-Id: Technical and development discussion regarding yaboot List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 02 Jan 2008 20:12:38 -0000 The CAS (Client-Architecture Support) call tells firmware what capabilities the 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. ------ diff --git a/include/prom.h b/include/prom.h index 6e4d890..eacee77 100644 --- a/include/prom.h +++ b/include/prom.h @@ -38,6 +38,8 @@ #define PROM_INVALID_HANDLE ((prom_handl #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 *); diff --git a/second/yaboot.c b/second/yaboot.c index 46ab0ef..5fc1213 100644 --- a/second/yaboot.c +++ b/second/yaboot.c @@ -114,6 +114,9 @@ int useconf = 0; 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; @@ -674,7 +677,7 @@ int get_params(struct boot_param_t* para cmdinit(); - if (first) { + if (first && !fw_reboot_cnt) { first = 0; imagename = bootargs; word_split(&imagename, ¶ms->args); @@ -689,6 +692,13 @@ int get_params(struct boot_param_t* para 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) { @@ -725,7 +735,9 @@ int get_params(struct boot_param_t* para if (!imagename) { if (bootoncelabel[0] != 0) imagename = bootoncelabel; - else + else if (bootlastlabel[0] != 0) + imagename = bootlastlabel; + else imagename = cfg_get_default(); } if (imagename) @@ -786,6 +798,9 @@ int get_params(struct boot_param_t* para 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; @@ -1676,6 +1691,7 @@ int yaboot_main(void) { char *ptype; + char *endp; int conf_given = 0; char conf_path[1024]; @@ -1686,6 +1702,10 @@ yaboot_main(void) 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