2
0
mirror of https://github.com/xcat2/xcat-dep.git synced 2024-11-25 19:08:31 +00:00
xcat-dep/yaboot/yaboot-fixes.patch
jbjohnso c30764d95e -Have yaboot request up to 100 transfer retries from firmware
-Skip searching by mac address, in our environment the ip should be less transient
2008-05-05 17:46:05 +00:00

387 lines
12 KiB
Diff

diff -urN yaboot-1.3.14/include/prom.h yaboot-1.3.14-fixes/include/prom.h
--- yaboot-1.3.14/include/prom.h 2007-08-17 10:29:26.000000000 -0400
+++ yaboot-1.3.14-fixes/include/prom.h 2008-05-05 13:40:11.000000000 -0400
@@ -37,6 +37,9 @@
#define PROM_INVALID_HANDLE ((prom_handle)-1UL)
#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 *);
@@ -85,6 +88,7 @@
/* memory */
+void *prom_claim_chunk(void *virt, unsigned int size, unsigned int align);
void *prom_claim (void *virt, unsigned int size, unsigned int align);
void prom_release(void *virt, unsigned int size);
void prom_map (void *phys, void *virt, int size);
@@ -154,5 +158,8 @@
struct bootp_packet * prom_get_netinfo (void);
char * prom_get_mac (struct bootp_packet * packet);
char * prom_get_ip (struct bootp_packet * packet);
+char * prom_get_yiaddr (struct bootp_packet * packet);
+char * prom_get_siaddr (struct bootp_packet * packet);
+char * prom_get_giaddr (struct bootp_packet * packet);
#endif
diff -urN yaboot-1.3.14/second/fs_of.c yaboot-1.3.14-fixes/second/fs_of.c
--- yaboot-1.3.14/second/fs_of.c 2007-08-17 10:29:26.000000000 -0400
+++ yaboot-1.3.14-fixes/second/fs_of.c 2008-05-05 13:41:53.000000000 -0400
@@ -44,9 +44,8 @@
#include "errors.h"
#include "debug.h"
-#define LOAD_BUFFER_POS 0x600000
-/* this cannot be safely increased any further */
-#define LOAD_BUFFER_SIZE 0x600000
+#define LOAD_BUFFER_POS 0x1000000
+#define LOAD_BUFFER_SIZE 0x1000000
static int of_open(struct boot_file_t* file, const char* dev_name,
struct partition_t* part, const char* file_name);
@@ -60,6 +59,8 @@
static int of_net_read(struct boot_file_t* file, unsigned int size, void* buffer);
static int of_net_seek(struct boot_file_t* file, unsigned int newpos);
+static int of_supports_real_tftp(void);
+static int of_net_use_tftp = -1;
struct fs_t of_filesystem =
{
@@ -131,6 +132,34 @@
return FILE_ERR_OK;
}
+/*
+ * older firmwares were really not capable of doing a tftp load. Ie, the
+ * 'boot' command line: <device>:<siaddr>,<file>,<ciaddr> requires that
+ * <siaddr> to be running a bootp server, not simply a tftp server. The
+ * above syntax works with new firmwares.
+ *
+ * This function should return 1 if the running firmware fully supports
+ * tftp and 0 if not.
+ */
+static int of_supports_real_tftp() {
+ of_net_use_tftp=1;
+ return(of_net_use_tftp);
+/*
+ prom_handle h;
+ if(of_net_use_tftp>=0) return(of_net_use_tftp);
+
+ h=prom_open("/packages/cas");
+ if(h) {
+ prom_close(h);
+ of_net_use_tftp=1;
+ } else {
+ of_net_use_tftp=0;
+ }
+ return(of_net_use_tftp);
+*/
+}
+
+
static int
of_net_open(struct boot_file_t* file, const char* dev_name,
struct partition_t* part, const char* file_name)
@@ -138,18 +167,34 @@
static char buffer[1024];
char *filename;
char *p;
+ struct bootp_packet *packet;
DEBUG_ENTER;
DEBUG_OPEN;
+
strncpy(buffer, dev_name, 768);
if (file_name && strlen(file_name)) {
+ if(of_supports_real_tftp()){
+ packet = prom_get_netinfo();
+ strcat(buffer, prom_get_siaddr(packet));
+ }
strcat(buffer, ",");
filename = strdup(file_name);
for (p = filename; *p; p++)
if (*p == '/')
*p = '\\';
strcat(buffer, filename);
+ if(of_supports_real_tftp()) {
+ strcat(buffer, ",");
+ strcat(buffer, prom_get_yiaddr(packet));
+ strcat(buffer, ",");
+ /* Hack required since giaddr not returned on some systems
+ and required to boot on those systems. This should work
+ for the client and server on the same subnet. */
+ strcat(buffer, prom_get_siaddr(packet));
+ }
+ strcat(buffer,",,100");
free(filename);
}
@@ -166,7 +211,9 @@
return FILE_ERR_BAD_FSYS;
}
- file->buffer = prom_claim((void *)LOAD_BUFFER_POS, LOAD_BUFFER_SIZE, 0);
+
+ file->buffer = prom_claim_chunk((void *)LOAD_BUFFER_POS,
+ LOAD_BUFFER_SIZE, 0);
if (file->buffer == (void *)-1) {
prom_printf("Can't claim memory for TFTP download\n");
prom_close(file->of_device);
diff -urN yaboot-1.3.14/second/prom.c yaboot-1.3.14-fixes/second/prom.c
--- yaboot-1.3.14/second/prom.c 2007-08-17 10:29:26.000000000 -0400
+++ yaboot-1.3.14-fixes/second/prom.c 2008-05-05 13:40:11.000000000 -0400
@@ -568,6 +568,25 @@
while (prom_getms() <= end);
}
+/* if address given is claimed look for other addresses to get the needed
+ * space before giving up
+ */
+void *
+prom_claim_chunk(void *virt, unsigned int size, unsigned int align)
+{
+ void *found, *addr;
+ for(addr=virt; addr <= (void*)PROM_CLAIM_MAX_ADDR;
+ addr+=(0x100000/sizeof(addr))) {
+ found = prom_claim(addr, size, 0);
+ if (found != (void *)-1) {
+ DEBUG_F("claimed %i at 0x%x (0x%x)\n",size,(int)found,(int)virt);
+ return(found);
+ }
+ }
+ prom_printf("Claim error, can't allocate %x at 0x%x\n",size,(int)virt);
+ return((void*)-1);
+}
+
void *
prom_claim (void *virt, unsigned int size, unsigned int align)
{
@@ -752,6 +771,78 @@
}
/*
+ * prom_get_yiaddr()
+ * returns the ip addr of the client in dotted decimal format
+ */
+char * prom_get_yiaddr (struct bootp_packet * packet)
+{
+ char * conf_path;
+
+ if (!packet)
+ return NULL;
+
+ /* 15 chars in yiaddr + \0 */
+ conf_path = malloc(16);
+ if (!conf_path)
+ return NULL;
+ sprintf(conf_path, "%d.%d.%d.%d",
+ packet->yiaddr >> 24,
+ (packet->yiaddr << 8) >> 24,
+ (packet->yiaddr << 16) >> 24,
+ (packet->yiaddr << 24) >> 24);
+
+ return conf_path;
+}
+
+/*
+ * prom_get_siaddr()
+ * returns the ip addr of the server in dotted decimal format
+ */
+char * prom_get_siaddr (struct bootp_packet * packet)
+{
+ char * conf_path;
+
+ if (!packet)
+ return NULL;
+
+ /* 15 chars in siaddr + \0 */
+ conf_path = malloc(16);
+ if (!conf_path)
+ return NULL;
+ sprintf(conf_path, "%d.%d.%d.%d",
+ packet->siaddr >> 24,
+ (packet->siaddr << 8) >> 24,
+ (packet->siaddr << 16) >> 24,
+ (packet->siaddr << 24) >> 24);
+
+ return conf_path;
+}
+
+/*
+ * prom_get_giaddr()
+ * returns the ip addr of the gateway in dotted decimal format
+ */
+char * prom_get_giaddr (struct bootp_packet * packet)
+{
+ char * conf_path;
+
+ if (!packet)
+ return NULL;
+
+ /* 15 chars in giaddr + \0 */
+ conf_path = malloc(16);
+ if (!conf_path)
+ return NULL;
+ sprintf(conf_path, "%d.%d.%d.%d",
+ packet->giaddr >> 24,
+ (packet->giaddr << 8) >> 24,
+ (packet->giaddr << 16) >> 24,
+ (packet->giaddr << 24) >> 24);
+
+ return conf_path;
+}
+
+/*
* Local variables:
* c-file-style: "k&r"
* c-basic-offset: 5
diff -urN yaboot-1.3.14/second/yaboot.c yaboot-1.3.14-fixes/second/yaboot.c
--- yaboot-1.3.14/second/yaboot.c 2007-08-17 10:29:26.000000000 -0400
+++ yaboot-1.3.14-fixes/second/yaboot.c 2008-05-05 13:43:48.000000000 -0400
@@ -114,6 +114,9 @@
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;
@@ -471,12 +474,13 @@
if (!fspec.file)
goto out;
- sprintf(fspec.file, "%s%02x-", cfgpath, packet->htype);
+ /* sprintf(fspec.file, "%s%02x-", cfgpath, packet->htype);
strcat(fspec.file, prom_get_mac(packet));
rc = load_config_file(&fspec);
if (rc)
goto out;
+ */
/*
* Now try to match on IP.
@@ -665,7 +669,7 @@
cmdinit();
- if (first) {
+ if (first && !fw_reboot_cnt) {
first = 0;
imagename = bootargs;
word_split(&imagename, &params->args);
@@ -680,6 +684,13 @@
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) {
@@ -716,7 +727,9 @@
if (!imagename) {
if (bootoncelabel[0] != 0)
imagename = bootoncelabel;
- else
+ else if (bootlastlabel[0] != 0)
+ imagename = bootlastlabel;
+ else
imagename = cfg_get_default();
}
if (imagename)
@@ -737,6 +750,9 @@
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;
@@ -1233,7 +1249,7 @@
Elf32_Ehdr *e = &(loadinfo->elf.elf32hdr);
Elf32_Phdr *p, *ph;
int size = sizeof(Elf32_Ehdr) - sizeof(Elf_Ident);
- unsigned long addr, loadaddr;
+ unsigned long loadaddr;
/* Read the rest of the Elf header... */
if ((*(file->fs->read))(file, size, &e->e_version) < size) {
@@ -1321,13 +1337,7 @@
loadaddr = loadinfo->load_loc;
}
- /* On some systems, loadaddr may already be claimed, so try some
- * other nearby addresses before giving up.
- */
- for(addr=loadaddr; addr <= loadaddr * 8 ;addr+=0x100000) {
- loadinfo->base = prom_claim((void *)addr, loadinfo->memsize, 0);
- if (loadinfo->base != (void *)-1) break;
- }
+ loadinfo->base = prom_claim_chunk((void *)loadaddr, loadinfo->memsize, 0);
if (loadinfo->base == (void *)-1) {
prom_printf("Claim error, can't allocate kernel memory\n");
goto bail;
@@ -1377,7 +1387,7 @@
Elf64_Ehdr *e = &(loadinfo->elf.elf64hdr);
Elf64_Phdr *p, *ph;
int size = sizeof(Elf64_Ehdr) - sizeof(Elf_Ident);
- unsigned long addr, loadaddr;
+ unsigned long loadaddr;
/* Read the rest of the Elf header... */
if ((*(file->fs->read))(file, size, &e->e_version) < size) {
@@ -1465,13 +1475,7 @@
loadaddr = e->e_entry;
}
- /* On some systems, loadaddr may already be claimed, so try some
- * other nearby addresses before giving up.
- */
- for(addr=loadaddr; addr <= loadaddr * 8 ;addr+=0x100000) {
- loadinfo->base = prom_claim((void *)addr, loadinfo->memsize, 0);
- if (loadinfo->base != (void *)-1) break;
- }
+ loadinfo->base = prom_claim_chunk((void *)loadaddr, loadinfo->memsize, 0);
if (loadinfo->base == (void *)-1) {
prom_printf("Claim error, can't allocate kernel memory\n");
goto bail;
@@ -1625,8 +1629,10 @@
yaboot_main(void)
{
char *ptype;
+ char *endp;
int conf_given = 0;
char conf_path[1024];
+ int ret;
if (_machine == _MACH_Pmac)
setup_display();
@@ -1635,6 +1641,11 @@
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,#reconfig-reboots",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