mpc512x: Move common files to share them by several boards

We will soon see several new MPC521x based boards added.  This patch
moves files that are not board specific to a common directory so they
can be shared by all such ports.  It also splits off common IDE code
into a new file, cpu/mpc512x/ide.c .

Signed-off-by: Wolfgang Denk <wd@denx.de>
Cc: John Rigby <jcrigby@gmail.com>
diff --git a/cpu/mpc512x/Makefile b/cpu/mpc512x/Makefile
index d6bfd59..022c676 100644
--- a/cpu/mpc512x/Makefile
+++ b/cpu/mpc512x/Makefile
@@ -22,11 +22,18 @@
 
 include $(TOPDIR)/config.mk
 
+$(shell mkdir -p $(OBJTREE)/board/freescale/common)
+
 LIB	= $(obj)lib$(CPU).a
 
 START	= start.o
 COBJS-y	:= traps.o cpu.o cpu_init.o speed.o interrupts.o serial.o i2c.o iopin.o
+COBJS-${CONFIG_FSL_DIU_FB} += diu.o
+COBJS-${CONFIG_FSL_DIU_FB} += ../../board/freescale/common/fsl_diu_fb.o
+COBJS-${CONFIG_FSL_DIU_FB} += ../../board/freescale/common/fsl_logo_bmp.o
+COBJS-${CONFIG_CMD_IDE} += ide.o
 COBJS-${CONFIG_IIM} += iim.o
+COBJS-$(CONFIG_PCI) += pci.o
 
 COBJS	:= $(COBJS-y)
 SRCS	:= $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
diff --git a/cpu/mpc512x/config.mk b/cpu/mpc512x/config.mk
index 5b7e1f2..6ab34b1 100644
--- a/cpu/mpc512x/config.mk
+++ b/cpu/mpc512x/config.mk
@@ -1,5 +1,5 @@
 #
-# (C) Copyright 2007 DENX Software Engineering
+# (C) Copyright 2007-2009 DENX Software Engineering
 #
 # See file CREDITS for list of people who contributed to this
 # project.
@@ -23,3 +23,7 @@
 
 PLATFORM_CPPFLAGS += -DCONFIG_MPC512X -DCONFIG_E300 \
 			-ffixed-r2 -msoft-float -mcpu=603e
+
+# Use default linker script.
+# A board port can override this setting in board/*/config.mk
+LDSCRIPT := $(SRCTREE)/cpu/mpc512x/u-boot.lds
diff --git a/cpu/mpc512x/diu.c b/cpu/mpc512x/diu.c
new file mode 100644
index 0000000..6d7e40f
--- /dev/null
+++ b/cpu/mpc512x/diu.c
@@ -0,0 +1,189 @@
+/*
+ * Copyright 2008 Freescale Semiconductor, Inc.
+ * York Sun <yorksun@freescale.com>
+ *
+ * FSL DIU Framebuffer driver
+ *
+ * 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 <common.h>
+#include <command.h>
+#include <asm/io.h>
+
+#include "../../board/freescale/common/pixis.h"
+#include "../../board/freescale/common/fsl_diu_fb.h"
+
+#if defined(CONFIG_VIDEO) || defined(CONFIG_CFB_CONSOLE)
+#include <devices.h>
+#include <video_fb.h>
+#endif
+
+#ifdef CONFIG_FSL_DIU_LOGO_BMP
+extern unsigned int FSL_Logo_BMP[];
+#else
+#define FSL_Logo_BMP NULL
+#endif
+
+static int xres, yres;
+
+void diu_set_pixel_clock(unsigned int pixclock)
+{
+	volatile immap_t *immap = (immap_t *)CONFIG_SYS_IMMR;
+	volatile clk512x_t *clk = &immap->clk;
+	volatile unsigned int *clkdvdr = &clk->scfr[0];
+	unsigned long speed_ccb, temp, pixval;
+
+	speed_ccb = get_bus_freq(0) * 4;
+	temp = 1000000000/pixclock;
+	temp *= 1000;
+	pixval = speed_ccb / temp;
+	debug("DIU pixval = %lu\n", pixval);
+
+	/* Modify PXCLK in GUTS CLKDVDR */
+	debug("DIU: Current value of CLKDVDR = 0x%08x\n", *clkdvdr);
+	temp = *clkdvdr & 0xFFFFFF00;
+	*clkdvdr = temp | (pixval & 0xFF);
+	debug("DIU: Modified value of CLKDVDR = 0x%08x\n", *clkdvdr);
+}
+
+char *valid_bmp(char *addr)
+{
+	unsigned long h_addr;
+
+	h_addr = simple_strtoul(addr, NULL, 16);
+	if (h_addr < CONFIG_SYS_FLASH_BASE ||
+			h_addr >= (CONFIG_SYS_FLASH_BASE + CONFIG_SYS_FLASH_SIZE - 1)) {
+		printf("bmp addr %lx is not a valid flash address\n", h_addr);
+		return 0;
+	} else if ((*(char *)(h_addr) != 'B') || (*(char *)(h_addr+1) != 'M')) {
+		printf("bmp addr is not a bmp\n");
+		return 0;
+	} else
+		return (char *)h_addr;
+}
+
+int mpc5121_diu_init(void)
+{
+	unsigned int pixel_format;
+	char *bmp = NULL;
+	char *bmp_env;
+
+	xres = 1024;
+	yres = 768;
+	pixel_format = 0x88883316;
+
+	debug("mpc5121_diu_init\n");
+	bmp_env = getenv("diu_bmp_addr");
+	if (bmp_env) {
+		bmp = valid_bmp(bmp_env);
+	}
+	if (!bmp)
+		bmp = FSL_Logo_BMP;
+	return fsl_diu_init(xres, pixel_format, 0, (unsigned char *)bmp);
+}
+
+int mpc5121diu_init_show_bmp(cmd_tbl_t *cmdtp,
+			     int flag, int argc, char *argv[])
+{
+	unsigned int addr;
+
+	if (argc < 2) {
+		cmd_usage(cmdtp);
+		return 1;
+	}
+
+	if (!strncmp(argv[1], "init", 4)) {
+#if defined(CONFIG_VIDEO) || defined(CONFIG_CFB_CONSOLE)
+		fsl_diu_clear_screen();
+		drv_video_init();
+#else
+		return mpc5121_diu_init();
+#endif
+	} else {
+		addr = simple_strtoul(argv[1], NULL, 16);
+		fsl_diu_clear_screen();
+		fsl_diu_display_bmp((unsigned char *)addr, 0, 0, 0);
+	}
+
+	return 0;
+}
+
+U_BOOT_CMD(
+	diufb, CONFIG_SYS_MAXARGS, 1, mpc5121diu_init_show_bmp,
+	"Init or Display BMP file",
+	"init\n    - initialize DIU\n"
+	"addr\n    - display bmp at address 'addr'"
+	);
+
+
+#if defined(CONFIG_VIDEO) || defined(CONFIG_CFB_CONSOLE)
+
+/*
+ * The Graphic Device
+ */
+GraphicDevice ctfb;
+void *video_hw_init(void)
+{
+	GraphicDevice *pGD = (GraphicDevice *) &ctfb;
+	struct fb_info *info;
+
+	if (mpc5121_diu_init() < 0)
+		return;
+
+	/* fill in Graphic device struct */
+	sprintf(pGD->modeIdent, "%dx%dx%d %ldkHz %ldHz",
+		xres, yres, 32, 64, 60);
+
+	pGD->frameAdrs = (unsigned int)fsl_fb_open(&info);
+	pGD->winSizeX = xres;
+	pGD->winSizeY = yres - info->logo_height;
+	pGD->plnSizeX = pGD->winSizeX;
+	pGD->plnSizeY = pGD->winSizeY;
+
+	pGD->gdfBytesPP = 4;
+	pGD->gdfIndex = GDF_32BIT_X888RGB;
+
+	pGD->isaBase = 0;
+	pGD->pciBase = 0;
+	pGD->memSize = info->screen_size - info->logo_size;
+
+	/* Cursor Start Address */
+	pGD->dprBase = 0;
+	pGD->vprBase = 0;
+	pGD->cprBase = 0;
+
+	return (void *)pGD;
+}
+
+/**
+  * Set the LUT
+  *
+  * @index: color number
+  * @r: red
+  * @b: blue
+  * @g: green
+  */
+void video_set_lut
+	(unsigned int index, unsigned char r, unsigned char g, unsigned char b)
+{
+	return;
+}
+
+#endif /* defined(CONFIG_VIDEO) || defined(CONFIG_CFB_CONSOLE) */
diff --git a/cpu/mpc512x/ide.c b/cpu/mpc512x/ide.c
new file mode 100644
index 0000000..16f1a01
--- /dev/null
+++ b/cpu/mpc512x/ide.c
@@ -0,0 +1,128 @@
+/*
+ * (C) Copyright 2007-2009 DENX Software Engineering
+ *
+ * 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 <common.h>
+#include <command.h>
+#include <asm/processor.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#if defined(CONFIG_IDE_RESET)
+
+void init_ide_reset (void)
+{
+	volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR;
+	debug ("init_ide_reset\n");
+
+	/*
+	 * Clear the reset bit to reset the interface
+	 * cf. RefMan MPC5121EE: 28.4.1 Resetting the ATA Bus
+	 */
+	immr->pata.pata_ata_control = 0;
+	udelay(100);
+	/* Assert the reset bit to enable the interface */
+	immr->pata.pata_ata_control = FSL_ATA_CTRL_ATA_RST_B;
+	udelay(100);
+}
+
+void ide_set_reset (int idereset)
+{
+	volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR;
+	debug ("ide_set_reset(%d)\n", idereset);
+
+	if (idereset) {
+		immr->pata.pata_ata_control = 0;
+		udelay(100);
+	} else {
+		immr->pata.pata_ata_control = FSL_ATA_CTRL_ATA_RST_B;
+		udelay(100);
+	}
+}
+
+#define CALC_TIMING(t) (t + period - 1) / period
+
+int ide_preinit (void)
+{
+	volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR;
+	long t;
+	const struct {
+		short t0;
+		short t1;
+		short t2_8;
+		short t2_16;
+		short t2i;
+		short t4;
+		short t9;
+		short tA;
+	} pio_specs = {
+		.t0    = 600,
+		.t1    =  70,
+		.t2_8  = 290,
+		.t2_16 = 165,
+		.t2i   =   0,
+		.t4    =  30,
+		.t9    =  20,
+		.tA    =  50,
+	};
+	union {
+		u32 config;
+		struct {
+			u8 field1;
+			u8 field2;
+			u8 field3;
+			u8 field4;
+		}bytes;
+	}cfg;
+
+	debug ("IDE preinit using PATA peripheral at IMMR-ADDR %08x\n",
+		(u32)&immr->pata);
+
+	/* Set the reset bit to 1 to enable the interface */
+	immr->pata.pata_ata_control = FSL_ATA_CTRL_ATA_RST_B;
+
+	/* Init timings : we use PIO mode 0 timings */
+	t = 1000000000 / gd->ips_clk;	/* period in ns */
+	cfg.bytes.field1 = 3;
+	cfg.bytes.field2 = 3;
+	cfg.bytes.field3 = (pio_specs.t1 + t) / t;
+	cfg.bytes.field4 = (pio_specs.t2_8 + t) / t;
+
+	immr->pata.pata_time1 = cfg.config;
+
+	cfg.bytes.field1 = (pio_specs.t2_8 + t) / t;
+	cfg.bytes.field2 = (pio_specs.tA + t) / t + 2;
+	cfg.bytes.field3 = 1;
+	cfg.bytes.field4 = (pio_specs.t4 + t) / t;
+
+	immr->pata.pata_time2 = cfg.config;
+
+	cfg.config = immr->pata.pata_time3;
+	cfg.bytes.field1 = (pio_specs.t9 + t) / t;
+
+	immr->pata.pata_time3 = cfg.config;
+	debug ("PATA preinit complete.\n");
+
+	return 0;
+}
+
+#endif /* defined(CONFIG_IDE_RESET) */
diff --git a/cpu/mpc512x/pci.c b/cpu/mpc512x/pci.c
new file mode 100644
index 0000000..806c428
--- /dev/null
+++ b/cpu/mpc512x/pci.c
@@ -0,0 +1,213 @@
+/*
+ * Copyright (C) Freescale Semiconductor, Inc. 2006, 2007. All rights reserved.
+ *
+ * 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 <common.h>
+
+#include <asm/mmu.h>
+#include <asm/global_data.h>
+#include <pci.h>
+#if defined(CONFIG_OF_LIBFDT)
+#include <libfdt.h>
+#include <fdt_support.h>
+#endif
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* System RAM mapped to PCI space */
+#define CONFIG_PCI_SYS_MEM_BUS	CONFIG_SYS_SDRAM_BASE
+#define CONFIG_PCI_SYS_MEM_PHYS	CONFIG_SYS_SDRAM_BASE
+
+static struct pci_controller pci_hose;
+
+
+/**************************************************************************
+ * pci_init_board()
+ *
+ */
+void
+pci_init_board(void)
+{
+	volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR;
+	volatile law512x_t *pci_law;
+	volatile pot512x_t *pci_pot;
+	volatile pcictrl512x_t *pci_ctrl;
+	volatile pciconf512x_t *pci_conf;
+	u16 reg16;
+	u32 reg32;
+	u32 dev;
+	struct pci_controller *hose;
+
+	/* Set PCI divider for 33MHz */
+	reg32 = immr->clk.scfr[0];
+	reg32 &= ~(SCFR1_PCI_DIV_MASK);
+	reg32 |= SCFR1_PCI_DIV << SCFR1_PCI_DIV_SHIFT;
+	immr->clk.scfr[0] = reg32;
+
+	pci_law = immr->sysconf.pcilaw;
+	pci_pot = immr->ios.pot;
+	pci_ctrl = &immr->pci_ctrl;
+	pci_conf = &immr->pci_conf;
+
+	hose = &pci_hose;
+
+	/*
+	 * Release PCI RST Output signal
+	 */
+	pci_ctrl->gcr = 0;
+	udelay(2000);
+	pci_ctrl->gcr = 1;
+
+	/* We need to wait at least a 1sec based on PCI specs */
+	{
+		int i;
+
+		for (i = 0; i < 1000; i++)
+			udelay(1000);
+	}
+
+	/*
+	 * Configure PCI Local Access Windows
+	 */
+	pci_law[0].bar = CONFIG_SYS_PCI_MEM_PHYS & LAWBAR_BAR;
+	pci_law[0].ar = LAWAR_EN | LAWAR_SIZE_512M;
+
+	pci_law[1].bar = CONFIG_SYS_PCI_IO_PHYS & LAWBAR_BAR;
+	pci_law[1].ar = LAWAR_EN | LAWAR_SIZE_16M;
+
+	/*
+	 * Configure PCI Outbound Translation Windows
+	 */
+
+	/* PCI mem space - prefetch */
+	pci_pot[0].potar = (CONFIG_SYS_PCI_MEM_BASE >> 12) & POTAR_TA_MASK;
+	pci_pot[0].pobar = (CONFIG_SYS_PCI_MEM_PHYS >> 12) & POBAR_BA_MASK;
+	pci_pot[0].pocmr = POCMR_EN | POCMR_PRE | POCMR_CM_256M;
+
+	/* PCI IO space */
+	pci_pot[1].potar = (CONFIG_SYS_PCI_IO_BASE >> 12) & POTAR_TA_MASK;
+	pci_pot[1].pobar = (CONFIG_SYS_PCI_IO_PHYS >> 12) & POBAR_BA_MASK;
+	pci_pot[1].pocmr = POCMR_EN | POCMR_IO | POCMR_CM_16M;
+
+	/* PCI mmio - non-prefetch mem space */
+	pci_pot[2].potar = (CONFIG_SYS_PCI_MMIO_BASE >> 12) & POTAR_TA_MASK;
+	pci_pot[2].pobar = (CONFIG_SYS_PCI_MMIO_PHYS >> 12) & POBAR_BA_MASK;
+	pci_pot[2].pocmr = POCMR_EN | POCMR_CM_256M;
+
+	/*
+	 * Configure PCI Inbound Translation Windows
+	 */
+
+	/* we need RAM mapped to PCI space for the devices to
+	 * access main memory */
+	pci_ctrl[0].pitar1 = 0x0;
+	pci_ctrl[0].pibar1 = 0x0;
+	pci_ctrl[0].piebar1 = 0x0;
+	pci_ctrl[0].piwar1 = PIWAR_EN | PIWAR_PF | PIWAR_RTT_SNOOP |
+	    PIWAR_WTT_SNOOP | (__ilog2(gd->ram_size) - 1);
+
+	hose->first_busno = 0;
+	hose->last_busno = 0xff;
+
+	/* PCI memory prefetch space */
+	pci_set_region(hose->regions + 0,
+		       CONFIG_SYS_PCI_MEM_BASE,
+		       CONFIG_SYS_PCI_MEM_PHYS,
+		       CONFIG_SYS_PCI_MEM_SIZE,
+		       PCI_REGION_MEM|PCI_REGION_PREFETCH);
+
+	/* PCI memory space */
+	pci_set_region(hose->regions + 1,
+		       CONFIG_SYS_PCI_MMIO_BASE,
+		       CONFIG_SYS_PCI_MMIO_PHYS,
+		       CONFIG_SYS_PCI_MMIO_SIZE,
+		       PCI_REGION_MEM);
+
+	/* PCI IO space */
+	pci_set_region(hose->regions + 2,
+		       CONFIG_SYS_PCI_IO_BASE,
+		       CONFIG_SYS_PCI_IO_PHYS,
+		       CONFIG_SYS_PCI_IO_SIZE,
+		       PCI_REGION_IO);
+
+	/* System memory space */
+	pci_set_region(hose->regions + 3,
+		       CONFIG_PCI_SYS_MEM_BUS,
+		       CONFIG_PCI_SYS_MEM_PHYS,
+		       gd->ram_size,
+		       PCI_REGION_MEM | PCI_REGION_SYS_MEMORY);
+
+	hose->region_count = 4;
+
+	pci_setup_indirect(hose,
+			   (CONFIG_SYS_IMMR + 0x8300),
+			   (CONFIG_SYS_IMMR + 0x8304));
+
+	pci_register_hose(hose);
+
+	/*
+	 * Write to Command register
+	 */
+	reg16 = 0xff;
+	dev = PCI_BDF(hose->first_busno, 0, 0);
+	pci_hose_read_config_word(hose, dev, PCI_COMMAND, &reg16);
+	reg16 |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
+	pci_hose_write_config_word(hose, dev, PCI_COMMAND, reg16);
+
+	/*
+	 * Clear non-reserved bits in status register.
+	 */
+	pci_hose_write_config_word(hose, dev, PCI_STATUS, 0xffff);
+	pci_hose_write_config_byte(hose, dev, PCI_LATENCY_TIMER, 0x80);
+	pci_hose_write_config_byte(hose, dev, PCI_CACHE_LINE_SIZE, 0x08);
+
+#ifdef CONFIG_PCI_SCAN_SHOW
+	printf("PCI:   Bus Dev VenId DevId Class Int\n");
+#endif
+	/*
+	 * Hose scan.
+	 */
+	hose->last_busno = pci_hose_scan(hose);
+}
+
+#if defined(CONFIG_OF_LIBFDT)
+void ft_pci_setup(void *blob, bd_t *bd)
+{
+	int nodeoffset;
+	int tmp[2];
+	const char *path;
+
+	nodeoffset = fdt_path_offset(blob, "/aliases");
+	if (nodeoffset >= 0) {
+		path = fdt_getprop(blob, nodeoffset, "pci", NULL);
+		if (path) {
+			tmp[0] = cpu_to_be32(pci_hose.first_busno);
+			tmp[1] = cpu_to_be32(pci_hose.last_busno);
+			do_fixup_by_path(blob, path, "bus-range",
+				&tmp, sizeof(tmp), 1);
+
+			tmp[0] = cpu_to_be32(gd->pci_clk);
+			do_fixup_by_path(blob, path, "clock-frequency",
+				&tmp, sizeof(tmp[0]), 1);
+		}
+	}
+}
+#endif /* CONFIG_OF_LIBFDT */
diff --git a/cpu/mpc512x/u-boot.lds b/cpu/mpc512x/u-boot.lds
new file mode 100644
index 0000000..dae3269
--- /dev/null
+++ b/cpu/mpc512x/u-boot.lds
@@ -0,0 +1,121 @@
+/*
+ * (C) Copyright 2007 DENX Software Engineering.
+ *
+ * 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)
+SECTIONS
+{
+  /* 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/mpc512x/start.o	(.text)
+    *(.text)
+    *(.fixup)
+    *(.got1)
+    . = ALIGN(16);
+    *(.eh_frame)
+    *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*)))
+  }
+  .fini      : { *(.fini)    } =0
+  .ctors     : { *(.ctors)   }
+  .dtors     : { *(.dtors)   }
+
+  /* Read-write section, merged into data segment: */
+  . = (. + 0x0FFF) & 0xFFFFF000;
+  _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(4096);
+  __init_begin = .;
+  .text.init : { *(.text.init) }
+  .data.init : { *(.data.init) }
+  . = ALIGN(4096);
+  __init_end = .;
+
+  __bss_start = .;
+  .bss (NOLOAD)       :
+  {
+   *(.sbss) *(.scommon)
+   *(.dynbss)
+   *(.bss)
+   *(COMMON)
+   . = ALIGN(4);
+  }
+  _end = . ;
+  PROVIDE (end = .);
+}
+ENTRY(_start)