From 99d8b23bc7e2be04fcbf49c5cec9f5ae76df290c Mon Sep 17 00:00:00 2001 From: Matthias Fuchs Date: Wed, 22 Jul 2009 13:56:21 +0200 Subject: ppc4xx: Add 405EP based PMC405DE board Signed-off-by: Matthias Fuchs Signed-off-by: Stefan Roese --- board/esd/pmc405de/Makefile | 53 ++++ board/esd/pmc405de/chip_config.c | 61 +++++ board/esd/pmc405de/config.mk | 23 ++ board/esd/pmc405de/pmc405de.c | 521 +++++++++++++++++++++++++++++++++++++++ board/esd/pmc405de/u-boot.lds | 133 ++++++++++ 5 files changed, 791 insertions(+) create mode 100644 board/esd/pmc405de/Makefile create mode 100644 board/esd/pmc405de/chip_config.c create mode 100644 board/esd/pmc405de/config.mk create mode 100644 board/esd/pmc405de/pmc405de.c create mode 100644 board/esd/pmc405de/u-boot.lds (limited to 'board/esd/pmc405de') diff --git a/board/esd/pmc405de/Makefile b/board/esd/pmc405de/Makefile new file mode 100644 index 0000000000..a080649539 --- /dev/null +++ b/board/esd/pmc405de/Makefile @@ -0,0 +1,53 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(BOARD).a + +COBJS-y = $(BOARD).o +COBJS-y += ../common/cmd_loadpci.o +COBJS-$(CONFIG_CMD_CHIP_CONFIG) += chip_config.o + +COBJS := $(COBJS-y) +SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS)) +SOBJS := $(addprefix $(obj),$(SOBJS)) + +$(LIB): $(OBJS) $(SOBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +clean: + rm -f $(SOBJS) $(OBJS) + +distclean: clean + rm -f $(LIB) core *.bak $(obj).depend + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/board/esd/pmc405de/chip_config.c b/board/esd/pmc405de/chip_config.c new file mode 100644 index 0000000000..e93a32cc9d --- /dev/null +++ b/board/esd/pmc405de/chip_config.c @@ -0,0 +1,61 @@ +/* + * (C) Copyright 2008-2009 + * Stefan Roese, DENX Software Engineering, sr@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +#include +#include + +struct ppc4xx_config ppc4xx_config_val[] = { + { + "133", + "CPU: 133 PLB: 133 OPB: 66 EBC: 44 PCI: 44/66", + { + 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x40, 0x12, 0x12, 0x42, 0x3e, 0x00, 0x00 + } + }, + { + "266", + "CPU: 266 PLB: 133 OPB: 66 EBC: 44 PCI: 44/66", + { + 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x50, 0x22, 0x2d, 0x42, 0x3e, 0x00, 0x00 + } + }, + { + "333", + "CPU: 333 PLB: 111 OPB: 55 EBC: 55 PCI: 55/111", + { + 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x60, 0x29, 0x2d, 0x42, 0xbe, 0x00, 0x00 + } + }, +}; + +int ppc4xx_config_count = ARRAY_SIZE(ppc4xx_config_val); diff --git a/board/esd/pmc405de/config.mk b/board/esd/pmc405de/config.mk new file mode 100644 index 0000000000..ae855dc057 --- /dev/null +++ b/board/esd/pmc405de/config.mk @@ -0,0 +1,23 @@ +# +# (C) Copyright 2000 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# +TEXT_BASE = 0xFFFC0000 diff --git a/board/esd/pmc405de/pmc405de.c b/board/esd/pmc405de/pmc405de.c new file mode 100644 index 0000000000..f68e1b5e86 --- /dev/null +++ b/board/esd/pmc405de/pmc405de.c @@ -0,0 +1,521 @@ +/* + * (C) Copyright 2009 + * Matthias Fuchs, esd gmbh germany, matthias.fuchs@esd.eu + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * PMC405-DE cpld registers + * - all registers are 8 bit + * - all registers are on 32 bit addesses + */ +struct pmc405de_cpld { + /* cpld design version */ + u8 version; + u8 reserved0[3]; + + /* misc. status lines */ + u8 status; + u8 reserved1[3]; + + /* + * gated control flags + * gate bit(s) must be written with '1' to + * access control flag + */ + u8 control; + u8 reserved2[3]; +}; + +#define CPLD_VERSION_MASK 0x0f +#define CPLD_CONTROL_POSTLED_N 0x01 +#define CPLD_CONTROL_POSTLED_GATE 0x02 +#define CPLD_CONTROL_RESETOUT_N 0x40 +#define CPLD_CONTROL_RESETOUT_N_GATE 0x80 + +DECLARE_GLOBAL_DATA_PTR; + +extern void __ft_board_setup(void *blob, bd_t *bd); +extern void pll_write(u32 a, u32 b); + +static int wait_for_pci_ready_done; + +static int is_monarch(void); +static int pci_is_66mhz(void); +static int board_revision(void); +static int cpld_revision(void); +static void upd_plb_pci_div(u32 pllmr0, u32 pllmr1, u32 div); + +int board_early_init_f(void) +{ + u32 pllmr0, pllmr1; + + /* + * check M66EN and patch PLB:PCI divider for 66MHz PCI + * + * fCPU==333MHz && fPCI==66MHz (PLBDiv==3 && M66EN==1): PLB/PCI=1 + * fCPU==333MHz && fPCI==33MHz (PLBDiv==3 && M66EN==0): PLB/PCI=2 + * fCPU==133|266MHz && fPCI==66MHz (PLBDiv==1|2 && M66EN==1): PLB/PCI=2 + * fCPU==133|266MHz && fPCI==33MHz (PLBDiv==1|2 && M66EN==0): PLB/PCI=3 + * + * calling upd_plb_pci_div() may end in calling pll_write() which will + * do a chip reset and never return. + */ + pllmr0 = mfdcr(CPC0_PLLMR0); + pllmr1 = mfdcr(CPC0_PLLMR1); + + if ((pllmr0 & PLLMR0_CPU_TO_PLB_MASK) == PLLMR0_CPU_PLB_DIV_3) { + /* fCPU=333MHz, fPLB=111MHz */ + if (pci_is_66mhz()) + upd_plb_pci_div(pllmr0, pllmr1, PLLMR0_PCI_PLB_DIV_1); + else + upd_plb_pci_div(pllmr0, pllmr1, PLLMR0_PCI_PLB_DIV_2); + } else { + /* fCPU=133|266MHz, fPLB=133MHz */ + if (pci_is_66mhz()) + upd_plb_pci_div(pllmr0, pllmr1, PLLMR0_PCI_PLB_DIV_2); + else + upd_plb_pci_div(pllmr0, pllmr1, PLLMR0_PCI_PLB_DIV_3); + } + + /* + * IRQ 25 (EXT IRQ 0) PCI-INTA#; active low; level sensitive + * IRQ 26 (EXT IRQ 1) PCI-INTB#; active low; level sensitive + * IRQ 27 (EXT IRQ 2) PCI-INTC#; active low; level sensitive + * IRQ 28 (EXT IRQ 3) PCI-INTD#; active low; level sensitive + * IRQ 29 (EXT IRQ 4) ETH0-PHY-IRQ#; active low; level sensitive + * IRQ 30 (EXT IRQ 5) ETH1-PHY-IRQ#; active low; level sensitive + * IRQ 31 (EXT IRQ 6) PLD-IRQ#; active low; level sensitive + */ + mtdcr(uicsr, 0xFFFFFFFF); /* clear all ints */ + mtdcr(uicer, 0x00000000); /* disable all ints */ + mtdcr(uiccr, 0x00000000); /* set all to be non-critical*/ + mtdcr(uicpr, 0xFFFFFF80); /* set int polarities */ + mtdcr(uictr, 0x10000000); /* set int trigger levels */ + mtdcr(uicvcr, 0x00000001); /* set vect base=0, INT0 highest prio */ + mtdcr(uicsr, 0xFFFFFFFF); /* clear all ints */ + + /* + * EBC Configuration Register: + * - set ready timeout to 512 ebc-clks -> ca. 15 us + * - EBC lines are always driven + */ + mtebc(epcr, 0xa8400000); + + return 0; +} + +static void upd_plb_pci_div(u32 pllmr0, u32 pllmr1, u32 div) +{ + if ((pllmr0 & PLLMR0_PCI_TO_PLB_MASK) != div) + pll_write((pllmr0 & ~PLLMR0_PCI_TO_PLB_MASK) | div, pllmr1); +} + +int misc_init_r(void) +{ + int i; + struct ppc4xx_gpio *gpio0 = (struct ppc4xx_gpio *)GPIO_BASE; + struct pmc405de_cpld *cpld = + (struct pmc405de_cpld *)CONFIG_SYS_CPLD_BASE; + + if (!is_monarch()) { + /* PCI configuration done: release EREADY */ + setbits_be32(&gpio0->or, CONFIG_SYS_GPIO_EREADY); + setbits_be32(&gpio0->tcr, CONFIG_SYS_GPIO_EREADY); + } + + /* turn off POST LED */ + out_8(&cpld->control, + CPLD_CONTROL_POSTLED_N | CPLD_CONTROL_POSTLED_GATE); + + /* turn on LEDs: RUN, A, B */ + clrbits_be32(&gpio0->or, + CONFIG_SYS_GPIO_LEDRUN_N | + CONFIG_SYS_GPIO_LEDA_N | + CONFIG_SYS_GPIO_LEDB_N); + + for (i=0; i < 200; i++) + udelay(1000); + + /* turn off LEDs: A, B */ + setbits_be32(&gpio0->or, + CONFIG_SYS_GPIO_LEDA_N | + CONFIG_SYS_GPIO_LEDB_N); + + return (0); +} + +static int is_monarch(void) +{ + struct ppc4xx_gpio *gpio0 = (struct ppc4xx_gpio *)GPIO_BASE; + return (in_be32(&gpio0->ir) & CONFIG_SYS_GPIO_MONARCH_N) == 0; +} + +static int pci_is_66mhz(void) +{ + struct ppc4xx_gpio *gpio0 = (struct ppc4xx_gpio *)GPIO_BASE; + return (in_be32(&gpio0->ir) & CONFIG_SYS_GPIO_M66EN); +} + +static int board_revision(void) +{ + struct ppc4xx_gpio *gpio0 = (struct ppc4xx_gpio *)GPIO_BASE; + return ((in_be32(&gpio0->ir) & CONFIG_SYS_GPIO_HWREV_MASK) >> + CONFIG_SYS_GPIO_HWREV_SHIFT); +} + +static int cpld_revision(void) +{ + struct pmc405de_cpld *cpld = + (struct pmc405de_cpld *)CONFIG_SYS_CPLD_BASE; + return ((in_8(&cpld->version) & CPLD_VERSION_MASK)); +} + +/* + * Check Board Identity + */ +int checkboard(void) +{ + puts("Board: esd GmbH - PMC-CPU/405-DE"); + + gd->board_type = board_revision(); + printf(", Rev 1.%ld, ", gd->board_type); + + if (!is_monarch()) + puts("non-"); + + printf("monarch, PCI=%s MHz, PLD-Rev 1.%d\n", + pci_is_66mhz() ? "66" : "33", cpld_revision()); + + return 0; +} + + +static void wait_for_pci_ready(void) +{ + struct ppc4xx_gpio *gpio0 = (struct ppc4xx_gpio *)GPIO_BASE; + int i; + char *s = getenv("pcidelay"); + + /* only wait once */ + if (wait_for_pci_ready_done) + return; + + /* + * We have our own handling of the pcidelay variable. + * Using CONFIG_PCI_BOOTDELAY enables pausing for host + * and adapter devices. For adapter devices we do not + * want this. + */ + if (s) { + int ms = simple_strtoul(s, NULL, 10); + printf("PCI: Waiting for %d ms\n", ms); + for (i=0; iir) & CONFIG_SYS_GPIO_EREADY)) { + printf("PCI: Waiting for EREADY (CTRL-C to skip) ... "); + while (1) { + if (ctrlc()) { + puts("abort\n"); + break; + } + if (in_be32(&gpio0->ir) & CONFIG_SYS_GPIO_EREADY) { + printf("done\n"); + break; + } + } + } + + wait_for_pci_ready_done = 1; +} + +/* + * Overwrite weak is_pci_host() + * + * This routine is called to determine if a pci scan should be + * performed. With various hardware environments (especially cPCI and + * PPMC) it's insufficient to depend on the state of the arbiter enable + * bit in the strap register, or generic host/adapter assumptions. + * + * Return 0 for adapter mode, non-zero for host (monarch) mode. + */ +int is_pci_host(struct pci_controller *hose) +{ + char *s; + + if (!is_monarch()) { + /* + * Overwrite PCI identification when running in + * non-monarch mode + * This should be moved into pci_target_init() + * when it is sometimes available for 405 CPUs + */ + pci_write_config_word(PCIDEVID_405GP, + PCI_SUBSYSTEM_ID, + CONFIG_SYS_PCI_SUBSYS_ID_NONMONARCH); + pci_write_config_word(PCIDEVID_405GP, + PCI_CLASS_SUB_CODE, + CONFIG_SYS_PCI_CLASSCODE_NONMONARCH); + } + + s = getenv("pciscan"); + if (s == NULL) { + if (is_monarch()) { + wait_for_pci_ready(); + return 1; + } else { + return 0; + } + } else { + if (!strcmp(s, "yes")) + return 1; + } + + return 0; +} + +/* + * Overwrite weak pci_pre_init() + * + * The default implementation enables the 405EP + * internal PCI arbiter. We do not want that + * on a PMC module. + */ +int pci_pre_init(struct pci_controller *hose) +{ + return 1; +} + +#if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP) +void ft_board_setup(void *blob, bd_t *bd) +{ + int rc; + + __ft_board_setup(blob, bd); + + /* + * Disable PCI in non-monarch mode. + */ + if (!is_monarch()) { + rc = fdt_find_and_setprop(blob, "/plb/pci@ec000000", "status", + "disabled", sizeof("disabled"), 1); + if (rc) { + printf("Unable to update property status in PCI node, " + "err=%s\n", + fdt_strerror(rc)); + } + } +} +#endif /* defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP) */ + +#if defined(CONFIG_SYS_EEPROM_WREN) +/* Input: I2C address of EEPROM device to enable. + * -1: deliver current state + * 0: disable write + * 1: enable write + * Returns: -1: wrong device address + * 0: dis-/en- able done + * 0/1: current state if was -1. + */ +int eeprom_write_enable(unsigned dev_addr, int state) +{ + struct ppc4xx_gpio *gpio0 = (struct ppc4xx_gpio *)GPIO_BASE; + + if (CONFIG_SYS_I2C_EEPROM_ADDR != dev_addr) { + return -1; + } else { + switch (state) { + case 1: + /* Enable write access, clear bit GPIO0. */ + clrbits_be32(&gpio0->or, CONFIG_SYS_GPIO_EEPROM_WP); + state = 0; + break; + case 0: + /* Disable write access, set bit GPIO0. */ + setbits_be32(&gpio0->or, CONFIG_SYS_GPIO_EEPROM_WP); + state = 0; + break; + default: + /* Read current status back. */ + state = (0 == (in_be32(&gpio0->or) & + CONFIG_SYS_GPIO_EEPROM_WP)); + break; + } + } + return state; +} + +int do_eep_wren(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + int query = argc == 1; + int state = 0; + + if (query) { + /* Query write access state. */ + state = eeprom_write_enable(CONFIG_SYS_I2C_EEPROM_ADDR, - 1); + if (state < 0) { + puts("Query of write access state failed.\n"); + } else { + printf("Write access for device 0x%0x is %sabled.\n", + CONFIG_SYS_I2C_EEPROM_ADDR, + state ? "en" : "dis"); + state = 0; + } + } else { + if ('0' == argv[1][0]) { + /* Disable write access. */ + state = eeprom_write_enable( + CONFIG_SYS_I2C_EEPROM_ADDR, 0); + } else { + /* Enable write access. */ + state = eeprom_write_enable( + CONFIG_SYS_I2C_EEPROM_ADDR, 1); + } + if (state < 0) + puts ("Setup of write access state failed.\n"); + } + + return state; +} + +U_BOOT_CMD(eepwren, 2, 0, do_eep_wren, + "Enable / disable / query EEPROM write access", + "" +); +#endif /* #if defined(CONFIG_SYS_EEPROM_WREN) */ + +#if defined(CONFIG_PRAM) +#include +extern env_t *env_ptr; + +int do_painit(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + u32 pram, nextbase, base; + char *v; + u32 param; + ulong *lptr; + + v = getenv("pram"); + if (v) + pram = simple_strtoul(v, NULL, 10); + else { + printf("Error: pram undefined. Please define pram in KiB\n"); + return 1; + } + + base = gd->bd->bi_memsize; +#if defined(CONFIG_LOGBUFFER) + base -= LOGBUFF_LEN + LOGBUFF_OVERHEAD; +#endif + /* + * gd->bd->bi_memsize == physical ram size - CONFIG_SYS_MM_TOP_HIDE + */ + param = base - (pram << 10); + printf("PARAM: @%08x\n", param); + debug("memsize=0x%08x, base=0x%08x\n", gd->bd->bi_memsize, base); + + /* clear entire PA ram */ + memset((void*)param, 0, (pram << 10)); + + /* reserve 4k for pointer field */ + nextbase = base - 4096; + lptr = (ulong*)(base); + + /* + * *(--lptr) = item_size; + * *(--lptr) = base - item_base = distance from field top; + */ + + /* env is first (4k aligned) */ + nextbase -= ((CONFIG_ENV_SIZE + 4096 - 1) & ~(4096 - 1)); + memcpy((void*)nextbase, env_ptr, CONFIG_ENV_SIZE); + *(--lptr) = CONFIG_ENV_SIZE; /* size */ + *(--lptr) = base - nextbase; /* offset | type=0 */ + + /* free section */ + *(--lptr) = nextbase - param; /* size */ + *(--lptr) = (base - param) | 126; /* offset | type=126 */ + + /* terminate pointer field */ + *(--lptr) = crc32(0, (void*)(base - 0x10), 0x10); + *(--lptr) = 0; /* offset=0 -> terminator */ + return 0; +} +U_BOOT_CMD( + painit, 1, 1, do_painit, + "prepare PciAccess system", + "" +); +#endif /* CONFIG_PRAM */ + +int do_selfreset(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + struct ppc4xx_gpio *gpio0 = (struct ppc4xx_gpio *)GPIO_BASE; + setbits_be32(&gpio0->tcr, CONFIG_SYS_GPIO_SELFRST_N); + return 0; +} +U_BOOT_CMD( + selfreset, 1, 1, do_selfreset, + "assert self-reset# signal", + "" +); + +int do_resetout(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + struct pmc405de_cpld *cpld = + (struct pmc405de_cpld *)CONFIG_SYS_CPLD_BASE; + + if (argc > 1) { + if (argv[1][0] == '0') { + /* assert */ + printf("PMC-RESETOUT# asserted\n"); + out_8(&cpld->control, + CPLD_CONTROL_RESETOUT_N_GATE); + } else { + /* deassert */ + printf("PMC-RESETOUT# deasserted\n"); + out_8(&cpld->control, + CPLD_CONTROL_RESETOUT_N | + CPLD_CONTROL_RESETOUT_N_GATE); + } + } else { + printf("PMC-RESETOUT# is %s\n", + (in_8(&cpld->control) & CPLD_CONTROL_RESETOUT_N) ? + "inactive" : "active"); + } + return 0; +} +U_BOOT_CMD( + resetout, 2, 1, do_resetout, + "assert PMC-RESETOUT# signal", + "" +); diff --git a/board/esd/pmc405de/u-boot.lds b/board/esd/pmc405de/u-boot.lds new file mode 100644 index 0000000000..8c010162f0 --- /dev/null +++ b/board/esd/pmc405de/u-boot.lds @@ -0,0 +1,133 @@ +/* + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +OUTPUT_ARCH(powerpc) +/* Do we need any of these for elf? + __DYNAMIC = 0; */ +SECTIONS +{ + .resetvec 0xFFFFFFFC : + { + *(.resetvec) + } = 0xffff + + /* Read-only sections, merged into text segment: */ + . = + SIZEOF_HEADERS; + .interp : { *(.interp) } + .hash : { *(.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .rel.text : { *(.rel.text) } + .rela.text : { *(.rela.text) } + .rel.data : { *(.rel.data) } + .rela.data : { *(.rela.data) } + .rel.rodata : { *(.rel.rodata) } + .rela.rodata : { *(.rela.rodata) } + .rel.got : { *(.rel.got) } + .rela.got : { *(.rela.got) } + .rel.ctors : { *(.rel.ctors) } + .rela.ctors : { *(.rela.ctors) } + .rel.dtors : { *(.rel.dtors) } + .rela.dtors : { *(.rela.dtors) } + .rel.bss : { *(.rel.bss) } + .rela.bss : { *(.rela.bss) } + .rel.plt : { *(.rel.plt) } + .rela.plt : { *(.rela.plt) } + .init : { *(.init) } + .plt : { *(.plt) } + .text : + { + cpu/ppc4xx/start.o (.text) + + *(.text) + *(.fixup) + *(.got1) + } + _etext = .; + PROVIDE (etext = .); + .rodata : + { + *(.eh_frame) + *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) + } + .fini : { *(.fini) } =0 + .ctors : { *(.ctors) } + .dtors : { *(.dtors) } + + /* Read-write section, merged into data segment: */ + . = (. + 0x00FF) & 0xFFFFFF00; + _erotext = .; + PROVIDE (erotext = .); + .reloc : + { + *(.got) + _GOT2_TABLE_ = .; + *(.got2) + _FIXUP_TABLE_ = .; + *(.fixup) + } + __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2; + __fixup_entries = (. - _FIXUP_TABLE_)>>2; + + .data : + { + *(.data) + *(.data1) + *(.sdata) + *(.sdata2) + *(.dynamic) + CONSTRUCTORS + } + _edata = .; + PROVIDE (edata = .); + + . = .; + __u_boot_cmd_start = .; + .u_boot_cmd : { *(.u_boot_cmd) } + __u_boot_cmd_end = .; + + + . = .; + __start___ex_table = .; + __ex_table : { *(__ex_table) } + __stop___ex_table = .; + + . = ALIGN(256); + __init_begin = .; + .text.init : { *(.text.init) } + .data.init : { *(.data.init) } + . = ALIGN(256); + __init_end = .; + + __bss_start = .; + .bss (NOLOAD) : + { + *(.sbss) *(.scommon) + *(.dynbss) + *(.bss) + *(COMMON) + . = ALIGN(4); + } + _end = . ; + PROVIDE (end = .); +} -- cgit v1.2.1