diff options
Diffstat (limited to 'arch/powerpc/boot')
23 files changed, 721 insertions, 51 deletions
diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile index aac1406..8fc6d72 100644 --- a/arch/powerpc/boot/Makefile +++ b/arch/powerpc/boot/Makefile @@ -68,7 +68,8 @@ src-plat := of.c cuboot-52xx.c cuboot-824x.c cuboot-83xx.c cuboot-85xx.c holly.c fixed-head.S ep88xc.c ep405.c cuboot-c2k.c \ cuboot-katmai.c cuboot-rainier.c redboot-8xx.c ep8248e.c \ cuboot-warp.c cuboot-85xx-cpm2.c cuboot-yosemite.c simpleboot.c \ - virtex405-head.S virtex.c redboot-83xx.c cuboot-sam440ep.c + virtex405-head.S virtex.c redboot-83xx.c cuboot-sam440ep.c \ + cuboot-acadia.c src-boot := $(src-wlib) $(src-plat) empty.c src-boot := $(addprefix $(obj)/, $(src-boot)) @@ -211,6 +212,7 @@ image-$(CONFIG_DEFAULT_UIMAGE) += uImage # Board ports in arch/powerpc/platform/40x/Kconfig image-$(CONFIG_EP405) += dtbImage.ep405 image-$(CONFIG_WALNUT) += treeImage.walnut +image-$(CONFIG_ACADIA) += cuImage.acadia # Board ports in arch/powerpc/platform/44x/Kconfig image-$(CONFIG_EBONY) += treeImage.ebony cuImage.ebony @@ -319,6 +321,9 @@ $(obj)/zImage.iseries: vmlinux $(obj)/uImage: vmlinux $(wrapperbits) $(call if_changed,wrap,uboot) +$(obj)/cuImage.initrd.%: vmlinux $(obj)/%.dtb $(wrapperbits) + $(call if_changed,wrap,cuboot-$*,,$(obj)/$*.dtb,$(obj)/ramdisk.image.gz) + $(obj)/cuImage.%: vmlinux $(obj)/%.dtb $(wrapperbits) $(call if_changed,wrap,cuboot-$*,,$(obj)/$*.dtb) diff --git a/arch/powerpc/boot/addnote.c b/arch/powerpc/boot/addnote.c index dcc9ab2..3091d1d 100644 --- a/arch/powerpc/boot/addnote.c +++ b/arch/powerpc/boot/addnote.c @@ -11,7 +11,7 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. * - * Usage: addnote zImage [note.elf] + * Usage: addnote [-r realbase] zImage [note.elf] * * If note.elf is supplied, it is the name of an ELF file that contains * an RPA note to use instead of the built-in one. Alternatively, the @@ -153,18 +153,31 @@ unsigned char *read_rpanote(const char *fname, int *nnp) int main(int ac, char **av) { - int fd, n, i; + int fd, n, i, ai; int ph, ps, np; int nnote, nnote2, ns; unsigned char *rpap; - - if (ac != 2 && ac != 3) { - fprintf(stderr, "Usage: %s elf-file [rpanote.elf]\n", av[0]); + char *p, *endp; + + ai = 1; + if (ac >= ai + 2 && strcmp(av[ai], "-r") == 0) { + /* process -r realbase */ + p = av[ai + 1]; + descr[1] = strtol(p, &endp, 16); + if (endp == p || *endp != 0) { + fprintf(stderr, "Can't parse -r argument '%s' as hex\n", + p); + exit(1); + } + ai += 2; + } + if (ac != ai + 1 && ac != ai + 2) { + fprintf(stderr, "Usage: %s [-r realbase] elf-file [rpanote.elf]\n", av[0]); exit(1); } - fd = open(av[1], O_RDWR); + fd = open(av[ai], O_RDWR); if (fd < 0) { - perror(av[1]); + perror(av[ai]); exit(1); } @@ -184,12 +197,12 @@ main(int ac, char **av) if (buf[E_IDENT+EI_CLASS] != ELFCLASS32 || buf[E_IDENT+EI_DATA] != ELFDATA2MSB) { fprintf(stderr, "%s is not a big-endian 32-bit ELF image\n", - av[1]); + av[ai]); exit(1); } - if (ac == 3) - rpap = read_rpanote(av[2], &nnote2); + if (ac == ai + 2) + rpap = read_rpanote(av[ai + 1], &nnote2); ph = GET_32BE(buf, E_PHOFF); ps = GET_16BE(buf, E_PHENTSIZE); @@ -202,7 +215,7 @@ main(int ac, char **av) for (i = 0; i < np; ++i) { if (GET_32BE(buf, ph + PH_TYPE) == PT_NOTE) { fprintf(stderr, "%s already has a note entry\n", - av[1]); + av[ai]); exit(0); } ph += ps; @@ -260,18 +273,18 @@ main(int ac, char **av) exit(1); } if (i < n) { - fprintf(stderr, "%s: write truncated\n", av[1]); + fprintf(stderr, "%s: write truncated\n", av[ai]); exit(1); } exit(0); notelf: - fprintf(stderr, "%s does not appear to be an ELF file\n", av[1]); + fprintf(stderr, "%s does not appear to be an ELF file\n", av[ai]); exit(1); nospace: fprintf(stderr, "sorry, I can't find space in %s to put the note\n", - av[1]); + av[ai]); exit(1); } diff --git a/arch/powerpc/boot/cuboot-52xx.c b/arch/powerpc/boot/cuboot-52xx.c index a861154..4c42ec8 100644 --- a/arch/powerpc/boot/cuboot-52xx.c +++ b/arch/powerpc/boot/cuboot-52xx.c @@ -37,6 +37,10 @@ static void platform_fixups(void) * this can do a simple path lookup. */ soc = find_node_by_devtype(NULL, "soc"); + if (!soc) + soc = find_node_by_compatible(NULL, "fsl,mpc5200-immr"); + if (!soc) + soc = find_node_by_compatible(NULL, "fsl,mpc5200b-immr"); if (soc) { setprop(soc, "bus-frequency", &bd.bi_ipbfreq, sizeof(bd.bi_ipbfreq)); diff --git a/arch/powerpc/boot/cuboot-acadia.c b/arch/powerpc/boot/cuboot-acadia.c new file mode 100644 index 0000000..0634aba --- /dev/null +++ b/arch/powerpc/boot/cuboot-acadia.c @@ -0,0 +1,174 @@ +/* + * Old U-boot compatibility for Acadia + * + * Author: Josh Boyer <jwboyer@linux.vnet.ibm.com> + * + * Copyright 2008 IBM Corporation + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + +#include "ops.h" +#include "io.h" +#include "dcr.h" +#include "stdio.h" +#include "4xx.h" +#include "44x.h" +#include "cuboot.h" + +#define TARGET_4xx +#include "ppcboot.h" + +static bd_t bd; + +#define CPR_PERD0_SPIDV_MASK 0x000F0000 /* SPI Clock Divider */ + +#define PLLC_SRC_MASK 0x20000000 /* PLL feedback source */ + +#define PLLD_FBDV_MASK 0x1F000000 /* PLL feedback divider value */ +#define PLLD_FWDVA_MASK 0x000F0000 /* PLL forward divider A value */ +#define PLLD_FWDVB_MASK 0x00000700 /* PLL forward divider B value */ + +#define PRIMAD_CPUDV_MASK 0x0F000000 /* CPU Clock Divisor Mask */ +#define PRIMAD_PLBDV_MASK 0x000F0000 /* PLB Clock Divisor Mask */ +#define PRIMAD_OPBDV_MASK 0x00000F00 /* OPB Clock Divisor Mask */ +#define PRIMAD_EBCDV_MASK 0x0000000F /* EBC Clock Divisor Mask */ + +#define PERD0_PWMDV_MASK 0xFF000000 /* PWM Divider Mask */ +#define PERD0_SPIDV_MASK 0x000F0000 /* SPI Divider Mask */ +#define PERD0_U0DV_MASK 0x0000FF00 /* UART 0 Divider Mask */ +#define PERD0_U1DV_MASK 0x000000FF /* UART 1 Divider Mask */ + +static void get_clocks(void) +{ + unsigned long sysclk, cpr_plld, cpr_pllc, cpr_primad, plloutb, i; + unsigned long pllFwdDiv, pllFwdDivB, pllFbkDiv, pllPlbDiv, pllExtBusDiv; + unsigned long pllOpbDiv, freqEBC, freqUART, freqOPB; + unsigned long div; /* total divisor udiv * bdiv */ + unsigned long umin; /* minimum udiv */ + unsigned short diff; /* smallest diff */ + unsigned long udiv; /* best udiv */ + unsigned short idiff; /* current diff */ + unsigned short ibdiv; /* current bdiv */ + unsigned long est; /* current estimate */ + unsigned long baud; + void *np; + + /* read the sysclk value from the CPLD */ + sysclk = (in_8((unsigned char *)0x80000000) == 0xc) ? 66666666 : 33333000; + + /* + * Read PLL Mode registers + */ + cpr_plld = CPR0_READ(DCRN_CPR0_PLLD); + cpr_pllc = CPR0_READ(DCRN_CPR0_PLLC); + + /* + * Determine forward divider A + */ + pllFwdDiv = ((cpr_plld & PLLD_FWDVA_MASK) >> 16); + + /* + * Determine forward divider B + */ + pllFwdDivB = ((cpr_plld & PLLD_FWDVB_MASK) >> 8); + if (pllFwdDivB == 0) + pllFwdDivB = 8; + + /* + * Determine FBK_DIV. + */ + pllFbkDiv = ((cpr_plld & PLLD_FBDV_MASK) >> 24); + if (pllFbkDiv == 0) + pllFbkDiv = 256; + + /* + * Read CPR_PRIMAD register + */ + cpr_primad = CPR0_READ(DCRN_CPR0_PRIMAD); + + /* + * Determine PLB_DIV. + */ + pllPlbDiv = ((cpr_primad & PRIMAD_PLBDV_MASK) >> 16); + if (pllPlbDiv == 0) + pllPlbDiv = 16; + + /* + * Determine EXTBUS_DIV. + */ + pllExtBusDiv = (cpr_primad & PRIMAD_EBCDV_MASK); + if (pllExtBusDiv == 0) + pllExtBusDiv = 16; + + /* + * Determine OPB_DIV. + */ + pllOpbDiv = ((cpr_primad & PRIMAD_OPBDV_MASK) >> 8); + if (pllOpbDiv == 0) + pllOpbDiv = 16; + + /* There is a bug in U-Boot that prevents us from using + * bd.bi_opbfreq because U-Boot doesn't populate it for + * 405EZ. We get to calculate it, yay! + */ + freqOPB = (sysclk *pllFbkDiv) /pllOpbDiv; + + freqEBC = (sysclk * pllFbkDiv) / pllExtBusDiv; + + plloutb = ((sysclk * ((cpr_pllc & PLLC_SRC_MASK) ? + pllFwdDivB : pllFwdDiv) * + pllFbkDiv) / pllFwdDivB); + + np = find_node_by_alias("serial0"); + if (getprop(np, "current-speed", &baud, sizeof(baud)) != sizeof(baud)) + fatal("no current-speed property\n\r"); + + udiv = 256; /* Assume lowest possible serial clk */ + div = plloutb / (16 * baud); /* total divisor */ + umin = (plloutb / freqOPB) << 1; /* 2 x OPB divisor */ + diff = 256; /* highest possible */ + + /* i is the test udiv value -- start with the largest + * possible (256) to minimize serial clock and constrain + * search to umin. + */ + for (i = 256; i > umin; i--) { + ibdiv = div / i; + est = i * ibdiv; + idiff = (est > div) ? (est-div) : (div-est); + if (idiff == 0) { + udiv = i; + break; /* can't do better */ + } else if (idiff < diff) { + udiv = i; /* best so far */ + diff = idiff; /* update lowest diff*/ + } + } + freqUART = plloutb / udiv; + + dt_fixup_cpu_clocks(bd.bi_procfreq, bd.bi_intfreq, bd.bi_plb_busfreq); + dt_fixup_clock("/plb/ebc", freqEBC); + dt_fixup_clock("/plb/opb", freqOPB); + dt_fixup_clock("/plb/opb/serial@ef600300", freqUART); + dt_fixup_clock("/plb/opb/serial@ef600400", freqUART); +} + +static void acadia_fixups(void) +{ + dt_fixup_memory(bd.bi_memstart, bd.bi_memsize); + get_clocks(); + dt_fixup_mac_address_by_alias("ethernet0", bd.bi_enetaddr); +} + +void platform_init(unsigned long r3, unsigned long r4, unsigned long r5, + unsigned long r6, unsigned long r7) +{ + CUBOOT_INIT(); + platform_ops.fixups = acadia_fixups; + platform_ops.exit = ibm40x_dbcr_reset; + fdt_init(_dtb_start); + serial_console_init(); +} diff --git a/arch/powerpc/boot/dts/acadia.dts b/arch/powerpc/boot/dts/acadia.dts new file mode 100644 index 0000000..57291f6 --- /dev/null +++ b/arch/powerpc/boot/dts/acadia.dts @@ -0,0 +1,224 @@ +/* + * Device Tree Source for AMCC Acadia (405EZ) + * + * Copyright IBM Corp. 2008 + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + model = "amcc,acadia"; + compatible = "amcc,acadia"; + dcr-parent = <&{/cpus/cpu@0}>; + + aliases { + ethernet0 = &EMAC0; + serial0 = &UART0; + serial1 = &UART1; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + model = "PowerPC,405EZ"; + reg = <0x0>; + clock-frequency = <0>; /* Filled in by wrapper */ + timebase-frequency = <0>; /* Filled in by wrapper */ + i-cache-line-size = <32>; + d-cache-line-size = <32>; + i-cache-size = <16384>; + d-cache-size = <16384>; + dcr-controller; + dcr-access-method = "native"; + }; + }; + + memory { + device_type = "memory"; + reg = <0x0 0x0>; /* Filled in by wrapper */ + }; + + UIC0: interrupt-controller { + compatible = "ibm,uic-405ez", "ibm,uic"; + interrupt-controller; + dcr-reg = <0x0c0 0x009>; + cell-index = <0>; + #address-cells = <0>; + #size-cells = <0>; + #interrupt-cells = <2>; + }; + + plb { + compatible = "ibm,plb-405ez", "ibm,plb3"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + clock-frequency = <0>; /* Filled in by wrapper */ + + MAL0: mcmal { + compatible = "ibm,mcmal-405ez", "ibm,mcmal"; + dcr-reg = <0x380 0x62>; + num-tx-chans = <1>; + num-rx-chans = <1>; + interrupt-parent = <&UIC0>; + /* 405EZ has only 3 interrupts to the UIC, as + * SERR, TXDE, and RXDE are or'd together into + * one UIC bit + */ + interrupts = < + 0x13 0x4 /* TXEOB */ + 0x15 0x4 /* RXEOB */ + 0x12 0x4 /* SERR, TXDE, RXDE */>; + }; + + POB0: opb { + compatible = "ibm,opb-405ez", "ibm,opb"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + dcr-reg = <0x0a 0x05>; + clock-frequency = <0>; /* Filled in by wrapper */ + + UART0: serial@ef600300 { + device_type = "serial"; + compatible = "ns16550"; + reg = <0xef600300 0x8>; + virtual-reg = <0xef600300>; + clock-frequency = <0>; /* Filled in by wrapper */ + current-speed = <115200>; + interrupt-parent = <&UIC0>; + interrupts = <0x5 0x4>; + }; + + UART1: serial@ef600400 { + device_type = "serial"; + compatible = "ns16550"; + reg = <0xef600400 0x8>; + clock-frequency = <0>; /* Filled in by wrapper */ + current-speed = <115200>; + interrupt-parent = <&UIC0>; + interrupts = <0x6 0x4>; + }; + + IIC: i2c@ef600500 { + compatible = "ibm,iic-405ez", "ibm,iic"; + reg = <0xef600500 0x11>; + interrupt-parent = <&UIC0>; + interrupts = <0xa 0x4>; + }; + + GPIO0: gpio@ef600700 { + compatible = "ibm,gpio-405ez"; + reg = <0xef600700 0x20>; + }; + + GPIO1: gpio@ef600800 { + compatible = "ibm,gpio-405ez"; + reg = <0xef600800 0x20>; + }; + + EMAC0: ethernet@ef600900 { + device_type = "network"; + compatible = "ibm,emac-405ez", "ibm,emac"; + interrupt-parent = <&UIC0>; + interrupts = < + 0x10 0x4 /* Ethernet */ + 0x11 0x4 /* Ethernet Wake up */>; + local-mac-address = [000000000000]; /* Filled in by wrapper */ + reg = <0xef600900 0x70>; + mal-device = <&MAL0>; + mal-tx-channel = <0>; + mal-rx-channel = <0>; + cell-index = <0>; + max-frame-size = <1500>; + rx-fifo-size = <4096>; + tx-fifo-size = <2048>; + phy-mode = "mii"; + phy-map = <0x0>; + }; + + CAN0: can@ef601000 { + compatible = "amcc,can-405ez"; + reg = <0xef601000 0x620>; + interrupt-parent = <&UIC0>; + interrupts = <0x7 0x4>; + }; + + CAN1: can@ef601800 { + compatible = "amcc,can-405ez"; + reg = <0xef601800 0x620>; + interrupt-parent = <&UIC0>; + interrupts = <0x8 0x4>; + }; + + cameleon@ef602000 { + compatible = "amcc,cameleon-405ez"; + reg = <0xef602000 0x800>; + interrupt-parent = <&UIC0>; + interrupts = <0xb 0x4 0xc 0x4>; + }; + + ieee1588@ef602800 { + compatible = "amcc,ieee1588-405ez"; + reg = <0xef602800 0x60>; + interrupt-parent = <&UIC0>; + interrupts = <0x4 0x4>; + /* This thing is a bit weird. It has it's own UIC + * that it uses to generate snapshot triggers. We + * don't really support this device yet, and it needs + * work to figure this out. + */ + dcr-reg = <0xe0 0x9>; + }; + + usb@ef603000 { + compatible = "ohci-be"; + reg = <0xef603000 0x80>; + interrupts-parent = <&UIC0>; + interrupts = <0xd 0x4 0xe 0x4>; + }; + + dac@ef603300 { + compatible = "amcc,dac-405ez"; + reg = <0xef603300 0x40>; + interrupt-parent = <&UIC0>; + interrupts = <0x18 0x4>; + }; + + adc@ef603400 { + compatible = "amcc,adc-405ez"; + reg = <0xef603400 0x40>; + interrupt-parent = <&UIC0>; + interrupts = <0x17 0x4>; + }; + + spi@ef603500 { + compatible = "amcc,spi-405ez"; + reg = <0xef603500 0x100>; + interrupt-parent = <&UIC0>; + interrupts = <0x9 0x4>; + }; + }; + + EBC0: ebc { + compatible = "ibm,ebc-405ez", "ibm,ebc"; + dcr-reg = <0x12 0x2>; + #address-cells = <2>; + #size-cells = <1>; + clock-frequency = <0>; /* Filled in by wrapper */ + }; + }; + + chosen { + linux,stdout-path = "/plb/opb/serial@ef600300"; + }; +}; diff --git a/arch/powerpc/boot/dts/hcu4.dts b/arch/powerpc/boot/dts/hcu4.dts new file mode 100644 index 0000000..7988598 --- /dev/null +++ b/arch/powerpc/boot/dts/hcu4.dts @@ -0,0 +1,168 @@ +/* +* Device Tree Source for Netstal Maschinen HCU4 +* based on the IBM Walnut +* +* Copyright 2008 +* Niklaus Giger <niklaus.giger@member.fsf.org> +* +* Copyright 2007 IBM Corp. +* Josh Boyer <jwboyer@linux.vnet.ibm.com> +* +* This file is licensed under the terms of the GNU General Public +* License version 2. This program is licensed "as is" without +* any warranty of any kind, whether express or implied. +*/ + +/dts-v1/; + +/ { + #address-cells = <0x1>; + #size-cells = <0x1>; + model = "netstal,hcu4"; + compatible = "netstal,hcu4"; + dcr-parent = <0x1>; + + aliases { + ethernet0 = "/plb/opb/ethernet@ef600800"; + serial0 = "/plb/opb/serial@ef600300"; + }; + + cpus { + #address-cells = <0x1>; + #size-cells = <0x0>; + + cpu@0 { + device_type = "cpu"; + model = "PowerPC,405GPr"; + reg = <0x0>; + clock-frequency = <0>; /* Filled in by U-Boot */ + timebase-frequency = <0x0>; /* Filled in by U-Boot */ + i-cache-line-size = <0x20>; + d-cache-line-size = <0x20>; + i-cache-size = <0x4000>; + d-cache-size = <0x4000>; + dcr-controller; + dcr-access-method = "native"; + linux,phandle = <0x1>; + }; + }; + + memory { + device_type = "memory"; + reg = <0x0 0x0>; /* Filled in by U-Boot */ + }; + + UIC0: interrupt-controller { + compatible = "ibm,uic"; + interrupt-controller; + cell-index = <0x0>; + dcr-reg = <0xc0 0x9>; + #address-cells = <0x0>; + #size-cells = <0x0>; + #interrupt-cells = <0x2>; + linux,phandle = <0x2>; + }; + + plb { + compatible = "ibm,plb3"; + #address-cells = <0x1>; + #size-cells = <0x1>; + ranges; + clock-frequency = <0x0>; /* Filled in by U-Boot */ + + SDRAM0: memory-controller { + compatible = "ibm,sdram-405gp"; + dcr-reg = <0x10 0x2>; + }; + + MAL: mcmal { + compatible = "ibm,mcmal-405gp", "ibm,mcmal"; + dcr-reg = <0x180 0x62>; + num-tx-chans = <0x1>; + num-rx-chans = <0x1>; + interrupt-parent = <0x2>; + interrupts = <0xb 0x4 0xc 0x4 0xa 0x4 0xd 0x4 0xe 0x4>; + linux,phandle = <0x3>; + }; + + POB0: opb { + compatible = "ibm,opb-405gp", "ibm,opb"; + #address-cells = <0x1>; + #size-cells = <0x1>; + ranges = <0xef600000 0xef600000 0xa00000>; + dcr-reg = <0xa0 0x5>; + clock-frequency = <0x0>; /* Filled in by U-Boot */ + + UART0: serial@ef600300 { + device_type = "serial"; + compatible = "ns16550"; + reg = <0xef600300 0x8>; + virtual-reg = <0xef600300>; + clock-frequency = <0x0>;/* Filled in by U-Boot */ + current-speed = <0>; /* Filled in by U-Boot */ + interrupt-parent = <0x2>; + interrupts = <0x0 0x4>; + }; + + IIC: i2c@ef600500 { + compatible = "ibm,iic-405gp", "ibm,iic"; + reg = <0xef600500 0x11>; + interrupt-parent = <0x2>; + interrupts = <0x2 0x4>; + }; + + GPIO: gpio@ef600700 { + compatible = "ibm,gpio-405gp"; + reg = <0xef600700 0x20>; + }; + + EMAC: ethernet@ef600800 { + device_type = "network"; + compatible = "ibm,emac-405gp", "ibm,emac"; + interrupt-parent = <0x2>; + interrupts = <0xf 0x4 0x9 0x4>; + local-mac-address = [00 00 00 00 00 00]; + reg = <0xef600800 0x70>; + mal-device = <0x3>; + mal-tx-channel = <0x0>; + mal-rx-channel = <0x0>; + cell-index = <0x0>; + max-frame-size = <0x5dc>; + rx-fifo-size = <0x1000>; + tx-fifo-size = <0x800>; + phy-mode = "rmii"; + phy-map = <0x1>; + }; + }; + + EBC0: ebc { + compatible = "ibm,ebc-405gp", "ibm,ebc"; + dcr-reg = <0x12 0x2>; + #address-cells = <0x2>; + #size-cells = <0x1>; + clock-frequency = <0x0>; /* Filled in by U-Boot */ + + sram@0,0 { + reg = <0x0 0x0 0x80000>; + }; + + flash@0,80000 { + compatible = "jedec-flash"; + bank-width = <0x1>; + reg = <0x0 0x80000 0x80000>; + #address-cells = <0x1>; + #size-cells = <0x1>; + + partition@0 { + label = "OpenBIOS"; + reg = <0x0 0x80000>; + read-only; + }; + }; + }; + }; + + chosen { + linux,stdout-path = "/plb/opb/serial@ef600300"; + }; +}; diff --git a/arch/powerpc/boot/dts/mpc8315erdb.dts b/arch/powerpc/boot/dts/mpc8315erdb.dts index 7449e54..6b85067 100644 --- a/arch/powerpc/boot/dts/mpc8315erdb.dts +++ b/arch/powerpc/boot/dts/mpc8315erdb.dts @@ -121,6 +121,14 @@ compatible = "dallas,ds1339"; reg = <0x68>; }; + + mcu_pio: mcu@a { + #gpio-cells = <2>; + compatible = "fsl,mc9s08qg8-mpc8315erdb", + "fsl,mcu-mpc8349emitx"; + reg = <0x0a>; + gpio-controller; + }; }; spi@7000 { diff --git a/arch/powerpc/boot/dts/mpc832x_mds.dts b/arch/powerpc/boot/dts/mpc832x_mds.dts index e4cc176..57c595b 100644 --- a/arch/powerpc/boot/dts/mpc832x_mds.dts +++ b/arch/powerpc/boot/dts/mpc832x_mds.dts @@ -60,7 +60,7 @@ }; bcsr@f8000000 { - device_type = "board-control"; + compatible = "fsl,mpc8323mds-bcsr"; reg = <0xf8000000 0x8000>; }; diff --git a/arch/powerpc/boot/dts/mpc8349emitx.dts b/arch/powerpc/boot/dts/mpc8349emitx.dts index 5cedf37..2c9d54a 100644 --- a/arch/powerpc/boot/dts/mpc8349emitx.dts +++ b/arch/powerpc/boot/dts/mpc8349emitx.dts @@ -83,6 +83,14 @@ interrupts = <15 0x8>; interrupt-parent = <&ipic>; dfsrr; + + rtc@68 { + device_type = "rtc"; + compatible = "dallas,ds1339"; + reg = <0x68>; + interrupts = <18 0x8>; + interrupt-parent = <&ipic>; + }; }; spi@7000 { @@ -131,6 +139,14 @@ interrupt-parent = <&ipic>; interrupts = <71 8>; }; + + mcu_pio: mcu@a { + #gpio-cells = <2>; + compatible = "fsl,mc9s08qg8-mpc8349emitx", + "fsl,mcu-mpc8349emitx"; + reg = <0x0a>; + gpio-controller; + }; }; usb@22000 { diff --git a/arch/powerpc/boot/dts/mpc8349emitxgp.dts b/arch/powerpc/boot/dts/mpc8349emitxgp.dts index 81ae1d3..fa40647 100644 --- a/arch/powerpc/boot/dts/mpc8349emitxgp.dts +++ b/arch/powerpc/boot/dts/mpc8349emitxgp.dts @@ -81,6 +81,14 @@ interrupts = <15 0x8>; interrupt-parent = <&ipic>; dfsrr; + + rtc@68 { + device_type = "rtc"; + compatible = "dallas,ds1339"; + reg = <0x68>; + interrupts = <18 0x8>; + interrupt-parent = <&ipic>; + }; }; spi@7000 { diff --git a/arch/powerpc/boot/dts/mpc834x_mds.dts b/arch/powerpc/boot/dts/mpc834x_mds.dts index 04bfde3..c986c54 100644 --- a/arch/powerpc/boot/dts/mpc834x_mds.dts +++ b/arch/powerpc/boot/dts/mpc834x_mds.dts @@ -49,7 +49,7 @@ }; bcsr@e2400000 { - device_type = "board-control"; + compatible = "fsl,mpc8349mds-bcsr"; reg = <0xe2400000 0x8000>; }; diff --git a/arch/powerpc/boot/dts/mpc836x_mds.dts b/arch/powerpc/boot/dts/mpc836x_mds.dts index 66a12d2..14534d0 100644 --- a/arch/powerpc/boot/dts/mpc836x_mds.dts +++ b/arch/powerpc/boot/dts/mpc836x_mds.dts @@ -69,7 +69,7 @@ }; bcsr@1,0 { - device_type = "board-control"; + compatible = "fsl,mpc8360mds-bcsr"; reg = <1 0 0x8000>; }; }; diff --git a/arch/powerpc/boot/dts/mpc8377_rdb.dts b/arch/powerpc/boot/dts/mpc8377_rdb.dts index 53191ba..435ef3d 100644 --- a/arch/powerpc/boot/dts/mpc8377_rdb.dts +++ b/arch/powerpc/boot/dts/mpc8377_rdb.dts @@ -121,6 +121,14 @@ compatible = "dallas,ds1339"; reg = <0x68>; }; + + mcu_pio: mcu@a { + #gpio-cells = <2>; + compatible = "fsl,mc9s08qg8-mpc8377erdb", + "fsl,mcu-mpc8349emitx"; + reg = <0x0a>; + gpio-controller; + }; }; i2c@3100 { diff --git a/arch/powerpc/boot/dts/mpc8378_rdb.dts b/arch/powerpc/boot/dts/mpc8378_rdb.dts index 4a09153..b11e68f 100644 --- a/arch/powerpc/boot/dts/mpc8378_rdb.dts +++ b/arch/powerpc/boot/dts/mpc8378_rdb.dts @@ -121,6 +121,14 @@ compatible = "dallas,ds1339"; reg = <0x68>; }; + + mcu_pio: mcu@a { + #gpio-cells = <2>; + compatible = "fsl,mc9s08qg8-mpc8378erdb", + "fsl,mcu-mpc8349emitx"; + reg = <0x0a>; + gpio-controller; + }; }; i2c@3100 { diff --git a/arch/powerpc/boot/dts/mpc8379_rdb.dts b/arch/powerpc/boot/dts/mpc8379_rdb.dts index bbd884a..337af6e 100644 --- a/arch/powerpc/boot/dts/mpc8379_rdb.dts +++ b/arch/powerpc/boot/dts/mpc8379_rdb.dts @@ -121,6 +121,14 @@ compatible = "dallas,ds1339"; reg = <0x68>; }; + + mcu_pio: mcu@a { + #gpio-cells = <2>; + compatible = "fsl,mc9s08qg8-mpc8379erdb", + "fsl,mcu-mpc8349emitx"; + reg = <0x0a>; + gpio-controller; + }; }; i2c@3100 { diff --git a/arch/powerpc/boot/dts/mpc8536ds.dts b/arch/powerpc/boot/dts/mpc8536ds.dts index 93fdd99..35db1e5 100644 --- a/arch/powerpc/boot/dts/mpc8536ds.dts +++ b/arch/powerpc/boot/dts/mpc8536ds.dts @@ -109,7 +109,7 @@ reg = <0x0 0x80>; cell-index = <0>; interrupt-parent = <&mpic>; - interrupts = <14 0x2>; + interrupts = <20 2>; }; dma-channel@80 { compatible = "fsl,mpc8536-dma-channel", @@ -117,7 +117,7 @@ reg = <0x80 0x80>; cell-index = <1>; interrupt-parent = <&mpic>; - interrupts = <15 0x2>; + interrupts = <21 2>; }; dma-channel@100 { compatible = "fsl,mpc8536-dma-channel", @@ -125,7 +125,7 @@ reg = <0x100 0x80>; cell-index = <2>; interrupt-parent = <&mpic>; - interrupts = <16 0x2>; + interrupts = <22 2>; }; dma-channel@180 { compatible = "fsl,mpc8536-dma-channel", @@ -133,7 +133,7 @@ reg = <0x180 0x80>; cell-index = <3>; interrupt-parent = <&mpic>; - interrupts = <17 0x2>; + interrupts = <23 2>; }; }; @@ -180,7 +180,7 @@ enet0: ethernet@24000 { cell-index = <0>; device_type = "network"; - model = "TSEC"; + model = "eTSEC"; compatible = "gianfar"; reg = <0x24000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; @@ -193,7 +193,7 @@ enet1: ethernet@26000 { cell-index = <1>; device_type = "network"; - model = "TSEC"; + model = "eTSEC"; compatible = "gianfar"; reg = <0x26000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; diff --git a/arch/powerpc/boot/dts/mpc8568mds.dts b/arch/powerpc/boot/dts/mpc8568mds.dts index a15f103..c80158f 100644 --- a/arch/powerpc/boot/dts/mpc8568mds.dts +++ b/arch/powerpc/boot/dts/mpc8568mds.dts @@ -52,7 +52,7 @@ }; bcsr@f8000000 { - device_type = "board-control"; + compatible = "fsl,mpc8568mds-bcsr"; reg = <0xf8000000 0x8000>; }; diff --git a/arch/powerpc/boot/dts/mpc8572ds.dts b/arch/powerpc/boot/dts/mpc8572ds.dts index e124dd1..cadd465 100644 --- a/arch/powerpc/boot/dts/mpc8572ds.dts +++ b/arch/powerpc/boot/dts/mpc8572ds.dts @@ -13,8 +13,8 @@ / { model = "fsl,MPC8572DS"; compatible = "fsl,MPC8572DS"; - #address-cells = <1>; - #size-cells = <1>; + #address-cells = <2>; + #size-cells = <2>; aliases { ethernet0 = &enet0; @@ -61,7 +61,6 @@ memory { device_type = "memory"; - reg = <0x0 0x0>; // Filled by U-Boot }; soc8572@ffe00000 { @@ -69,8 +68,8 @@ #size-cells = <1>; device_type = "soc"; compatible = "simple-bus"; - ranges = <0x0 0xffe00000 0x100000>; - reg = <0xffe00000 0x1000>; // CCSRBAR & soc regs, remove once parse code for immrbase fixed + ranges = <0x0 0 0xffe00000 0x100000>; + reg = <0 0xffe00000 0 0x1000>; // CCSRBAR & soc regs, remove once parse code for immrbase fixed bus-frequency = <0>; // Filled out by uboot. memory-controller@2000 { @@ -351,10 +350,10 @@ #interrupt-cells = <1>; #size-cells = <2>; #address-cells = <3>; - reg = <0xffe08000 0x1000>; + reg = <0 0xffe08000 0 0x1000>; bus-range = <0 255>; - ranges = <0x2000000 0x0 0x80000000 0x80000000 0x0 0x20000000 - 0x1000000 0x0 0x0 0xffc00000 0x0 0x10000>; + ranges = <0x2000000 0x0 0x80000000 0 0x80000000 0x0 0x20000000 + 0x1000000 0x0 0x00000000 0 0xffc00000 0x0 0x00010000>; clock-frequency = <33333333>; interrupt-parent = <&mpic>; interrupts = <24 2>; @@ -561,10 +560,10 @@ #interrupt-cells = <1>; #size-cells = <2>; #address-cells = <3>; - reg = <0xffe09000 0x1000>; + reg = <0 0xffe09000 0 0x1000>; bus-range = <0 255>; - ranges = <0x2000000 0x0 0xa0000000 0xa0000000 0x0 0x20000000 - 0x1000000 0x0 0x0 0xffc10000 0x0 0x10000>; + ranges = <0x2000000 0x0 0xa0000000 0 0xa0000000 0x0 0x20000000 + 0x1000000 0x0 0x00000000 0 0xffc10000 0x0 0x00010000>; clock-frequency = <33333333>; interrupt-parent = <&mpic>; interrupts = <26 2>; @@ -598,10 +597,10 @@ #interrupt-cells = <1>; #size-cells = <2>; #address-cells = <3>; - reg = <0xffe0a000 0x1000>; + reg = <0 0xffe0a000 0 0x1000>; bus-range = <0 255>; - ranges = <0x2000000 0x0 0xc0000000 0xc0000000 0x0 0x20000000 - 0x1000000 0x0 0x0 0xffc20000 0x0 0x10000>; + ranges = <0x2000000 0x0 0xc0000000 0 0xc0000000 0x0 0x20000000 + 0x1000000 0x0 0x00000000 0 0xffc20000 0x0 0x00010000>; clock-frequency = <33333333>; interrupt-parent = <&mpic>; interrupts = <27 2>; diff --git a/arch/powerpc/boot/libfdt-wrapper.c b/arch/powerpc/boot/libfdt-wrapper.c index c541fd8..9276327 100644 --- a/arch/powerpc/boot/libfdt-wrapper.c +++ b/arch/powerpc/boot/libfdt-wrapper.c @@ -105,6 +105,11 @@ static int fdt_wrapper_setprop(const void *devp, const char *name, return check_err(rc); } +static int fdt_wrapper_del_node(const void *devp) +{ + return fdt_del_node(fdt, devp_offset(devp)); +} + static void *fdt_wrapper_get_parent(const void *devp) { return offset_devp(fdt_parent_offset(fdt, devp_offset(devp))); @@ -165,6 +170,7 @@ static unsigned long fdt_wrapper_finalize(void) void fdt_init(void *blob) { int err; + int bufsize; dt_ops.finddevice = fdt_wrapper_finddevice; dt_ops.getprop = fdt_wrapper_getprop; @@ -173,21 +179,21 @@ void fdt_init(void *blob) dt_ops.create_node = fdt_wrapper_create_node; dt_ops.find_node_by_prop_value = fdt_wrapper_find_node_by_prop_value; dt_ops.find_node_by_compatible = fdt_wrapper_find_node_by_compatible; + dt_ops.del_node = fdt_wrapper_del_node; dt_ops.get_path = fdt_wrapper_get_path; dt_ops.finalize = fdt_wrapper_finalize; /* Make sure the dt blob is the right version and so forth */ fdt = blob; - err = fdt_open_into(fdt, fdt, fdt_totalsize(blob)); - if (err == -FDT_ERR_NOSPACE) { - int bufsize = fdt_totalsize(fdt) + 4; - buf = malloc(bufsize); - err = fdt_open_into(fdt, buf, bufsize); - } + bufsize = fdt_totalsize(fdt) + 4; + buf = malloc(bufsize); + if(!buf) + fatal("malloc failed. can't relocate the device tree\n\r"); + + err = fdt_open_into(fdt, buf, bufsize); if (err != 0) fatal("fdt_init(): %s\n\r", fdt_strerror(err)); - if (buf) - fdt = buf; + fdt = buf; } diff --git a/arch/powerpc/boot/main.c b/arch/powerpc/boot/main.c index 9e7f3dd..ae32801 100644 --- a/arch/powerpc/boot/main.c +++ b/arch/powerpc/boot/main.c @@ -56,9 +56,19 @@ static struct addr_range prep_kernel(void) if (platform_ops.vmlinux_alloc) { addr = platform_ops.vmlinux_alloc(ei.memsize); } else { - if ((unsigned long)_start < ei.memsize) + /* + * Check if the kernel image (without bss) would overwrite the + * bootwrapper. The device tree has been moved in fdt_init() + * to an area allocated with malloc() (somewhere past _end). + */ + if ((unsigned long)_start < ei.loadsize) fatal("Insufficient memory for kernel at address 0!" - " (_start=%p)\n\r", _start); + " (_start=%p, uncomressed size=%08x)\n\r", + _start, ei.loadsize); + + if ((unsigned long)_end < ei.memsize) + fatal("The final kernel image would overwrite the " + "device tree\n\r"); } /* Finally, gunzip the kernel */ diff --git a/arch/powerpc/boot/ops.h b/arch/powerpc/boot/ops.h index 321e2f5..b3218ce 100644 --- a/arch/powerpc/boot/ops.h +++ b/arch/powerpc/boot/ops.h @@ -40,6 +40,7 @@ struct dt_ops { const int buflen); int (*setprop)(const void *phandle, const char *name, const void *buf, const int buflen); + int (*del_node)(const void *phandle); void *(*get_parent)(const void *phandle); /* The node must not already exist. */ void *(*create_node)(const void *parent, const char *name); @@ -126,6 +127,11 @@ static inline int setprop_str(void *devp, const char *name, const char *buf) return -1; } +static inline int del_node(const void *devp) +{ + return dt_ops.del_node ? dt_ops.del_node(devp) : -1; +} + static inline void *get_parent(const char *devp) { return dt_ops.get_parent ? dt_ops.get_parent(devp) : NULL; diff --git a/arch/powerpc/boot/string.S b/arch/powerpc/boot/string.S index 643e4cb..acc9428 100644 --- a/arch/powerpc/boot/string.S +++ b/arch/powerpc/boot/string.S @@ -235,7 +235,7 @@ memchr: .globl memcmp memcmp: cmpwi 0,r5,0 - blelr + ble 2f mtctr r5 addi r6,r3,-1 addi r4,r4,-1 @@ -244,6 +244,8 @@ memcmp: subf. r3,r0,r3 bdnzt 2,1b blr +2: li r3,0 + blr /* diff --git a/arch/powerpc/boot/wrapper b/arch/powerpc/boot/wrapper index ee0dc41..f390735 100755 --- a/arch/powerpc/boot/wrapper +++ b/arch/powerpc/boot/wrapper @@ -306,11 +306,14 @@ fi # post-processing needed for some platforms case "$platform" in -pseries|chrp) +pseries) ${CROSS}objcopy -O binary -j .fakeelf "$kernel" "$ofile".rpanote $objbin/addnote "$ofile" "$ofile".rpanote rm -r "$ofile".rpanote ;; +chrp) + $objbin/addnote -r c00000 "$ofile" + ;; coff) ${CROSS}objcopy -O aixcoff-rs6000 --set-start "$entry" "$ofile" $objbin/hack-coff "$ofile" |