All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH 01/17] SPARC: added unaligned definitions, patch supplied by Magnus Sjalander.
@ 2010-01-28 12:16 Daniel Hellstrom
  2010-01-28 12:16 ` [U-Boot] [PATCH 02/17] GRETH: Added support for selecting PHY address from config, PHY address was always set to zero before Daniel Hellstrom
                   ` (17 more replies)
  0 siblings, 18 replies; 26+ messages in thread
From: Daniel Hellstrom @ 2010-01-28 12:16 UTC (permalink / raw)
  To: u-boot

Signed-off-by: Daniel Hellstrom <daniel@gaisler.com>
---
 include/asm-sparc/unaligned.h |   17 +++++++++++++++++
 1 files changed, 17 insertions(+), 0 deletions(-)
 create mode 100644 include/asm-sparc/unaligned.h

diff --git a/include/asm-sparc/unaligned.h b/include/asm-sparc/unaligned.h
new file mode 100644
index 0000000..4e604c1
--- /dev/null
+++ b/include/asm-sparc/unaligned.h
@@ -0,0 +1,17 @@
+#ifndef _ASM_SPARC_UNALIGNED_H
+#define _ASM_SPARC_UNALIGNED_H
+
+#ifdef __KERNEL__
+
+/*
+ * The SPARC can not do unaligned accesses, it must be split into multiple
+ * byte accesses. The SPARC is in big endian mode.
+ */
+#include <linux/unaligned/be_byteshift.h>
+#include <linux/unaligned/generic.h>
+
+#define get_unaligned	__get_unaligned_be
+#define put_unaligned	__put_unaligned_be
+
+#endif	/* __KERNEL__ */
+#endif	/* _ASM_SPARC_UNALIGNED_H */
-- 
1.5.4

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [U-Boot] [PATCH 02/17] GRETH: Added support for selecting PHY address from config, PHY address was always set to zero before.
  2010-01-28 12:16 [U-Boot] [PATCH 01/17] SPARC: added unaligned definitions, patch supplied by Magnus Sjalander Daniel Hellstrom
@ 2010-01-28 12:16 ` Daniel Hellstrom
  2010-01-28 12:16 ` [U-Boot] [PATCH 03/17] GRETH: Added extra RESET, this is needed if GRETH was stopped during an ethernet frame reception Daniel Hellstrom
                   ` (16 subsequent siblings)
  17 siblings, 0 replies; 26+ messages in thread
From: Daniel Hellstrom @ 2010-01-28 12:16 UTC (permalink / raw)
  To: u-boot

Signed-off-by: Daniel Hellstrom <daniel@gaisler.com>
---
 drivers/net/greth.c |   69 +++++++++++++++++++++++++++++++-------------------
 1 files changed, 43 insertions(+), 26 deletions(-)

diff --git a/drivers/net/greth.c b/drivers/net/greth.c
index 79bc4d9..833915d 100644
--- a/drivers/net/greth.c
+++ b/drivers/net/greth.c
@@ -45,7 +45,7 @@
 /* ByPass Cache when reading regs */
 #define GRETH_REGLOAD(addr)		SPARC_NOCACHE_READ(addr)
 /* Write-through cache ==> no bypassing needed on writes */
-#define GRETH_REGSAVE(addr,data)	(*(unsigned int *)(addr) = (data))
+#define GRETH_REGSAVE(addr,data) (*(volatile unsigned int *)(addr) = (data))
 #define GRETH_REGORIN(addr,data) GRETH_REGSAVE(addr,GRETH_REGLOAD(addr)|data)
 #define GRETH_REGANDIN(addr,data) GRETH_REGSAVE(addr,GRETH_REGLOAD(addr)&data)
 
@@ -102,12 +102,12 @@ typedef struct {
 } greth_priv;
 
 /* Read MII register 'addr' from core 'regs' */
-static int read_mii(int addr, volatile greth_regs * regs)
+static int read_mii(int phyaddr, int regaddr, volatile greth_regs * regs)
 {
 	while (GRETH_REGLOAD(&regs->mdio) & GRETH_MII_BUSY) {
 	}
 
-	GRETH_REGSAVE(&regs->mdio, (0 << 11) | ((addr & 0x1F) << 6) | 2);
+	GRETH_REGSAVE(&regs->mdio, ((phyaddr & 0x1F) << 11) | ((regaddr & 0x1F) << 6) | 2);
 
 	while (GRETH_REGLOAD(&regs->mdio) & GRETH_MII_BUSY) {
 	}
@@ -119,14 +119,14 @@ static int read_mii(int addr, volatile greth_regs * regs)
 	}
 }
 
-static void write_mii(int addr, int data, volatile greth_regs * regs)
+static void write_mii(int phyaddr, int regaddr, int data, volatile greth_regs * regs)
 {
 	while (GRETH_REGLOAD(&regs->mdio) & GRETH_MII_BUSY) {
 	}
 
 	GRETH_REGSAVE(&regs->mdio,
-		      ((data & 0xFFFF) << 16) | (0 << 11) | ((addr & 0x1F) << 6)
-		      | 1);
+		      ((data & 0xFFFF) << 16) | ((phyaddr & 0x1F) << 11) | 
+		      ((regaddr & 0x1F) << 6) | 1);
 
 	while (GRETH_REGLOAD(&regs->mdio) & GRETH_MII_BUSY) {
 	}
@@ -146,8 +146,6 @@ int greth_init(struct eth_device *dev, bd_t * bis)
 	printf("greth_init\n");
 #endif
 
-	GRETH_REGSAVE(&regs->control, 0);
-
 	if (!greth->rxbd_base) {
 
 		/* allocate descriptors */
@@ -161,6 +159,7 @@ int greth_init(struct eth_device *dev, bd_t * bis)
 		    malloc(GRETH_RXBUF_EFF_SIZE * GRETH_RXBD_CNT);
 	}
 
+	memset(greth->rxbuf_base, 0, GRETH_RXBUF_EFF_SIZE * GRETH_RXBD_CNT);
 	/* initate rx decriptors */
 	for (i = 0; i < GRETH_RXBD_CNT; i++) {
 		greth->rxbd_base[i].addr = (unsigned int)
@@ -219,6 +218,11 @@ int greth_init_phy(greth_priv * dev, bd_t * bis)
 	greth_regs *regs = dev->regs;
 	int tmp, tmp1, tmp2, i;
 	unsigned int start, timeout;
+#ifdef CONFIG_SYS_GRLIB_GRETH_PHYADDR
+	int phyaddr = CONFIG_SYS_GRLIB_GRETH_PHYADDR;
+#else
+	int phyaddr = 0;
+#endif
 
 	/* X msecs to ticks */
 	timeout = usec2ticks(GRETH_PHY_TIMEOUT_MS * 1000);
@@ -230,17 +234,25 @@ int greth_init_phy(greth_priv * dev, bd_t * bis)
 
 	/* get phy control register default values */
 
-	while ((tmp = read_mii(0, regs)) & 0x8000) {
-		if (get_timer(start) > timeout)
+	while ((tmp = read_mii(phyaddr, 0, regs)) & 0x8000) {
+		if (get_timer(start) > timeout) {
+#ifdef DEBUG
+			printf("greth_init_phy: PHY read 1 failed\n");
+#endif
 			return 1;	/* Fail */
+		}
 	}
 
 	/* reset PHY and wait for completion */
-	write_mii(0, 0x8000 | tmp, regs);
+	write_mii(phyaddr, 0, 0x8000 | tmp, regs);
 
-	while (((tmp = read_mii(0, regs))) & 0x8000) {
-		if (get_timer(start) > timeout)
+	while (((tmp = read_mii(phyaddr, 0, regs))) & 0x8000) {
+		if (get_timer(start) > timeout) {
+#ifdef DEBUG
+			printf("greth_init_phy: PHY read 2 failed\n");
+#endif
 			return 1;	/* Fail */
+		}
 	}
 
 	/* Check if PHY is autoneg capable and then determine operating
@@ -251,16 +263,16 @@ int greth_init_phy(greth_priv * dev, bd_t * bis)
 	dev->sp = 0;
 	dev->auto_neg = 0;
 	if (!((tmp >> 12) & 1)) {
-		write_mii(0, 0, regs);
+		write_mii(phyaddr, 0, 0, regs);
 	} else {
 		/* wait for auto negotiation to complete and then check operating mode */
 		dev->auto_neg = 1;
 		i = 0;
-		while (!(((tmp = read_mii(1, regs)) >> 5) & 1)) {
+		while (!(((tmp = read_mii(phyaddr, 1, regs)) >> 5) & 1)) {
 			if (get_timer(start) > timeout) {
 				printf("Auto negotiation timed out. "
 				       "Selecting default config\n");
-				tmp = read_mii(0, regs);
+				tmp = read_mii(phyaddr, 0, regs);
 				dev->gb = ((tmp >> 6) & 1)
 				    && !((tmp >> 13) & 1);
 				dev->sp = !((tmp >> 6) & 1)
@@ -270,8 +282,8 @@ int greth_init_phy(greth_priv * dev, bd_t * bis)
 			}
 		}
 		if ((tmp >> 8) & 1) {
-			tmp1 = read_mii(9, regs);
-			tmp2 = read_mii(10, regs);
+			tmp1 = read_mii(phyaddr, 9, regs);
+			tmp2 = read_mii(phyaddr, 10, regs);
 			if ((tmp1 & GRETH_MII_EXTADV_1000FD) &&
 			    (tmp2 & GRETH_MII_EXTPRT_1000FD)) {
 				dev->gb = 1;
@@ -284,8 +296,8 @@ int greth_init_phy(greth_priv * dev, bd_t * bis)
 			}
 		}
 		if ((dev->gb == 0) || ((dev->gb == 1) && (dev->gbit_mac == 0))) {
-			tmp1 = read_mii(4, regs);
-			tmp2 = read_mii(5, regs);
+			tmp1 = read_mii(phyaddr, 4, regs);
+			tmp2 = read_mii(phyaddr, 5, regs);
 			if ((tmp1 & GRETH_MII_100TXFD) &&
 			    (tmp2 & GRETH_MII_100TXFD)) {
 				dev->sp = 1;
@@ -302,7 +314,7 @@ int greth_init_phy(greth_priv * dev, bd_t * bis)
 			if ((dev->gb == 1) && (dev->gbit_mac == 0)) {
 				dev->gb = 0;
 				dev->fd = 0;
-				write_mii(0, dev->sp << 13, regs);
+				write_mii(phyaddr, 0, dev->sp << 13, regs);
 			}
 		}
 
@@ -314,8 +326,8 @@ int greth_init_phy(greth_priv * dev, bd_t * bis)
 #endif
 	/* Read out PHY info if extended registers are available */
 	if (tmp & 1) {
-		tmp1 = read_mii(2, regs);
-		tmp2 = read_mii(3, regs);
+		tmp1 = read_mii(phyaddr, 2, regs);
+		tmp2 = read_mii(phyaddr, 3, regs);
 		tmp1 = (tmp1 << 6) | ((tmp2 >> 10) & 0x3F);
 		tmp = tmp2 & 0xF;
 
@@ -542,10 +554,9 @@ int greth_recv(struct eth_device *dev)
 		/* increase index */
 		greth->rxbd_curr =
 		    ((unsigned int)greth->rxbd_curr >=
-		     (unsigned int)greth->rxbd_max) ? greth->
-		    rxbd_base : (greth->rxbd_curr + 1);
+		     (unsigned int)greth->rxbd_max) ? greth->rxbd_base : (greth->rxbd_curr + 1);
 
-	};
+	}
 
 	if (enable) {
 		GRETH_REGORIN(&regs->control, GRETH_RXEN);
@@ -630,6 +641,9 @@ int greth_initialize(bd_t * bis)
 	/* initiate PHY, select speed/duplex depending on connected PHY */
 	if (greth_init_phy(greth, bis)) {
 		/* Failed to init PHY (timedout) */
+#ifdef DEBUG
+		printf("GRETH[0x%08x]: Failed to init PHY\n", greth->regs);
+#endif
 		return -1;
 	}
 
@@ -658,5 +672,8 @@ int greth_initialize(bd_t * bis)
 	/* set and remember MAC address */
 	greth_set_hwaddr(greth, addr);
 
+#ifdef DEBUG
+	printf("GRETH[0x%08x]: Initialized successfully\n", greth->regs);
+#endif
 	return 0;
 }
-- 
1.5.4

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [U-Boot] [PATCH 03/17] GRETH: Added extra RESET, this is needed if GRETH was stopped during an ethernet frame reception.
  2010-01-28 12:16 [U-Boot] [PATCH 01/17] SPARC: added unaligned definitions, patch supplied by Magnus Sjalander Daniel Hellstrom
  2010-01-28 12:16 ` [U-Boot] [PATCH 02/17] GRETH: Added support for selecting PHY address from config, PHY address was always set to zero before Daniel Hellstrom
@ 2010-01-28 12:16 ` Daniel Hellstrom
  2010-01-28 12:16 ` [U-Boot] [PATCH 04/17] LEON3: reimplemented AMBA Plug&Play scanning routines Daniel Hellstrom
                   ` (15 subsequent siblings)
  17 siblings, 0 replies; 26+ messages in thread
From: Daniel Hellstrom @ 2010-01-28 12:16 UTC (permalink / raw)
  To: u-boot

Signed-off-by: Daniel Hellstrom <daniel@gaisler.com>
---
 drivers/net/greth.c |   14 ++++++++++++--
 1 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/drivers/net/greth.c b/drivers/net/greth.c
index 833915d..383b25c 100644
--- a/drivers/net/greth.c
+++ b/drivers/net/greth.c
@@ -146,13 +146,23 @@ int greth_init(struct eth_device *dev, bd_t * bis)
 	printf("greth_init\n");
 #endif
 
+	/* Reset core */
+	GRETH_REGSAVE(&regs->control, (GRETH_RESET | (greth->gb << 8) |
+		(greth->sp << 7) | (greth->fd << 4)));
+
+	/* Wait for Reset to complete */
+	while ( GRETH_REGLOAD(&regs->control) & GRETH_RESET) ;
+
+	GRETH_REGSAVE(&regs->control,
+		((greth->gb << 8) | (greth->sp << 7) | (greth->fd << 4)));
+
 	if (!greth->rxbd_base) {
 
 		/* allocate descriptors */
 		greth->rxbd_base = (greth_bd *)
 		    memalign(0x1000, GRETH_RXBD_CNT * sizeof(greth_bd));
 		greth->txbd_base = (greth_bd *)
-		    memalign(0x1000, GRETH_RXBD_CNT * sizeof(greth_bd));
+		    memalign(0x1000, GRETH_TXBD_CNT * sizeof(greth_bd));
 
 		/* allocate buffers to all descriptors  */
 		greth->rxbuf_base =
@@ -185,7 +195,7 @@ int greth_init(struct eth_device *dev, bd_t * bis)
 	for (i = 0; i < GRETH_TXBD_CNT; i++) {
 		greth->txbd_base[i].addr = 0;
 		/* enable desciptor & set wrap bit if last descriptor */
-		if (i >= (GRETH_RXBD_CNT - 1)) {
+		if (i >= (GRETH_TXBD_CNT - 1)) {
 			greth->txbd_base[i].stat = GRETH_BD_WR;
 		} else {
 			greth->txbd_base[i].stat = 0;
-- 
1.5.4

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [U-Boot] [PATCH 04/17] LEON3: reimplemented AMBA Plug&Play scanning routines.
  2010-01-28 12:16 [U-Boot] [PATCH 01/17] SPARC: added unaligned definitions, patch supplied by Magnus Sjalander Daniel Hellstrom
  2010-01-28 12:16 ` [U-Boot] [PATCH 02/17] GRETH: Added support for selecting PHY address from config, PHY address was always set to zero before Daniel Hellstrom
  2010-01-28 12:16 ` [U-Boot] [PATCH 03/17] GRETH: Added extra RESET, this is needed if GRETH was stopped during an ethernet frame reception Daniel Hellstrom
@ 2010-01-28 12:16 ` Daniel Hellstrom
  2010-01-28 12:16 ` [U-Boot] [PATCH 05/17] LEON3: added memory controller initialization using the new AMBA PnP routines Daniel Hellstrom
                   ` (14 subsequent siblings)
  17 siblings, 0 replies; 26+ messages in thread
From: Daniel Hellstrom @ 2010-01-28 12:16 UTC (permalink / raw)
  To: u-boot

Signed-off-by: Daniel Hellstrom <daniel@gaisler.com>
---
 common/cmd_ambapp.c      |  566 +++++++++++++++++++++++++-------
 cpu/leon3/Makefile       |    2 +-
 cpu/leon3/ambapp.c       |  581 +++++++++++++++++-----------------
 cpu/leon3/ambapp_low.S   |  798 ++++++++++++++++++++++++++++++++++++++++++++++
 cpu/leon3/ambapp_low_c.S |  133 ++++++++
 cpu/leon3/cpu_init.c     |  182 ++++-------
 cpu/leon3/serial.c       |    8 +-
 cpu/leon3/usb_uhci.c     |    4 +-
 drivers/net/greth.c      |   15 +-
 include/ambapp.h         |  365 ++++++++++-----------
 include/ambapp_ids.h     |  256 +++++++++++++++
 11 files changed, 2180 insertions(+), 730 deletions(-)
 create mode 100644 cpu/leon3/ambapp_low.S
 create mode 100644 cpu/leon3/ambapp_low_c.S
 create mode 100644 include/ambapp_ids.h

diff --git a/common/cmd_ambapp.c b/common/cmd_ambapp.c
index bb20ab5..55b2757 100644
--- a/common/cmd_ambapp.c
+++ b/common/cmd_ambapp.c
@@ -31,92 +31,380 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
-/* We put these variables into .data section so that they are zero
- * when entering the AMBA Plug & Play routines (in cpu/cpu/ambapp.c)
- * the first time. BSS is not garantueed to be zero since BSS
- * hasn't been cleared the first times entering the CPU AMBA functions.
- *
- * The AMBA PnP routines call these functions if ambapp_???_print is set.
- *
- */
-int ambapp_apb_print __attribute__ ((section(".data"))) = 0;
-int ambapp_ahb_print __attribute__ ((section(".data"))) = 0;
-
 typedef struct {
 	int device_id;
 	char *name;
+	char *desc;
 } ambapp_device_name;
 
-static ambapp_device_name gaisler_devices[] = {
-	{GAISLER_LEON3, "GAISLER_LEON3"},
-	{GAISLER_LEON3DSU, "GAISLER_LEON3DSU"},
-	{GAISLER_ETHAHB, "GAISLER_ETHAHB"},
-	{GAISLER_ETHMAC, "GAISLER_ETHMAC"},
-	{GAISLER_APBMST, "GAISLER_APBMST"},
-	{GAISLER_AHBUART, "GAISLER_AHBUART"},
-	{GAISLER_SRCTRL, "GAISLER_SRCTRL"},
-	{GAISLER_SDCTRL, "GAISLER_SDCTRL"},
-	{GAISLER_APBUART, "GAISLER_APBUART"},
-	{GAISLER_IRQMP, "GAISLER_IRQMP"},
-	{GAISLER_AHBRAM, "GAISLER_AHBRAM"},
-	{GAISLER_GPTIMER, "GAISLER_GPTIMER"},
-	{GAISLER_PCITRG, "GAISLER_PCITRG"},
-	{GAISLER_PCISBRG, "GAISLER_PCISBRG"},
-	{GAISLER_PCIFBRG, "GAISLER_PCIFBRG"},
-	{GAISLER_PCITRACE, "GAISLER_PCITRACE"},
-	{GAISLER_AHBTRACE, "GAISLER_AHBTRACE"},
-	{GAISLER_ETHDSU, "GAISLER_ETHDSU"},
-	{GAISLER_PIOPORT, "GAISLER_PIOPORT"},
-	{GAISLER_AHBJTAG, "GAISLER_AHBJTAG"},
-	{GAISLER_ATACTRL, "GAISLER_ATACTRL"},
-	{GAISLER_VGA, "GAISLER_VGA"},
-	{GAISLER_KBD, "GAISLER_KBD"},
-	{GAISLER_L2TIME, "GAISLER_L2TIME"},
-	{GAISLER_L2C, "GAISLER_L2C"},
-	{GAISLER_PLUGPLAY, "GAISLER_PLUGPLAY"},
-	{GAISLER_SPW, "GAISLER_SPW"},
-	{GAISLER_SPW2, "GAISLER_SPW2"},
-	{GAISLER_EHCI, "GAISLER_EHCI"},
-	{GAISLER_UHCI, "GAISLER_UHCI"},
-	{GAISLER_AHBSTAT, "GAISLER_AHBSTAT"},
-	{GAISLER_DDR2SPA, "GAISLER_DDR2SPA"},
-	{GAISLER_DDRSPA, "GAISLER_DDRSPA"},
-	{0, NULL}
+typedef struct {
+        unsigned int vendor_id;
+        char *name;
+        char *desc;
+        ambapp_device_name *devices;
+} ambapp_vendor_devnames;    
+
+/** Vendor GAISLER devices */
+static ambapp_device_name GAISLER_devices[] =
+{
+  {GAISLER_LEON2DSU, "LEON2DSU", "Leon2 Debug Support Unit"},
+  {GAISLER_LEON3, "LEON3", "Leon3 SPARC V8 Processor"},
+  {GAISLER_LEON3DSU, "LEON3DSU", "Leon3 Debug Support Unit"},
+  {GAISLER_ETHAHB, "ETHAHB", "OC ethernet AHB interface"},
+  {GAISLER_APBMST, "APBMST", "AHB/APB Bridge"},
+  {GAISLER_AHBUART, "AHBUART", "AHB Debug UART"},
+  {GAISLER_SRCTRL, "SRCTRL", "Simple SRAM Controller"},
+  {GAISLER_SDCTRL, "SDCTRL", "PC133 SDRAM Controller"},
+  {GAISLER_SSRCTRL, "SSRCTRL", "Synchronous SRAM Controller"},
+  {GAISLER_APBUART, "APBUART", "Generic UART"},
+  {GAISLER_IRQMP, "IRQMP", "Multi-processor Interrupt Ctrl."},
+  {GAISLER_AHBRAM, "AHBRAM", "Single-port AHB SRAM module"},
+  {GAISLER_AHBDPRAM, "AHBDPRAM", "Dual-port AHB SRAM module"},
+  {GAISLER_GPTIMER, "GPTIMER", "Modular Timer Unit"},
+  {GAISLER_PCITRG, "PCITRG", "Simple 32-bit PCI Target"},
+  {GAISLER_PCISBRG, "PCISBRG", "Simple 32-bit PCI Bridge"},
+  {GAISLER_PCIFBRG, "PCIFBRG", "Fast 32-bit PCI Bridge"},
+  {GAISLER_PCITRACE, "PCITRACE", "32-bit PCI Trace Buffer"},
+  {GAISLER_DMACTRL, "DMACTRL", "AMBA DMA controller"},
+  {GAISLER_AHBTRACE, "AHBTRACE", "AMBA Trace Buffer"},
+  {GAISLER_DSUCTRL, "DSUCTRL", "DSU/ETH controller"},
+  {GAISLER_CANAHB, "CANAHB", "OC CAN AHB interface"},
+  {GAISLER_GPIO, "GPIO", "General Purpose I/O port"},
+  {GAISLER_AHBROM, "AHBROM", "Generic AHB ROM"},
+  {GAISLER_AHBJTAG, "AHBJTAG", "JTAG Debug Link"},
+  {GAISLER_ETHMAC, "ETHMAC", "GR Ethernet MAC"},
+  {GAISLER_SWNODE, "SWNODE", "SpaceWire Node Interface"},
+  {GAISLER_SPW, "SPW", "SpaceWire Serial Link"},
+  {GAISLER_AHB2AHB, "AHB2AHB", "AHB-to-AHB Bridge"},
+  {GAISLER_USBDC, "USBDC", "GR USB 2.0 Device Controller"},
+  {GAISLER_USB_DCL, "USB_DCL", "USB Debug Communication Link"},
+  {GAISLER_DDRMP, "DDRMP", "Multi-port DDR controller"},
+  {GAISLER_ATACTRL, "ATACTRL", "ATA controller"},
+  {GAISLER_DDRSP, "DDRSP", "Single-port DDR266 controller"},
+  {GAISLER_EHCI, "EHCI", "USB Enhanced Host Controller"},
+  {GAISLER_UHCI, "UHCI", "USB Universal Host Controller"},
+  {GAISLER_I2CMST, "I2CMST", "AMBA Wrapper for OC I2C-master"},
+  {GAISLER_SPW2, "SPW2", "GRSPW2 SpaceWire Serial Link"},
+  {GAISLER_AHBDMA, "AHBDMA", ""},
+  {GAISLER_NUHOSP3, "NUHOSP3", "Nuhorizons Spartan3 IO I/F"},
+  {GAISLER_CLKGATE, "CLKGATE", "Clock gating unit"},
+  {GAISLER_SPICTRL, "SPICTRL", "SPI Controller"},
+  {GAISLER_DDR2SP, "DDR2SP", "Single-port DDR2 controller"},
+  {GAISLER_SLINK, "SLINK", "SLINK Master"},
+  {GAISLER_GRTM, "GRTM", "CCSDS Telemetry Encoder"},
+  {GAISLER_GRTC, "GRTC", "CCSDS Telecommand Decoder"},
+  {GAISLER_GRPW, "GRPW", "PacketWire to AMBA AHB I/F"},
+  {GAISLER_GRCTM, "GRCTM", "CCSDS Time Manager"},
+  {GAISLER_GRHCAN, "GRHCAN", "ESA HurriCANe CAN with DMA"},
+  {GAISLER_GRFIFO, "GRFIFO", "FIFO Controller"},
+  {GAISLER_GRADCDAC, "GRADCDAC", "ADC / DAC Interface"},
+  {GAISLER_GRPULSE, "GRPULSE", "General Purpose I/O with Pulses"},
+  {GAISLER_GRTIMER, "GRTIMER", "Timer Unit with Latches"},
+  {GAISLER_AHB2PP, "AHB2PP", "AMBA AHB to Packet Parallel I/F"},
+  {GAISLER_GRVERSION, "GRVERSION", "Version and Revision Register"},
+  {GAISLER_APB2PW, "APB2PW", "PacketWire Transmit Interface"},
+  {GAISLER_PW2APB, "PW2APB", "PacketWire Receive Interface"},
+  {GAISLER_GRCAN, "GRCAN", "CAN Controller with DMA"},
+  {GAISLER_I2CSLV, "I2CSLV", "I2C Slave"},
+  {GAISLER_U16550, "U16550", "Simple 16550 UART"},
+  {GAISLER_AHBMST_EM, "AHBMST_EM", "AMBA Master Emulator"},
+  {GAISLER_AHBSLV_EM, "AHBSLV_EM", "AMBA Slave Emulator"},
+  {GAISLER_GRTESTMOD, "GRTESTMOD", "Test report module"},
+  {GAISLER_ASCS, "ASCS", "ASCS Master"},
+  {GAISLER_IPMVBCTRL, "IPMVBCTRL", "IPM-bus/MVBC memory controller"},
+  {GAISLER_SPIMCTRL, "SPIMCTRL", "SPI Memory Controller"},
+  {GAISLER_LEON4, "LEON4", "Leon4 SPARC V8 Processor"},
+  {GAISLER_LEON4DSU, "LEON4DSU", "Leon4 Debug Support Unit"},
+  {GAISLER_PWM, "PWM", "PWM generator"},
+  {GAISLER_L2CACHE, "L2CACHE", "L2-Cache Controller"},
+  {GAISLER_SDCTRL64, "SDCTRL64", ""},
+  {GAISLER_FTAHBRAM, "FTAHBRAM", "Generic FT AHB SRAM module"},
+  {GAISLER_FTSRCTRL, "FTSRCTRL", "Simple FT SRAM Controller"},
+  {GAISLER_AHBSTAT, "AHBSTAT", "AHB Status Register"},
+  {GAISLER_LEON3FT, "LEON3FT", "Leon3-FT SPARC V8 Processor"},
+  {GAISLER_FTMCTRL, "FTMCTRL", "Memory controller with EDAC"},
+  {GAISLER_FTSDCTRL, "FTSDCTRL", "FT PC133 SDRAM Controller"},
+  {GAISLER_FTSRCTRL8, "FTSRCTRL8", "FT 8-bit SRAM/16-bit IO Ctrl"},
+  {GAISLER_APBPS2, "APBPS2", "PS2 interface"},
+  {GAISLER_VGACTRL, "VGACTRL", "VGA controller"},
+  {GAISLER_LOGAN, "LOGAN", "On chip Logic Analyzer"},
+  {GAISLER_SVGACTRL, "SVGACTRL", "SVGA frame buffer"},
+  {GAISLER_T1AHB, "T1AHB", "Niagara T1 PCX/AHB bridge"},
+  {GAISLER_MP7WRAP, "MP7WRAP", "CoreMP7 wrapper"},
+  {GAISLER_GRSYSMON, "GRSYSMON", "AMBA wrapper for System Monitor"},
+  {GAISLER_GRACECTRL, "GRACECTRL", "System ACE I/F Controller"},
+  {GAISLER_ATAHBSLV, "ATAHBSLV", "AMBA Test Framework AHB Slave"},
+  {GAISLER_ATAHBMST, "ATAHBMST", "AMBA Test Framework AHB Master"},
+  {GAISLER_ATAPBSLV, "ATAPBSLV", "AMBA Test Framework APB Slave"},
+  {GAISLER_B1553BC, "B1553BC", "AMBA Wrapper for Core1553BBC"},
+  {GAISLER_B1553RT, "B1553RT", "AMBA Wrapper for Core1553BRT"},
+  {GAISLER_B1553BRM, "B1553BRM", "AMBA Wrapper for Core1553BRM"},
+  {GAISLER_AES, "AES", "Advanced Encryption Standard"},
+  {GAISLER_ECC, "ECC", "Elliptic Curve Cryptography"},
+  {GAISLER_PCIF, "PCIF", "AMBA Wrapper for CorePCIF"},
+  {GAISLER_CLKMOD, "CLKMOD", "CPU Clock Switching Ctrl module"},
+  {GAISLER_HAPSTRAK, "HAPSTRAK", "HAPS HapsTrak I/O Port"},
+  {GAISLER_TEST_1X2, "TEST_1X2", "HAPS TEST_1x2 interface"},
+  {GAISLER_WILD2AHB, "WILD2AHB", "WildCard CardBus interface"},
+  {GAISLER_BIO1, "BIO1", "Basic I/O board BIO1"},
+  {GAISLER_SATCAN, "SATCAN", "SatCAN controller"},
+  {GAISLER_CANMUX, "CANMUX", "CAN Bus multiplexer"},
+  {GAISLER_GRTMRX, "GRTMRX", "CCSDS Telemetry Receiver"},
+  {GAISLER_GRTCTX, "GRTCTX", "CCSDS Telecommand Transmitter"},
+  {GAISLER_GRTMDESC, "GRTMDESC", "CCSDS Telemetry Descriptor"},
+  {GAISLER_GRTMVC, "GRTMVC", "CCSDS Telemetry VC Generator"},
+  {GAISLER_GEFFE, "GEFFE", "Geffe Generator"},
+  {GAISLER_GPREG, "GPREG", ""},
+  {GAISLER_GRTMPAHB, "GRTMPAHB", "CCSDS Telemetry VC AHB Input"},
+  {0, NULL, NULL}
 };
 
-static ambapp_device_name esa_devices[] = {
-	{ESA_LEON2, "ESA_LEON2"},
-	{ESA_MCTRL, "ESA_MCTRL"},
-	{0, NULL}
+
+/** Vendor PENDER devices */
+static ambapp_device_name PENDER_devices[] =
+{
+  {0, NULL, NULL}
 };
 
-static ambapp_device_name opencores_devices[] = {
-	{OPENCORES_PCIBR, "OPENCORES_PCIBR"},
-	{OPENCORES_ETHMAC, "OPENCORES_ETHMAC"},
+
+/** Vendor ESA devices */
+static ambapp_device_name ESA_devices[] =
+{
+  {ESA_LEON2, "LEON2", "Leon2 SPARC V8 Processor"},
+  {ESA_LEON2APB, "LEON2APB", "Leon2 Peripheral Bus"},
+  {ESA_IRQ, "IRQ", "Leon2 Interrupt Controller"},
+  {ESA_TIMER, "TIMER", "Leon2 Timer"},
+  {ESA_UART, "UART", "Leon2 UART"},
+  {ESA_CFG, "CFG", "Leon2 Configuration Register"},
+  {ESA_IO, "IO", "Leon2 Input/Output"},
+  {ESA_MCTRL, "MCTRL", "Leon2 Memory Controller"},
+  {ESA_PCIARB, "PCIARB", "PCI Arbiter"},
+  {ESA_HURRICANE, "HURRICANE", "HurriCANe/HurryAMBA CAN Ctrl"},
+  {ESA_SPW_RMAP, "SPW_RMAP", "UoD/Saab SpaceWire/RMAP link"},
+  {ESA_AHBUART, "AHBUART", "Leon2 AHB Debug UART"},
+  {ESA_SPWA, "SPWA", "ESA/ASTRIUM SpaceWire link"},
+  {ESA_BOSCHCAN, "BOSCHCAN", "SSC/BOSCH CAN Ctrl"},
+  {ESA_IRQ2, "IRQ2", "Leon2 Secondary Irq Controller"},
+  {ESA_AHBSTAT, "AHBSTAT", "Leon2 AHB Status Register"},
+  {ESA_WPROT, "WPROT", "Leon2 Write Protection"},
+  {ESA_WPROT2, "WPROT2", "Leon2 Extended Write Protection"},
+  {ESA_PDEC3AMBA, "PDEC3AMBA", "ESA CCSDS PDEC3AMBA TC Decoder"},
+  {ESA_PTME3AMBA, "PTME3AMBA", "ESA CCSDS PTME3AMBA TM Encoder"},
+  {0, NULL, NULL}
+};
+
+
+/** Vendor ASTRIUM devices */
+static ambapp_device_name ASTRIUM_devices[] =
+{
+  {0, NULL, NULL}
+};
+
+
+/** Vendor OPENCHIP devices */
+static ambapp_device_name OPENCHIP_devices[] =
+{
+  {OPENCHIP_APBGPIO, "APBGPIO", "APB General Purpose IO"},
+  {OPENCHIP_APBI2C, "APBI2C", "APB I2C Interface"},
+  {OPENCHIP_APBSPI, "APBSPI", "APB SPI Interface"},
+  {OPENCHIP_APBCHARLCD, "APBCHARLCD", "APB Character LCD"},
+  {OPENCHIP_APBPWM, "APBPWM", "APB PWM"},
+  {OPENCHIP_APBPS2, "APBPS2", "APB PS/2 Interface"},
+  {OPENCHIP_APBMMCSD, "APBMMCSD", "APB MMC/SD Card Interface"},
+  {OPENCHIP_APBNAND, "APBNAND", "APB NAND(SmartMedia) Interface"},
+  {OPENCHIP_APBLPC, "APBLPC", "APB LPC Interface"},
+  {OPENCHIP_APBCF, "APBCF", "APB CompactFlash (IDE)"},
+  {OPENCHIP_APBSYSACE, "APBSYSACE", "APB SystemACE Interface"},
+  {OPENCHIP_APB1WIRE, "APB1WIRE", "APB 1-Wire Interface"},
+  {OPENCHIP_APBJTAG, "APBJTAG", "APB JTAG TAP Master"},
+  {OPENCHIP_APBSUI, "APBSUI", "APB Simple User Interface"},
+  {0, NULL, NULL}
+};
+
+
+/** Vendor OPENCORES devices */
+static ambapp_device_name OPENCORES_devices[] =
+{
+	{OPENCORES_PCIBR, "PCIBR", "PCI Bridge"},
+	{OPENCORES_ETHMAC, "ETHMAC", "Ethernet MAC"},
 	{0, NULL}
 };
 
-typedef struct {
-	unsigned int vendor_id;
-	char *name;
-	ambapp_device_name *devices;
-} ambapp_vendor_devnames;
-
-static ambapp_vendor_devnames vendors[] = {
-	{VENDOR_GAISLER, "VENDOR_GAISLER", gaisler_devices},
-	{VENDOR_ESA, "VENDOR_ESA", esa_devices},
-	{VENDOR_OPENCORES, "VENDOR_OPENCORES", opencores_devices},
-	{0, NULL, 0}
+
+/** Vendor CONTRIB devices */
+static ambapp_device_name CONTRIB_devices[] =
+{
+  {CONTRIB_CORE1, "CORE1", "Contributed core 1"},
+  {CONTRIB_CORE2, "CORE2", "Contributed core 2"},
+  {0, NULL, NULL}
 };
 
-static char *ambapp_get_devname(ambapp_device_name * devs, int id)
+
+/** Vendor EONIC devices */
+static ambapp_device_name EONIC_devices[] =
+{
+  {0, NULL, NULL}
+};
+
+
+/** Vendor RADIONOR devices */
+static ambapp_device_name RADIONOR_devices[] =
+{
+  {0, NULL, NULL}
+};
+
+
+/** Vendor GLEICHMANN devices */
+static ambapp_device_name GLEICHMANN_devices[] =
+{
+  {GLEICHMANN_CUSTOM, "CUSTOM", "Custom device"},
+  {GLEICHMANN_GEOLCD01, "GEOLCD01", "GEOLCD01 graphics system"},
+  {GLEICHMANN_DAC, "DAC", "Sigma delta DAC"},
+  {GLEICHMANN_HPI, "HPI", "AHB-to-HPI bridge"},
+  {GLEICHMANN_SPI, "SPI", "SPI master"},
+  {GLEICHMANN_HIFC, "HIFC", "Human interface controller"},
+  {GLEICHMANN_ADCDAC, "ADCDAC", "Sigma delta ADC/DAC"},
+  {GLEICHMANN_SPIOC, "SPIOC", ""},
+  {GLEICHMANN_AC97, "AC97", ""},
+  {0, NULL, NULL}
+};
+
+
+/** Vendor MENTA devices */
+static ambapp_device_name MENTA_devices[] =
+{
+  {0, NULL, NULL}
+};
+
+
+/** Vendor SUN devices */
+static ambapp_device_name SUN_devices[] =
+{
+  {SUN_T1, "T1", "Niagara T1 SPARC V9 Processor"},
+  {SUN_S1, "S1", "Niagara S1 SPARC V9 Processor"},
+  {0, NULL, NULL}
+};
+
+
+/** Vendor MOVIDIA devices */
+static ambapp_device_name MOVIDIA_devices[] =
+{
+  {0, NULL, NULL}
+};
+
+
+/** Vendor ORBITA devices */
+static ambapp_device_name ORBITA_devices[] =
+{
+  {ORBITA_1553B, "1553B", "MIL-STD-1553B Controller"},
+  {ORBITA_429, "429", "429 Interface"},
+  {ORBITA_SPI, "SPI", "SPI Interface"},
+  {ORBITA_I2C, "I2C", "I2C Interface"},
+  {ORBITA_SMARTCARD, "SMARTCARD", "Smart Card Reader"},
+  {ORBITA_SDCARD, "SDCARD", "SD Card Reader"},
+  {ORBITA_UART16550, "UART16550", "16550 UART"},
+  {ORBITA_CRYPTO, "CRYPTO", "Crypto Engine"},
+  {ORBITA_SYSIF, "SYSIF", "System Interface"},
+  {ORBITA_PIO, "PIO", "Programmable IO module"},
+  {ORBITA_RTC, "RTC", "Real-Time Clock"},
+  {ORBITA_COLORLCD, "COLORLCD", "Color LCD Controller"},
+  {ORBITA_PCI, "PCI", "PCI Module"},
+  {ORBITA_DSP, "DSP", "DPS Co-Processor"},
+  {ORBITA_USBHOST, "USBHOST", "USB Host"},
+  {ORBITA_USBDEV, "USBDEV", "USB Device"},
+  {0, NULL, NULL}
+};
+
+
+/** Vendor SYNOPSYS devices */
+static ambapp_device_name SYNOPSYS_devices[] =
+{
+  {0, NULL, NULL}
+};
+
+
+/** Vendor NASA devices */
+static ambapp_device_name NASA_devices[] =
+{
+  {NASA_EP32, "EP32", "EP32 Forth processor"},
+  {0, NULL, NULL}
+};
+
+
+/** Vendor CAL devices */
+static ambapp_device_name CAL_devices[] =
+{
+  {CAL_DDRCTRL, "DDRCTRL", ""},
+  {0, NULL, NULL}
+};
+
+
+/** Vendor EMBEDDIT devices */
+static ambapp_device_name EMBEDDIT_devices[] =
+{
+  {0, NULL, NULL}
+};
+
+
+/** Vendor CETON devices */
+static ambapp_device_name CETON_devices[] =
+{
+  {0, NULL, NULL}
+};
+
+
+/** Vendor ACTEL devices */
+static ambapp_device_name ACTEL_devices[] =
+{
+  {ACTEL_COREMP7, "COREMP7", "CoreMP7 Processor"},
+  {0, NULL, NULL}
+};
+
+
+/** Vendor APPLECORE devices */
+static ambapp_device_name APPLECORE_devices[] =
+{
+  {APPLECORE_UTLEON3, "UTLEON3", "AppleCore uT-LEON3 Processor"},
+  {APPLECORE_UTLEON3DSU, "UTLEON3DSU", "AppleCore uT-LEON3 DSU"},
+  {0, NULL, NULL}
+};
+
+
+/** Vendors and their devices */
+static ambapp_vendor_devnames vendors[] = 
+{
+  {VENDOR_GAISLER, "GAISLER", "Gaisler Research", GAISLER_devices},
+  {VENDOR_PENDER, "PENDER", "", PENDER_devices},
+  {VENDOR_ESA, "ESA", "European Space Agency", ESA_devices},
+  {VENDOR_ASTRIUM, "ASTRIUM", "", ASTRIUM_devices},
+  {VENDOR_OPENCHIP, "OPENCHIP", "OpenChip", OPENCHIP_devices},
+  {VENDOR_OPENCORES, "OPENCORES", "OpenCores", OPENCORES_devices},
+  {VENDOR_CONTRIB, "CONTRIB", "Various contributions", CONTRIB_devices},
+  {VENDOR_EONIC, "EONIC", "Eonic BV", EONIC_devices},
+  {VENDOR_RADIONOR, "RADIONOR", "Radionor Communications", RADIONOR_devices},
+  {VENDOR_GLEICHMANN, "GLEICHMANN", "Gleichmann Electronics", GLEICHMANN_devices},
+  {VENDOR_MENTA, "MENTA", "Menta", MENTA_devices},
+  {VENDOR_SUN, "SUN", "Sun Microsystems", SUN_devices},
+  {VENDOR_MOVIDIA, "MOVIDIA", "", MOVIDIA_devices},
+  {VENDOR_ORBITA, "ORBITA", "Orbita", ORBITA_devices},
+  {VENDOR_SYNOPSYS, "SYNOPSYS", "Synopsys Inc.", SYNOPSYS_devices},
+  {VENDOR_NASA, "NASA", "NASA", NASA_devices},
+  {VENDOR_CAL, "CAL", "", CAL_devices},
+  {VENDOR_EMBEDDIT, "EMBEDDIT", "Embedd.it", EMBEDDIT_devices},
+  {VENDOR_CETON, "CETON", "Ceton Corporation", CETON_devices},
+  {VENDOR_ACTEL, "ACTEL", "Actel Corporation", ACTEL_devices},
+  {VENDOR_APPLECORE, "APPLECORE", "AppleCore", APPLECORE_devices},
+  {0, NULL, NULL, NULL}
+};
+
+static ambapp_device_name *ambapp_get_dev(ambapp_device_name * devs, int id)
 {
 	if (!devs)
 		return NULL;
 
 	while (devs->device_id > 0) {
 		if (devs->device_id == id)
-			return devs->name;
+			return devs;
 		devs++;
 	}
 	return NULL;
@@ -125,10 +413,31 @@ static char *ambapp_get_devname(ambapp_device_name * devs, int id)
 char *ambapp_device_id2str(int vendor, int id)
 {
 	ambapp_vendor_devnames *ven = &vendors[0];
+	ambapp_device_name *dev;
+
+	while (ven->vendor_id > 0) {
+		if (ven->vendor_id == vendor) {
+			dev = ambapp_get_dev(ven->devices, id);
+			if ( !dev )
+				return NULL;
+			return dev->name;
+		}
+		ven++;
+	}
+	return NULL;
+}
+
+char *ambapp_device_id2desc(int vendor, int id)
+{
+	ambapp_vendor_devnames *ven = &vendors[0];
+	ambapp_device_name *dev;
 
 	while (ven->vendor_id > 0) {
 		if (ven->vendor_id == vendor) {
-			return ambapp_get_devname(ven->devices, id);
+			dev = ambapp_get_dev(ven->devices, id);
+			if ( !dev )
+				return NULL;
+			return dev->desc;
 		}
 		ven++;
 	}
@@ -150,101 +459,107 @@ char *ambapp_vendor_id2str(int vendor)
 
 static char *unknown = "unknown";
 
+char *ambapp_type_names[4] =
+{
+	/* 0 */ "UNUSED",
+	/* 1 */ "apb",
+	/* 2 */ "ahbmem",
+	/* 3 */ "ahbio"
+};
+
 /* Print one APB device */
-void ambapp_print_apb(apbctrl_pp_dev * apb, ambapp_ahbdev * apbmst, int index)
+void ambapp_print_apb(ambapp_apbdev *dev, int index)
 {
 	char *dev_str, *ven_str;
-	int irq, ver, vendor, deviceid;
-	unsigned int address, apbmst_base, mask;
-
-	vendor = amba_vendor(apb->conf);
-	deviceid = amba_device(apb->conf);
-	irq = amba_irq(apb->conf);
-	ver = amba_ver(apb->conf);
-	apbmst_base = apbmst->address[0] & LEON3_IO_AREA;
-	address = (apbmst_base | (((apb->bar & 0xfff00000) >> 12))) &
-	    (((apb->bar & 0x0000fff0) << 4) | 0xfff00000);
-
-	mask = amba_membar_mask(apb->bar) << 8;
-	mask = ((~mask) & 0x000fffff) + 1;
+	unsigned int freq;
 
-	ven_str = ambapp_vendor_id2str(vendor);
+	ven_str = ambapp_vendor_id2str(dev->vendor);
 	if (!ven_str) {
 		ven_str = unknown;
 		dev_str = unknown;
 	} else {
-		dev_str = ambapp_device_id2str(vendor, deviceid);
+		dev_str = ambapp_device_id2str(dev->vendor, dev->device);
 		if (!dev_str)
 			dev_str = unknown;
 	}
+	
+	/* Get Frequency of Core */
+	freq = ambapp_bus_freq(&ambapp_plb, dev->ahb_bus_index);
 
-	printf("0x%02x:0x%02x:0x%02x: %s  %s\n"
+	printf("0x%02x:0x%02x:0x%02x: %s  %s  (%dkHz)\n"
 	       "   apb: 0x%08x - 0x%08x\n"
 	       "   irq: %-2d (ver: %-2d)\n",
-	       index, vendor, deviceid, ven_str, dev_str, address,
-	       address + mask, irq, ver);
+	       index, dev->vendor, dev->device, ven_str, dev_str, freq / 1000,
+	       dev->address, dev->address + (dev->mask-1),
+	       dev->irq, dev->ver);
 }
 
-void ambapp_print_ahb(ahbctrl_pp_dev * ahb, int index)
+void ambapp_print_ahb(ambapp_ahbdev *dev, int index)
 {
-	char *dev_str, *ven_str;
-	int irq, ver, vendor, deviceid;
-	unsigned int addr, mask;
-	int j;
-
-	vendor = amba_vendor(ahb->conf);
-	deviceid = amba_device(ahb->conf);
-	irq = amba_irq(ahb->conf);
-	ver = amba_ver(ahb->conf);
+	char *dev_str, *ven_str, *type_str;
+	int i;
+	unsigned int freq;
 
-	ven_str = ambapp_vendor_id2str(vendor);
+	ven_str = ambapp_vendor_id2str(dev->vendor);
 	if (!ven_str) {
 		ven_str = unknown;
 		dev_str = unknown;
 	} else {
-		dev_str = ambapp_device_id2str(vendor, deviceid);
+		dev_str = ambapp_device_id2str(dev->vendor, dev->device);
 		if (!dev_str)
 			dev_str = unknown;
 	}
 
-	printf("0x%02x:0x%02x:0x%02x: %s  %s\n",
-	       index, vendor, deviceid, ven_str, dev_str);
+	/* Get Frequency of Core */
+	freq = ambapp_bus_freq(&ambapp_plb, dev->ahb_bus_index);
 
-	for (j = 0; j < 4; j++) {
-		addr = amba_membar_start(ahb->bars[j]);
-		if (amba_membar_type(ahb->bars[j]) == 0)
+	printf("0x%02x:0x%02x:0x%02x: %s  %s  (%dkHz)\n",
+	       index, dev->vendor, dev->device, ven_str, dev_str, freq / 1000);
+
+	for (i = 0; i < 4; i++) {
+		if ( dev->type[i] == 0 )
 			continue;
-		if (amba_membar_type(ahb->bars[j]) == AMBA_TYPE_AHBIO)
-			addr = AMBA_TYPE_AHBIO_ADDR(addr);
-		mask = amba_membar_mask(ahb->bars[j]) << 20;
-		printf("   mem: 0x%08x - 0x%08x\n", addr, addr + ((~mask) + 1));
+		type_str = ambapp_type_names[dev->type[i]];
+		printf("   %-7s: 0x%08x - 0x%08x\n", type_str, dev->address[i], 	
+			dev->address[i] + (dev->mask[i]-1));
 	}
 
-	printf("   irq: %-2d (ver: %d)\n", irq, ver);
+	printf("   irq: %-2d (ver: %d)\n", dev->irq, dev->ver);
 }
 
 int do_ambapp_print(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
 {
+	int index;
+	ambapp_apbdev apbdev;
+	ambapp_ahbdev ahbdev;
 
 	/* Print AHB Masters */
-	puts("--------- AHB Masters ---------\n");
-	ambapp_apb_print = 0;
-	ambapp_ahb_print = 1;
-	ambapp_ahbmst_count(99, 99);	/* Get vendor&device 99 = nonexistent... */
+	puts("\n--------- AHB Masters ---------\n");
+	index = 0;
+	while ( ambapp_ahbmst_find(&ambapp_plb, 0, 0, index, &ahbdev) == 1 ) {
+		/* Found a AHB Master Device */
+		ambapp_print_ahb(&ahbdev, index);
+		index++;
+	}
 
 	/* Print AHB Slaves */
-	puts("--------- AHB Slaves  ---------\n");
-	ambapp_ahbslv_count(99, 99);	/* Get vendor&device 99 = nonexistent... */
+	puts("\n--------- AHB Slaves  ---------\n");
+	index = 0;
+	while ( ambapp_ahbslv_find(&ambapp_plb, 0, 0, index, &ahbdev) == 1 ) {
+		/* Found a AHB Slave Device */
+		ambapp_print_ahb(&ahbdev, index);
+		index++;
+	}
 
 	/* Print APB Slaves */
-	puts("--------- APB Slaves  ---------\n");
-	ambapp_apb_print = 1;
-	ambapp_ahb_print = 0;
-	ambapp_apb_count(99, 99);	/* Get vendor&device 99 = nonexistent... */
-
-	/* Reset, no futher printing */
-	ambapp_apb_print = 0;
-	ambapp_ahb_print = 0;
+	puts("\n--------- APB Slaves  ---------\n");
+	index = 0;
+	while ( ambapp_apb_find(&ambapp_plb, 0, 0, index, &apbdev) == 1 ) {
+		/* Found a APB Slave Device */
+		ambapp_print_apb(&apbdev, index);
+		index++;
+	}
+
 	puts("\n");
 	return 0;
 }
@@ -256,16 +571,19 @@ int ambapp_init_reloc(void)
 
 	while (vend->vendor_id && vend->name) {
 		vend->name = (char *)((unsigned int)vend->name + gd->reloc_off);
+		vend->desc = (char *)((unsigned int)vend->desc + gd->reloc_off);
 		vend->devices =
 		    (ambapp_device_name *) ((unsigned int)vend->devices +
-					    gd->reloc_off);;
+					    gd->reloc_off);
 		dev = vend->devices;
 		vend++;
 		if (!dev)
 			continue;
 		while (dev->device_id && dev->name) {
 			dev->name =
-			    (char *)((unsigned int)dev->name + gd->reloc_off);;
+			    (char *)((unsigned int)dev->name + gd->reloc_off);
+			dev->desc =
+			    (char *)((unsigned int)dev->desc + gd->reloc_off);
 			dev++;
 		}
 	}
diff --git a/cpu/leon3/Makefile b/cpu/leon3/Makefile
index 182543d..d8f89bc 100644
--- a/cpu/leon3/Makefile
+++ b/cpu/leon3/Makefile
@@ -26,7 +26,7 @@ include $(TOPDIR)/config.mk
 LIB	= $(obj)lib$(CPU).a
 
 START	= start.o
-SOBJS	=
+SOBJS	= ambapp_low.o ambapp_low_c.o
 COBJS	= cpu_init.o serial.o cpu.o ambapp.o interrupts.o prom.o usb_uhci.o
 
 SRCS	:= $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
diff --git a/cpu/leon3/ambapp.c b/cpu/leon3/ambapp.c
index efd41ae..d332294 100644
--- a/cpu/leon3/ambapp.c
+++ b/cpu/leon3/ambapp.c
@@ -1,9 +1,8 @@
-/* Gaisler AMBA Plug&Play bus scanning. Functions
- * ending on _nomem is inteded to be used only during
- * initialization, only registers are used (no ram).
+/* GRLIB AMBA Plug&Play information scanning, relies on assembler
+ * routines.
  *
- * (C) Copyright 2007
- * Daniel Hellstrom, Gaisler Research, daniel at gaisler.com
+ * (C) Copyright 2010
+ * Daniel Hellstrom, Aeroflex Gaisler, daniel at gaisler.com.
  *
  * See file CREDITS for list of people who contributed to this
  * project.
@@ -22,338 +21,348 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  * MA 02111-1307 USA
+ *
  */
 
+/* #define DEBUG */
+
 #include <common.h>
-#include <command.h>
 #include <ambapp.h>
+#include <config.h>
+
+/************ C INTERFACE OF ASSEMBLER SCAN ROUTINES ************/
+struct ambapp_find_apb_info {
+	/* Address of APB device Plug&Play information */
+	struct ambapp_pnp_apb	*pnp;	
+	/* AHB Bus index of where the APB-Master Bridge device was found */
+	int			ahb_bus_index;
+	int			dec_index;
+};
 
-#if defined(CONFIG_CMD_AMBAPP)
-extern void ambapp_print_apb(apbctrl_pp_dev * apb,
-			     ambapp_ahbdev * apbmst, int index);
-extern void ambapp_print_ahb(ahbctrl_pp_dev * ahb, int index);
-extern int ambapp_apb_print;
-extern int ambapp_ahb_print;
-#endif
+struct ambapp_find_ahb_info {
+	/* Address of AHB device Plug&Play information */
+	struct ambapp_pnp_ahb	*pnp;
+	/* AHB Bus index of where the AHB device was found */
+	int			ahb_bus_index;
+	int			dec_index;
+};
 
-static int ambapp_apb_scan(unsigned int vendor,	/* Plug&Play Vendor ID */
-			   unsigned int driver,	/* Plug&Play Device ID */
-			   ambapp_apbdev * dev,	/* Result(s) is placed here */
-			   int index,	/* Index of device to start copying Plug&Play
-					 * info into dev
-					 */
-			   int max_cnt	/* Maximal count that dev can hold, if dev
-					 * is NULL function will stop scanning after
-					 * max_cnt devices are found.
-					 */
-    )
+extern void ambapp_find_buses(
+	unsigned int ioarea,
+	struct ambapp_bus *abus
+	);
+
+extern int ambapp_find_apb(
+	struct ambapp_bus *abus,
+	unsigned int dev_vend,
+	int index,
+	struct ambapp_find_apb_info *result
+	);
+
+extern int ambapp_find_ahb(
+	struct ambapp_bus *abus,
+	unsigned int dev_vend,
+	int index,
+	int type,
+	struct ambapp_find_ahb_info *result
+	);
+
+/************ C ROUTINES USED BY U-BOOT AMBA CORE DRIVERS ************/
+struct ambapp_bus ambapp_plb;
+
+void ambapp_bus_init(
+	unsigned int ioarea,
+	unsigned int freq,
+	struct ambapp_bus *abus)
 {
-	int i, cnt = 0;
-	unsigned int apbmst_base;
-	ambapp_ahbdev apbmst;
-	apbctrl_pp_dev *apb;
-
-	if (max_cnt == 0)
-		return 0;
-
-	/* Get AMBA APB Master */
-	if (ambapp_ahbslv_first(VENDOR_GAISLER, GAISLER_APBMST, &apbmst) != 1) {
-		return 0;
-	}
-
-	/* Get APB CTRL Plug&Play info area */
-	apbmst_base = apbmst.address[0] & LEON3_IO_AREA;
-	apb = (apbctrl_pp_dev *) (apbmst_base | LEON3_CONF_AREA);
+	int i;
+
+	ambapp_find_buses(ioarea, abus);
+	for(i=0; i<6; i++)
+		if ( abus->ioareas[i] == 0 )
+			break;
+	abus->buses = i;
+	abus->freq = freq;
+}
 
-	for (i = 0; i < LEON3_APB_SLAVES; i++) {
-#if defined(CONFIG_CMD_AMBAPP)
-		if (ambapp_apb_print && amba_vendor(apb->conf)
-		    && amba_device(apb->conf)) {
-			ambapp_print_apb(apb, &apbmst, i);
-		}
-#endif
-		if ((amba_vendor(apb->conf) == vendor) &&
-		    (amba_device(apb->conf) == driver) && ((index < 0)
-							   || (index-- == 0))) {
-			/* Convert Plug&Play info into a more readable format */
-			cnt++;
-			if (dev) {
-				dev->irq = amba_irq(apb->conf);
-				dev->ver = amba_ver(apb->conf);
-				dev->address =
-				    (apbmst_base |
-				     (((apb->
-					bar & 0xfff00000) >> 12))) & (((apb->
-									bar &
-									0x0000fff0)
-								       << 4) |
-								      0xfff00000);
-				dev++;
-			}
-			/* found max devices? */
-			if (cnt >= max_cnt)
-				return cnt;
-		}
-		/* Get next Plug&Play entry */
-		apb++;
-	}
-	return cnt;
+/* Parse APB PnP Information */
+void ambapp_apb_parse(struct ambapp_find_apb_info *info, ambapp_apbdev *dev)
+{
+	struct ambapp_pnp_apb *apb = info->pnp;
+	unsigned int apbbase = (unsigned int)apb & 0xfff00000;
+
+	dev->vendor = amba_vendor(apb->id);
+	dev->device = amba_device(apb->id);
+	dev->irq = amba_irq(apb->id);
+	dev->ver = amba_ver(apb->id);
+	dev->address = (apbbase | (((apb->iobar & 0xfff00000) >> 12))) & 
+			(((apb->iobar &	0x0000fff0) << 4) | 0xfff00000);
+	dev->mask = amba_apb_mask(apb->iobar);
+	dev->ahb_bus_index = info->ahb_bus_index - 1;
 }
 
-unsigned int ambapp_apb_next_nomem(register unsigned int vendor,	/* Plug&Play Vendor ID */
-				   register unsigned int driver,	/* Plug&Play Device ID */
-				   register int index)
+/* Parse AHB PnP information */
+void ambapp_ahb_parse(struct ambapp_find_ahb_info *info, ambapp_ahbdev *dev)
 {
-	register int i;
-	register ahbctrl_pp_dev *apbmst;
-	register apbctrl_pp_dev *apb;
-	register unsigned int apbmst_base;
-
-	/* APBMST is a AHB Slave */
-	apbmst = ambapp_ahb_next_nomem(VENDOR_GAISLER, GAISLER_APBMST, 1, 0);
-	if (!apbmst)
-		return 0;
-
-	apbmst_base = amba_membar_start(apbmst->bars[0]);
-	if (amba_membar_type(apbmst->bars[0]) == AMBA_TYPE_AHBIO)
-		apbmst_base = AMBA_TYPE_AHBIO_ADDR(apbmst_base);
-	apbmst_base &= LEON3_IO_AREA;
-
-	/* Find the vendor/driver device on the first APB bus */
-	apb = (apbctrl_pp_dev *) (apbmst_base | LEON3_CONF_AREA);
-
-	for (i = 0; i < LEON3_APB_SLAVES; i++) {
-		if ((amba_vendor(apb->conf) == vendor) &&
-		    (amba_device(apb->conf) == driver) && ((index < 0)
-							   || (index-- == 0))) {
-			/* Convert Plug&Play info info a more readable format */
-			return (apbmst_base | (((apb->bar & 0xfff00000) >> 12)))
-			    & (((apb->bar & 0x0000fff0) << 4) | 0xfff00000);
+	struct ambapp_pnp_ahb *ahb = info->pnp;
+	unsigned int ahbbase = (unsigned int)ahb & 0xfff00000;
+	int i, type;
+	unsigned int addr, mask, mbar;
+
+	dev->vendor = amba_vendor(ahb->id);
+	dev->device = amba_device(ahb->id);
+	dev->irq = amba_irq(ahb->id);
+	dev->ver = amba_ver(ahb->id);
+	dev->userdef[0] = ahb->custom[0];
+	dev->userdef[1] = ahb->custom[1];
+	dev->userdef[2] = ahb->custom[2];
+	dev->ahb_bus_index = info->ahb_bus_index - 1;
+	for (i=0; i<4; i++) {
+		mbar = ahb->mbar[i];
+		addr = amba_membar_start(mbar);
+		type = amba_membar_type(mbar);
+		if ( type == AMBA_TYPE_AHBIO ) {
+			addr = amba_ahbio_adr(addr, ahbbase);
+			mask = (((unsigned int)
+				(amba_membar_mask((~mbar))<<8)|0xff))+1;
+		} else {
+			/* AHB memory area, absolute address */
+			mask = (~((unsigned int)
+				(amba_membar_mask(mbar)<<20)))+1;
 		}
-		/* Get next Plug&Play entry */
-		apb++;
+		dev->address[i] = addr;
+		dev->mask[i] = mask;
+		dev->type[i] = type;
 	}
-	return 0;
 }
 
-/****************************** APB SLAVES ******************************/
-
-int ambapp_apb_count(unsigned int vendor, unsigned int driver)
+int ambapp_apb_find(
+	struct ambapp_bus *abus,
+	int vendor,
+	int device,
+	int index,
+	ambapp_apbdev *dev)
 {
-	return ambapp_apb_scan(vendor, driver, NULL, 0, LEON3_APB_SLAVES);
-}
+	unsigned int devid = AMBA_PNP_ID(vendor, device);
+	int found;
+	struct ambapp_find_apb_info apbdev;
 
-int ambapp_apb_first(unsigned int vendor,
-		     unsigned int driver, ambapp_apbdev * dev)
-{
-	return ambapp_apb_scan(vendor, driver, dev, 0, 1);
+	found = ambapp_find_apb(abus, devid, index, &apbdev);
+	if ( found == 1 ) {
+		ambapp_apb_parse(&apbdev, dev);
+	}
+	return found;
 }
 
-int ambapp_apb_next(unsigned int vendor,
-		    unsigned int driver, ambapp_apbdev * dev, int index)
+int ambapp_apb_count(struct ambapp_bus *abus, int vendor, int device)
 {
-	return ambapp_apb_scan(vendor, driver, dev, index, 1);
-}
+	unsigned int devid = AMBA_PNP_ID(vendor, device);
+	int found;
+	struct ambapp_find_apb_info apbdev;
 
-int ambapp_apbs_first(unsigned int vendor,
-		      unsigned int driver, ambapp_apbdev * dev, int max_cnt)
-{
-	return ambapp_apb_scan(vendor, driver, dev, 0, max_cnt);
+	found = ambapp_find_apb(abus, devid, 63, &apbdev);
+	if ( found == 1 ) {
+		return 64;
+	} else {
+		return 63 - apbdev.dec_index;
+	}
 }
 
-enum {
-	AHB_SCAN_MASTER = 0,
-	AHB_SCAN_SLAVE = 1
-};
-
-/* Scan AMBA Plug&Play bus for AMBA AHB Masters or AHB Slaves
- * for a certain matching Vendor and Device ID.
- *
- * Return number of devices found.
- *
- * Compact edition...
- */
-static int ambapp_ahb_scan(unsigned int vendor,	/* Plug&Play Vendor ID */
-			   unsigned int driver,	/* Plug&Play Device ID */
-			   ambapp_ahbdev * dev,	/* Result(s) is placed here */
-			   int index,	/* Index of device to start copying Plug&Play
-					 * info into dev
-					 */
-			   int max_cnt,	/* Maximal count that dev can hold, if dev
-					 * is NULL function will stop scanning after
-					 * max_cnt devices are found.
-					 */
-			   int type	/* Selectes what type of devices to scan.
-					 * 0=AHB Masters
-					 * 1=AHB Slaves
-					 */
-    )
+int ambapp_ahb_find(
+	struct ambapp_bus *abus,
+	int vendor,
+	int device,
+	int index,
+	ambapp_ahbdev *dev,
+	int type
+	)
 {
-	int i, j, cnt = 0, max_pp_devs;
-	unsigned int addr;
-	ahbctrl_info *info = (ahbctrl_info *) (LEON3_IO_AREA | LEON3_CONF_AREA);
-	ahbctrl_pp_dev *ahb;
-
-	if (max_cnt == 0)
-		return 0;
-
-	if (type == 0) {
-		max_pp_devs = LEON3_AHB_MASTERS;
-		ahb = info->masters;
-	} else {
-		max_pp_devs = LEON3_AHB_SLAVES;
-		ahb = info->slaves;
-	}
+	int found;
+	struct ambapp_find_ahb_info ahbdev;
+	unsigned int devid = AMBA_PNP_ID(vendor, device);
 
-	for (i = 0; i < max_pp_devs; i++) {
-#if defined(CONFIG_CMD_AMBAPP)
-		if (ambapp_ahb_print && amba_vendor(ahb->conf) &&
-		    amba_device(ahb->conf)) {
-			ambapp_print_ahb(ahb, i);
-		}
-#endif
-		if ((amba_vendor(ahb->conf) == vendor) &&
-		    (amba_device(ahb->conf) == driver) &&
-		    ((index < 0) || (index-- == 0))) {
-			/* Convert Plug&Play info info a more readable format */
-			cnt++;
-			if (dev) {
-				dev->irq = amba_irq(ahb->conf);
-				dev->ver = amba_ver(ahb->conf);
-				dev->userdef[0] = ahb->userdef[0];
-				dev->userdef[1] = ahb->userdef[1];
-				dev->userdef[2] = ahb->userdef[2];
-				for (j = 0; j < 4; j++) {
-					addr = amba_membar_start(ahb->bars[j]);
-					if (amba_membar_type(ahb->bars[j]) ==
-					    AMBA_TYPE_AHBIO)
-						addr =
-						    AMBA_TYPE_AHBIO_ADDR(addr);
-					dev->address[j] = addr;
-				}
-				dev++;
-			}
-			/* found max devices? */
-			if (cnt >= max_cnt)
-				return cnt;
-		}
-		/* Get next Plug&Play entry */
-		ahb++;
+	found = ambapp_find_ahb(abus, devid, index, type, &ahbdev);
+	if ( found == 1 ) {
+		ambapp_ahb_parse(&ahbdev, dev);
 	}
-	return cnt;
+	return found;
 }
 
-unsigned int ambapp_ahb_get_info(ahbctrl_pp_dev * ahb, int info)
+int ambapp_ahbmst_find(
+	struct ambapp_bus *abus,
+	int vendor,
+	int device,
+	int index,
+	ambapp_ahbdev *dev)
 {
-	register unsigned int ret;
-
-	if (!ahb)
-		return 0;
-
-	switch (info) {
-	default:
-		info = 0;
-	case 0:
-	case 1:
-	case 2:
-	case 3:
-		/* Get Address from PnP Info */
-		ret = amba_membar_start(ahb->bars[info]);
-		if (amba_membar_type(ahb->bars[info]) == AMBA_TYPE_AHBIO)
-			ret = AMBA_TYPE_AHBIO_ADDR(ret);
-		return ret;
-	}
-	return 0;
+	return ambapp_ahb_find(abus, vendor, device, index, dev, DEV_AHB_MST);
+}
 
+int ambapp_ahbslv_find(
+	struct ambapp_bus *abus,
+	int vendor,
+	int device,
+	int index,
+	ambapp_ahbdev *dev)
+{
+	return ambapp_ahb_find(abus, vendor, device, index, dev, DEV_AHB_SLV);
 }
 
-ahbctrl_pp_dev *ambapp_ahb_next_nomem(register unsigned int vendor,	/* Plug&Play Vendor ID */
-				      register unsigned int driver,	/* Plug&Play Device ID */
-				      register unsigned int opts,	/* 1=slave, 0=master */
-				      register int index)
+int ambapp_ahb_count(struct ambapp_bus *abus, int vendor, int device, int type)
 {
-	register ahbctrl_pp_dev *ahb;
-	register ahbctrl_info *info =
-	    (ahbctrl_info *) (LEON3_IO_AREA | LEON3_CONF_AREA);
-	register int i;
-	register int max_pp_devs;
-
-	if (opts == 0) {
-		max_pp_devs = LEON3_AHB_MASTERS;
-		ahb = info->masters;
-	} else {
-		max_pp_devs = LEON3_AHB_SLAVES;
-		ahb = info->slaves;
-	}
+	int found;
+	struct ambapp_find_ahb_info ahbdev;
+	unsigned int devid = AMBA_PNP_ID(vendor, device);
 
-	for (i = 0; i < max_pp_devs; i++) {
-		if ((amba_vendor(ahb->conf) == vendor) &&
-		    (amba_device(ahb->conf) == driver) &&
-		    ((index < 0) || (index-- == 0))) {
-			/* Convert Plug&Play info info a more readable format */
-			return ahb;
-		}
-		/* Get next Plug&Play entry */
-		ahb++;
+	found = ambapp_find_ahb(abus, devid, 63, type, &ahbdev);
+	if ( found == 1 ) {
+		return 64;
+	} else {
+		return 63 - ahbdev.dec_index;
 	}
-	return 0;
 }
 
-/****************************** AHB MASTERS ******************************/
-int ambapp_ahbmst_count(unsigned int vendor, unsigned int driver)
+int ambapp_ahbmst_count(struct ambapp_bus *abus, int vendor, int device)
 {
-	/* Get number of devices of this vendor&device ID */
-	return ambapp_ahb_scan(vendor, driver, NULL, 0, LEON3_AHB_MASTERS,
-			       AHB_SCAN_MASTER);
+	return ambapp_ahb_count(abus, vendor, device, DEV_AHB_MST);
 }
 
-int ambapp_ahbmst_first(unsigned int vendor, unsigned int driver,
-			ambapp_ahbdev * dev)
+int ambapp_ahbslv_count(struct ambapp_bus *abus, int vendor, int device)
 {
-	/* find first device of this */
-	return ambapp_ahb_scan(vendor, driver, dev, 0, 1, AHB_SCAN_MASTER);
+	return ambapp_ahb_count(abus, vendor, device, DEV_AHB_SLV);
 }
 
-int ambapp_ahbmst_next(unsigned int vendor,
-		       unsigned int driver, ambapp_ahbdev * dev, int index)
-{
-	/* find first device of this */
-	return ambapp_ahb_scan(vendor, driver, dev, index, 1, AHB_SCAN_MASTER);
-}
+/* The define CONFIG_SYS_GRLIB_SINGLE_BUS may be defined on GRLIB systems
+ * where only one AHB Bus is available - no bridges are present. This option
+ * is available only to reduce the footprint.
+ *
+ * Defining this on a multi-bus GRLIB system may also work depending on the
+ * design.
+ */
 
-int ambapp_ahbmsts_first(unsigned int vendor,
-			 unsigned int driver, ambapp_ahbdev * dev, int max_cnt)
-{
-	/* find first device of this */
-	return ambapp_ahb_scan(vendor, driver, dev, 0, max_cnt,
-			       AHB_SCAN_MASTER);
-}
+#ifndef CONFIG_SYS_GRLIB_SINGLE_BUS
 
-/****************************** AHB SLAVES ******************************/
-int ambapp_ahbslv_count(unsigned int vendor, unsigned int driver)
-{
-	/* Get number of devices of this vendor&device ID */
-	return ambapp_ahb_scan(vendor, driver, NULL, 0, LEON3_AHB_SLAVES,
-			       AHB_SCAN_SLAVE);
-}
+/* GAISLER AHB2AHB Version 1 Bridge Definitions */
+#define AHB2AHB_V1_FLAG_FFACT     0x0f0	/* Frequency factor against top bus */
+#define AHB2AHB_V1_FLAG_FFACT_DIR 0x100	/* Factor direction, 0=down, 1=up */
+#define AHB2AHB_V1_FLAG_MBUS      0x00c	/* Master bus number mask */
+#define AHB2AHB_V1_FLAG_SBUS      0x003	/* Slave bus number mask */
 
-int ambapp_ahbslv_first(unsigned int vendor, unsigned int driver,
-			ambapp_ahbdev * dev)
+/* Get Parent bus frequency. Note that since we go from a "child" bus 
+ * to a parent bus, the frequency factor direction is inverted.
+ */
+unsigned int gaisler_ahb2ahb_v1_freq(ambapp_ahbdev *ahb, unsigned int freq)
 {
-	/* find first device of this */
-	return ambapp_ahb_scan(vendor, driver, dev, 0, 1, AHB_SCAN_SLAVE);
+	int dir;
+	unsigned char ffact;
+
+	/* Get division/multiple factor */
+	ffact = (ahb->userdef[0] & AHB2AHB_V1_FLAG_FFACT) >> 4;
+	if ( ffact != 0 ) {
+		dir = ahb->userdef[0] & AHB2AHB_V1_FLAG_FFACT_DIR;
+
+		/* Calculate frequency by dividing or 
+		 * multiplying system frequency 
+		 */
+		if ( dir ) {
+			freq = freq * ffact;
+		} else {
+			freq = freq / ffact;
+		}
+	}
+
+	return freq;
 }
 
-int ambapp_ahbslv_next(unsigned int vendor,
-		       unsigned int driver, ambapp_ahbdev * dev, int index)
+/* AHB2AHB and L2CACHE ver 2 is not supported yet. */
+unsigned int gaisler_ahb2ahb_v2_freq(ambapp_ahbdev *ahb, unsigned int freq)
 {
-	/* find first device of this */
-	return ambapp_ahb_scan(vendor, driver, dev, index, 1, AHB_SCAN_SLAVE);
+	printf("gaisler_ahb2ahb_v2_freq: AHB2AHB ver 2 not supported\n");
+	while(1) ;
 }
+#endif
 
-int ambapp_ahbslvs_first(unsigned int vendor,
-			 unsigned int driver, ambapp_ahbdev * dev, int max_cnt)
+/* Return the frequency of a AHB bus identified by index found 
+ * note that this is not the AHB Bus number.
+ */
+unsigned int ambapp_bus_freq (
+	struct ambapp_bus *abus,
+	int ahb_bus_index
+	)
 {
-	/* find first device of this */
-	return ambapp_ahb_scan(vendor, driver, dev, 0, max_cnt, AHB_SCAN_SLAVE);
+	unsigned int freq = abus->freq;
+#ifndef CONFIG_SYS_GRLIB_SINGLE_BUS
+	unsigned int ioarea, ioarea_parent, bridge_pnp_ofs;
+	struct ambapp_find_ahb_info ahbinfo;
+	ambapp_ahbdev ahb;
+	int parent;
+
+	debug("ambapp_bus_freq: get freq on bus %d\n", ahb_bus_index);
+
+	while ( ahb_bus_index != 0) {
+
+		debug("  BUS[0]: 0x%08x\n", abus->ioareas[0]);
+		debug("  BUS[1]: 0x%08x\n", abus->ioareas[1]);
+		debug("  BUS[2]: 0x%08x\n", abus->ioareas[2]);
+		debug("  BUS[3]: 0x%08x\n", abus->ioareas[3]);
+		debug("  BUS[4]: 0x%08x\n", abus->ioareas[4]);
+		debug("  BUS[5]: 0x%08x\n", abus->ioareas[5]);
+
+		/* Get I/O area of AHB bus */
+		ioarea = abus->ioareas[ahb_bus_index];
+		
+		printf("  IOAREA: 0x%08x\n", ioarea);
+
+		/* Get parent bus */
+		parent = (ioarea & 0x7);
+		if ( parent == 0 ) {
+			printf("ambapp_bus_freq: parent=0 indicates no parent! Stopping.\n");
+			while(1) ;
+		}
+		parent = parent - 1;
+		bridge_pnp_ofs = ioarea & 0x7e0;
+
+		debug("  PARENT: %d\n", parent);
+		debug("  BRIDGE_OFS: 0x%08x\n", bridge_pnp_ofs);
+
+		/* Get AHB/AHB bridge PnP address */
+		ioarea_parent = (abus->ioareas[parent] & 0xfff00000) | 
+				AMBA_CONF_AREA | AMBA_AHB_SLAVE_CONF_AREA;
+		ahbinfo.pnp = (struct ambapp_pnp_ahb *)
+			(ioarea_parent | bridge_pnp_ofs);
+
+		debug("  IOAREA PARENT: 0x%08x\n", ioarea_parent);
+		debug("  BRIDGE PNP: 0x%08x\n", ahbinfo.pnp);
+
+		/* Parse the AHB information */
+		ahbinfo.ahb_bus_index = parent;
+		ambapp_ahb_parse(&ahbinfo, &ahb);
+
+		debug("  BRIDGE ID: VENDOR=%d(0x%x), DEVICE=%d(0x%x)\n", 
+			ahb.vendor, ahb.vendor, ahb.device, ahb.device);
+
+		/* Different bridges may convert frequency differently */
+		if ( (ahb.vendor == VENDOR_GAISLER) &&
+			((ahb.device == GAISLER_AHB2AHB) ||
+			(ahb.device == GAISLER_L2CACHE)) ) {
+			/* Get new frequency */
+			if ( ahb.ver > 1 ) {
+				freq = gaisler_ahb2ahb_v2_freq(&ahb, freq);
+			} else {
+				freq = gaisler_ahb2ahb_v1_freq(&ahb, freq);
+			}
+			debug("  NEW FREQ: %dHz\n", freq);
+		} else {
+			printf("ambapp_bus_freq: unsupported AMBA bridge\n");
+			while(1) ;
+		}
+
+		/* Step upwards towards system top bus */
+		ahb_bus_index = parent;
+	}
+#endif
+
+	debug("ambapp_bus_freq: %dHz\n", freq);
+
+	return freq;
 }
diff --git a/cpu/leon3/ambapp_low.S b/cpu/leon3/ambapp_low.S
new file mode 100644
index 0000000..bbf2d01
--- /dev/null
+++ b/cpu/leon3/ambapp_low.S
@@ -0,0 +1,798 @@
+/* GRLIB AMBA Plug&Play information scanning implemented without
+ * using memory (stack) and one register window. The code scan
+ * the PnP info and inserts the AHB bridges/buses into register
+ * i0-i5.
+ * The code support 
+ *  - up to 6 AHB buses
+ *  - multiple APB buses
+ *  - support for AHB2AHB & L2CACHE bridges
+ *
+ * (C) Copyright 2010
+ * Daniel Hellstrom, Aeroflex Gaisler, daniel at gaisler.com.
+ *
+ * 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 <ambapp.h>
+
+	.seg	"text"
+	.globl	_nomem_amba_init
+	.globl	_nomem_ambapp_find_buses
+	.globl	_nomem_find_apb
+	.globl	_nomem_find_ahb
+
+/* Overview
+ * ========
+ *
+ * _nomem_amba_init         - Init AMBA bus and calls _nomem_ambapp_find_buses
+ * _nomem_ambapp_find_buses - Scan AMBA PnP info for AHB buses/bridges and 
+ *                            place them in i0-i5, see below
+ * _nomem_find_apb          - Find one APB device identified by VENDOR:DEVICE
+ *                            ID and an index.
+ * _nomem_find_ahb          - Find one AHB Master or Slave device identified 
+ *                            by VENDOR:DEVICE ID and an index.
+ * init_ahb_bridges         - Local function. Clears i0-i5
+ * insert_ahb_bridge        - Local function. Insert a new AHB bus into first
+ *                            free register in i0-i5. It also checks that the
+ *                            bus has not already been added.
+ * get_ahb_bridge           - Local function. Get AHB bus from registers, 
+ *                            return register iN, where N is defined by o0.
+ *
+ * The _nomem_find_apb and _nomem_find_ahb function requires that i0-i5
+ * are populated with the AHB buses of the system. The registers are 
+ * initialized by _nomem_ambapp_find_buses.
+ *
+ * AHB Bus result and requirements of i0-i5
+ * ========================================
+ *
+ * i0: AHB BUS0 IOAREA, no parent bus
+ * i1: AHB BUS1 IOAREA, parent bus is always i0 (AHB BUS0) and bridge address
+ * i2: AHB BUS2 IOAREA, 3-bit parent bus number and bridge address
+ * i3: AHB BUS3 IOAREA, 3-bit parent bus number and bridge address
+ * i4: AHB BUS4 IOAREA, 3-bit parent bus number and bridge address
+ * i5: AHB BUS5 IOAREA, 3-bit parent bus number and bridge address
+ *
+ * AHB BUS
+ * -------
+ * Bits 31-20 (0xfff00000) contain the found bus I/O Area (AHB PnP area).
+ *
+ * 3-bit Parent bus
+ * ----------------
+ * Bits 2-0 (0x00000007) contain parent bus number. Zero if no parent
+ * bus, 1 = parent is AHB BUS 0 (i0), 2 = parent is AHB BUS 1 (i1)..
+ * 
+ * Bridge Address
+ * --------------
+ * Bits 10-5 (0x000007e0) contain the index of the Bridge's PnP 
+ * information on the parent. Since all bridges are found in the
+ * PnP information they all have a PnP entry. Together with the
+ * parent bus number the PnP entry can be found:
+ *  PnPEntry = (BRIDGE_ADDRESS + (iN & 0xfff00000)) | 0x000ff800
+ *  where N is the parent bus minus one.
+ *
+ */
+
+/* Function initializes the AHB Bridge I/O AREA storage. (Clears i0-i5)
+ *
+ * Arguments
+ *  none
+ * 
+ * Results
+ *  none
+ *
+ * Clobbered
+ *  none
+ */
+
+init_ahb_bridges:
+	mov	%g0, %i0
+	mov	%g0, %i1
+	mov	%g0, %i2
+	mov	%g0, %i3
+	mov	%g0, %i4
+	retl
+	 mov	%g0, %i5
+
+/* Function returns AHB Bridge I/O AREA for specified bus. 
+ *
+ * Arguments
+ *  - o0 = bus number
+ * 
+ * Results
+ *  - o0 = I/O AREA
+ *
+ * Clobbered
+ *  none
+ */
+get_ahb_bridge:
+	cmp	%o0, 1
+	be,a	L1
+	 mov	%i0, %o0
+
+	cmp	%o0, 2
+	be,a	L1
+	 mov	%i1, %o0
+
+	cmp	%o0, 3
+	be,a	L1
+	 mov	%i2, %o0
+
+	cmp	%o0, 4
+	be,a	L1
+	 mov	%i3, %o0
+
+	cmp	%o0, 5
+	be,a	L1
+	 mov	%i4, %o0
+
+	cmp	%o0, 6
+	be,a	L1
+	 mov	%i5, %o0
+
+	/* o0 > 6: only 6 buses supported */
+	mov	%g0, %o0
+L1:
+	retl
+	 nop
+
+/* Function adds a AHB Bridge I/O AREA to the i0-i5 registers if
+ * not already added. It stores the bus PnP start information.
+ *
+ * Arguments
+ *  - o0 = AHB Bridge I/O area
+ * 
+ * Results
+ *  none
+ *
+ * Clobbered
+ *  o2, o3
+ */
+insert_ahb_bridge:
+	/* Check that bridge hasn't already been added */
+	andn	%o0, 0x7ff, %o2
+	andn	%i0, 0x7ff, %o3
+	cmp	%o3, %o2
+	be	L2
+	 andn	%i1, 0x7ff, %o3
+	cmp	%o3, %o2
+	be	L2
+	 andn	%i2, 0x7ff, %o3
+	cmp	%o3, %o2
+	be	L2
+	 andn	%i3, 0x7ff, %o3
+	cmp	%o3, %o2
+	be	L2
+	 andn	%i4, 0x7ff, %o3
+	cmp	%o3, %o2
+	be	L2
+	 andn	%i5, 0x7ff, %o3
+	cmp	%o3, %o2
+	be	L2
+
+	/* Insert into first free posistion */
+	 cmp	%i0, %g0
+	be,a	L2
+	 mov	%o0, %i0
+
+	cmp	%i1, %g0
+	be,a	L2
+	 mov	%o0, %i1
+
+	cmp	%i2, %g0
+	be,a	L2
+	 mov	%o0, %i2
+
+	cmp	%i3, %g0
+	be,a	L2
+	 mov	%o0, %i3
+
+	cmp	%i4, %g0
+	be,a	L2
+	 mov	%o0, %i4
+
+	cmp	%i5, %g0
+	be,a	L2
+	 mov	%o0, %i5
+L2:
+	retl
+	 nop
+
+/* FUNCTION int _nomem_find_ahb_bus(
+ *	unsigned int bridge,
+ *	int vendor_device,
+ *	int index,
+ *	void **pconf,
+ *	int not_used,
+ *	int option
+ *	)
+ *
+ * Scans the AHB Master or Slave area for a matching VENDOR:DEVICE, the 
+ * index is decremented when a matching device is found but index is 
+ * greater than zero. When index is zero and a matching DEVICE:VENDOR
+ * is found the AHB configuration address and AHB I/O area is returned.
+ *
+ * i0-i7,l0,l1,l2,l3,l4,g2,o6 is not available for use.
+ * o1,o5 Must be left untouched
+ *
+ * Results
+ *  - o0 Number of found devices (1 or 0)
+ *  - o2 is decremented for each matching VENDOR:DEVICE found, zero if found
+ *  - o3 Address of the AHB PnP configuration entry (Only valid if o0=1)
+ *
+ * Clobbered
+ *  - o3 (Clobbered when no device was found)
+ *  - o4 (Number of Devices left to search)
+ *  - o0 (Bus ID, PnP ID, Device)
+ */
+_nomem_find_ahb_bus:
+
+	/* Get number of Slaves/Masters. Only AHB Bus 0 has 64 AHB Masters/Slaves 
+	 * the other AHB buses has 16 slaves and 16 masters.
+	 */
+	add	%g0, 16, %o4		/* Defaulting to 16 */
+	andcc	%o0, 0x7, %g0		/* 3-bit bus id */
+	be,a	.L_maxloops_detected
+	 add	%g0, 64, %o4		/* AHB Bus 0 has 64 AHB Masters and Slaves */
+.L_maxloops_detected:
+
+	/* Get start address of AHB Slave or AHB Master area depending on what
+	 * we are searching for.
+	 */
+	andn	%o0, 0x7ff, %o0		/* Remove Bus ID and 5-bit AHB/AHB Bridge PnP Address to get I/O Area */
+	set	AMBA_CONF_AREA, %o3
+	or	%o3, %o0, %o3		/* Master area address */
+
+	cmp	%o5, DEV_AHB_SLV
+	be,a	.L_conf_area_calculated
+	 or	%o3, AMBA_AHB_SLAVE_CONF_AREA, %o3	/* Add 0x800 to get to slave area */
+.L_conf_area_calculated:
+
+	/* Iterate over all AHB device and try to find matching DEVICE:VENDOR 
+	 * o1 - VENDOR|DEVICE
+	 * o2 - Index
+	 * o3 - Current AHB Device Configuration address
+	 * o5 - Type (leave untouched)
+	 * 
+	 * o4 - Number of AHB device left to process
+	 * o0 - tmp
+	 */
+.L_process_one_conf:
+	ld	[%o3], %o0
+	andn	%o0, 0xfff, %o0
+	cmp	%o0, 0			/* No device if zero */
+	beq	.L_next_conf
+	 cmp	%o1, 0 			/* If VENDOR:DEVICE==0, consider all matching */
+	beq	.L_process_ahb_dev_found
+	 cmp	%o0, %o1		/* Does VENDOR and DEVICE Match? */
+	bne	.L_next_conf
+	 nop
+.L_process_ahb_dev_found:
+	/* Found a Matching VENDOR:DEVICE, index must also match */
+	cmp	%o2, %g0
+	bne	.L_next_conf
+	 dec	%o2
+	/* Index matches also, return happy with o3 set to AHB Conf Address */
+	mov	%g0, %o2
+	retl
+	 add	%g0, 1, %o0
+
+.L_next_conf:
+	subcc	%o4, 1, %o4			/* One device has been processed, Are there more devices to process? */
+	bne	.L_process_one_conf
+	 add	%o3, AMBA_AHB_CONF_LENGH, %o3	/* Next Configuration entry */
+	/* No Matching device found */
+	retl
+	 mov	%g0, %o0
+
+/* FUNCTION int _nomem_find_ahb(
+ *      int unused,
+ *	int vendor_device,
+ *	int index,
+ *	void **pconf,
+ *	int *ahb_bus_index,
+ *	int option,
+ *	)
+ * 
+ * Find a AHB Master or AHB Slave device, it puts the address of the AHB PnP
+ * configuration in o3 (pconf), the I/O Area base address in o4 (pioarea).
+ *
+ * Calls _nomem_find_ahb_bus for every AHB bus.
+ *
+ * i0-i7, l0, l1, o6, g1, g4-g7 is not available for use.
+ *
+ * Arguments
+ *  - o0 Unused
+ *
+ * Results
+ *  - o0 Number of found devices (1 or 0)
+ *  - o2 Decremented Index (Zero if found)
+ *  - o3 Address of the AHB PnP configuration entry
+ *  - o4 AHB Bus index the device was found on (if o0=1)
+ *  - o5 Left untouched
+ *
+ * Clobbered
+ *  - o0 (AHB Bridge and used by _nomem_find_ahb_bus)
+ *  - o2 (index is decremented)
+ *  - l2 (Current AHB Bus index)
+ *  - g2 (return address)
+ */
+_nomem_find_ahb:
+	mov	%o7, %g2		/* Save return address */
+	/* Scan all AHB Buses found for the AHB Master/Slave matching VENDOR:DEVICE */
+	clr	%l2
+.L_search_next_ahb_bus:
+	add	%l2, 1, %l2
+	call	get_ahb_bridge			/* Get bus %l0 I/O Area */
+	 mov	%l2, %o0
+	cmp	%o0, %g0
+	be	.L_no_device_found		/* If no more AHB bus is left to be scanned, proceed */
+	 nop
+	call	_nomem_find_ahb_bus		/* Scan AHB bus %o0 for VENDOR:DEVICE. Index in o3 is decremented  */
+	 nop
+	cmp	%o0, %g0			/* If VENDOR:DEVICE was not found scan next AHB Bus */
+	be	.L_search_next_ahb_bus		/* Do next bus is o0=0 (not found) */
+	 nop
+	/* The device was found, o0 is 1 */
+	mov	%g2, %o7		/* Restore return address */
+	retl
+	 mov	%l2, %o4		/* The AHB bus index the device was found on */
+
+	/* No device found matching */
+.L_no_device_found:
+	mov	%g2, %o7		/* Restore return address */
+	retl
+	 mov	%g0, %o0
+
+
+/* FUNCTION int _nomem_find_apb_bus(
+ *      int apbmst,
+ *	int vendor_device,
+ *	int index,
+ *	void **pconf
+ *	)
+ * 
+ * Find a APB Slave device, it puts the address of the APB PnP configuration 
+ * in o3 (pconf).
+ *
+ * Calls _nomem_find_ahb_bus for every AHB bus searching for AHB/APB Bridges.
+ * The AHB/APB bridges are AHB Slaves with ID GAISLER_APBMST.
+ *
+ * Results
+ *  - o0 Number of found devices (1 or 0)
+ *  - o2 Decremented Index
+ *  - o3 Address of the found APB device PnP configuration entry
+ *
+ * Clobbered
+ *  - o5 PnP VENDOR:DEVICE ID
+ */
+
+_nomem_find_apb_bus:
+	set	AMBA_CONF_AREA, %o3
+	or	%o0, %o3, %o3		/* Calc start of APB device PnP info */
+	add	%g0, 16, %o0		/* o0, number of APB Slaves left to scan */
+.L_process_one_apb_conf:
+	ld	[%o3], %o5
+	andn	%o5, 0xfff, %o5
+	cmp	%o5, 0			/* No device if zero */
+	beq	.L_process_apb_dev_not_found
+	 cmp	%o1, 0			/* If VENDOR:DEVICE == -1, consider all matching */
+	beq	.L_process_apb_dev_found
+	 cmp	%o1, %o5		/* Found VENDOR:DEVICE */
+	bne	.L_process_apb_dev_not_found
+	 nop
+
+.L_process_apb_dev_found:
+	/* Found matching device, compare index */
+	cmp	%o2, %g0
+	bne	.L_process_apb_dev_not_found
+	 dec	%o2
+	/* Matching index and VENDOR:DEVICE */
+	retl
+	 add	%g0, 1, %o0
+
+.L_process_apb_dev_not_found:
+	subcc	%o0, 1, %o0
+	bne	.L_process_one_apb_conf
+	 add	%o3, 8, %o3
+	retl
+	 mov	%g0, %o0
+
+/* FUNCTION int _nomem_find_apb(
+ *      int unused,
+ *	int vendor_device,
+ *	int index,
+ *	void **pconf,
+ *	int *ahb_bus_index
+ *	)
+ * 
+ * Find a APB Slave device, it puts the address of the APB PnP configuration 
+ * in o3 (pconf), the APB Master I/O Area base address in o4 (papbarea).
+ *
+ * Calls _nomem_find_ahb_bus for every AHB bus searching for AHB/APB Bridges.
+ * The AHB/APB bridges are AHB Slaves with ID GAISLER_APBMST.
+ *
+ * i0-i7, l0, l1, o6 is not available for use.
+ *
+ * Arguments
+ *  - o0 Unused
+ *
+ * Results
+ *  - o0 Number of found devices (1 or 0)
+ *  - o2 Decremented Index if not found
+ *  - o3 Address of the APB PnP configuration entry
+ *  - o4 AHB Bus index of APB Bridge/APB Device
+ *
+ * Clobbered
+ *  - o0 (AHB Bridge)
+ *  - o2 (index is decremented)
+ *  - l2 (APB DEV Index [7..4] : APBMST AHB Index [3..0])
+ *  - l3 (Current AHB Bus index)
+ *  - l4 (temporary storage for APB VENDOR:DEVICE)
+ *  - o5 (AHB Slave ID)
+ *  - o0 (clobbered by _nomem_find_ahb_bus)
+ *  - g2 (Return address)
+ */
+_nomem_find_apb:
+	/* Scan all AHB Buses found for AHB/APB Bridges */
+	mov	%o7, %g2		/* Save return address */
+	mov	%o1, %l4		/* Save APB VENDOR:DEVICE */
+	sll	%o2, 4, %l2		/* APB MST index = 0 */
+	add	%g0, 1, %l3		/* AHB Bus index = 0 */
+.L2_search_next_ahb_bus:
+	call	get_ahb_bridge		/* Get bus %l3 I/O Area */
+	 mov	%l3, %o0
+	cmp	%o0, %g0
+	be	.L2_no_device_found	/* If no more AHB bus is left to be scanned, proceed */
+	 add	%g0, DEV_AHB_SLV, %o5	/* Search for AHB Slave */
+	sethi	%hi(AMBA_PNP_ID(VENDOR_GAISLER, GAISLER_APBMST)), %o1
+	call	_nomem_find_ahb_bus	/* Scan AHB bus %o0 for VENDOR:DEVICE. Index in o3 is decremented  */
+	 and	%l2, 0xf, %o2		/* Set APBMST index */
+	cmp	%o0, %g0		/* If no AHB/APB Bridge was not found, scan next AHB Bus */
+	be	.L_no_apb_bridge_found	/* Do next bus */
+	 nop
+
+	/* The AHB/APB Bridge was found.
+         * Search for the requested APB Device on the APB bus using
+	 * find_apb_bus, it will decrement the index.
+         */
+	ld	[%o3 + AMBA_AHB_MBAR0_OFS], %o3
+	sll	%o3, 16, %o0
+	and	%o0, %o3, %o0		/* Address AND Address Mask */
+	sethi	%hi(0xfff00000), %o3
+	and	%o0, %o3, %o0		/* AHB/APB Bridge address */
+
+	srl	%l2, 4, %o2		/* APB DEV Index */
+	call	_nomem_find_apb_bus
+	 mov	%l4, %o1		/* APB VENDOR:DEVICE */
+	cmp	%o0, %g0
+	be	.L_apb_dev_not_found
+	 mov	%g2, %o7		/* Restore return address */
+	/* APB Device found
+	 * o0 1
+	 * o2 Index is decremented to zero
+	 * o3 APB configuration address,
+	 * o4 APB Bridge Configuration address.
+	 */
+	mov	%g0, %o2
+	retl
+	 mov	%l3, %o4
+
+.L_apb_dev_not_found:
+	/* Update APB DEV Index by saving output from find_apb_bus
+	 * (index parameter) into bits [31..4] in L2.
+	 */
+	sll	%o2, 4, %o2
+	and	%l2, 0xf, %l2
+	or	%o2, %l2, %l2
+	/* Try finding the next AHB/APB Bridge on the same AHB bus
+	 * to find more APB devices
+	 */
+	ba	.L2_search_next_ahb_bus	/* Find next AHB/APB bridge */
+	 inc	%l2
+
+.L_no_apb_bridge_found:
+	inc	%l3			/* Next AHB Bus */
+	ba	.L2_search_next_ahb_bus	/* Process next AHB bus */
+	 andn	%l2, 0xf, %l2		/* Start at APB Bridge index 0 at every AHB Bus */
+	/* No device found matching */
+.L2_no_device_found:
+	mov	%g2, %o7		/* Restore return address */
+	srl	%l2, 4, %o2		/* APB DEV Index */
+	retl
+	 mov	%g0, %o0
+
+
+
+/* FUNCTION _nomem_amba_scan_gaisler_ahb2ahb_bridge(unsigned int bridge, int bus)
+ *
+ * Constraints:
+ *   - o1 may not be used
+ *   - o0, o2, o3 may be used.
+ *
+ * Arguments
+ *  - o0 PnP Address of Bridge AHB device
+ *  - o2 PnP ID of AHB device
+ *
+ * Results
+ *  - o0 Address of new bus PnP area or a 1 if AHB device is no bridge
+ *
+ * Clobbered
+ *   - o0, o2
+ *
+ */
+_nomem_amba_scan_gaisler_ahb2ahb_bridge:
+	andn	%o2, 0xfff, %o2
+	sethi	%hi(AMBA_PNP_ID(VENDOR_GAISLER,GAISLER_AHB2AHB)), %o3
+	cmp	%o2, %o3
+	beq	.L_is_ahb2ahb_bridge
+	 nop
+
+	retl
+	 add	%g0, 1, %o0
+
+.L_is_ahb2ahb_bridge:
+	/* Found a GAISLER AHB2AHB bridge */
+	retl
+	 ld	[%o0 + AMBA_AHB_CUSTOM1_OFS], %o0 /* Get address of bridge PnP area */
+
+
+/* FUNCTION _nomem_amba_scan_gaisler_l2cache_bridge(unsigned int bridge, int bus)
+ *
+ * Constraints:
+ *   - o1 may not be used
+ *   - o0, o2, o3 may be used.
+ *
+ * Arguments
+ *  - o0 PnP Address of Bridge AHB device
+ *  - o2 PnP ID of AHB device
+ *
+ * Results
+ *  - o0 Address of new bus PnP area or a 1 if AHB device is no bridge
+ *
+ * Clobbered
+ *   - o0, o2
+ *
+ */
+_nomem_amba_scan_gaisler_l2cache_bridge:
+	andn	%o2, 0xfff, %o2
+	sethi	%hi(AMBA_PNP_ID(VENDOR_GAISLER,GAISLER_L2CACHE)), %o3
+	cmp	%o2, %o3
+	beq	.L_is_l2cache_bridge
+	 nop
+
+	retl
+	 add	%g0, 1, %o0
+
+.L_is_l2cache_bridge:
+	/* Found a GAISLER l2cache bridge */
+	retl
+	 ld	[%o0 + AMBA_AHB_CUSTOM1_OFS], %o0 /* Get address of bridge PnP area */
+
+
+/* FUNCTION _nomem_amba_scan(unsigned int bridge, int bus)
+ * 
+ * Constraints:
+ *  i0-i7, l0 is used by caller
+ *  o5-o7 may not be used.
+ *
+ * Arguments
+ *  - o0 Bridge Information: I/O AREA and parent bus
+ *  - o1 Bus
+ *
+ * Results
+ *  - o0 Number of AHB bridges found
+ *
+ * Clobbered
+ *  - o0 (Current AHB slave conf address)
+ *  - o2 (Used by insert_bridge)
+ *  - o3 (Used by insert_bridge)
+ *  - l1 (Number of AHB Slaves left to process)
+ *  - l2 (Current AHB slave conf address)
+ *  - g2 (Return address)
+ */
+_nomem_amba_scan:
+	mov	%o7, %g2	/* Save return address */
+	set	16, %l1	
+	cmp	%o1, 1
+	be,a	.L2_maxloops_detected
+	 add	%g0, 64, %l1
+.L2_maxloops_detected:
+
+	/* Clear 3-bit parent bus from bridge to get I/O AREA, then or
+	 * (AMBA_CONF_AREA | AMBA_AHB_SLAVE_CONF_AREA) to get first AHB slave
+	 * conf address.
+	 */
+	andn	%o0, 0x7ff, %o0
+	set	(AMBA_CONF_AREA | AMBA_AHB_SLAVE_CONF_AREA), %l2
+	or	%o0, %l2, %l2
+
+	/* Scan AHB Slave area for AHB<->AHB bridges. For each AHB device
+	 * all "bridge drivers" are called, the driver function interface:
+	 *
+	 * Input: 
+	 *   - o0 PnP Address of Bridge AHB device
+	 *   - o2 PnP ID of AHB device
+	 * Return values:
+	 *   - o0 Address of new bus PnP area, returning a 1 in o2 means not found
+	 *
+	 * Constraints:
+	 *   - o1 may not be used
+	 *   - o0, o2, o3 may be used.
+	 *
+	 */
+.L_scan_one_ahb_slave:
+	ld	[%l2], %o2
+
+	cmp	%o2, %g0
+	beq	.L_scan_next_ahb_slave
+	 nop
+
+	/* Call the GAISLER AHB2AHB bridge driver */
+	call	_nomem_amba_scan_gaisler_ahb2ahb_bridge
+	 mov	%l2, %o0
+	cmp	%o0, 1
+	bne	.L_found_bridge
+	 ld	[%l2], %o2
+
+	/* Call the GAISLER L2CACHE bridge driver */
+	call	_nomem_amba_scan_gaisler_l2cache_bridge
+	 mov	%l2, %o0
+	cmp	%o0, 1
+	bne	.L_found_bridge
+	 ld	[%l2], %o2
+
+	/* Insert next bridge "driver" function here */
+
+
+	/* The PnP ID did not match a bridge - a new bus was not found ==> 
+	 * step to next AHB device */
+	ba	.L_scan_next_ahb_slave
+	 nop
+
+	/* Add Found bus */
+.L_found_bridge:
+	and	%l2, 0x7e0, %o2
+	or	%o2, %o0, %o0		/* Add AHB/AHB Bridge PnP address */
+	call	insert_ahb_bridge	/* Insert Bridge into found buses storage */
+	 or	%o1, %o0, %o0		/* Add parent bus LSB 3-bits */
+
+.L_scan_next_ahb_slave:
+	/* More Slaves to process? */
+	subcc	%l1, 1, %l1
+	bne	.L_scan_one_ahb_slave
+	 add	%l2, AMBA_AHB_CONF_LENGH, %l2
+
+	/* No more AHB devices to process */
+	mov	%g2, %o7	/* Restore return address */
+	retl
+	 nop
+
+/* FUNCTION _nomem_ambapp_find_buses(unsigned int ioarea)
+ * 
+ * Find AMBA AHB buses.
+ *
+ * Constraints:
+ *  i6-i7, l7 is used by caller
+ *
+ * Arguments
+ *  - o0 Bridge Information: I/O AREA and parent bus
+ *
+ * Results
+ *  - o0 Number of AHB bridges found
+ *  - i0-i5 initialized
+ *
+ * Clobbered
+ *  - o0 (Current AHB slave conf address)
+ *  - o2 (Used by insert_bridge)
+ *  - o3 (Used by insert_bridge)
+ *  - l0 (Current AHB Bus)
+ *  - l1 (Used by nomem_amba_scan)
+ *  - l2 (Used by nomem_amba_scan)
+ *  - l3 (Used by nomem_amba_scan)
+ *  - l4 (Used by nomem_amba_scan)
+ *
+ *  - g1 (level 1 return address)
+ *  - g2 (Used by nomem_amba_scan)
+ */
+_nomem_ambapp_find_buses:
+	mov	%o7, %g1	/* Save return address */
+
+	/* Initialize AHB Bus storage */
+	call	init_ahb_bridges
+	 nop
+
+	/* Insert AHB Bus 0 */
+	call	insert_ahb_bridge
+	 nop			/* Argument already prepared by caller */
+
+	/* Scan AHB Bus 0 for AHB Bridges */
+	call	_nomem_amba_scan
+	 add	%g0, 1, %o1
+
+	/* Scan all AHB Buses found for more AHB Bridges */
+	add	%g0, 2, %l0
+.L100_search_next_ahb_bus:
+	call	get_ahb_bridge			/* Get bus %l0 I/O Area */
+	 mov	%l0, %o0
+	cmp	%o0, %g0
+	be	.L100_return			/* If no more AHB bus is left to be scanned, proceed */
+	 nop
+	call	_nomem_amba_scan		/* Scan bus %l0 for AHB Bridges. i0-i7,l0 is used */
+	 mov	%l0, %o1			/* I/O AREA untouched in o0 */
+	ba	.L100_search_next_ahb_bus	/* Do next bus */
+	 add	%l0, 1, %l0
+
+.L100_return:
+	mov	%g1, %o7
+	retl
+	 nop
+
+
+/* FUNCTION _nomem_amba_init(unsigned int ioarea)
+ * 
+ *  Find all AHB buses
+ *
+ * Constraints:
+ *  i6, i7, o6, o7, l7, l6, g3, g4, g5, g6, g7 is used by caller
+ *
+ * Arguments
+ *  - o0 Bridge Information: I/O AREA and parent bus
+ *
+ * Results
+ *  - o0 Number of AHB bridges found
+ *
+ * Clobbered
+ *  - l0, l1, l2, l3, l4, g1, g2 (used by _nomem_ambapp_find_buses)
+ *  - o0, o1, o2, o3 (Used as arguments)
+ *  - o5 (return address)
+ *  - g1 (level 1 return address)
+ *  - g2 (level 2 return address)
+ */
+_nomem_amba_init:
+	mov	%o7, %o5	/* Save return address, o5 not used */
+
+	/* Scan for buses, it will init i0-i5 */
+	call	_nomem_ambapp_find_buses
+	 nop
+
+	mov	%o5, %o7
+	retl
+	 nop
+
+/* Call tree and their return address register
+ *
+ *_nomem_amba_scan           (g1)
+ * -> init_ahb_bridges       (o7)
+ * -> insert_ahb_bridge      (o7)
+ * -> _nomem_amba_scan       (g2)
+ *    -> insert_ahb_bridge   (o7)
+ * -> get_ahb_bridge         (o7)
+ *
+ *
+ * -> _nomem_find_apb        (g2)
+ *    -> get_ahb_bridge      (o7)
+ *    -> _nomem_find_ahb_bus (o7)
+ *    -> _nomem_find_apb_bus (o7)
+ * -> _nomem_find_ahb        (g2)
+ *    -> get_ahb_bridge      (o7)
+ *    -> _nomem_find_ahb_bus (o7)
+ * -> mem_handler.func()     (o7)
+ * 
+ */
diff --git a/cpu/leon3/ambapp_low_c.S b/cpu/leon3/ambapp_low_c.S
new file mode 100644
index 0000000..4ca6d55
--- /dev/null
+++ b/cpu/leon3/ambapp_low_c.S
@@ -0,0 +1,133 @@
+/* C-interface for AMBA PnP scanning functions implemented in 
+ * ambapp_low.S. At the point the memory and stack can be 
+ * used.
+ *
+ * (C) Copyright 2010
+ * Daniel Hellstrom, Aeroflex Gaisler, daniel at gaisler.com.
+ *
+ * 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
+ *
+ */
+
+
+	.seg	"text"
+	.extern	_nomem_ambapp_find_buses
+	.extern	_nomem_find_apb
+	.extern	_nomem_find_ahb
+
+	.globl	ambapp_find_buses
+	.globl	ambapp_find_apb
+	.globl	ambapp_find_ahb
+
+
+/* C-interface for _nomem_ambapp_find_buses used when memory is
+ * available.
+ */
+ambapp_find_buses:
+	save	%sp, -104, %sp
+	mov	%i1, %l7	/* Save second argument */
+	call _nomem_ambapp_find_buses
+	 mov	%i0, %o0
+
+	/* Store result */
+	st	%g0, [%l7+0x00]
+	st	%i0, [%l7+0x04]
+	st	%i1, [%l7+0x08]
+	st	%i2, [%l7+0x0c]
+	st	%i3, [%l7+0x10]
+	st	%i4, [%l7+0x14]
+	st	%i5, [%l7+0x18]
+
+	ret
+	 restore
+
+/* C-interface for _nomem_find_apb used when memory is
+ * available.
+ *
+ * void ambapp_find_apb(
+ *	struct ambapp_bus *abus,
+ *	unsigned int dev_vend,
+ *	int index,
+ *	struct ambapp_find_apb_info *result
+ *	);
+ *
+ */
+ambapp_find_apb:
+	save	%sp, -104, %sp
+
+	mov	%i3, %l7	/* Save second argument */
+	mov	%i1, %o1
+	mov	%i2, %o2
+
+	/* Initialize buses available in system */
+	ld	[%i0+0x08], %i1
+	ld	[%i0+0x0c], %i2
+	ld	[%i0+0x10], %i3
+	ld	[%i0+0x14], %i4
+	ld	[%i0+0x18], %i5
+
+	call _nomem_find_apb
+	 ld	[%i0+0x04], %i0
+
+	st	%o2, [%l7+0x08]	/* Decremented Index */
+	st	%o3, [%l7]	/* PnP configuration address of APB Device */
+	st	%o4, [%l7+0x04]	/* AHB Bus Index of AHB/APB bridge and APB Device */
+	mov	%o0, %i0
+	ret
+	 restore
+
+/* C-interface for _nomem_find_ahb used when memory is
+ * available.
+ *
+ * void ambapp_find_ahb(
+ *	struct ambapp_bus *abus,
+ *	unsigned int dev_vend,
+ *	int index,
+ *	int type,
+ *	struct ambapp_find_ahb_info *result
+ *	);
+ *
+ */
+ambapp_find_ahb:
+	save	%sp, -104, %sp
+
+	mov	%i4, %l7	/* Save second argument */
+	clr	%o0
+	mov	%i1, %o1
+	mov	%i2, %o2
+	clr	%o3
+	clr	%o4
+	mov	%i3, %o5
+
+	/* Initialize buses available in system */
+	ld	[%i0+0x08], %i1
+	ld	[%i0+0x0c], %i2
+	ld	[%i0+0x10], %i3
+	ld	[%i0+0x14], %i4
+	ld	[%i0+0x18], %i5
+
+	call _nomem_find_ahb
+	 ld	[%i0+0x04], %i0
+
+	st	%o2, [%l7+0x08]	/* Decremented Index */
+	st	%o3, [%l7]	/* PnP configuration address of AHB Device */
+	st	%o4, [%l7+0x04]	/* AHB Bus Index of AHB Device */
+	mov	%o0, %i0
+	ret
+	 restore
diff --git a/cpu/leon3/cpu_init.c b/cpu/leon3/cpu_init.c
index be22ec2..046cfb8 100644
--- a/cpu/leon3/cpu_init.c
+++ b/cpu/leon3/cpu_init.c
@@ -31,6 +31,11 @@
 
 #include <config.h>
 
+/* Default Plug&Play I/O area */
+#ifndef CONFIG_AMBAPP_IOAREA
+#define CONFIG_AMBAPP_IOAREA AMBA_DEFAULT_IOAREA
+#endif
+
 DECLARE_GLOBAL_DATA_PTR;
 
 /* reset CPU (jump to 0, without reset) */
@@ -53,64 +58,29 @@ struct {
 /*
  * Breath some life into the CPU...
  *
- * Set up the memory map,
- * initialize a bunch of registers.
- *
  * Run from FLASH/PROM:
- *  - until memory controller is set up, only registers avaiable
+ *  - memory controller has already been setup up, stack can be used
  *  - no global variables available for writing
  *  - constants avaiable
  */
-
 void cpu_init_f(void)
 {
-	/* these varaiable must not be initialized */
-	ambapp_dev_irqmp *irqmp;
-	ambapp_apbdev apbdev;
-	register unsigned int apbmst;
-
-	/* find AMBA APB Master */
-	apbmst = (unsigned int)
-	    ambapp_ahb_next_nomem(VENDOR_GAISLER, GAISLER_APBMST, 1, 0);
-	if (!apbmst) {
-		/*
-		 * no AHB/APB bridge, something is wrong
-		 * ==> jump to start (or hang)
-		 */
-		while (1) ;
-	}
-	/* Init memory controller */
-	if (init_memory_ctrl()) {
-		while (1) ;
-	}
-
-	/****************************************************
-	 * From here we can use the main memory and the stack.
-	 */
 
-	/* Find AMBA APB IRQMP Controller */
-	if (ambapp_apb_first(VENDOR_GAISLER, GAISLER_IRQMP, &apbdev) != 1) {
-		/* no IRQ controller, something is wrong
-		 * ==> jump to start (or hang)
-		 */
-		while (1) ;
-	}
-	irqmp = (ambapp_dev_irqmp *) apbdev.address;
-
-	/* initialize the IRQMP */
-	irqmp->ilevel = 0xf;	/* all IRQ off */
-	irqmp->iforce = 0;
-	irqmp->ipend = 0;
-	irqmp->iclear = 0xfffe;	/* clear all old pending interrupts */
-	irqmp->cpu_mask[0] = 0;	/* mask all IRQs on CPU 0 */
-	irqmp->cpu_force[0] = 0;	/* no force IRQ on CPU 0 */
-
-	/* cache */
 }
 
+/* Routine called from start.S, 
+ *
+ * Run from FLASH/PROM:
+ *  - memory controller has already been setup up, stack can be used
+ *  - global variables available for read/writing
+ *  - constants avaiable
+ */
 void cpu_init_f2(void)
 {
-
+	/* Initialize the AMBA Plug & Play bus structure, the bus
+	 * structure represents the AMBA bus that the CPU is located at.
+	 */
+	ambapp_bus_init(CONFIG_AMBAPP_IOAREA, CONFIG_SYS_CLK_FREQ, &ambapp_plb);
 }
 
 /*
@@ -119,95 +89,59 @@ void cpu_init_f2(void)
 int cpu_init_r(void)
 {
 	ambapp_apbdev apbdev;
+	int index, cpu;
+	ambapp_dev_gptimer *timer = NULL;
+	unsigned int bus_freq;
 
 	/*
 	 * Find AMBA APB IRQMP Controller,
-	 * When we come so far we know there is a IRQMP available
 	 */
-	ambapp_apb_first(VENDOR_GAISLER, GAISLER_IRQMP, &apbdev);
-	irqmp = (ambapp_dev_irqmp *) apbdev.address;
-
-	/* timer */
-	if (ambapp_apb_first(VENDOR_GAISLER, GAISLER_GPTIMER, &apbdev) != 1) {
-		printf("cpu_init_r: gptimer not found!\n");
-		return 1;
-	}
-	gptimer = (ambapp_dev_gptimer *) apbdev.address;
-	gptimer_irq = apbdev.irq;
-
-	/* initialize prescaler common to all timers to 1MHz */
-	gptimer->scalar = gptimer->scalar_reload =
-	    (((CONFIG_SYS_CLK_FREQ / 1000) + 500) / 1000) - 1;
-
-	return (0);
-}
-
-/* find & setup memory controller */
-int init_memory_ctrl()
-{
-	register ambapp_dev_mctrl *mctrl;
-	register ambapp_dev_sdctrl *sdctrl;
-	register ambapp_dev_ddrspa *ddrspa;
-	register ambapp_dev_ddr2spa *ddr2spa;
-	register ahbctrl_pp_dev *ahb;
-	register unsigned int base;
-	register int not_found_mctrl = -1;
-
-	/* find ESA Memory controller */
-	base = ambapp_apb_next_nomem(VENDOR_ESA, ESA_MCTRL, 0);
-	if (base) {
-		mctrl = (ambapp_dev_mctrl *) base;
-
-		/* config MCTRL memory controller */
-		mctrl->mcfg1 = CONFIG_SYS_GRLIB_MEMCFG1 | (mctrl->mcfg1 & 0x300);
-		mctrl->mcfg2 = CONFIG_SYS_GRLIB_MEMCFG2;
-		mctrl->mcfg3 = CONFIG_SYS_GRLIB_MEMCFG3;
-		not_found_mctrl = 0;
+	if ( ambapp_apb_find(&ambapp_plb, VENDOR_GAISLER, 
+		GAISLER_IRQMP, 0, &apbdev) != 1 ) {
+		printf("cpu_init_r: IRQ controller not found\n");
+		while (1) ;
 	}
+	irqmp = (ambapp_dev_irqmp *) apbdev.address;
 
-	/* find Gaisler Fault Tolerant Memory controller */
-	base = ambapp_apb_next_nomem(VENDOR_GAISLER, GAISLER_FTMCTRL, 0);
-	if (base) {
-		mctrl = (ambapp_dev_mctrl *) base;
-
-		/* config MCTRL memory controller */
-		mctrl->mcfg1 = CONFIG_SYS_GRLIB_FT_MEMCFG1 | (mctrl->mcfg1 & 0x300);
-		mctrl->mcfg2 = CONFIG_SYS_GRLIB_FT_MEMCFG2;
-		mctrl->mcfg3 = CONFIG_SYS_GRLIB_FT_MEMCFG3;
-		not_found_mctrl = 0;
+	/* initialize the IRQMP */
+	irqmp->ilevel = 0xf;	/* all IRQ off */
+	irqmp->iforce = 0;
+	irqmp->ipend = 0;
+	irqmp->iclear = 0xfffe;	/* clear all old pending interrupts */
+	for (cpu=0; cpu<16; cpu++) {
+		/* mask and clear force for all IRQs on CPU[N] */
+		irqmp->cpu_mask[cpu] = 0;	
+		irqmp->cpu_force[cpu] = 0;
 	}
 
-	/* find SDRAM controller */
-	base = ambapp_apb_next_nomem(VENDOR_GAISLER, GAISLER_SDCTRL, 0);
-	if (base) {
-		sdctrl = (ambapp_dev_sdctrl *) base;
-
-		/* config memory controller */
-		sdctrl->sdcfg = CONFIG_SYS_GRLIB_SDRAM;
-		not_found_mctrl = 0;
-	}
+	/* timer */
+	index = 0;
+	while (ambapp_apb_find(&ambapp_plb, VENDOR_GAISLER, GAISLER_GPTIMER, 
+		index, &apbdev) == 1)
+	{
+		timer = (ambapp_dev_gptimer *) apbdev.address;
+		if ( gptimer == NULL ) {
+			gptimer = timer;
+			gptimer_irq = apbdev.irq;
+		}
+
+		/* Different buses may have different frequency, the 
+		 * frequency of the bus tell in which frequency the timer
+		 * prescaler operates.
+		 */
+		bus_freq = ambapp_bus_freq(&ambapp_plb, apbdev.ahb_bus_index);
 
-	ahb = ambapp_ahb_next_nomem(VENDOR_GAISLER, GAISLER_DDR2SPA, 1, 0);
-	if (ahb) {
-		ddr2spa = (ambapp_dev_ddr2spa *) ambapp_ahb_get_info(ahb, 1);
+		/* initialize prescaler common to all timers to 1MHz */
+		timer->scalar = timer->scalar_reload =
+		    (((bus_freq / 1000) + 500) / 1000) - 1;
 
-		/* Config DDR2 memory controller */
-		ddr2spa->cfg1 = CONFIG_SYS_GRLIB_DDR2_CFG1;
-		ddr2spa->cfg3 = CONFIG_SYS_GRLIB_DDR2_CFG3;
-		not_found_mctrl = 0;
+		index++;
 	}
-
-	ahb = ambapp_ahb_next_nomem(VENDOR_GAISLER, GAISLER_DDRSPA, 1, 0);
-	if (ahb) {
-		ddrspa = (ambapp_dev_ddrspa *) ambapp_ahb_get_info(ahb, 1);
-
-		/* Config DDR memory controller */
-		ddrspa->ctrl = CONFIG_SYS_GRLIB_DDR_CFG;
-		not_found_mctrl = 0;
+	if ( !gptimer ) {
+		printf("cpu_init_r: gptimer not found!\n");
+		return 1;
 	}
-
-	/* failed to find any memory controller */
-	return not_found_mctrl;
+	return (0);
 }
 
 /* Uses Timer 0 to get accurate
diff --git a/cpu/leon3/serial.c b/cpu/leon3/serial.c
index 4b2fcb8..15c380e 100644
--- a/cpu/leon3/serial.c
+++ b/cpu/leon3/serial.c
@@ -30,6 +30,11 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
+/* Select which UART that will become u-boot console */
+#ifndef CONFIG_SYS_GRLIB_APBUART_INDEX
+#define CONFIG_SYS_GRLIB_APBUART_INDEX 0
+#endif
+
 /* Force cache miss each time a serial controller reg is read */
 #define CACHE_BYPASS 1
 
@@ -48,7 +53,8 @@ int serial_init(void)
 	unsigned int tmp;
 
 	/* find UART */
-	if (ambapp_apb_first(VENDOR_GAISLER, GAISLER_APBUART, &apbdev) == 1) {
+	if (ambapp_apb_find(&ambapp_plb, VENDOR_GAISLER, GAISLER_APBUART,
+		CONFIG_SYS_GRLIB_APBUART_INDEX, &apbdev) == 1) {
 
 		leon3_apbuart = (ambapp_dev_apbuart *) apbdev.address;
 
diff --git a/cpu/leon3/usb_uhci.c b/cpu/leon3/usb_uhci.c
index 8f99e1d..01310e2 100644
--- a/cpu/leon3/usb_uhci.c
+++ b/cpu/leon3/usb_uhci.c
@@ -708,11 +708,11 @@ void handle_usb_interrupt(void)
  */
 int usb_lowlevel_init(void)
 {
-	unsigned char temp;
 	ambapp_ahbdev ahbdev;
 
 	/* Find GRUSB core using AMBA Plug&Play information */
-	if (ambapp_ahbslv_first(VENDOR_GAISLER, GAISLER_UHCI, &ahbdev) != 1) {
+	if (ambapp_ahbslv_find(&ambapp_plb, VENDOR_GAISLER, GAISLER_UHCI,
+		CONFIG_SYS_GRLIB_GRUSB_INDEX, &ahbdev) != 1 ) {
 		printf("USB UHCI: Failed to find GRUSB controller\n");
 		return -1;
 	}
diff --git a/drivers/net/greth.c b/drivers/net/greth.c
index 383b25c..5ac0379 100644
--- a/drivers/net/greth.c
+++ b/drivers/net/greth.c
@@ -42,6 +42,13 @@
 #define GRETH_PHY_TIMEOUT_MS 3000
 #endif
 
+/* Let board select which GRETH to use as network interface, set
+ * this to zero if only one GRETH is available.
+ */
+#ifndef CONFIG_SYS_GRLIB_GRETH_INDEX
+#define CONFIG_SYS_GRLIB_GRETH_INDEX 0
+#endif
+
 /* ByPass Cache when reading regs */
 #define GRETH_REGLOAD(addr)		SPARC_NOCACHE_READ(addr)
 /* Write-through cache ==> no bypassing needed on writes */
@@ -605,8 +612,12 @@ int greth_initialize(bd_t * bis)
 #ifdef DEBUG
 	printf("Scanning for GRETH\n");
 #endif
-	/* Find Device & IRQ via AMBA Plug&Play information */
-	if (ambapp_apb_first(VENDOR_GAISLER, GAISLER_ETHMAC, &apbdev) != 1) {
+	/* Find Device & IRQ via AMBA Plug&Play information,
+	 * CONFIG_SYS_GRLIB_GRETH_INDEX select which GRETH if multiple
+	 * GRETHs in system.
+	 */
+	if (ambapp_apb_find(&ambapp_plb, VENDOR_GAISLER, GAISLER_ETHMAC,
+			CONFIG_SYS_GRLIB_GRETH_INDEX, &apbdev) != 1) {
 		return -1;	/* GRETH not found */
 	}
 
diff --git a/include/ambapp.h b/include/ambapp.h
index 42c990c..c1c07aa 100644
--- a/include/ambapp.h
+++ b/include/ambapp.h
@@ -3,8 +3,8 @@
  * the APB bus, also freely available in GRLIB at
  * www.gaisler.com.
  *
- * (C) Copyright 2007
- * Daniel Hellstrom, Gaisler Research, daniel at gaisler.com.
+ * (C) Copyright 2009
+ * Daniel Hellstrom, Aeroflex Gaisler, daniel at gaisler.com.
  *
  * See file CREDITS for list of people who contributed to this
  * project.
@@ -29,116 +29,136 @@
 #ifndef __AMBAPP_H__
 #define __AMBAPP_H__
 
-/* Default location of Plug&Play info
- * normally 0xfffff000 for AHB masters
- * and 0xfffff800 for AHB slaves.
- * Normally no need to change this.
- */
-#define LEON3_IO_AREA 0xfff00000
-#define LEON3_CONF_AREA  0xff000
-#define LEON3_AHB_SLAVE_CONF_AREA (1 << 11)
-
-/* Max devices this software will support */
-#define LEON3_AHB_MASTERS 16
-#define LEON3_AHB_SLAVES 16
-/*#define LEON3_APB_MASTERS 1*/ /* Number of APB buses that has Plug&Play */
-#define LEON3_APB_SLAVES 16	/* Total number of APB slaves per APB bus */
-
-/* Vendor codes */
-#define VENDOR_GAISLER       1
-#define VENDOR_PENDER        2
-#define VENDOR_ESA           4
-#define VENDOR_ASTRIUM       6
-#define VENDOR_OPENCHIP      7
-#define VENDOR_OPENCORES     8
-#define VENDOR_CONTRIB       9
-#define VENDOR_EONIC         11
-#define VENDOR_RADIONOR      15
-#define VENDOR_GLEICHMANN    16
-#define VENDOR_MENTA         17
-#define VENDOR_SUN           19
-#define VENDOR_EMBEDDIT      234
-#define VENDOR_CAL           202
-
-/* Gaisler Research device id's */
-#define GAISLER_LEON3    0x003
-#define GAISLER_LEON3DSU 0x004
-#define GAISLER_ETHAHB   0x005
-#define GAISLER_APBMST   0x006
-#define GAISLER_AHBUART  0x007
-#define GAISLER_SRCTRL   0x008
-#define GAISLER_SDCTRL   0x009
-#define GAISLER_APBUART  0x00C
-#define GAISLER_IRQMP    0x00D
-#define GAISLER_AHBRAM   0x00E
-#define GAISLER_GPTIMER  0x011
-#define GAISLER_PCITRG   0x012
-#define GAISLER_PCISBRG  0x013
-#define GAISLER_PCIFBRG  0x014
-#define GAISLER_PCITRACE 0x015
-#define GAISLER_PCIDMA   0x016
-#define GAISLER_AHBTRACE 0x017
-#define GAISLER_ETHDSU   0x018
-#define GAISLER_PIOPORT  0x01A
-#define GAISLER_AHBJTAG  0x01c
-#define GAISLER_SPW      0x01f
-#define GAISLER_ATACTRL  0x024
-#define GAISLER_VGA      0x061
-#define GAISLER_KBD      0X060
-#define GAISLER_ETHMAC   0x01D
-#define GAISLER_DDRSPA   0x025
-#define GAISLER_EHCI     0x026
-#define GAISLER_UHCI     0x027
-#define GAISLER_SPW2     0x029
-#define GAISLER_DDR2SPA  0x02E
-#define GAISLER_AHBSTAT  0x052
-#define GAISLER_FTMCTRL  0x054
-
-#define GAISLER_L2TIME   0xffd	/* internal device: leon2 timer */
-#define GAISLER_L2C      0xffe	/* internal device: leon2compat */
-#define GAISLER_PLUGPLAY 0xfff	/* internal device: plug & play configarea */
-
-/* European Space Agency device id's */
-#define ESA_LEON2        0x2
-#define ESA_MCTRL        0xF
-
-/* Opencores device id's */
-#define OPENCORES_PCIBR  0x4
-#define OPENCORES_ETHMAC 0x5
-
-/* Vendor codes */
-
-/*
- *
- * Macros for manipulating Configuration registers
- *
- */
-
-#define amba_vendor(x) (((x) >> 24) & 0xff)
-
-#define amba_device(x) (((x) >> 12) & 0xfff)
-
-#define amba_membar_start(mbar) \
- (((mbar) & 0xfff00000) & (((mbar) & 0xfff0) << 16))
-
-#define amba_iobar_start(base, iobar) \
- ((base) | ((((iobar) & 0xfff00000)>>12) & (((iobar) & 0xfff0)<<4)) )
+#include <ambapp_ids.h>
 
-#define amba_irq(conf) ((conf) & 0xf)
+#ifndef __ASSEMBLER__
+/* Structures used to access Plug&Play information directly */
+struct ambapp_pnp_ahb {
+	const unsigned int	id;		/* VENDOR, DEVICE, VER, IRQ, */
+	const unsigned int	custom[3];
+	const unsigned int	mbar[4];	/* MASK, ADDRESS, TYPE,
+						 * CACHABLE/PREFETCHABLE */
+};
+
+struct ambapp_pnp_apb {
+	const unsigned int	id;		/* VENDOR, DEVICE, VER, IRQ, */
+	const unsigned int	iobar;		/* MASK, ADDRESS, TYPE,
+						 * CACHABLE/PREFETCHABLE */
+};
 
-#define amba_ver(conf) (((conf)>>5) & 0x1f)
+/* AMBA Plug&Play AHB Masters & Slaves information locations
+ * Max devices is 64 supported by HW, however often only 16
+ * are used.
+ */
+struct ambapp_pnp_info {
+	struct ambapp_pnp_ahb	masters[64];
+	struct ambapp_pnp_ahb	slaves[63];
+	const unsigned int	unused[4];
+	const unsigned int	systemid[4];
+};
+
+/* Describes a AMBA PnP bus */
+struct ambapp_bus {
+	int		buses;		/* Number of buses */
+	unsigned int	ioareas[6];	/* PnP I/O AREAs of AHB buses */
+	unsigned int	freq;		/* Frequency of bus0 [Hz] */
+};
+
+/* Processor Local AMBA bus */
+extern struct ambapp_bus ambapp_plb;
+
+/* Get Bus frequency of a certain AMBA bus */
+extern unsigned int ambapp_bus_freq(
+	struct ambapp_bus *abus,
+	int ahb_bus_index
+	);
+
+/* AMBA PnP information of a APB Device */
+typedef struct {
+	unsigned int vendor;
+	unsigned int device;
+	unsigned char irq;
+	unsigned char ver;
+	unsigned int address;
+	unsigned int mask;
+	int ahb_bus_index;
+} ambapp_apbdev;
 
-#define amba_membar_type(mbar) ((mbar) & 0xf)
+/* AMBA PnP information of a AHB Device */
+typedef struct {
+	unsigned int vendor;
+	unsigned int device;
+	unsigned char irq;
+	unsigned char ver;
+	unsigned int userdef[3];
+	unsigned int address[4];
+	unsigned int mask[4];
+	int type[4];
+	int ahb_bus_index;
+} ambapp_ahbdev;
 
-#define amba_membar_mask(mbar) (((mbar)>>4) & 0xfff)
+/* Scan AMBA Bus for AHB Bridges */
+extern void ambapp_bus_init(
+	unsigned int ioarea,
+	unsigned int freq,
+	struct ambapp_bus *abus);
 
-#define AMBA_TYPE_APBIO 0x1
-#define AMBA_TYPE_MEM   0x2
-#define AMBA_TYPE_AHBIO 0x3
+/* Find APB Slave device by index using breath first search.
+ *
+ * When vendor and device are both set to zero, any device 
+ * with a non-zero device ID will match the search. It may be
+ * useful when processing all devices on a AMBA bus.
+ */
+extern int ambapp_apb_find(
+	struct ambapp_bus *abus,
+	int vendor,
+	int device,
+	int index,
+	ambapp_apbdev *dev
+	);
+
+/* Find AHB Master device by index using breath first search. 
+ *
+ * When vendor and device are both set to zero, any device 
+ * with a non-zero device ID will match the search. It may be
+ * useful when processing all devices on a AMBA bus.
+ */
+extern int ambapp_ahbmst_find(
+	struct ambapp_bus *abus,
+	int vendor,
+	int device,
+	int index,
+	ambapp_ahbdev *dev
+	);
+
+/* Find AHB Slave device by index using breath first search.
+ *
+ * When vendor and device are both set to zero, any device 
+ * with a non-zero device ID will match the search. It may be
+ * useful when processing all devices on a AMBA bus.
+ */
+extern int ambapp_ahbslv_find(
+	struct ambapp_bus *abus,
+	int vendor,
+	int device,
+	int index,
+	ambapp_ahbdev *dev
+	);
+
+/* Return number of APB Slave devices of a certain ID (VENDOR:DEVICE)
+ * zero is returned if no devices was found.
+ */
+extern int ambapp_apb_count(struct ambapp_bus *abus, int vendor, int device);
 
-#define AMBA_TYPE_AHBIO_ADDR(addr) (LEON3_IO_AREA | ((addr) >> 12))
+/* Return number of AHB Master devices of a certain ID (VENDOR:DEVICE)
+ * zero is returned if no devices was found.
+ */
+extern int ambapp_ahbmst_count(struct ambapp_bus *abus, int vendor, int device);
 
-#ifndef __ASSEMBLER__
+/* Return number of AHB Slave devices of a certain ID (VENDOR:DEVICE)
+ * zero is returned if no devices was found.
+ */
+extern int ambapp_ahbslv_count(struct ambapp_bus *abus, int vendor, int device);
 
 #ifdef CONFIG_CMD_AMBAPP
 
@@ -152,109 +172,72 @@ char *ambapp_device_id2str(int vendor, int id);
 
 /* Return name of vendor */
 char *ambapp_vendor_id2str(int vendor);
-#endif
 
-/*
- *  Types and structure used for AMBA Plug & Play bus scanning
- */
+/* Return description of a device */
+char *ambapp_device_id2desc(int vendor, int id);
 
-/* AMBA Plug&Play AHB information layout */
-typedef struct {
-	unsigned int conf;
-	unsigned int userdef[3];
-	unsigned int bars[4];
-} ahbctrl_pp_dev;
-
-/* Prototypes for scanning AMBA Plug&Play bus for AMBA
- *  i)   AHB Masters
- *  ii)  AHB Slaves
- *  iii) APB Slaves (APB MST is a AHB Slave)
- */
+#endif
 
-typedef struct {
-	unsigned char irq;
-	unsigned char ver;
-	unsigned int address;
-} ambapp_apbdev;
+#endif /* defined(__ASSEMBLER__) */
 
-typedef struct {
-	unsigned char irq;
-	unsigned char ver;
-	unsigned int userdef[3];
-	unsigned int address[4];
-} ambapp_ahbdev;
+#define AMBA_DEFAULT_IOAREA 0xfff00000
+#define AMBA_CONF_AREA 0xff000
+#define AMBA_AHB_SLAVE_CONF_AREA 0x800
 
-/* AMBA Plug&Play AHB Masters & Slaves information locations
- * Max devices is 64 supported by HW, however often only 8
- * are used.
- */
-typedef struct {
-	ahbctrl_pp_dev masters[64];
-	ahbctrl_pp_dev slaves[64];
-} ahbctrl_info;
+#define DEV_NONE	0
+#define DEV_AHB_MST	1
+#define DEV_AHB_SLV	2
+#define DEV_APB_SLV	3
 
-/* AMBA Plug&Play AHB information layout */
-typedef struct {
-	unsigned int conf;
-	unsigned int bar;
-} apbctrl_pp_dev;
+#define AMBA_TYPE_APBIO 0x1
+#define AMBA_TYPE_MEM 0x2
+#define AMBA_TYPE_AHBIO 0x3
 
-/* All functions return the number of found devices
- * 0 = no devices found
+/* ID layout for APB and AHB devices */
+#define AMBA_PNP_ID(vendor, device) ( ((vendor)<<24) | ((device)<<12) )
+
+/* APB Slave PnP layout definitions */
+#define AMBA_APB_ID_OFS		(0*4)
+#define AMBA_APB_IOBAR_OFS	(1*4)
+#define AMBA_APB_CONF_LENGH	(2*4)
+
+/* AHB Master/Slave layout PnP definitions */
+#define AMBA_AHB_ID_OFS		(0*4)
+#define AMBA_AHB_CUSTOM0_OFS	(1*4)
+#define AMBA_AHB_CUSTOM1_OFS	(2*4)
+#define AMBA_AHB_CUSTOM2_OFS	(3*4)
+#define AMBA_AHB_MBAR0_OFS	(4*4)
+#define AMBA_AHB_MBAR1_OFS	(5*4)
+#define AMBA_AHB_MBAR2_OFS	(6*4)
+#define AMBA_AHB_MBAR3_OFS	(7*4)
+#define AMBA_AHB_CONF_LENGH	(8*4)
+
+/* Macros for extracting information from AMBA PnP information
+ * registers.
  */
 
-/****************************** APB SLAVES ******************************/
-int ambapp_apb_count(unsigned int vendor, unsigned int driver);
-
-int ambapp_apb_first(unsigned int vendor,
-		     unsigned int driver, ambapp_apbdev * dev);
-
-int ambapp_apb_next(unsigned int vendor,
-		    unsigned int driver, ambapp_apbdev * dev, int index);
-
-int ambapp_apbs_first(unsigned int vendor,
-		      unsigned int driver, ambapp_apbdev * dev, int max_cnt);
-
-/****************************** AHB MASTERS ******************************/
-int ambapp_ahbmst_count(unsigned int vendor, unsigned int driver);
-
-int ambapp_ahbmst_first(unsigned int vendor,
-			unsigned int driver, ambapp_ahbdev * dev);
+#define amba_vendor(x) (((x) >> 24) & 0xff)
 
-int ambapp_ahbmst_next(unsigned int vendor,
-		       unsigned int driver, ambapp_ahbdev * dev, int index);
+#define amba_device(x) (((x) >> 12) & 0xfff)
 
-int ambapp_ahbmsts_first(unsigned int vendor,
-			 unsigned int driver, ambapp_ahbdev * dev, int max_cnt);
+#define amba_irq(conf) ((conf) & 0x1f)
 
-/****************************** AHB SLAVES ******************************/
-int ambapp_ahbslv_count(unsigned int vendor, unsigned int driver);
+#define amba_ver(conf) (((conf)>>5) & 0x1f)
 
-int ambapp_ahbslv_first(unsigned int vendor,
-			unsigned int driver, ambapp_ahbdev * dev);
+#define amba_iobar_start(base, iobar) \
+ ((base) | ((((iobar) & 0xfff00000)>>12) & (((iobar) & 0xfff0)<<4)) )
 
-int ambapp_ahbslv_next(unsigned int vendor,
-		       unsigned int driver, ambapp_ahbdev * dev, int index);
+#define amba_membar_start(mbar) \
+ (((mbar) & 0xfff00000) & (((mbar) & 0xfff0) << 16))
 
-int ambapp_ahbslvs_first(unsigned int vendor,
-			 unsigned int driver, ambapp_ahbdev * dev, int max_cnt);
+#define amba_membar_type(mbar) ((mbar) & 0xf)
 
-/*************************** AHB/APB only regs functions *************************
- * During start up, no memory is available we can use the simplified functions
- * to get to the memory controller.
- *
- * Functions uses no stack/memory, only registers.
- */
-unsigned int ambapp_apb_next_nomem(register unsigned int vendor,	/* Plug&Play Vendor ID */
-				   register unsigned int driver,	/* Plug&Play Device ID */
-				   register int index);
+#define amba_membar_mask(mbar) (((mbar) >> 4) & 0xfff)
 
-ahbctrl_pp_dev *ambapp_ahb_next_nomem(register unsigned int vendor,	/* Plug&Play Vendor ID */
-				      register unsigned int driver,	/* Plug&Play Device ID */
-				      register unsigned int opts,	/* scan for AHB 1=slave, 0=masters */
-				      register int index);
+#define amba_ahbio_adr(addr,base_ioarea) \
+	((unsigned int)(base_ioarea) | ((addr) >> 12))
 
-unsigned int ambapp_ahb_get_info(ahbctrl_pp_dev * ahb, int info);
+#define amba_apb_mask(iobar) ((~(amba_membar_mask(iobar)<<8) & 0x000fffff) + 1)
 
 /*************************** AMBA Plug&Play device register MAPS *****************/
 
@@ -308,6 +291,8 @@ unsigned int ambapp_ahb_get_info(ahbctrl_pp_dev * ahb, int info);
 #define LEON_REG_PS2_CTRL_RI     0x00000004	/* Keyboard receive interrupt  */
 #define LEON_REG_PS2_CTRL_TI     0x00000008	/* Keyboard transmit interrupt */
 
+#ifndef __ASSEMBLER__
+
 typedef struct {
 	volatile unsigned int ilevel;
 	volatile unsigned int ipend;
diff --git a/include/ambapp_ids.h b/include/ambapp_ids.h
new file mode 100644
index 0000000..b7eb98b
--- /dev/null
+++ b/include/ambapp_ids.h
@@ -0,0 +1,256 @@
+/* AMBA Plug & Play Bus Vendor and Device IDs.
+ *
+ * (C) Copyright 2010
+ * Daniel Hellstrom, Aeroflex Gaisler, daniel@gaisler.com.
+ *
+ * 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
+ *
+ */
+
+
+#ifndef __AMBAPP_IDS_H__
+#define __AMBAPP_IDS_H__
+
+/* Vendor ID defines */
+#define VENDOR_GAISLER       0x01
+#define VENDOR_PENDER        0x02
+#define VENDOR_ESA           0x04
+#define VENDOR_ASTRIUM       0x06
+#define VENDOR_OPENCHIP      0x07
+#define VENDOR_OPENCORES     0x08
+#define VENDOR_CONTRIB       0x09
+#define VENDOR_EONIC         0x0b
+#define VENDOR_RADIONOR      0x0f
+#define VENDOR_GLEICHMANN    0x10
+#define VENDOR_MENTA         0x11
+#define VENDOR_SUN           0x13
+#define VENDOR_MOVIDIA       0x14
+#define VENDOR_ORBITA        0x17
+#define VENDOR_SYNOPSYS      0x21
+#define VENDOR_NASA          0x22
+#define VENDOR_CAL           0xca
+#define VENDOR_EMBEDDIT      0xea
+#define VENDOR_CETON         0xcb
+#define VENDOR_ACTEL         0xac
+#define VENDOR_APPLECORE     0xae
+
+/* Aeroflex Gaisler device ID defines */
+#define GAISLER_LEON2DSU     0x002
+#define GAISLER_LEON3        0x003
+#define GAISLER_LEON3DSU     0x004
+#define GAISLER_ETHAHB       0x005
+#define GAISLER_APBMST       0x006
+#define GAISLER_AHBUART      0x007
+#define GAISLER_SRCTRL       0x008
+#define GAISLER_SDCTRL       0x009
+#define GAISLER_SSRCTRL      0x00a
+#define GAISLER_APBUART      0x00c
+#define GAISLER_IRQMP        0x00d
+#define GAISLER_AHBRAM       0x00e
+#define GAISLER_AHBDPRAM     0x00f
+#define GAISLER_GPTIMER      0x011
+#define GAISLER_PCITRG       0x012
+#define GAISLER_PCISBRG      0x013
+#define GAISLER_PCIFBRG      0x014
+#define GAISLER_PCITRACE     0x015
+#define GAISLER_DMACTRL      0x016
+#define GAISLER_AHBTRACE     0x017
+#define GAISLER_DSUCTRL      0x018
+#define GAISLER_CANAHB       0x019
+#define GAISLER_GPIO         0x01a
+#define GAISLER_AHBROM       0x01b
+#define GAISLER_AHBJTAG      0x01c
+#define GAISLER_ETHMAC       0x01d
+#define GAISLER_SWNODE       0x01e
+#define GAISLER_SPW          0x01f
+#define GAISLER_AHB2AHB      0x020
+#define GAISLER_USBDC        0x021
+#define GAISLER_USB_DCL      0x022
+#define GAISLER_DDRMP        0x023
+#define GAISLER_ATACTRL      0x024
+#define GAISLER_DDRSP        0x025
+#define GAISLER_EHCI         0x026
+#define GAISLER_UHCI         0x027
+#define GAISLER_I2CMST       0x028
+#define GAISLER_SPW2         0x029
+#define GAISLER_AHBDMA       0x02a
+#define GAISLER_NUHOSP3      0x02b
+#define GAISLER_CLKGATE      0x02c
+#define GAISLER_SPICTRL      0x02d
+#define GAISLER_DDR2SP       0x02e
+#define GAISLER_SLINK        0x02f
+#define GAISLER_GRTM         0x030
+#define GAISLER_GRTC         0x031
+#define GAISLER_GRPW         0x032
+#define GAISLER_GRCTM        0x033
+#define GAISLER_GRHCAN       0x034
+#define GAISLER_GRFIFO       0x035
+#define GAISLER_GRADCDAC     0x036
+#define GAISLER_GRPULSE      0x037
+#define GAISLER_GRTIMER      0x038
+#define GAISLER_AHB2PP       0x039
+#define GAISLER_GRVERSION    0x03a
+#define GAISLER_APB2PW       0x03b
+#define GAISLER_PW2APB       0x03c
+#define GAISLER_GRCAN        0x03d
+#define GAISLER_I2CSLV       0x03e
+#define GAISLER_U16550       0x03f
+#define GAISLER_AHBMST_EM    0x040
+#define GAISLER_AHBSLV_EM    0x041
+#define GAISLER_GRTESTMOD    0x042
+#define GAISLER_ASCS         0x043
+#define GAISLER_IPMVBCTRL    0x044
+#define GAISLER_SPIMCTRL     0x045
+#define GAISLER_LEON4        0x048
+#define GAISLER_LEON4DSU     0x049
+#define GAISLER_PWM          0x04a
+#define GAISLER_L2CACHE      0x04b
+#define GAISLER_SDCTRL64     0x04c
+#define GAISLER_FTAHBRAM     0x050
+#define GAISLER_FTSRCTRL     0x051
+#define GAISLER_AHBSTAT      0x052
+#define GAISLER_LEON3FT      0x053
+#define GAISLER_FTMCTRL      0x054
+#define GAISLER_FTSDCTRL     0x055
+#define GAISLER_FTSRCTRL8    0x056
+#define GAISLER_APBPS2       0x060
+#define GAISLER_VGACTRL      0x061
+#define GAISLER_LOGAN        0x062
+#define GAISLER_SVGACTRL     0x063
+#define GAISLER_T1AHB        0x064
+#define GAISLER_MP7WRAP      0x065
+#define GAISLER_GRSYSMON     0x066
+#define GAISLER_GRACECTRL    0x067
+#define GAISLER_ATAHBSLV     0x068
+#define GAISLER_ATAHBMST     0x069
+#define GAISLER_ATAPBSLV     0x06a
+#define GAISLER_B1553BC      0x070
+#define GAISLER_B1553RT      0x071
+#define GAISLER_B1553BRM     0x072
+#define GAISLER_AES          0x073
+#define GAISLER_ECC          0x074
+#define GAISLER_PCIF         0x075
+#define GAISLER_CLKMOD       0x076
+#define GAISLER_HAPSTRAK     0x077
+#define GAISLER_TEST_1X2     0x078
+#define GAISLER_WILD2AHB     0x079
+#define GAISLER_BIO1         0x07a
+#define GAISLER_SATCAN       0x080
+#define GAISLER_CANMUX       0x081
+#define GAISLER_GRTMRX       0x082
+#define GAISLER_GRTCTX       0x083
+#define GAISLER_GRTMDESC     0x084
+#define GAISLER_GRTMVC       0x085
+#define GAISLER_GEFFE        0x086
+#define GAISLER_GPREG        0x087
+#define GAISLER_GRTMPAHB     0x088
+
+/* European Space Agency device ID defines */
+#define ESA_LEON2            0x002
+#define ESA_LEON2APB         0x003
+#define ESA_IRQ              0x005
+#define ESA_TIMER            0x006
+#define ESA_UART             0x007
+#define ESA_CFG              0x008
+#define ESA_IO               0x009
+#define ESA_MCTRL            0x00f
+#define ESA_PCIARB           0x010
+#define ESA_HURRICANE        0x011
+#define ESA_SPW_RMAP         0x012
+#define ESA_AHBUART          0x013
+#define ESA_SPWA             0x014
+#define ESA_BOSCHCAN         0x015
+#define ESA_IRQ2             0x016
+#define ESA_AHBSTAT          0x017
+#define ESA_WPROT            0x018
+#define ESA_WPROT2           0x019
+#define ESA_PDEC3AMBA        0x020
+#define ESA_PTME3AMBA        0x021
+
+/* OpenChip device ID defines */
+#define OPENCHIP_APBGPIO     0x001
+#define OPENCHIP_APBI2C      0x002
+#define OPENCHIP_APBSPI      0x003
+#define OPENCHIP_APBCHARLCD  0x004
+#define OPENCHIP_APBPWM      0x005
+#define OPENCHIP_APBPS2      0x006
+#define OPENCHIP_APBMMCSD    0x007
+#define OPENCHIP_APBNAND     0x008
+#define OPENCHIP_APBLPC      0x009
+#define OPENCHIP_APBCF       0x00a
+#define OPENCHIP_APBSYSACE   0x00b
+#define OPENCHIP_APB1WIRE    0x00c
+#define OPENCHIP_APBJTAG     0x00d
+#define OPENCHIP_APBSUI      0x00e
+
+/* Various contributions device ID defines */
+#define CONTRIB_CORE1        0x001
+#define CONTRIB_CORE2        0x002
+
+/* Gleichmann Electronics device ID defines */
+#define GLEICHMANN_CUSTOM    0x001
+#define GLEICHMANN_GEOLCD01  0x002
+#define GLEICHMANN_DAC       0x003
+#define GLEICHMANN_HPI       0x004
+#define GLEICHMANN_SPI       0x005
+#define GLEICHMANN_HIFC      0x006
+#define GLEICHMANN_ADCDAC    0x007
+#define GLEICHMANN_SPIOC     0x008
+#define GLEICHMANN_AC97      0x009
+
+/* Sun Microsystems device ID defines */
+#define SUN_T1               0x001
+#define SUN_S1               0x011
+
+/* Orbita device ID defines */
+#define ORBITA_1553B         0x001
+#define ORBITA_429           0x002
+#define ORBITA_SPI           0x003
+#define ORBITA_I2C           0x004
+#define ORBITA_SMARTCARD     0x064
+#define ORBITA_SDCARD        0x065
+#define ORBITA_UART16550     0x066
+#define ORBITA_CRYPTO        0x067
+#define ORBITA_SYSIF         0x068
+#define ORBITA_PIO           0x069
+#define ORBITA_RTC           0x0c8
+#define ORBITA_COLORLCD      0x12c
+#define ORBITA_PCI           0x190
+#define ORBITA_DSP           0x1f4
+#define ORBITA_USBHOST       0x258
+#define ORBITA_USBDEV        0x2bc
+
+/* NASA device ID defines */
+#define NASA_EP32            0x001
+
+/* CAL device ID defines */
+#define CAL_DDRCTRL          0x188
+
+/* Actel Corporation device ID defines */
+#define ACTEL_COREMP7        0x001
+
+/* AppleCore device ID defines */
+#define APPLECORE_UTLEON3    0x001
+#define APPLECORE_UTLEON3DSU 0x002
+
+/* Opencores device id's */
+#define OPENCORES_PCIBR  0x4
+#define OPENCORES_ETHMAC 0x5
+
+#endif
-- 
1.5.4

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [U-Boot] [PATCH 05/17] LEON3: added memory controller initialization using the new AMBA PnP routines.
  2010-01-28 12:16 [U-Boot] [PATCH 01/17] SPARC: added unaligned definitions, patch supplied by Magnus Sjalander Daniel Hellstrom
                   ` (2 preceding siblings ...)
  2010-01-28 12:16 ` [U-Boot] [PATCH 04/17] LEON3: reimplemented AMBA Plug&Play scanning routines Daniel Hellstrom
@ 2010-01-28 12:16 ` Daniel Hellstrom
  2010-01-28 12:16 ` [U-Boot] [PATCH 06/17] LEON3: Moved GRLIB core header files to common include/grlib directory Daniel Hellstrom
                   ` (13 subsequent siblings)
  17 siblings, 0 replies; 26+ messages in thread
From: Daniel Hellstrom @ 2010-01-28 12:16 UTC (permalink / raw)
  To: u-boot

Signed-off-by: Daniel Hellstrom <daniel@gaisler.com>
---
 cpu/leon3/Makefile               |    5 +-
 cpu/leon3/memcfg.c               |  276 ++++++++++++++++++++++++++++++++++++++
 cpu/leon3/memcfg.h               |  106 +++++++++++++++
 cpu/leon3/memcfg_low.S           |  270 +++++++++++++++++++++++++++++++++++++
 cpu/leon3/start.S                |   36 +++++
 include/configs/gr_cpci_ax2000.h |   27 ++--
 include/configs/gr_ep2s60.h      |   32 +++--
 include/configs/gr_xc3s_1500.h   |   23 ++--
 include/configs/grsim.h          |   27 +++--
 9 files changed, 754 insertions(+), 48 deletions(-)
 create mode 100644 cpu/leon3/memcfg.c
 create mode 100644 cpu/leon3/memcfg.h
 create mode 100644 cpu/leon3/memcfg_low.S

diff --git a/cpu/leon3/Makefile b/cpu/leon3/Makefile
index d8f89bc..f1bb808 100644
--- a/cpu/leon3/Makefile
+++ b/cpu/leon3/Makefile
@@ -26,8 +26,9 @@ include $(TOPDIR)/config.mk
 LIB	= $(obj)lib$(CPU).a
 
 START	= start.o
-SOBJS	= ambapp_low.o ambapp_low_c.o
-COBJS	= cpu_init.o serial.o cpu.o ambapp.o interrupts.o prom.o usb_uhci.o
+SOBJS	= ambapp_low.o ambapp_low_c.o memcfg_low.o
+COBJS	= cpu_init.o serial.o cpu.o ambapp.o interrupts.o prom.o usb_uhci.o \
+	memcfg.o
 
 SRCS	:= $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
 OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
diff --git a/cpu/leon3/memcfg.c b/cpu/leon3/memcfg.c
new file mode 100644
index 0000000..83e55e4
--- /dev/null
+++ b/cpu/leon3/memcfg.c
@@ -0,0 +1,276 @@
+/* GRLIB Memory controller setup. The register values are used
+ * from the associated low level assembler routine implemented
+ * in memcfg_low.S.
+ *
+ * (C) Copyright 2010
+ * Daniel Hellstrom, Aeroflex Gaisler, daniel at gaisler.com.
+ *
+ * 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 <ambapp.h>
+#include "memcfg.h"
+#include <config.h>
+
+#ifdef CONFIG_SYS_GRLIB_ESA_MCTRL1
+struct mctrl_setup esa_mctrl1_cfg =
+{
+	.reg_mask = 0x7,
+	.regs =
+	{
+		{ 
+			.mask = 0x00000300,
+			.value = CONFIG_SYS_GRLIB_ESA_MCTRL1_CFG1,
+		},
+		{
+			.mask = 0x00000000,
+			.value = CONFIG_SYS_GRLIB_ESA_MCTRL1_CFG2,
+		},	
+		{
+			.mask = 0x00000000,
+			.value = CONFIG_SYS_GRLIB_ESA_MCTRL1_CFG3,
+		},
+	}
+};
+#ifdef CONFIG_SYS_GRLIB_ESA_MCTRL2
+struct mctrl_setup esa_mctrl2_cfg =
+{
+	.reg_mask = 0x7,
+	.regs =
+	{
+		{ 
+			.mask = 0x00000300,
+			.value = CONFIG_SYS_GRLIB_ESA_MCTRL2_CFG1,
+		},
+		{
+			.mask = 0x00000000,
+			.value = CONFIG_SYS_GRLIB_ESA_MCTRL2_CFG2,
+		},	
+		{
+			.mask = 0x00000000,
+			.value = CONFIG_SYS_GRLIB_ESA_MCTRL2_CFG3,
+		},
+	}
+};
+#endif
+#endif
+
+#ifdef CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1
+struct mctrl_setup gaisler_ftmctrl1_cfg =
+{
+	.reg_mask = 0x7,
+	.regs =
+	{
+		{ 
+			.mask = 0x00000300,
+			.value = CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1_CFG1,
+		},
+		{
+			.mask = 0x00000000,
+			.value = CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1_CFG2,
+		},	
+		{
+			.mask = 0x00000000,
+			.value = CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1_CFG3,
+		},
+	}
+};
+#ifdef CONFIG_SYS_GRLIB_GAISLER_FTMCTRL2
+struct mctrl_setup gaisler_ftmctrl2_cfg =
+{
+	.reg_mask = 0x7,
+	.regs =
+	{
+		{ 
+			.mask = 0x00000300,
+			.value = CONFIG_SYS_GRLIB_GAISLER_FTMCTRL2_CFG1,
+		},
+		{
+			.mask = 0x00000000,
+			.value = CONFIG_SYS_GRLIB_GAISLER_FTMCTRL2_CFG2,
+		},	
+		{
+			.mask = 0x00000000,
+			.value = CONFIG_SYS_GRLIB_GAISLER_FTMCTRL2_CFG3,
+		},
+	}
+};
+#endif
+#endif
+
+#ifdef CONFIG_SYS_GRLIB_GAISLER_SDCTRL1
+struct mctrl_setup gaisler_sdctrl1_cfg =
+{
+	.reg_mask = 0x1,
+	.regs =
+	{
+		{ 
+			.mask = 0x00000000,
+			.value = CONFIG_SYS_GRLIB_GAISLER_SDCTRL1_CTRL,
+		},
+	}
+};
+#ifdef CONFIG_SYS_GRLIB_GAISLER_SDCTRL2
+struct mctrl_setup gaisler_sdctrl2_cfg =
+{
+	.reg_mask = 0x1,
+	.regs =
+	{
+		{ 
+			.mask = 0x00000000,
+			.value = CONFIG_SYS_GRLIB_GAISLER_SDCTRL2_CTRL,
+		},
+	}
+};
+#endif
+#endif
+
+#ifdef CONFIG_SYS_GRLIB_GAISLER_DDR2SPA1
+struct ahbmctrl_setup gaisler_ddr2spa1_cfg =
+{
+	.ahb_mbar_no = 1,
+	.reg_mask = 0xd,
+	.regs =
+	{
+		{
+			.mask = 0x00000000,
+			.value = CONFIG_SYS_GRLIB_GAISLER_DDR2SPA1_CFG1,
+		},
+		{ 0x00000000, 0},
+		{
+			.mask = 0x00000000,
+			.value = CONFIG_SYS_GRLIB_GAISLER_DDR2SPA1_CFG3,
+		},
+		{
+			.mask = 0x00000000,
+			.value = CONFIG_SYS_GRLIB_GAISLER_DDR2SPA1_CFG4,
+		},
+	}
+};
+#ifdef CONFIG_SYS_GRLIB_GAISLER_DDR2SPA2
+struct ahbmctrl_setup gaisler_ddr2spa2_cfg =
+{
+	.ahb_mbar_no = 1,
+	.reg_mask = 0xd,
+	.regs =
+	{
+		{
+			.mask = 0x00000000,
+			.value = CONFIG_SYS_GRLIB_GAISLER_DDR2SPA2_CFG1,
+		},
+		{ 0x00000000, 0},
+		{
+			.mask = 0x00000000,
+			.value = CONFIG_SYS_GRLIB_GAISLER_DDR2SPA2_CFG3,
+		},
+		{
+			.mask = 0x00000000,
+			.value = CONFIG_SYS_GRLIB_GAISLER_DDR2SPA2_CFG4,
+		},
+	}
+};
+#endif
+#endif
+
+#ifdef CONFIG_SYS_GRLIB_GAISLER_DDRSPA1
+struct ahbmctrl_setup gaisler_ddrspa1_cfg =
+{
+	.ahb_mbar_no = 1,
+	.reg_mask = 0x1,
+	.regs =
+	{
+		{
+			.mask = 0x00000000,
+			.value = CONFIG_SYS_GRLIB_GAISLER_DDRSPA1_CTRL,
+		},
+	}
+};
+#ifdef CONFIG_SYS_GRLIB_GAISLER_DDRSPA2
+struct ahbmctrl_setup gaisler_ddrspa2_cfg =
+{
+	.ahb_mbar_no = 1,
+	.reg_mask = 0x1,
+	.regs =
+	{
+		{
+			.mask = 0x00000000,
+			.value = CONFIG_SYS_GRLIB_GAISLER_DDRSPA2_CTRL,
+		},
+	}
+};
+#endif
+#endif
+
+struct grlib_mctrl_handler grlib_mctrl_handlers[] = 
+{
+
+/* ESA MCTRL (PROM/FLASH/IO/SRAM/SDRAM) */
+#ifdef CONFIG_SYS_GRLIB_ESA_MCTRL1
+	{DEV_APB_SLV, 0, MH_UNUSED, AMBA_PNP_ID(VENDOR_ESA,ESA_MCTRL),
+	_nomem_mctrl_init, (void *)&esa_mctrl1_cfg},
+#ifdef CONFIG_SYS_GRLIB_ESA_MCTRL2
+	{DEV_APB_SLV, 1, MH_UNUSED, AMBA_PNP_ID(VENDOR_ESA,ESA_MCTRL),
+	_nomem_mctrl_init, (void *)&esa_mctrl2_cfg},
+#endif
+#endif
+
+/* GAISLER Fault Tolerant Memory controller (PROM/FLASH/IO/SRAM/SDRAM) */
+#ifdef CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1
+	{DEV_APB_SLV, 0, MH_UNUSED, AMBA_PNP_ID(VENDOR_GAISLER,GAISLER_FTMCTRL),
+	_nomem_mctrl_init, (void *)&gaisler_ftmctrl1_cfg},
+#ifdef CONFIG_SYS_GRLIB_GAISLER_FTMCTRL2
+	{DEV_APB_SLV, 1, MH_UNUSED, AMBA_PNP_ID(VENDOR_GAISLER,GAISLER_FTMCTRL),
+	_nomem_mctrl_init, (void *)&gaisler_ftmctrl2_cfg},
+#endif
+#endif
+
+/* GAISLER SDRAM-only Memory controller (SDRAM) */
+#ifdef CONFIG_SYS_GRLIB_GAISLER_SDCTRL1
+	{DEV_APB_SLV, 0, MH_UNUSED, AMBA_PNP_ID(VENDOR_GAISLER,GAISLER_SDCTRL),
+	_nomem_mctrl_init, (void *)&gaisler_sdctrl1_cfg},
+#ifdef CONFIG_SYS_GRLIB_GAISLER_SDCTRL2
+	{DEV_APB_SLV, 1, MH_UNUSED, AMBA_PNP_ID(VENDOR_GAISLER,GAISLER_SDCTRL),
+	_nomem_mctrl_init, (void *)&gaisler_sdctrl2_cfg},
+#endif
+#endif
+
+/* GAISLER DDR Memory controller (DDR) */
+#ifdef CONFIG_SYS_GRLIB_GAISLER_DDRSPA1
+	{DEV_AHB_SLV, 0, MH_UNUSED, AMBA_PNP_ID(VENDOR_GAISLER,GAISLER_DDRSP),
+	_nomem_ahbmctrl_init, (void *)&gaisler_ddrspa1_cfg},
+#ifdef CONFIG_SYS_GRLIB_GAISLER_DDRSPA2
+	{DEV_AHB_SLV, 1, MH_UNUSED, AMBA_PNP_ID(VENDOR_GAISLER,GAISLER_DDRSP),
+	_nomem_ahbmctrl_init, (void *)&gaisler_ddrspa2_cfg},
+#endif
+#endif
+
+/* GAISLER DDR2 Memory controller (DDR2) */
+#ifdef CONFIG_SYS_GRLIB_GAISLER_DDR2SPA1
+	{DEV_AHB_SLV, 0, MH_UNUSED, AMBA_PNP_ID(VENDOR_GAISLER,GAISLER_DDR2SP),
+	_nomem_ahbmctrl_init, (void *)&gaisler_ddr2spa1_cfg},
+#ifdef CONFIG_SYS_GRLIB_GAISLER_DDR2SPA2
+	{DEV_AHB_SLV, 1, MH_UNUSED, AMBA_PNP_ID(VENDOR_GAISLER,GAISLER_DDR2SP),
+	_nomem_ahbmctrl_init, (void *)&gaisler_ddr2spa2_cfg},
+#endif
+#endif
+
+	/* Mark end */
+	MH_END
+};
diff --git a/cpu/leon3/memcfg.h b/cpu/leon3/memcfg.h
new file mode 100644
index 0000000..0b4738e
--- /dev/null
+++ b/cpu/leon3/memcfg.h
@@ -0,0 +1,106 @@
+/* GRLIB Memory controller setup structures
+ *
+ * (C) Copyright 2010
+ * Daniel Hellstrom, Aeroflex Gaisler, daniel at gaisler.com.
+ *
+ * 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
+ *
+ */
+
+#ifndef __MEMCFG_H__
+#define __MEMCFG_H__
+
+/*********** Low Level Memory Controller Initalization ***********/
+
+#ifndef __ASSEMBLER__
+
+typedef void (*mctrl_handler_t)(
+	struct grlib_mctrl_handler *dev,
+	void *conf,
+	unsigned int ioarea
+	);
+
+/* Memory Controller Handler Structure */
+struct grlib_mctrl_handler {
+	unsigned char	type;		/* 0x00. MASK: AHB MST&SLV, APB SLV */
+	char		index;		/* 0x01. Unit number, 0, 1, 2... */
+	char		unused[2];	/* 0x02 */
+	unsigned int	ven_dev;	/* 0x04. Device and Vendor */
+	mctrl_handler_t	func;		/* 0x08. Memory Controller Handler */
+	void		*priv;		/* 0x0c. Optional private data, ptr to
+					 * info how to set up controller */
+};
+
+extern struct grlib_mctrl_handler grlib_mctrl_handlers[];
+
+#endif
+
+#define MH_STRUCT_SIZE		(4*4)
+#define MH_TYPE			0x00
+#define MH_INDEX		0x01
+#define MH_UNUSED		0x02
+#define MH_VENDOR_DEVICE	0x04
+#define MH_FUNC			0x08
+#define MH_PRIV			0x0c
+
+#define MH_TYPE_NONE	DEV_NONE
+#define MH_TYPE_AHB_MST	DEV_AHB_MST
+#define MH_TYPE_AHB_SLV	DEV_AHB_SLV
+#define MH_TYPE_APB_SLV	DEV_APB_SLV
+
+#define MH_UNUSED	{0, 0}
+#define MH_END		{DEV_NONE, 0, MH_UNUSED, AMBA_PNP_ID(0,0), 0, 0}
+
+/*********** Low Level Memory Controller Initalization Handlers ***********/
+
+#ifndef __ASSEMBLER__
+extern void _nomem_mctrl_init(
+	struct grlib_mctrl_handler *dev,
+	void *conf,
+	unsigned int ioarea_apbmst);
+
+struct mctrl_setup {
+	unsigned int reg_mask;		/* Which registers to write */
+	struct {
+		unsigned int mask;	/* Mask used keep reg bits unchanged */
+		unsigned int value;	/* Value written to register */
+	} regs[8];
+};
+
+extern void _nomem_ahbmctrl_init(
+	struct grlib_mctrl_handler *dev,
+	void *conf,
+	unsigned int ioarea_apbmst);
+
+struct ahbmctrl_setup {
+	int ahb_mbar_no;		/* MBAR to get register address from */
+	unsigned int reg_mask;		/* Which registers to write */
+	struct {
+		unsigned int mask;	/* Mask used keep reg bits unchanged */
+		unsigned int value;	/* Value written to register */
+	} regs[8];
+};
+#endif
+
+/* mctrl_setup data structure defines */
+#define NREGS_OFS 0
+#define REGS_OFS 0x4
+#define REGS_SIZE 8
+
+#endif
diff --git a/cpu/leon3/memcfg_low.S b/cpu/leon3/memcfg_low.S
new file mode 100644
index 0000000..7ff7230
--- /dev/null
+++ b/cpu/leon3/memcfg_low.S
@@ -0,0 +1,270 @@
+/* This is the memory initialization functions, the function
+ * implemented below initializes each memory controller 
+ * found and specified by the input grlib_mctrl_handler structure.
+ *
+ * After the memory controllers have been initialized the stack
+ * can be used.
+ *
+ * (C) Copyright 2010
+ * Daniel Hellstrom, Aeroflex Gaisler, daniel at gaisler.com.
+ *
+ * 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 <ambapp.h>
+#include "memcfg.h"
+#include <config.h>
+
+	.seg	"text"
+	.globl	_nomem_memory_ctrl_init
+	.globl	_nomem_mctrl_init, _nomem_ahbmctrl_init
+	.extern	_nomem_find_apb
+	.extern	_nomem_find_ahb
+
+
+/* FUNCTION
+ *   _nomem_memory_controller_init(struct grlib_mctrl_handler *mem_handlers)
+ *
+ * Initialize AMBA devices, _nomem_amba_init() has prepared i0-i5
+ * with the AHB buses on the system.
+ *
+ * For each entry in mem_handlers find the VENDOR:DEVICE and handle it
+ * by calling the handler function pointer.
+ *
+ * Constraints:
+ *  i6, i7, o6, l7, l6, g3, g4, g5, g6, g7 is used by caller
+ *  o7 is return address
+ *  l5 reserved for this function for future use.
+ *
+ * Arguments
+ *  - o0 Pointer to memory handler array
+ *
+ * Results
+ *  - o0 Number of memory controllers found
+ *
+ * Clobbered
+ *  - o0 (Current AHB slave conf address)
+ *  - l0 (mem handler entry address)
+ *  - l1 (Return value, number of memory controllers found)
+ *  - o7 (function pointer)
+ *  - l0, l1, l2, l3, l4, g1, g2 (used by _nomem_ambapp_find_buses)
+ *  - o0, o1, o2, o3, o4, o5 (Used as arguments)
+ *
+ *  - g1 ( level 1 return address)
+ *  - g2 ( level 2 return address)
+ */
+
+_nomem_memory_ctrl_init:
+	/* At this point all AHB buses has been found and the I/O Areas of 
+	 * all AHB buses is stored in the i0-i5 registers. Max 6 buses. Next,
+	 * memory controllers are found by searching all buses for matching
+	 * VENDOR:DEVICE. The VENDOR:DEVICE to search for are taken from the
+	 * mem_handlers array. For each match the function pointer stored in 
+	 * the mem_handler entry is called to handle the hardware setup.
+	 */
+	mov	%o7, %g1	/* Save return address */
+	mov	%o0, %l0
+	mov	%g0, %l1	/* The return value */
+
+.L_do_one_mem_handler:
+	ld	[%l0 + MH_FUNC], %o7
+	cmp	%o7, %g0
+	be	.L_all_mctrl_handled
+	 nop
+
+	/*** Scan for memory controller ***/
+
+	/* Set up argments, o5 not used by _nomem_find_apb */
+	ldub	[%l0 + MH_TYPE], %o5
+	clr	%o4
+	clr	%o3
+	ldub	[%l0 + MH_INDEX], %o2
+	ld	[%l0 + MH_VENDOR_DEVICE], %o1
+
+	/* An empty config? */
+	cmp	%o5, DEV_NONE
+	beq	.L_all_mctrl_next
+
+	/* Select function (APB or AHB) */
+	 cmp	%o5, DEV_APB_SLV
+	bne	.L_find_ahb_memctrl
+	 clr	%o0
+.L_find_apb_memctrl:
+	call	_nomem_find_apb			/* Scan for APB slave device */
+	 nop
+
+	/* o3 = iobar address
+	 * o4 = AHB Bus index
+	 *
+	 * REG ADR = ((iobar >> 12) & (iobar << 4) & 0xfff00) | "APB Base"
+	 */
+	ld	[%o3 + AMBA_APB_IOBAR_OFS], %o5
+	srl	%o5, 12, %o2
+	sll	%o5, 4, %o5
+	and	%o2, %o5, %o5
+	set	0xfff00, %o2
+	and	%o2, %o5, %o5
+	sethi	%hi(0xfff00000), %o2
+	and	%o3, %o2, %o2
+	or	%o5, %o2, %o5	/* Register base address */
+
+	ba	.L_call_one_mem_handler
+	 nop
+
+.L_find_ahb_memctrl:
+	call	_nomem_find_ahb		/* Scan for AHB Slave or Master.
+					 * o5 determine type. */
+	 nop
+	clr	%o5
+
+	/* Call the handler function if the hardware was found
+	 *
+	 * o0 = mem_handler
+	 * o1 = Configuration address
+	 * o2 = AHB Bus index
+	 * o3 = APB Base register (if APB Slave)
+	 *
+	 * Constraints:
+	 * i0-i7, l0, l1, l5, g1, g3-g7 may no be used.
+	 */
+.L_call_one_mem_handler:
+	cmp	%o0, %g0
+	be	.L_all_mctrl_next
+	 mov	%l0, %o0			/* Mem handler pointer */
+	mov	%o3, %o1			/* AMBA PnP Configuration address */
+	mov	%o4, %o2			/* AHB Bus index */
+	ld	[%l0 + MH_FUNC], %o7	/* Get Function pointer */
+	call	%o7
+	 mov	%o5, %o3			/* APB Register Base Address */
+
+	inc	%l1				/* Number of Memory controllers
+						 * handled. */
+
+	/* Do next entry in mem_handlers */
+.L_all_mctrl_next:
+	ba	.L_do_one_mem_handler
+	 add	%l0, MH_STRUCT_SIZE, %l0
+
+.L_all_mctrl_handled:
+	mov	%g1, %o7	/* Restore return address */
+	retl
+	 mov	%l1, %o0
+
+
+
+/* Generic Memory controller initialization routine (APB Registers)
+ *
+ * o0 = mem_handler structure pointer
+ * o1 = Configuration address
+ * o2 = AHB Bus index
+ * o3 = APB Base register
+ *
+ * Clobbered
+ *  o0-o4
+ */
+_nomem_mctrl_init:
+	ld	[%o0 + MH_PRIV], %o0	/* Get Private structure */
+	ld	[%o0], %o1		/* Get Reg Mask */
+	and	%o1, 0xff, %o1
+	add	%o0, REGS_OFS, %o0	/* Point to first reg */
+.L_do_one_reg:
+	andcc	%o1, 0x1, %g0
+	beq	.L_do_next_reg
+	 ld	[%o0], %o2
+	ld	[%o3], %o4
+	and	%o4, %o2, %o4
+	ld	[%o0 + 4], %o2
+	or	%o4, %o2, %o4
+	st	%o4, [%o3]
+
+.L_do_next_reg:
+	add	%o0, REGS_SIZE, %o0
+	add	%o3, 4, %o3
+	srl	%o1, 1, %o1
+	cmp	%o1, 0
+	bne	.L_do_one_reg
+	 nop
+
+	/* No more registers to write */
+	retl
+	 nop
+
+
+
+/* Generic Memory controller initialization routine (AHB Registers)
+ *
+ * o0 = mem_handler structure pointer
+ * o1 = Configuration address of memory controller
+ * o2 = AHB Bus index
+ *
+ * Clobbered
+ *  o0-o5
+ */
+_nomem_ahbmctrl_init:
+	ld	[%o0 + MH_PRIV], %o0		/* Get Private structure */
+
+	/* Get index of AHB MBAR to get registers from */
+	ld	[%o0], %o5			
+	add	%o0, 4, %o0
+
+	/* Get Address of MBAR in PnP info */
+	add	%o5, 4, %o5
+	sll	%o5, 2, %o5
+	add	%o5, %o1, %o5			/* Address of MBAR */
+
+	/* Get Address of registers from PnP information 
+	 * Address is in AHB I/O format, i.e. relative to bus
+	 *
+	 * ADR = (iobar & (iobar << 16) & 0xfff00000)
+	 * IOADR = (ADR >> 12) | "APB Base"
+	 */
+	ld	[%o5], %o5
+	sll	%o5, 16, %o4
+	and	%o5, %o4, %o5
+	sethi	%hi(0xfff00000), %o4
+	and	%o5, %o4, %o5			/* ADR */
+	and	%o4, %o1, %o4
+	srl	%o5, 12, %o5
+	or	%o5, %o4, %o3			/* IOADR in o3 */
+
+	ld	[%o0], %o1			/* Get Reg Mask */
+	and	%o1, 0xff, %o1
+	add	%o0, REGS_OFS, %o0		/* Point to first reg */
+.L_do_one_ahbreg:
+	andcc	%o1, 0x1, %g0
+	beq	.L_do_next_reg
+	 ld	[%o0], %o2
+	ld	[%o3], %o4
+	and	%o4, %o2, %o4
+	ld	[%o0 + 4], %o2
+	or	%o4, %o2, %o4
+	st	%o4, [%o3]
+
+.L_do_next_ahbreg:
+	add	%o0, REGS_SIZE, %o0
+	add	%o3, 4, %o3
+	srl	%o1, 1, %o1
+	cmp	%o1, 0
+	bne	.L_do_one_reg
+	 nop
+
+	/* No more registers to write */
+	retl
+	 nop
diff --git a/cpu/leon3/start.S b/cpu/leon3/start.S
index bd634bd..d9faa86 100644
--- a/cpu/leon3/start.S
+++ b/cpu/leon3/start.S
@@ -29,6 +29,12 @@
 #include <asm/leon.h>
 #include <timestamp.h>
 #include <version.h>
+#include <ambapp.h>
+
+/* Default Plug&Play I/O area */
+#ifndef CONFIG_AMBAPP_IOAREA
+#define CONFIG_AMBAPP_IOAREA AMBA_DEFAULT_IOAREA
+#endif
 
 /* Entry for traps which jump to a programmer-specified trap handler.  */
 #define TRAPR(H)  \
@@ -205,6 +211,7 @@ version_string:
 	.ascii CONFIG_IDENT_STRING, "\0"
 
 	.section	".text"
+	.extern	_nomem_amba_init, _nomem_memory_ctrl_init
 	.align 4
 
 _hardreset:
@@ -256,6 +263,34 @@ stackp:
 	andn	%fp, 0x0f, %fp
 	sub	%fp, 64, %sp
 
+/* Scan AMBA Bus for AMBA buses using PnP information. All found
+ * AMBA buses I/O area will be located in i0-i5 upon return.
+ * The i0-i5 registers are later used by _nomem_amba_init2
+ */
+ambainit:
+	call	_nomem_amba_init
+	 sethi	%hi(CONFIG_AMBAPP_IOAREA), %o0
+
+/* Scan AMBA Buses for memory controllers, then initialize the
+ * memory controllers. Note that before setting up the memory controller
+ * the stack can not be used.
+ */
+memory_ctrl_init:
+ 	sethi	%hi(grlib_mctrl_handlers), %o0
+	call	_nomem_memory_ctrl_init
+	 or	%o0, %lo(grlib_mctrl_handlers), %o0
+
+/* The return valu indicate how many memory controllers where found and 
+ * initialized, if no memory controller was initialized, we can not continue
+ * because from here on we expect memory to be working.
+ */
+	cmp	%o0, 0
+memory_ctrl_init_failed:
+	beq	memory_ctrl_init_failed
+	 nop
+
+/*** From now on the stack can be used. ***/
+
 cpu_init_unreloc:
 	call	cpu_init_f
 	nop
@@ -385,6 +420,7 @@ jump:
 
 	set	board_init_f,%o1
 	set	CONFIG_SYS_RELOC_MONITOR_BASE,%o2
+	set	TEXT_START, %g1
 	add	%o1,%o2,%o1
 	sub	%o1,%g1,%o1
 	call	%o1
diff --git a/include/configs/gr_cpci_ax2000.h b/include/configs/gr_cpci_ax2000.h
index d188439..b9d45dd 100644
--- a/include/configs/gr_cpci_ax2000.h
+++ b/include/configs/gr_cpci_ax2000.h
@@ -340,33 +340,36 @@
 /* AMBA Plug & Play info display on startup */
 /*#define CONFIG_SYS_AMBAPP_PRINT_ON_STARTUP*/
 
-#define CONFIG_SYS_GRLIB_SDRAM    0
+/* No SDRAM Configuration */
+#undef CONFIG_SYS_GRLIB_GAISLER_SDCTRL1
 
 /* See, GRLIB Docs (grip.pdf) on how to set up
  * These the memory controller registers.
  */
-#define CONFIG_SYS_GRLIB_MEMCFG1   (0x10f800ff | (1<<11))
+#define CONFIG_SYS_GRLIB_ESA_MCTRL1
+#define CONFIG_SYS_GRLIB_ESA_MCTRL1_CFG1   (0x10f800ff | (1<<11))
 #if CONFIG_LEON_RAM_SELECT == CONFIG_LEON_RAM_SDRAM_NOSRAM
-#define CONFIG_SYS_GRLIB_MEMCFG2   0x82206000
+#define CONFIG_SYS_GRLIB_ESA_MCTRL1_CFG2   0x82206000
 #else
-#define CONFIG_SYS_GRLIB_MEMCFG2   0x82205260
+#define CONFIG_SYS_GRLIB_ESA_MCTRL1_CFG2   0x82205260
 #endif
-#define CONFIG_SYS_GRLIB_MEMCFG3   0x0809a000
+#define CONFIG_SYS_GRLIB_ESA_MCTRL1_CFG3   0x0809a000
 
-#define CONFIG_SYS_GRLIB_FT_MEMCFG1   (0x10f800ff | (1<<11))
+/* GRLIB FT-MCTRL configuration */
+#define CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1
+#define CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1_CFG1   (0x10f800ff | (1<<11))
 #if CONFIG_LEON_RAM_SELECT == CONFIG_LEON_RAM_SDRAM_NOSRAM
-#define CONFIG_SYS_GRLIB_FT_MEMCFG2   0x82206000
+#define CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1_CFG2   0x82206000
 #else
-#define CONFIG_SYS_GRLIB_FT_MEMCFG2   0x82205260
+#define CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1_CFG2   0x82205260
 #endif
-#define CONFIG_SYS_GRLIB_FT_MEMCFG3   0x0809a000
+#define CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1_CFG3   0x0809a000
 
 /* no DDR controller */
-#define CONFIG_SYS_GRLIB_DDR_CFG   0x00000000
+#undef CONFIG_SYS_GRLIB_GAISLER_DDRSPA1
 
 /* no DDR2 Controller */
-#define CONFIG_SYS_GRLIB_DDR2_CFG1 0x00000000
-#define CONFIG_SYS_GRLIB_DDR2_CFG3 0x00000000
+#undef CONFIG_SYS_GRLIB_GAISLER_DDR2SPA1
 
 /* Calculate scaler register value from default baudrate */
 #define CONFIG_SYS_GRLIB_APBUART_SCALER \
diff --git a/include/configs/gr_ep2s60.h b/include/configs/gr_ep2s60.h
index 3a568ff..6edb92c 100644
--- a/include/configs/gr_ep2s60.h
+++ b/include/configs/gr_ep2s60.h
@@ -326,23 +326,29 @@
 /* AMBA Plug & Play info display on startup */
 /*#define CONFIG_SYS_AMBAPP_PRINT_ON_STARTUP*/
 
-#define CONFIG_SYS_GRLIB_SDRAM    0
+/* No SDRAM Configuration */
+#undef CONFIG_SYS_GRLIB_GAISLER_SDCTRL1
 
 /* See, GRLIB Docs (grip.pdf) on how to set up
  * These the memory controller registers.
  */
-#define CONFIG_SYS_GRLIB_MEMCFG1  (0x10f800ff | (1<<11))
-#define CONFIG_SYS_GRLIB_MEMCFG2  0x00000000
-#define CONFIG_SYS_GRLIB_MEMCFG3  0x00000000
-
-#define CONFIG_SYS_GRLIB_FT_MEMCFG1  (0x10f800ff | (1<<11))
-#define CONFIG_SYS_GRLIB_FT_MEMCFG2  0x00000000
-#define CONFIG_SYS_GRLIB_FT_MEMCFG3  0x00000000
-
-#define CONFIG_SYS_GRLIB_DDR_CFG  0xa900830a
-
-#define CONFIG_SYS_GRLIB_DDR2_CFG1 0x00000000
-#define CONFIG_SYS_GRLIB_DDR2_CFG3 0x00000000
+#define CONFIG_SYS_GRLIB_ESA_MCTRL1
+#define CONFIG_SYS_GRLIB_ESA_MCTRL1_CFG1  (0x10f800ff | (1<<11))
+#define CONFIG_SYS_GRLIB_ESA_MCTRL1_CFG2  0x00000000
+#define CONFIG_SYS_GRLIB_ESA_MCTRL1_CFG3  0x00000000
+
+/* GRLIB FT-MCTRL configuration */
+#define CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1
+#define CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1_CFG1  (0x10f800ff | (1<<11))
+#define CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1_CFG2  0x00000000
+#define CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1_CFG3  0x00000000
+
+/* DDR controller */
+#define CONFIG_SYS_GRLIB_GAISLER_DDRSPA1
+#define CONFIG_SYS_GRLIB_GAISLER_DDRSPA1_CTRL  0xa900830a
+
+/* no DDR2 Controller */
+#undef CONFIG_SYS_GRLIB_GAISLER_DDR2SPA1
 
 /* Calculate scaler register value from default baudrate */
 #define CONFIG_SYS_GRLIB_APBUART_SCALER \
diff --git a/include/configs/gr_xc3s_1500.h b/include/configs/gr_xc3s_1500.h
index 4dd9a0f..1f9dd4a 100644
--- a/include/configs/gr_xc3s_1500.h
+++ b/include/configs/gr_xc3s_1500.h
@@ -288,25 +288,28 @@
 /* AMBA Plug & Play info display on startup */
 /*#define CONFIG_SYS_AMBAPP_PRINT_ON_STARTUP*/
 
-#define CONFIG_SYS_GRLIB_SDRAM    0
+/* No SDRAM Configuration */
+#undef CONFIG_SYS_GRLIB_GAISLER_SDCTRL1
 
 /* See, GRLIB Docs (grip.pdf) on how to set up
  * These the memory controller registers.
  */
-#define CONFIG_SYS_GRLIB_MEMCFG1   (0x000000ff | (1<<11))
-#define CONFIG_SYS_GRLIB_MEMCFG2   0x82206000
-#define CONFIG_SYS_GRLIB_MEMCFG3   0x00136000
+#define CONFIG_SYS_GRLIB_ESA_MCTRL1
+#define CONFIG_SYS_GRLIB_ESA_MCTRL1_CFG1   (0x000000ff | (1<<11))
+#define CONFIG_SYS_GRLIB_ESA_MCTRL1_CFG2   0x82206000
+#define CONFIG_SYS_GRLIB_ESA_MCTRL1_CFG3   0x00136000
 
-#define CONFIG_SYS_GRLIB_FT_MEMCFG1   (0x000000ff | (1<<11))
-#define CONFIG_SYS_GRLIB_FT_MEMCFG2   0x82206000
-#define CONFIG_SYS_GRLIB_FT_MEMCFG3   0x00136000
+/* GRLIB FT-MCTRL configuration */
+#define CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1
+#define CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1_CFG1   (0x000000ff | (1<<11))
+#define CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1_CFG2   0x82206000
+#define CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1_CFG3   0x00136000
 
 /* no DDR controller */
-#define CONFIG_SYS_GRLIB_DDR_CFG   0x00000000
+#undef CONFIG_SYS_GRLIB_GAISLER_DDRSPA1
 
 /* no DDR2 Controller */
-#define CONFIG_SYS_GRLIB_DDR2_CFG1 0x00000000
-#define CONFIG_SYS_GRLIB_DDR2_CFG3 0x00000000
+#undef CONFIG_SYS_GRLIB_GAISLER_DDR2SPA1
 
 /* Calculate scaler register value from default baudrate */
 #define CONFIG_SYS_GRLIB_APBUART_SCALER \
diff --git a/include/configs/grsim.h b/include/configs/grsim.h
index c3f1a31..f815672 100644
--- a/include/configs/grsim.h
+++ b/include/configs/grsim.h
@@ -307,27 +307,32 @@
 /* AMBA Plug & Play info display on startup */
 /*#define CONFIG_SYS_AMBAPP_PRINT_ON_STARTUP*/
 
-#define CONFIG_SYS_GRLIB_SDRAM     0
-#define CONFIG_SYS_GRLIB_MEMCFG1   (0x000000ff | (1<<11))
+/* No SDRAM Configuration */
+#undef CONFIG_SYS_GRLIB_GAISLER_SDCTRL1
+
+/* LEON2 MCTRL configuration */
+#define CONFIG_SYS_GRLIB_ESA_MCTRL1
+#define CONFIG_SYS_GRLIB_ESA_MCTRL1_CFG1   (0x000000ff | (1<<11))
 #if CONFIG_GRSIM
 /* GRSIM configuration */
-#define CONFIG_SYS_GRLIB_MEMCFG2   0x82206000
+#define CONFIG_SYS_GRLIB_ESA_MCTRL1_CFG2   0x82206000
 #else
 /* TSIM configuration */
-#define CONFIG_SYS_GRLIB_MEMCFG2   0x00001820
+#define CONFIG_SYS_GRLIB_ESA_MCTRL1_CFG2   0x00001820
 #endif
-#define CONFIG_SYS_GRLIB_MEMCFG3   0x00136000
+#define CONFIG_SYS_GRLIB_ESA_MCTRL1_CFG3   0x00136000
 
-#define CONFIG_SYS_GRLIB_FT_MEMCFG1   (0x000000ff | (1<<11))
-#define CONFIG_SYS_GRLIB_FT_MEMCFG2   0x82206000
-#define CONFIG_SYS_GRLIB_FT_MEMCFG3   0x00136000
+/* GRLIB FT-MCTRL configuration */
+#define CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1
+#define CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1_CFG1   (0x000000ff | (1<<11))
+#define CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1_CFG2   0x82206000
+#define CONFIG_SYS_GRLIB_GAISLER_FTMCTRL1_CFG3   0x00136000
 
 /* no DDR controller */
-#define CONFIG_SYS_GRLIB_DDR_CFG   0x00000000
+#undef CONFIG_SYS_GRLIB_GAISLER_DDRSPA1
 
 /* no DDR2 Controller */
-#define CONFIG_SYS_GRLIB_DDR2_CFG1 0x00000000
-#define CONFIG_SYS_GRLIB_DDR2_CFG3 0x00000000
+#undef CONFIG_SYS_GRLIB_GAISLER_DDR2SPA1
 
 #define CONFIG_SYS_GRLIB_APBUART_SCALER \
  ((((CONFIG_SYS_CLK_FREQ*10)/(CONFIG_BAUDRATE*8))-5)/10)
-- 
1.5.4

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [U-Boot] [PATCH 06/17] LEON3: Moved GRLIB core header files to common include/grlib directory
  2010-01-28 12:16 [U-Boot] [PATCH 01/17] SPARC: added unaligned definitions, patch supplied by Magnus Sjalander Daniel Hellstrom
                   ` (3 preceding siblings ...)
  2010-01-28 12:16 ` [U-Boot] [PATCH 05/17] LEON3: added memory controller initialization using the new AMBA PnP routines Daniel Hellstrom
@ 2010-01-28 12:16 ` Daniel Hellstrom
  2010-01-28 12:16 ` [U-Boot] [PATCH 07/17] LEON3: serial baud rate register support multiple buses with different frequency Daniel Hellstrom
                   ` (12 subsequent siblings)
  17 siblings, 0 replies; 26+ messages in thread
From: Daniel Hellstrom @ 2010-01-28 12:16 UTC (permalink / raw)
  To: u-boot

Signed-off-by: Daniel Hellstrom <daniel@gaisler.com>
---
 cpu/leon3/cpu_init.c    |   10 ++--
 cpu/leon3/interrupts.c  |    7 ++-
 cpu/leon3/memcfg.h      |    1 -
 cpu/leon3/prom.c        |    7 ++-
 cpu/leon3/serial.c      |   16 +++---
 drivers/net/greth.c     |    2 +-
 include/ambapp.h        |  137 -----------------------------------------------
 include/grlib/apbuart.h |   63 +++++++++++++++++++++
 include/grlib/gptimer.h |   50 +++++++++++++++++
 include/grlib/greth.h   |  103 +++++++++++++++++++++++++++++++++++
 include/grlib/irqmp.h   |   39 +++++++++++++
 11 files changed, 277 insertions(+), 158 deletions(-)
 create mode 100644 include/grlib/apbuart.h
 create mode 100644 include/grlib/gptimer.h
 create mode 100644 include/grlib/greth.h
 create mode 100644 include/grlib/irqmp.h

diff --git a/cpu/leon3/cpu_init.c b/cpu/leon3/cpu_init.c
index 046cfb8..e2e1181 100644
--- a/cpu/leon3/cpu_init.c
+++ b/cpu/leon3/cpu_init.c
@@ -28,6 +28,8 @@
 #include <asm/asi.h>
 #include <asm/leon.h>
 #include <ambapp.h>
+#include <grlib/irqmp.h>
+#include <grlib/gptimer.h>
 
 #include <config.h>
 
@@ -41,11 +43,7 @@ DECLARE_GLOBAL_DATA_PTR;
 /* reset CPU (jump to 0, without reset) */
 void start(void);
 
-/* find & initialize the memory controller */
-int init_memory_ctrl(void);
-
 ambapp_dev_irqmp *irqmp = NULL;
-ambapp_dev_mctrl memctrl;
 ambapp_dev_gptimer *gptimer = NULL;
 unsigned int gptimer_irq = 0;
 int leon3_snooping_avail = 0;
@@ -164,8 +162,8 @@ int timer_interrupt_init_cpu(void)
 	gptimer->e[0].val = 0;
 	gptimer->e[0].rld = 999;	/* (((1000000 / 100) - 1)) */
 	gptimer->e[0].ctrl =
-	    (LEON3_GPTIMER_EN |
-	     LEON3_GPTIMER_RL | LEON3_GPTIMER_LD | LEON3_GPTIMER_IRQEN);
+	    (GPTIMER_CTRL_EN | GPTIMER_CTRL_RS |
+	     GPTIMER_CTRL_LD | GPTIMER_CTRL_IE);
 
 	return gptimer_irq;
 }
diff --git a/cpu/leon3/interrupts.c b/cpu/leon3/interrupts.c
index ac6aca5..d927de1 100644
--- a/cpu/leon3/interrupts.c
+++ b/cpu/leon3/interrupts.c
@@ -39,6 +39,8 @@
 
 #include <asm/leon.h>
 #include <ambapp.h>
+#include <grlib/irqmp.h>
+#include <grlib/gptimer.h>
 
 /* 15 normal irqs and a non maskable interrupt */
 #define NR_IRQS 15
@@ -141,9 +143,8 @@ int interrupt_init_cpu(void)
 /* Handle Timer 0 IRQ */
 void timer_interrupt_cpu(void *arg)
 {
-	gptimer->e[0].ctrl = (LEON3_GPTIMER_EN |
-			      LEON3_GPTIMER_RL |
-			      LEON3_GPTIMER_LD | LEON3_GPTIMER_IRQEN);
+	gptimer->e[0].ctrl = (GPTIMER_CTRL_EN | GPTIMER_CTRL_RS |
+			      GPTIMER_CTRL_LD | GPTIMER_CTRL_IE);
 	/* nothing to do here */
 	return;
 }
diff --git a/cpu/leon3/memcfg.h b/cpu/leon3/memcfg.h
index 0b4738e..02086ce 100644
--- a/cpu/leon3/memcfg.h
+++ b/cpu/leon3/memcfg.h
@@ -54,7 +54,6 @@ extern struct grlib_mctrl_handler grlib_mctrl_handlers[];
 #define MH_STRUCT_SIZE		(4*4)
 #define MH_TYPE			0x00
 #define MH_INDEX		0x01
-#define MH_UNUSED		0x02
 #define MH_VENDOR_DEVICE	0x04
 #define MH_FUNC			0x08
 #define MH_PRIV			0x0c
diff --git a/cpu/leon3/prom.c b/cpu/leon3/prom.c
index 18d2fb2..86376bb 100644
--- a/cpu/leon3/prom.c
+++ b/cpu/leon3/prom.c
@@ -32,6 +32,9 @@
 #include <asm/irq.h>
 #include <asm/leon.h>
 #include <ambapp.h>
+#include <grlib/apbuart.h>
+#include <grlib/irqmp.h>
+#include <grlib/gptimer.h>
 
 #include <config.h>
 /*
@@ -757,14 +760,14 @@ static int PROM_TEXT leon_nbputchar(int c)
 
 	/* Wait for last character to go. */
 	while (!(SPARC_BYPASS_READ(&uart->status)
-		 & LEON_REG_UART_STATUS_THE)) ;
+		 & APBUART_STATUS_THE)) ;
 
 	/* Send data */
 	SPARC_BYPASS_WRITE(&uart->data, c);
 
 	/* Wait for data to be sent */
 	while (!(SPARC_BYPASS_READ(&uart->status)
-		 & LEON_REG_UART_STATUS_TSE)) ;
+		 & APBUART_STATUS_TSE)) ;
 
 	return 0;
 }
diff --git a/cpu/leon3/serial.c b/cpu/leon3/serial.c
index 15c380e..8964310 100644
--- a/cpu/leon3/serial.c
+++ b/cpu/leon3/serial.c
@@ -27,6 +27,7 @@
 #include <asm/processor.h>
 #include <asm/leon.h>
 #include <ambapp.h>
+#include <grlib/apbuart.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -69,9 +70,9 @@ int serial_init(void)
 		/* Let bit 11 be unchanged (debug bit for GRMON) */
 		tmp = READ_WORD(leon3_apbuart->ctrl);
 
-		leon3_apbuart->ctrl = ((tmp & LEON_REG_UART_CTRL_DBG) |
-				       LEON_REG_UART_CTRL_RE |
-				       LEON_REG_UART_CTRL_TE);
+		leon3_apbuart->ctrl = ((tmp & APBUART_CTRL_DBG) |
+				       APBUART_CTRL_RE |
+				       APBUART_CTRL_TE);
 
 		return 0;
 	}
@@ -92,14 +93,14 @@ void serial_putc_raw(const char c)
 		return;
 
 	/* Wait for last character to go. */
-	while (!(READ_WORD(leon3_apbuart->status) & LEON_REG_UART_STATUS_THE)) ;
+	while (!(READ_WORD(leon3_apbuart->status) & APBUART_STATUS_THE)) ;
 
 	/* Send data */
 	leon3_apbuart->data = c;
 
 #ifdef LEON_DEBUG
 	/* Wait for data to be sent */
-	while (!(READ_WORD(leon3_apbuart->status) & LEON_REG_UART_STATUS_TSE)) ;
+	while (!(READ_WORD(leon3_apbuart->status) & APBUART_STATUS_TSE)) ;
 #endif
 }
 
@@ -116,7 +117,7 @@ int serial_getc(void)
 		return 0;
 
 	/* Wait for a character to arrive. */
-	while (!(READ_WORD(leon3_apbuart->status) & LEON_REG_UART_STATUS_DR)) ;
+	while (!(READ_WORD(leon3_apbuart->status) & APBUART_STATUS_DR)) ;
 
 	/* read data */
 	return READ_WORD(leon3_apbuart->data);
@@ -125,8 +126,7 @@ int serial_getc(void)
 int serial_tstc(void)
 {
 	if (leon3_apbuart)
-		return (READ_WORD(leon3_apbuart->status) &
-			LEON_REG_UART_STATUS_DR);
+		return (READ_WORD(leon3_apbuart->status) & APBUART_STATUS_DR);
 	return 0;
 }
 
diff --git a/drivers/net/greth.c b/drivers/net/greth.c
index 5ac0379..582bc81 100644
--- a/drivers/net/greth.c
+++ b/drivers/net/greth.c
@@ -35,7 +35,7 @@
 
 /* #define DEBUG */
 
-#include "greth.h"
+#include <grlib/greth.h>
 
 /* Default to 3s timeout on autonegotiation */
 #ifndef GRETH_PHY_TIMEOUT_MS
diff --git a/include/ambapp.h b/include/ambapp.h
index c1c07aa..2a4c966 100644
--- a/include/ambapp.h
+++ b/include/ambapp.h
@@ -239,141 +239,4 @@ char *ambapp_device_id2desc(int vendor, int id);
 
 #define amba_apb_mask(iobar) ((~(amba_membar_mask(iobar)<<8) & 0x000fffff) + 1)
 
-/*************************** AMBA Plug&Play device register MAPS *****************/
-
-/*
- *  The following defines the bits in the LEON UART Status Registers.
- */
-
-#define LEON_REG_UART_STATUS_DR   0x00000001	/* Data Ready */
-#define LEON_REG_UART_STATUS_TSE  0x00000002	/* TX Send Register Empty */
-#define LEON_REG_UART_STATUS_THE  0x00000004	/* TX Hold Register Empty */
-#define LEON_REG_UART_STATUS_BR   0x00000008	/* Break Error */
-#define LEON_REG_UART_STATUS_OE   0x00000010	/* RX Overrun Error */
-#define LEON_REG_UART_STATUS_PE   0x00000020	/* RX Parity Error */
-#define LEON_REG_UART_STATUS_FE   0x00000040	/* RX Framing Error */
-#define LEON_REG_UART_STATUS_ERR  0x00000078	/* Error Mask */
-
-/*
- *  The following defines the bits in the LEON UART Ctrl Registers.
- */
-
-#define LEON_REG_UART_CTRL_RE     0x00000001	/* Receiver enable */
-#define LEON_REG_UART_CTRL_TE     0x00000002	/* Transmitter enable */
-#define LEON_REG_UART_CTRL_RI     0x00000004	/* Receiver interrupt enable */
-#define LEON_REG_UART_CTRL_TI     0x00000008	/* Transmitter interrupt enable */
-#define LEON_REG_UART_CTRL_PS     0x00000010	/* Parity select */
-#define LEON_REG_UART_CTRL_PE     0x00000020	/* Parity enable */
-#define LEON_REG_UART_CTRL_FL     0x00000040	/* Flow control enable */
-#define LEON_REG_UART_CTRL_LB     0x00000080	/* Loop Back enable */
-#define LEON_REG_UART_CTRL_DBG    (1<<11)	/* Debug Bit used by GRMON */
-
-#define LEON3_GPTIMER_EN 1
-#define LEON3_GPTIMER_RL 2
-#define LEON3_GPTIMER_LD 4
-#define LEON3_GPTIMER_IRQEN 8
-
-/*
- *  The following defines the bits in the LEON PS/2 Status Registers.
- */
-
-#define LEON_REG_PS2_STATUS_DR   0x00000001	/* Data Ready */
-#define LEON_REG_PS2_STATUS_PE   0x00000002	/* Parity error */
-#define LEON_REG_PS2_STATUS_FE   0x00000004	/* Framing error */
-#define LEON_REG_PS2_STATUS_KI   0x00000008	/* Keyboard inhibit */
-
-/*
- *  The following defines the bits in the LEON PS/2 Ctrl Registers.
- */
-
-#define LEON_REG_PS2_CTRL_RE     0x00000001	/* Receiver enable */
-#define LEON_REG_PS2_CTRL_TE     0x00000002	/* Transmitter enable */
-#define LEON_REG_PS2_CTRL_RI     0x00000004	/* Keyboard receive interrupt  */
-#define LEON_REG_PS2_CTRL_TI     0x00000008	/* Keyboard transmit interrupt */
-
-#ifndef __ASSEMBLER__
-
-typedef struct {
-	volatile unsigned int ilevel;
-	volatile unsigned int ipend;
-	volatile unsigned int iforce;
-	volatile unsigned int iclear;
-	volatile unsigned int mstatus;
-	volatile unsigned int notused[11];
-	volatile unsigned int cpu_mask[16];
-	volatile unsigned int cpu_force[16];
-} ambapp_dev_irqmp;
-
-typedef struct {
-	volatile unsigned int data;
-	volatile unsigned int status;
-	volatile unsigned int ctrl;
-	volatile unsigned int scaler;
-} ambapp_dev_apbuart;
-
-typedef struct {
-	volatile unsigned int val;
-	volatile unsigned int rld;
-	volatile unsigned int ctrl;
-	volatile unsigned int unused;
-} ambapp_dev_gptimer_element;
-
-#define LEON3_GPTIMER_CTRL_EN	0x1	/* Timer enable */
-#define LEON3_GPTIMER_CTRL_RS	0x2	/* Timer reStart  */
-#define LEON3_GPTIMER_CTRL_LD	0x4	/* Timer reLoad */
-#define LEON3_GPTIMER_CTRL_IE	0x8	/* interrupt enable */
-#define LEON3_GPTIMER_CTRL_IP	0x10	/* interrupt flag/pending */
-#define LEON3_GPTIMER_CTRL_CH	0x20	/* Chain with previous timer */
-
-typedef struct {
-	volatile unsigned int scalar;
-	volatile unsigned int scalar_reload;
-	volatile unsigned int config;
-	volatile unsigned int unused;
-	volatile ambapp_dev_gptimer_element e[8];
-} ambapp_dev_gptimer;
-
-typedef struct {
-	volatile unsigned int iodata;
-	volatile unsigned int ioout;
-	volatile unsigned int iodir;
-	volatile unsigned int irqmask;
-	volatile unsigned int irqpol;
-	volatile unsigned int irqedge;
-} ambapp_dev_ioport;
-
-typedef struct {
-	volatile unsigned int write;
-	volatile unsigned int dummy;
-	volatile unsigned int txcolor;
-	volatile unsigned int bgcolor;
-} ambapp_dev_textvga;
-
-typedef struct {
-	volatile unsigned int data;
-	volatile unsigned int status;
-	volatile unsigned int ctrl;
-} ambapp_dev_apbps2;
-
-typedef struct {
-	unsigned int mcfg1, mcfg2, mcfg3;
-} ambapp_dev_mctrl;
-
-typedef struct {
-	unsigned int sdcfg;
-} ambapp_dev_sdctrl;
-
-typedef struct {
-	unsigned int cfg1;
-	unsigned int cfg2;
-	unsigned int cfg3;
-} ambapp_dev_ddr2spa;
-
-typedef struct {
-	unsigned int ctrl;
-	unsigned int cfg;
-} ambapp_dev_ddrspa;
-
-#endif
-
 #endif
diff --git a/include/grlib/apbuart.h b/include/grlib/apbuart.h
new file mode 100644
index 0000000..92bbcdf
--- /dev/null
+++ b/include/grlib/apbuart.h
@@ -0,0 +1,63 @@
+/* GRLIB APBUART definitions
+ *
+ * (C) Copyright 2010
+ * Daniel Hellstrom, Aeroflex Gaisler, daniel at gaisler.com
+ *
+ * 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
+ */
+
+#ifndef __GRLIB_APBUART_H__
+#define __GRLIB_APBUART_H__
+
+/* APBUART Register map */
+typedef struct {
+	volatile unsigned int data;
+	volatile unsigned int status;
+	volatile unsigned int ctrl;
+	volatile unsigned int scaler;
+} ambapp_dev_apbuart;
+
+/*
+ *  The following defines the bits in the LEON UART Status Registers.
+ */
+
+#define APBUART_STATUS_DR   0x00000001	/* Data Ready */
+#define APBUART_STATUS_TSE  0x00000002	/* TX Send Register Empty */
+#define APBUART_STATUS_THE  0x00000004	/* TX Hold Register Empty */
+#define APBUART_STATUS_BR   0x00000008	/* Break Error */
+#define APBUART_STATUS_OE   0x00000010	/* RX Overrun Error */
+#define APBUART_STATUS_PE   0x00000020	/* RX Parity Error */
+#define APBUART_STATUS_FE   0x00000040	/* RX Framing Error */
+#define APBUART_STATUS_ERR  0x00000078	/* Error Mask */
+
+/*
+ *  The following defines the bits in the LEON UART Ctrl Registers.
+ */
+
+#define APBUART_CTRL_RE     0x00000001	/* Receiver enable */
+#define APBUART_CTRL_TE     0x00000002	/* Transmitter enable */
+#define APBUART_CTRL_RI     0x00000004	/* Receiver interrupt enable */
+#define APBUART_CTRL_TI     0x00000008	/* Transmitter interrupt enable */
+#define APBUART_CTRL_PS     0x00000010	/* Parity select */
+#define APBUART_CTRL_PE     0x00000020	/* Parity enable */
+#define APBUART_CTRL_FL     0x00000040	/* Flow control enable */
+#define APBUART_CTRL_LB     0x00000080	/* Loop Back enable */
+#define APBUART_CTRL_DBG    (1<<11)	/* Debug Bit used by GRMON */
+
+#endif
diff --git a/include/grlib/gptimer.h b/include/grlib/gptimer.h
new file mode 100644
index 0000000..4e79874
--- /dev/null
+++ b/include/grlib/gptimer.h
@@ -0,0 +1,50 @@
+/* GRLIB GPTIMER (General Purpose Timer) definitions
+ *
+ * (C) Copyright 2010
+ * Daniel Hellstrom, Aeroflex Gaisler, daniel at gaisler.com
+ *
+ * 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
+ */
+
+#ifndef __GRLIB_GPTIMER_H__
+#define __GRLIB_GPTIMER_H__
+
+typedef struct {
+	volatile unsigned int val;
+	volatile unsigned int rld;
+	volatile unsigned int ctrl;
+	volatile unsigned int unused;
+} ambapp_dev_gptimer_element;
+
+#define GPTIMER_CTRL_EN	0x1	/* Timer enable */
+#define GPTIMER_CTRL_RS	0x2	/* Timer reStart  */
+#define GPTIMER_CTRL_LD	0x4	/* Timer reLoad */
+#define GPTIMER_CTRL_IE	0x8	/* interrupt enable */
+#define GPTIMER_CTRL_IP	0x10	/* interrupt flag/pending */
+#define GPTIMER_CTRL_CH	0x20	/* Chain with previous timer */
+
+typedef struct {
+	volatile unsigned int scalar;
+	volatile unsigned int scalar_reload;
+	volatile unsigned int config;
+	volatile unsigned int unused;
+	volatile ambapp_dev_gptimer_element e[8];
+} ambapp_dev_gptimer;
+
+#endif
diff --git a/include/grlib/greth.h b/include/grlib/greth.h
new file mode 100644
index 0000000..08cdad4
--- /dev/null
+++ b/include/grlib/greth.h
@@ -0,0 +1,103 @@
+/* Gaisler.com GRETH 10/100/1000 Ethernet MAC definitions
+ *
+ * (C) Copyright 2010
+ * Daniel Hellstrom, Aeroflex Gaisler, daniel at gaisler.com
+ *
+ * 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
+ */
+
+#ifndef __GRLIB_GRETH_H__
+#define __GRLIB_GRETH_H__
+
+#define GRETH_FD 0x10
+#define GRETH_RESET 0x40
+#define GRETH_MII_BUSY 0x8
+#define GRETH_MII_NVALID 0x10
+
+/* MII registers */
+#define GRETH_MII_EXTADV_1000FD 0x00000200
+#define GRETH_MII_EXTADV_1000HD 0x00000100
+#define GRETH_MII_EXTPRT_1000FD 0x00000800
+#define GRETH_MII_EXTPRT_1000HD 0x00000400
+
+#define GRETH_MII_100T4 0x00000200
+#define GRETH_MII_100TXFD 0x00000100
+#define GRETH_MII_100TXHD 0x00000080
+#define GRETH_MII_10FD 0x00000040
+#define GRETH_MII_10HD 0x00000020
+
+#define GRETH_BD_EN 0x800
+#define GRETH_BD_WR 0x1000
+#define GRETH_BD_IE 0x2000
+#define GRETH_BD_LEN 0x7FF
+
+#define GRETH_TXEN 0x1
+#define GRETH_INT_TX 0x8
+#define GRETH_TXI 0x4
+#define GRETH_TXBD_STATUS 0x0001C000
+#define GRETH_TXBD_MORE 0x20000
+#define GRETH_TXBD_IPCS 0x40000
+#define GRETH_TXBD_TCPCS 0x80000
+#define GRETH_TXBD_UDPCS 0x100000
+#define GRETH_TXBD_ERR_LC 0x10000
+#define GRETH_TXBD_ERR_UE 0x4000
+#define GRETH_TXBD_ERR_AL 0x8000
+#define GRETH_TXBD_NUM 128
+#define GRETH_TXBD_NUM_MASK (GRETH_TXBD_NUM-1)
+#define GRETH_TX_BUF_SIZE 2048
+
+#define GRETH_INT_RX         0x4
+#define GRETH_RXEN           0x2
+#define GRETH_RXI            0x8
+#define GRETH_RXBD_STATUS    0xFFFFC000
+#define GRETH_RXBD_ERR_AE    0x4000
+#define GRETH_RXBD_ERR_FT    0x8000
+#define GRETH_RXBD_ERR_CRC   0x10000
+#define GRETH_RXBD_ERR_OE    0x20000
+#define GRETH_RXBD_ERR_LE    0x40000
+#define GRETH_RXBD_IP_DEC    0x80000
+#define GRETH_RXBD_IP_CSERR  0x100000
+#define GRETH_RXBD_UDP_DEC   0x200000
+#define GRETH_RXBD_UDP_CSERR 0x400000
+#define GRETH_RXBD_TCP_DEC   0x800000
+#define GRETH_RXBD_TCP_CSERR 0x1000000
+
+#define GRETH_RXBD_NUM 128
+#define GRETH_RXBD_NUM_MASK (GRETH_RXBD_NUM-1)
+#define GRETH_RX_BUF_SIZE 2048
+
+/* Ethernet configuration registers */
+typedef struct _greth_regs {
+	volatile unsigned int control;
+	volatile unsigned int status;
+	volatile unsigned int esa_msb;
+	volatile unsigned int esa_lsb;
+	volatile unsigned int mdio;
+	volatile unsigned int tx_desc_p;
+	volatile unsigned int rx_desc_p;
+	volatile unsigned int edcl_ip;
+} greth_regs;
+
+/* Ethernet buffer descriptor */
+typedef struct _greth_bd {
+	volatile unsigned int stat;
+	unsigned int addr;	/* Buffer address not changed by HW */
+} greth_bd;
+
+#endif
diff --git a/include/grlib/irqmp.h b/include/grlib/irqmp.h
new file mode 100644
index 0000000..1cf45ee
--- /dev/null
+++ b/include/grlib/irqmp.h
@@ -0,0 +1,39 @@
+/* GRLIB IRQMP (IRQ Multi-processor controller) definitions
+ *
+ * (C) Copyright 2010
+ * Daniel Hellstrom, Aeroflex Gaisler, daniel@gaisler.com
+ *
+ * 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
+ */
+
+#ifndef __GRLIB_IRQMP_H__
+#define __GRLIB_IRQMP_H__
+
+typedef struct {
+	volatile unsigned int ilevel;
+	volatile unsigned int ipend;
+	volatile unsigned int iforce;
+	volatile unsigned int iclear;
+	volatile unsigned int mstatus;
+	volatile unsigned int notused[11];
+	volatile unsigned int cpu_mask[16];
+	volatile unsigned int cpu_force[16];
+} ambapp_dev_irqmp;
+
+#endif
-- 
1.5.4

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [U-Boot] [PATCH 07/17] LEON3: serial baud rate register support multiple buses with different frequency.
  2010-01-28 12:16 [U-Boot] [PATCH 01/17] SPARC: added unaligned definitions, patch supplied by Magnus Sjalander Daniel Hellstrom
                   ` (4 preceding siblings ...)
  2010-01-28 12:16 ` [U-Boot] [PATCH 06/17] LEON3: Moved GRLIB core header files to common include/grlib directory Daniel Hellstrom
@ 2010-01-28 12:16 ` Daniel Hellstrom
  2010-01-28 12:16 ` [U-Boot] [PATCH 08/17] SPARC: added function that checks if IRQ is on or off Daniel Hellstrom
                   ` (11 subsequent siblings)
  17 siblings, 0 replies; 26+ messages in thread
From: Daniel Hellstrom @ 2010-01-28 12:16 UTC (permalink / raw)
  To: u-boot

Signed-off-by: Daniel Hellstrom <daniel@gaisler.com>
---
 cpu/leon3/serial.c |   17 ++++++++++++++---
 1 files changed, 14 insertions(+), 3 deletions(-)

diff --git a/cpu/leon3/serial.c b/cpu/leon3/serial.c
index 8964310..1f17ede 100644
--- a/cpu/leon3/serial.c
+++ b/cpu/leon3/serial.c
@@ -47,11 +47,18 @@ DECLARE_GLOBAL_DATA_PTR;
 #endif
 
 ambapp_dev_apbuart *leon3_apbuart = NULL;
+unsigned int apbuart_freq = CONFIG_SYS_CLK_FREQ;
+
+unsigned int apbuart_calc_scaler(unsigned int apbuart_freq, unsigned int baud)
+{
+	return ((((apbuart_freq*10)/(baud*8))-5)/10);
+}
 
 int serial_init(void)
 {
 	ambapp_apbdev apbdev;
 	unsigned int tmp;
+	unsigned int freq;
 
 	/* find UART */
 	if (ambapp_apb_find(&ambapp_plb, VENDOR_GAISLER, GAISLER_APBUART,
@@ -65,7 +72,13 @@ int serial_init(void)
 		 *
 		 * Receiver & transmitter enable
 		 */
+#ifdef CONFIG_SYS_GRLIB_APBUART_SCALER
 		leon3_apbuart->scaler = CONFIG_SYS_GRLIB_APBUART_SCALER;
+#else
+		/* APBUART Frequency is equal to bus frequency */
+		freq = ambapp_bus_freq(&ambapp_plb, apbdev.ahb_bus_index);
+		leon3_apbuart->scaler = apbuart_calc_scaler(freq, CONFIG_BAUDRATE);
+#endif
 
 		/* Let bit 11 be unchanged (debug bit for GRMON) */
 		tmp = READ_WORD(leon3_apbuart->ctrl);
@@ -136,9 +149,7 @@ void serial_setbrg(void)
 	/* update baud rate settings, read it from gd->baudrate */
 	unsigned int scaler;
 	if (leon3_apbuart && (gd->baudrate > 0)) {
-		scaler =
-		    (((CONFIG_SYS_CLK_FREQ * 10) / (gd->baudrate * 8)) -
-		     5) / 10;
+		scaler = apbuart_calc_scaler(apbuart_freq, gd->baudrate);
 		leon3_apbuart->scaler = scaler;
 	}
 	return;
-- 
1.5.4

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [U-Boot] [PATCH 08/17] SPARC: added function that checks if IRQ is on or off.
  2010-01-28 12:16 [U-Boot] [PATCH 01/17] SPARC: added unaligned definitions, patch supplied by Magnus Sjalander Daniel Hellstrom
                   ` (5 preceding siblings ...)
  2010-01-28 12:16 ` [U-Boot] [PATCH 07/17] LEON3: serial baud rate register support multiple buses with different frequency Daniel Hellstrom
@ 2010-01-28 12:16 ` Daniel Hellstrom
  2010-01-28 12:16 ` [U-Boot] [PATCH 09/17] LEON3: added busy wait function, made wait_ms() work when IRQ is disabled Daniel Hellstrom
                   ` (10 subsequent siblings)
  17 siblings, 0 replies; 26+ messages in thread
From: Daniel Hellstrom @ 2010-01-28 12:16 UTC (permalink / raw)
  To: u-boot

Signed-off-by: Daniel Hellstrom <daniel@gaisler.com>
---
 include/asm-sparc/irq.h |    3 +++
 lib_sparc/interrupts.c  |    7 +++++++
 2 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/include/asm-sparc/irq.h b/include/asm-sparc/irq.h
index c5538c0..ce78169 100644
--- a/include/asm-sparc/irq.h
+++ b/include/asm-sparc/irq.h
@@ -46,4 +46,7 @@ extern int intLock(void);
 /* Sets the PIL to oldLevel */
 extern void intUnlock(int oldLevel);
 
+/* Return non-zero if interrupts are currently enabled */
+extern int interrupt_is_enabled(void);
+
 #endif
diff --git a/lib_sparc/interrupts.c b/lib_sparc/interrupts.c
index 4c73b82..4d53e8c 100644
--- a/lib_sparc/interrupts.c
+++ b/lib_sparc/interrupts.c
@@ -63,6 +63,13 @@ int disable_interrupts(void)
 	return intLock();
 }
 
+int interrupt_is_enabled(void)
+{
+	if ( get_pil() == 15 )
+		return 0;
+	return 1;
+}
+
 int interrupt_init(void)
 {
 	int ret;
-- 
1.5.4

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [U-Boot] [PATCH 09/17] LEON3: added busy wait function, made wait_ms() work when IRQ is disabled.
  2010-01-28 12:16 [U-Boot] [PATCH 01/17] SPARC: added unaligned definitions, patch supplied by Magnus Sjalander Daniel Hellstrom
                   ` (6 preceding siblings ...)
  2010-01-28 12:16 ` [U-Boot] [PATCH 08/17] SPARC: added function that checks if IRQ is on or off Daniel Hellstrom
@ 2010-01-28 12:16 ` Daniel Hellstrom
  2010-01-28 12:16 ` [U-Boot] [PATCH 10/17] LEON3: added CPU count and frequency detection Daniel Hellstrom
                   ` (9 subsequent siblings)
  17 siblings, 0 replies; 26+ messages in thread
From: Daniel Hellstrom @ 2010-01-28 12:16 UTC (permalink / raw)
  To: u-boot

Signed-off-by: Daniel Hellstrom <daniel@gaisler.com>
---
 cpu/leon3/cpu_init.c |   30 ++++++++++++++++++++++++++++--
 1 files changed, 28 insertions(+), 2 deletions(-)

diff --git a/cpu/leon3/cpu_init.c b/cpu/leon3/cpu_init.c
index e2e1181..d2f47e1 100644
--- a/cpu/leon3/cpu_init.c
+++ b/cpu/leon3/cpu_init.c
@@ -142,14 +142,40 @@ int cpu_init_r(void)
 	return (0);
 }
 
+/* Busy wait a number of ms */
+void cpu_wait_ms_busy(unsigned long ms)
+{
+	unsigned int ms_delay;
+	volatile unsigned int tmp;
+
+	/* ~10-20 cycles per decrement */
+	ms_delay = leon_cpu_freq / (1000 * 10);
+	do {
+		/* Wait ~1ms */
+		tmp = ms_delay;
+		while ( tmp-- > 0 )
+			;
+	} while ( --ms > 0 );
+}
+
 /* Uses Timer 0 to get accurate
  * pauses. Max 2 raised to 32 ticks
  *
  */
 void cpu_wait_ticks(unsigned long ticks)
 {
-	unsigned long start = get_timer(0);
-	while (get_timer(start) < ticks) ;
+	unsigned long start;
+
+	if ( interrupt_is_enabled() ) {
+		start = get_timer(0);
+		while (get_timer(start) < ticks) ;
+	} else {
+		/* Interrupts disabled, this means that we cannot 
+		 * use get_timer(), it relies on IRQ. Instead the
+		 * CPU frequency is used.
+		 */
+		cpu_wait_ms_busy( ticks2usec(ticks) / 1000 );
+	}
 }
 
 /* initiate and setup timer0 interrupt to 1MHz
-- 
1.5.4

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [U-Boot] [PATCH 10/17] LEON3: added CPU count and frequency detection.
  2010-01-28 12:16 [U-Boot] [PATCH 01/17] SPARC: added unaligned definitions, patch supplied by Magnus Sjalander Daniel Hellstrom
                   ` (7 preceding siblings ...)
  2010-01-28 12:16 ` [U-Boot] [PATCH 09/17] LEON3: added busy wait function, made wait_ms() work when IRQ is disabled Daniel Hellstrom
@ 2010-01-28 12:16 ` Daniel Hellstrom
  2010-01-28 12:16 ` [U-Boot] [PATCH 11/17] SPARC: removed USB stop from linux bootm, arch-independent bootm stop USB Daniel Hellstrom
                   ` (8 subsequent siblings)
  17 siblings, 0 replies; 26+ messages in thread
From: Daniel Hellstrom @ 2010-01-28 12:16 UTC (permalink / raw)
  To: u-boot

Signed-off-by: Daniel Hellstrom <daniel@gaisler.com>
---
 cpu/leon3/cpu.c           |   42 +++++++++++++++++++++++++++++++++++++++++-
 include/asm-sparc/leon3.h |   13 +++++++++++++
 2 files changed, 54 insertions(+), 1 deletions(-)

diff --git a/cpu/leon3/cpu.c b/cpu/leon3/cpu.c
index 976f311..5cc9513 100644
--- a/cpu/leon3/cpu.c
+++ b/cpu/leon3/cpu.c
@@ -29,15 +29,55 @@
 
 #include <asm/io.h>
 #include <asm/processor.h>
+#include <ambapp.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
 extern void _reset_reloc(void);
 
+int leon_cpu_cnt = 1;
+int leon_ver = 3;
+unsigned int leon_cpu_freq = CONFIG_SYS_CLK_FREQ;
+
+int cpu_freq(void)
+{
+	ambapp_ahbdev dev;
+
+	if ( leon_ver == 3 ) {
+		ambapp_ahbmst_find(&ambapp_plb, VENDOR_GAISLER,
+			GAISLER_LEON3, 0, &dev);
+	} else {
+		ambapp_ahbmst_find(&ambapp_plb, VENDOR_GAISLER,
+			GAISLER_LEON4, 0, &dev);
+	}
+
+	leon_cpu_freq = ambapp_bus_freq(&ambapp_plb, dev.ahb_bus_index);
+}
+
 int checkcpu(void)
 {
+	int cnt;
+	char str[4];
+
 	/* check LEON version here */
-	printf("CPU: LEON3\n");
+	cnt = ambapp_ahbmst_count(&ambapp_plb, VENDOR_GAISLER, GAISLER_LEON3);
+	if ( cnt <= 0 ) {
+		cnt = ambapp_ahbmst_count(&ambapp_plb, VENDOR_GAISLER, GAISLER_LEON4);
+		if ( cnt > 0 )
+			leon_ver = 4;
+	}
+
+	cpu_freq();
+
+	str[0] = '\0';
+	if ( cnt > 1 ) {
+		leon_cpu_cnt = cnt;
+		str[0] = '0' + cnt;
+		str[1] = 'x';
+		str[2] = '\0';
+	}
+	printf("CPU: %sLEON%d @ %dMHz\n", str, leon_ver, leon_cpu_freq / 1000000);
+
 	return 0;
 }
 
diff --git a/include/asm-sparc/leon3.h b/include/asm-sparc/leon3.h
index b90d35b..60396c4 100644
--- a/include/asm-sparc/leon3.h
+++ b/include/asm-sparc/leon3.h
@@ -33,4 +33,17 @@
  * ctrl, memory controllers etc.
  */
 
+
+#ifndef __ASSEMBLER__
+/* The frequency of the CPU */
+extern unsigned int leon_cpu_freq;
+
+/* Number of LEON processors in system */
+extern int leon_cpu_cnt;
+
+/* Ver/subversion of CPU */
+extern int leon_ver;
+
+#endif /* __ASSEMBLER__ */
+
 #endif
-- 
1.5.4

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [U-Boot] [PATCH 11/17] SPARC: removed USB stop from linux bootm, arch-independent bootm stop USB.
  2010-01-28 12:16 [U-Boot] [PATCH 01/17] SPARC: added unaligned definitions, patch supplied by Magnus Sjalander Daniel Hellstrom
                   ` (8 preceding siblings ...)
  2010-01-28 12:16 ` [U-Boot] [PATCH 10/17] LEON3: added CPU count and frequency detection Daniel Hellstrom
@ 2010-01-28 12:16 ` Daniel Hellstrom
  2010-01-28 12:16 ` [U-Boot] [PATCH 12/17] SPARC: added optional cpu_late_init routine Daniel Hellstrom
                   ` (7 subsequent siblings)
  17 siblings, 0 replies; 26+ messages in thread
From: Daniel Hellstrom @ 2010-01-28 12:16 UTC (permalink / raw)
  To: u-boot

Signed-off-by: Daniel Hellstrom <daniel@gaisler.com>
---
 lib_sparc/bootm.c |    8 --------
 1 files changed, 0 insertions(+), 8 deletions(-)

diff --git a/lib_sparc/bootm.c b/lib_sparc/bootm.c
index c62cf57..f517325 100644
--- a/lib_sparc/bootm.c
+++ b/lib_sparc/bootm.c
@@ -35,10 +35,6 @@ extern image_header_t header;
 extern void srmmu_init_cpu(unsigned int entry);
 extern void prepare_bootargs(char *bootargs);
 
-#ifdef CONFIG_USB_UHCI
-extern int usb_lowlevel_stop(void);
-#endif
-
 /* sparc kernel argument (the ROM vector) */
 struct linux_romvec *kernel_arg_promvec;
 
@@ -125,10 +121,6 @@ int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t * images)
 	       linux_hdr->linuxver_minor, linux_hdr->linuxver_revision);
 #endif
 
-#ifdef CONFIG_USB_UHCI
-	usb_lowlevel_stop();
-#endif
-
 	/* set basic boot params in kernel header now that it has been
 	 * extracted and is writeable.
 	 */
-- 
1.5.4

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [U-Boot] [PATCH 12/17] SPARC: added optional cpu_late_init routine.
  2010-01-28 12:16 [U-Boot] [PATCH 01/17] SPARC: added unaligned definitions, patch supplied by Magnus Sjalander Daniel Hellstrom
                   ` (9 preceding siblings ...)
  2010-01-28 12:16 ` [U-Boot] [PATCH 11/17] SPARC: removed USB stop from linux bootm, arch-independent bootm stop USB Daniel Hellstrom
@ 2010-01-28 12:16 ` Daniel Hellstrom
  2010-01-28 12:16 ` [U-Boot] [PATCH 13/17] LEON3: Added GRETH EDCL debug link IP address initialization Daniel Hellstrom
                   ` (6 subsequent siblings)
  17 siblings, 0 replies; 26+ messages in thread
From: Daniel Hellstrom @ 2010-01-28 12:16 UTC (permalink / raw)
  To: u-boot

Signed-off-by: Daniel Hellstrom <daniel@gaisler.com>
---
 lib_sparc/board.c |    5 +++++
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/lib_sparc/board.c b/lib_sparc/board.c
index 11eea60..d829af0 100644
--- a/lib_sparc/board.c
+++ b/lib_sparc/board.c
@@ -65,6 +65,7 @@ extern void timer_interrupt_init(void);
 extern void malloc_bin_reloc(void);
 extern int do_ambapp_print(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]);
 extern int prom_init(void);
+extern void cpu_late_init(void);
 
 #if defined(CONFIG__CMD_DOC)
 void doc_init(void);
@@ -353,6 +354,10 @@ void board_init_f(ulong bootflag)
 	/* relocate environment function pointers etc. */
 	env_relocate();
 
+#if defined(CONFIG_CPU_LATE_INIT)
+	cpu_late_init();
+#endif
+
 #if defined(CONFIG_BOARD_LATE_INIT)
 	board_late_init();
 #endif
-- 
1.5.4

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [U-Boot] [PATCH 13/17] LEON3: Added GRETH EDCL debug link IP address initialization.
  2010-01-28 12:16 [U-Boot] [PATCH 01/17] SPARC: added unaligned definitions, patch supplied by Magnus Sjalander Daniel Hellstrom
                   ` (10 preceding siblings ...)
  2010-01-28 12:16 ` [U-Boot] [PATCH 12/17] SPARC: added optional cpu_late_init routine Daniel Hellstrom
@ 2010-01-28 12:16 ` Daniel Hellstrom
  2010-01-28 12:16 ` [U-Boot] [PATCH 14/17] LEON: added support for GRLIB SPI Memory controller, spi command interface Daniel Hellstrom
                   ` (5 subsequent siblings)
  17 siblings, 0 replies; 26+ messages in thread
From: Daniel Hellstrom @ 2010-01-28 12:16 UTC (permalink / raw)
  To: u-boot

Signed-off-by: Daniel Hellstrom <daniel@gaisler.com>
---
 cpu/leon3/cpu_init.c |   14 +++++
 cpu/leon3/greth.c    |  152 ++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 166 insertions(+), 0 deletions(-)
 create mode 100644 cpu/leon3/greth.c

diff --git a/cpu/leon3/cpu_init.c b/cpu/leon3/cpu_init.c
index d2f47e1..39c4bb8 100644
--- a/cpu/leon3/cpu_init.c
+++ b/cpu/leon3/cpu_init.c
@@ -43,6 +43,9 @@ DECLARE_GLOBAL_DATA_PTR;
 /* reset CPU (jump to 0, without reset) */
 void start(void);
 
+/* Initialize GRETH EDCL on startup */
+extern void greth_edcl_init(void);
+
 ambapp_dev_irqmp *irqmp = NULL;
 ambapp_dev_gptimer *gptimer = NULL;
 unsigned int gptimer_irq = 0;
@@ -142,6 +145,17 @@ int cpu_init_r(void)
 	return (0);
 }
 
+/* Late CPU initialization
+ *
+ * At this point environment variables is available.
+ */
+void cpu_late_init(void)
+{
+#ifdef CONFIG_SYS_GRETH_EDCL_IP
+	greth_edcl_init();
+#endif
+}
+
 /* Busy wait a number of ms */
 void cpu_wait_ms_busy(unsigned long ms)
 {
diff --git a/cpu/leon3/greth.c b/cpu/leon3/greth.c
new file mode 100644
index 0000000..7f341e6
--- /dev/null
+++ b/cpu/leon3/greth.c
@@ -0,0 +1,152 @@
+/* GRETH EDCL IP number initialization
+ *
+ * (C) Copyright 2010
+ * Daniel Hellstrom, Aeroflex Gaisler, daniel at gaisler.com.
+ *
+ * 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 <ambapp.h>
+#include <config.h>
+#include <grlib/greth.h>
+
+#ifdef CONFIG_SYS_GRETH_EDCL_IP
+
+/* Set EDCL IP of GRETH[core_index] to IP number as indicated by ip_str
+ *
+ * This is useful for designs that have a disabled EDCL (IP=0.0.0.0) on
+ * reset, or when the default EDCL IP is no correct. Often 192.168.0.51
+ * is default, the IP must be unique which is a problem when multiple
+ * boards are used.
+ *
+ * NOTE: The EDCL IP must not be the same IP as U-BOOT is using.
+ *
+ * NOTE: This code should not be located in the GRETH driver, because
+ *       we might want to set the EDCL debug link IP but not enable
+ *       u-boot networking.
+ */
+int greth_edcl_ip_set(int core_index, char *ip_str)
+{
+	ambapp_apbdev apbdev;
+	unsigned int *greth_ip_reg;
+	unsigned int ip;
+	char *start, *end;
+	unsigned char ipbyte;
+	int i;
+
+	/* Find Device & IRQ via AMBA Plug&Play information,
+	 * CONFIG_SYS_GRLIB_GRETH_INDEX select which GRETH if multiple
+	 * GRETHs in system.
+	 */
+	if (ambapp_apb_find(&ambapp_plb, VENDOR_GAISLER, GAISLER_ETHMAC,
+				core_index, &apbdev) != 1) {
+		return -1;	/* GRETH not found */
+	}
+	greth_ip_reg = (unsigned int *)(apbdev.address + 0x1C);
+
+	/* Convert IP String into IP number */
+	ip = 0;
+	start = ip_str;
+	for (i = 0; i < 4; i++) {
+		ipbyte = simple_strtoul(start, &end, 10);
+		ip |= ipbyte << (24-i*8);
+		start = end + 1; /* Next byte in IP-string */
+	}
+
+	/* Set new IP address of EDCL */
+	*greth_ip_reg = ip;
+
+	printf("GRETH[0x%08x] EDCL IP: %s\n",
+		(unsigned int)greth_ip_reg, ip_str);
+
+	return 0;
+};
+
+char *greth_edcl_ip_table[8] =
+{
+#ifdef CONFIG_SYS_GRETH0_EDCL_IP_STR
+	CONFIG_SYS_GRETH0_EDCL_IP_STR,
+#else
+	NULL,
+#endif
+#ifdef CONFIG_SYS_GRETH1_EDCL_IP_STR
+	CONFIG_SYS_GRETH1_EDCL_IP_STR,
+#else
+	NULL,
+#endif
+#ifdef CONFIG_SYS_GRETH2_EDCL_IP_STR
+	CONFIG_SYS_GRETH2_EDCL_IP_STR,
+#else
+	NULL,
+#endif
+#ifdef CONFIG_SYS_GRETH3_EDCL_IP_STR
+	CONFIG_SYS_GRETH3_EDCL_IP_STR,
+#else
+	NULL,
+#endif
+#ifdef CONFIG_SYS_GRETH4_EDCL_IP_STR
+	CONFIG_SYS_GRETH4_EDCL_IP_STR,
+#else
+	NULL,
+#endif
+#ifdef CONFIG_SYS_GRETH5_EDCL_IP_STR
+	CONFIG_SYS_GRETH5_EDCL_IP_STR,
+#else
+	NULL,
+#endif
+#ifdef CONFIG_SYS_GRETH6_EDCL_IP_STR
+	CONFIG_SYS_GRETH6_EDCL_IP_STR,
+#else
+	NULL,
+#endif
+#ifdef CONFIG_SYS_GRETH7_EDCL_IP_STR
+	CONFIG_SYS_GRETH7_EDCL_IP_STR,
+#else
+	NULL,
+#endif
+};
+
+void greth_edcl_init(void)
+{
+	int i;
+	char *ip_str;
+	char envname[16];
+
+	/* Set EDCL IP of the first 8 cores, if requested by user through 
+	 * Environment variable "greth_edcl_ipN" when N identifies which 
+	 * GRETH core, or through defines set in board configuration.
+	 */
+	strcpy(envname, "greth_edcl_ipX");
+	for (i=0; i<8; i++) {
+		/* Is there a config for */
+		envname[13] = '0' + i;
+		ip_str = getenv(envname);
+		if ( ip_str == NULL ) {
+			ip_str = greth_edcl_ip_table[i];
+		}
+		if ( ip_str != NULL ) {
+			if ( greth_edcl_ip_set(i, ip_str) )
+				break;
+		}
+	}
+}
+
+#endif
-- 
1.5.4

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [U-Boot] [PATCH 14/17] LEON: added support for GRLIB SPI Memory controller, spi command interface.
  2010-01-28 12:16 [U-Boot] [PATCH 01/17] SPARC: added unaligned definitions, patch supplied by Magnus Sjalander Daniel Hellstrom
                   ` (11 preceding siblings ...)
  2010-01-28 12:16 ` [U-Boot] [PATCH 13/17] LEON3: Added GRETH EDCL debug link IP address initialization Daniel Hellstrom
@ 2010-01-28 12:16 ` Daniel Hellstrom
  2010-01-28 12:16 ` [U-Boot] [PATCH 15/17] LEON3: fixed MMU table for systems with larger memory than 128MB Daniel Hellstrom
                   ` (4 subsequent siblings)
  17 siblings, 0 replies; 26+ messages in thread
From: Daniel Hellstrom @ 2010-01-28 12:16 UTC (permalink / raw)
  To: u-boot

Signed-off-by: Daniel Hellstrom <daniel@gaisler.com>
---
 drivers/spi/Makefile       |    1 +
 drivers/spi/spimctrl_spi.c |  261 ++++++++++++++++++++++++++++++++++++++++++++
 include/grlib/spimctrl.h   |   69 ++++++++++++
 lib_sparc/board.c          |   14 +++
 4 files changed, 345 insertions(+), 0 deletions(-)
 create mode 100644 drivers/spi/spimctrl_spi.c
 create mode 100644 include/grlib/spimctrl.h

diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 824d8e7..a730d45 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -34,6 +34,7 @@ COBJS-$(CONFIG_MPC52XX_SPI) += mpc52xx_spi.o
 COBJS-$(CONFIG_MPC8XXX_SPI) += mpc8xxx_spi.o
 COBJS-$(CONFIG_MXC_SPI) += mxc_spi.o
 COBJS-$(CONFIG_SOFT_SPI) += soft_spi.o
+COBJS-$(CONFIG_SPIMCTRL_SPI) += spimctrl_spi.o
 
 COBJS	:= $(COBJS-y)
 SRCS	:= $(COBJS:.o=.c)
diff --git a/drivers/spi/spimctrl_spi.c b/drivers/spi/spimctrl_spi.c
new file mode 100644
index 0000000..a37cfa9
--- /dev/null
+++ b/drivers/spi/spimctrl_spi.c
@@ -0,0 +1,261 @@
+/* SPI interface driver for GRLIB SPIMCTRL (SPI Memory controller)
+ *
+ * (C) Copyright 2010
+ * Daniel Hellstrom <daniel@gaisler.com>
+ *
+ * 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 <malloc.h>
+#include <spi.h>
+#include <ambapp.h>
+#include <grlib/spimctrl.h>
+
+struct spimctrl_priv {
+	struct spimctrl_regs *regs;
+	int irq;
+	unsigned int mode;
+	unsigned int max_hz;
+};
+
+struct spi_slave_internal {
+	struct spi_slave dev;
+	struct spimctrl_priv *priv;
+	int locked;
+};
+
+static int spimctrl_cnt = 0;
+static struct spimctrl_priv *spimctrl_devs;
+
+int spimctrl_probe(void)
+{
+	int cnt, i, found;
+	ambapp_ahbdev ahbdev;
+	struct spimctrl_priv *priv;
+
+	cnt = ambapp_ahbslv_count(&ambapp_plb,VENDOR_GAISLER,GAISLER_SPIMCTRL);
+	debug("Found %d SPIMCTRLS\n", cnt);
+	if ( cnt < 1 )
+		return 0;
+
+	spimctrl_cnt = cnt;
+	spimctrl_devs = (struct spimctrl_priv *) malloc(sizeof(*priv) * cnt);
+	memset(spimctrl_devs, 0, sizeof(struct spimctrl_priv) * cnt);
+
+	for (i=0; i<cnt; i++) {
+		found = ambapp_ahbslv_find(&ambapp_plb, VENDOR_GAISLER,
+				GAISLER_SPIMCTRL, i, &ahbdev);
+		if ( !found ) {
+			printf("spimctrl_probe: internal AMBA error\n");
+			while (1) ;
+		}
+
+		priv = &spimctrl_devs[i];
+		priv->regs = (struct spimctrl_regs *)ahbdev.address[0];
+		priv->irq = ahbdev.irq;
+
+		debug("SPIMCTRL[%d]: 0x%x irq %d\n",
+			i, (unsigned int)priv->regs, priv->irq);
+	}
+
+	return cnt;
+}
+
+void spimctrl_init(struct spimctrl_priv *priv)
+{
+	debug("SPIMCTRL_INIT\n");
+
+	/* Finish any previous ongoing user activity, this should
+	 * not normally happen, but may when debugging.
+	 */
+	if ( priv->regs->stat & SPIMCTRL_STAT_DONE )
+		priv->regs->stat = SPIMCTRL_STAT_DONE;
+
+	if ( priv->regs->ctrl & SPIMCTRL_CTRL_USRC ) {
+		/* Exit User mode */
+		priv->regs->ctrl = SPIMCTRL_CTRL_CSN;
+	}
+}
+
+void spimctrl_cs_activate(struct spimctrl_priv *priv)
+{
+	debug("CS ACT\n");
+
+	if ( priv->regs->stat & SPIMCTRL_STAT_DONE )
+		priv->regs->stat = SPIMCTRL_STAT_DONE;
+
+	/* Enter User mode */
+	priv->regs->ctrl = SPIMCTRL_CTRL_CSN | SPIMCTRL_CTRL_USRC;
+
+	/* Lower chip-select */
+	priv->regs->ctrl = SPIMCTRL_CTRL_USRC;
+}
+
+void spimctrl_cs_deactivate(struct spimctrl_priv *priv)
+{
+	debug("CS INACT\n");
+
+	/* Rise chip select */
+	priv->regs->ctrl = SPIMCTRL_CTRL_CSN | SPIMCTRL_CTRL_USRC;
+
+	/* Exit User mode */
+	priv->regs->ctrl = SPIMCTRL_CTRL_CSN;
+}
+
+void spimctrl_transfer_byte(struct spimctrl_priv *priv, char *out, char *in)
+{
+	unsigned int stat;
+	unsigned char rx;
+
+	while( (stat=priv->regs->stat) & 
+		(SPIMCTRL_STAT_BUSY|SPIMCTRL_STAT_DONE) ) {
+		debug("WAITING1: 0x%x\n", stat);
+	}
+	debug("OK STAT1: 0x%x\n", stat);
+
+	if ( out ) {
+		priv->regs->tx = out[0];	
+	} else {
+		priv->regs->tx = 0;
+	}
+
+	while ( ((stat=priv->regs->stat) & SPIMCTRL_STAT_DONE) == 0 ) {
+		debug("WAITING2: 0x%x\n", stat);
+	}
+	debug("OK STAT2: 0x%x\n", stat);
+	rx = priv->regs->rx;
+	if ( in ) {
+		in[0] = rx;
+	}
+	priv->regs->stat = SPIMCTRL_STAT_DONE;
+
+	if ( out && in ) {
+		debug("OUT 0x%02x ; IN 0x%02x\n", out[0], in[0]);
+	} else if ( out ) {
+		debug("OUT 0x%02x\n", out[0]);
+	} else if ( in ) {
+		debug("IN: 0x%02x\n", in[0]);
+	}
+}
+
+void spi_init(void)
+{
+	int i;
+
+	debug("SPI INIT\n");
+
+	/* Find SPIMCTRL cores */
+	spimctrl_probe();
+
+	/* Init SPIMCTRL Core */
+	for ( i=0; i<spimctrl_cnt; i++) {
+		spimctrl_init(&spimctrl_devs[i]);
+	}
+}
+
+struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
+				  unsigned int max_hz, unsigned int mode)
+{
+	struct spi_slave_internal *slave;
+
+	debug("spi_setup_slave(%d, %d, %d, %d)\n", bus, cs, max_hz, mode);
+
+	if ( bus >= spimctrl_cnt ) {
+		printf("spi_setup_slave: NO SUCH BUS: %d\n", bus);
+		return NULL;
+	}
+
+	slave = malloc(sizeof(struct spi_slave_internal));
+	if (!slave)
+		return NULL;
+
+	slave->dev.bus = bus;
+	slave->dev.cs = cs;
+	slave->priv = &spimctrl_devs[bus];
+	slave->priv->mode = mode;
+	slave->priv->max_hz = max_hz;
+	slave->locked = 0;
+
+	return &slave->dev;
+}
+
+void spi_free_slave(struct spi_slave *slave)
+{
+	free(slave);
+}
+
+int spi_claim_bus(struct spi_slave *slave)
+{
+	struct spi_slave_internal *slv = (void *)slave;
+
+	if ( slv->locked )
+		return -1;
+	slv->locked = 1;
+
+	return 0;
+}
+
+void spi_release_bus(struct spi_slave *slave)
+{
+	struct spi_slave_internal *slv = (void *)slave;
+
+	slv->locked = 0;
+	return;
+}
+
+int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
+		void *din, unsigned long flags)
+{
+	struct spi_slave_internal *slv = (void *)slave;
+	int i, cnt;
+	unsigned char *out, *in;
+
+	debug("spi_xfer: slave %u:%u dout %08X din %08X bitlen %u\n",
+		slave->bus, slave->cs, (uint)dout, (uint)din, bitlen);
+
+	if ( (bitlen & 0x7) != 0 ) {
+		printf("spi_xfer: Bitlength of != 8 not supported\n");
+		return -1;
+	}
+
+	if (flags & SPI_XFER_BEGIN) {
+		/* Set Chip Select */
+		spimctrl_cs_activate(slv->priv);
+	}
+
+	out = (unsigned char *)dout;
+	in = (unsigned char *)din;
+	cnt = bitlen / 8;
+	for (i=0; i<cnt; i++){
+		spimctrl_transfer_byte(slv->priv, out, in);
+
+		if ( out )
+			out++;
+		if ( in )
+			in++;
+	}
+
+	if (flags & SPI_XFER_END) {
+		/* End transfer by rising ChipSelect again */
+		spimctrl_cs_deactivate(slv->priv);
+	}
+
+	return 0;
+}
diff --git a/include/grlib/spimctrl.h b/include/grlib/spimctrl.h
new file mode 100644
index 0000000..8329745
--- /dev/null
+++ b/include/grlib/spimctrl.h
@@ -0,0 +1,69 @@
+/* GRLIB SPI Memory controller (SPIMCTRL) definitions
+ *
+ * (C) Copyright 2010
+ * Daniel Hellstrom, Aeroflex Gaisler, daniel at gaisler.com
+ *
+ * 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
+ */
+
+#ifndef __GRLIB_SPIMCTRL_H__
+#define __GRLIB_SPIMCTRL_H__
+
+/*** REGISTER LAYOUT ***/
+struct spimctrl_regs {
+	volatile unsigned int conf;		/* 0x00 */
+	volatile unsigned int ctrl;		/* 0x04 */
+	volatile unsigned int stat;		/* 0x08 */
+	volatile unsigned int rx;		/* 0x0C */
+	volatile unsigned int tx;		/* 0x10 */
+};
+
+/*** CONFIGURATION REGISTER 0x00 ***/
+#define SPIMCTRL_CONF_READCMD_BIT	0
+#define SPIMCTRL_CONF_READCMD		0xff
+
+/*** CONTROL REGISTER 0x04 ***/
+#define SPIMCTRL_CTRL_USRC_BIT	0
+#define SPIMCTRL_CTRL_IEN_BIT	1
+#define SPIMCTRL_CTRL_EAS_BIT	2
+#define SPIMCTRL_CTRL_CSN_BIT	3
+#define SPIMCTRL_CTRL_RST_BIT	4
+
+#define SPIMCTRL_CTRL_USRC	(1<<SPIMCTRL_CTRL_USRC_BIT)
+#define SPIMCTRL_CTRL_IEN	(1<<SPIMCTRL_CTRL_IEN_BIT)
+#define SPIMCTRL_CTRL_EAS	(1<<SPIMCTRL_CTRL_EAS_BIT)
+#define SPIMCTRL_CTRL_CSN	(1<<SPIMCTRL_CTRL_CSN_BIT)
+#define SPIMCTRL_CTRL_RST	(1<<SPIMCTRL_CTRL_RST_BIT)
+
+/*** STATUS REGISTER 0x08 ***/
+#define SPIMCTRL_STAT_DONE_BIT	0
+#define SPIMCTRL_STAT_BUSY_BIT	1
+#define SPIMCTRL_STAT_INT_BIT	2
+#define SPIMCTRL_STAT_ERR_BIT	3
+#define SPIMCTRL_STAT_TO_BIT	4
+#define SPIMCTRL_STAT_CD_BIT	5
+
+#define SPIMCTRL_STAT_DONE	(1<<SPIMCTRL_STAT_DONE_BIT)
+#define SPIMCTRL_STAT_BUSY	(1<<SPIMCTRL_STAT_BUSY_BIT)
+#define SPIMCTRL_STAT_INT	(1<<SPIMCTRL_STAT_INT_BIT)
+#define SPIMCTRL_STAT_ERR	(1<<SPIMCTRL_STAT_ERR_BIT)
+#define SPIMCTRL_STAT_TO	(1<<SPIMCTRL_STAT_TO_BIT)
+#define SPIMCTRL_STAT_CD	(1<<SPIMCTRL_STAT_CD_BIT)
+
+#endif
diff --git a/lib_sparc/board.c b/lib_sparc/board.c
index d829af0..3362f39 100644
--- a/lib_sparc/board.c
+++ b/lib_sparc/board.c
@@ -97,6 +97,16 @@ static int init_baudrate(void)
 	return (0);
 }
 
+#if defined(CONFIG_HARD_SPI)
+static int init_func_spi (void)
+{
+        puts ("SPI:   ");
+        spi_init ();
+        puts ("ready\n");
+        return (0);
+}
+#endif
+
 /***********************************************************************/
 
 /*
@@ -304,6 +314,10 @@ void board_init_f(ulong bootflag)
 			CONFIG_SYS_MALLOC_END - CONFIG_SYS_MALLOC_BASE);
 	malloc_bin_reloc();
 
+#if defined(CONFIG_HARD_SPI)
+	init_func_spi();
+#endif
+
 #if !defined(CONFIG_SYS_NO_FLASH)
 	puts("FLASH: ");
 
-- 
1.5.4

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [U-Boot] [PATCH 15/17] LEON3: fixed MMU table for systems with larger memory than 128MB.
  2010-01-28 12:16 [U-Boot] [PATCH 01/17] SPARC: added unaligned definitions, patch supplied by Magnus Sjalander Daniel Hellstrom
                   ` (12 preceding siblings ...)
  2010-01-28 12:16 ` [U-Boot] [PATCH 14/17] LEON: added support for GRLIB SPI Memory controller, spi command interface Daniel Hellstrom
@ 2010-01-28 12:16 ` Daniel Hellstrom
  2010-01-28 12:16 ` [U-Boot] [PATCH 16/17] bootm command: added argument to arch_preboot_os, function may depend on OS type Daniel Hellstrom
                   ` (3 subsequent siblings)
  17 siblings, 0 replies; 26+ messages in thread
From: Daniel Hellstrom @ 2010-01-28 12:16 UTC (permalink / raw)
  To: u-boot

Signed-off-by: Daniel Hellstrom <daniel@gaisler.com>
---
 cpu/leon3/prom.c |   16 ++++++++++++++++
 1 files changed, 16 insertions(+), 0 deletions(-)

diff --git a/cpu/leon3/prom.c b/cpu/leon3/prom.c
index 86376bb..6cd2281 100644
--- a/cpu/leon3/prom.c
+++ b/cpu/leon3/prom.c
@@ -1059,6 +1059,22 @@ void srmmu_init_cpu(unsigned int entry)
 	    ((CONFIG_SYS_SDRAM_BASE + 0x6000000) >> 4) | ACC_SU_ALL | PTE;
 	psrmmu_tables->pgd_table[0xf7] =
 	    ((CONFIG_SYS_SDRAM_BASE + 0x7000000) >> 4) | ACC_SU_ALL | PTE;
+	psrmmu_tables->pgd_table[0xf8] =
+	    ((CONFIG_SYS_SDRAM_BASE + 0x8000000) >> 4) | ACC_SU_ALL | PTE;
+	psrmmu_tables->pgd_table[0xf9] =
+	    ((CONFIG_SYS_SDRAM_BASE + 0x9000000) >> 4) | ACC_SU_ALL | PTE;
+	psrmmu_tables->pgd_table[0xfa] =
+	    ((CONFIG_SYS_SDRAM_BASE + 0xa000000) >> 4) | ACC_SU_ALL | PTE;
+	psrmmu_tables->pgd_table[0xfb] =
+	    ((CONFIG_SYS_SDRAM_BASE + 0xb000000) >> 4) | ACC_SU_ALL | PTE;
+	psrmmu_tables->pgd_table[0xfc] =
+	    ((CONFIG_SYS_SDRAM_BASE + 0xc000000) >> 4) | ACC_SU_ALL | PTE;
+	psrmmu_tables->pgd_table[0xfd] =
+	    ((CONFIG_SYS_SDRAM_BASE + 0xd000000) >> 4) | ACC_SU_ALL | PTE;
+	psrmmu_tables->pgd_table[0xfe] =
+	    ((CONFIG_SYS_SDRAM_BASE + 0xe000000) >> 4) | ACC_SU_ALL | PTE;
+	psrmmu_tables->pgd_table[0xff] =
+	    ((CONFIG_SYS_SDRAM_BASE + 0xf000000) >> 4) | ACC_SU_ALL | PTE;	
 
 	/* convert rom vec pointer to virtual address */
 	kernel_arg_promvec = (struct linux_romvec *)
-- 
1.5.4

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [U-Boot] [PATCH 16/17] bootm command: added argument to arch_preboot_os, function may depend on OS type.
  2010-01-28 12:16 [U-Boot] [PATCH 01/17] SPARC: added unaligned definitions, patch supplied by Magnus Sjalander Daniel Hellstrom
                   ` (13 preceding siblings ...)
  2010-01-28 12:16 ` [U-Boot] [PATCH 15/17] LEON3: fixed MMU table for systems with larger memory than 128MB Daniel Hellstrom
@ 2010-01-28 12:16 ` Daniel Hellstrom
  2010-01-28 12:16 ` [U-Boot] [PATCH 17/17] SPARC, LEON3: added support for multiprocessing, tested Linux 2.6.21.1 SMP and RTEMS-4.10 AMP Daniel Hellstrom
                   ` (2 subsequent siblings)
  17 siblings, 0 replies; 26+ messages in thread
From: Daniel Hellstrom @ 2010-01-28 12:16 UTC (permalink / raw)
  To: u-boot

Signed-off-by: Daniel Hellstrom <daniel@gaisler.com>
---
 common/cmd_bootm.c     |    8 ++++----
 cpu/mpc85xx/cpu_init.c |    2 +-
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c
index 94ddac3..f795857 100644
--- a/common/cmd_bootm.c
+++ b/common/cmd_bootm.c
@@ -170,11 +170,11 @@ void __arch_lmb_reserve(struct lmb *lmb)
 void arch_lmb_reserve(struct lmb *lmb) __attribute__((weak, alias("__arch_lmb_reserve")));
 
 /* Allow for arch specific config before we boot */
-void __arch_preboot_os(void)
+void __arch_preboot_os(int os)
 {
 	/* please define platform specific arch_preboot_os() */
 }
-void arch_preboot_os(void) __attribute__((weak, alias("__arch_preboot_os")));
+void arch_preboot_os(int os) __attribute__((weak, alias("__arch_preboot_os")));
 
 #if defined(__ARM__)
   #define IH_INITRD_ARCH IH_ARCH_ARM
@@ -571,7 +571,7 @@ int do_bootm_subcommand (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 			break;
 		case BOOTM_STATE_OS_GO:
 			disable_interrupts();
-			arch_preboot_os();
+			arch_preboot_os(images.os.os);
 			boot_fn(BOOTM_STATE_OS_GO, argc, argv, &images);
 			break;
 	}
@@ -704,7 +704,7 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 		return 1;
 	}
 
-	arch_preboot_os();
+	arch_preboot_os(images.os.os);
 
 	boot_fn(0, argc, argv, &images);
 
diff --git a/cpu/mpc85xx/cpu_init.c b/cpu/mpc85xx/cpu_init.c
index 0041a60..100f8f4 100644
--- a/cpu/mpc85xx/cpu_init.c
+++ b/cpu/mpc85xx/cpu_init.c
@@ -382,7 +382,7 @@ int cpu_init_r(void)
 
 extern void setup_ivors(void);
 
-void arch_preboot_os(void)
+void arch_preboot_os(int os)
 {
 	u32 msr;
 
-- 
1.5.4

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [U-Boot] [PATCH 17/17] SPARC, LEON3: added support for multiprocessing, tested Linux 2.6.21.1 SMP and RTEMS-4.10 AMP.
  2010-01-28 12:16 [U-Boot] [PATCH 01/17] SPARC: added unaligned definitions, patch supplied by Magnus Sjalander Daniel Hellstrom
                   ` (14 preceding siblings ...)
  2010-01-28 12:16 ` [U-Boot] [PATCH 16/17] bootm command: added argument to arch_preboot_os, function may depend on OS type Daniel Hellstrom
@ 2010-01-28 12:16 ` Daniel Hellstrom
  2010-01-28 20:41 ` [U-Boot] [PATCH 01/17] SPARC: added unaligned definitions, patch supplied by Magnus Sjalander Mike Frysinger
  2010-05-05 21:35 ` Wolfgang Denk
  17 siblings, 0 replies; 26+ messages in thread
From: Daniel Hellstrom @ 2010-01-28 12:16 UTC (permalink / raw)
  To: u-boot

Signed-off-by: Daniel Hellstrom <daniel@gaisler.com>
---
 board/gaisler/gr_cpci_ax2000/u-boot.lds |    7 ++
 board/gaisler/gr_ep2s60/u-boot.lds      |    7 ++
 board/gaisler/gr_xc3s_1500/u-boot.lds   |    7 ++
 board/gaisler/grsim/u-boot.lds          |    7 ++
 cpu/leon3/Makefile                      |    2 +-
 cpu/leon3/cpu.c                         |   10 ++-
 cpu/leon3/cpu_mp.c                      |   80 ++++++++++++++
 cpu/leon3/prom.c                        |   32 +++---
 cpu/leon3/start.S                       |   70 ++++++++++++
 include/asm-sparc/boot_mp.h             |   70 ++++++++++++
 include/configs/gr_cpci_ax2000.h        |   12 ++-
 include/configs/gr_ep2s60.h             |   12 ++-
 include/configs/gr_xc3s_1500.h          |   14 ++-
 include/configs/grsim.h                 |   12 ++-
 lib_sparc/Makefile                      |    2 +-
 lib_sparc/boot_mp.c                     |  177 +++++++++++++++++++++++++++++++
 lib_sparc/bootm.c                       |   57 ++++++++--
 17 files changed, 540 insertions(+), 38 deletions(-)
 create mode 100644 cpu/leon3/cpu_mp.c
 create mode 100644 include/asm-sparc/boot_mp.h
 create mode 100644 lib_sparc/boot_mp.c

diff --git a/board/gaisler/gr_cpci_ax2000/u-boot.lds b/board/gaisler/gr_cpci_ax2000/u-boot.lds
index d5d7842..17a0fc3 100644
--- a/board/gaisler/gr_cpci_ax2000/u-boot.lds
+++ b/board/gaisler/gr_cpci_ax2000/u-boot.lds
@@ -72,6 +72,13 @@ SECTIONS
 		*(.prom.text)
 		. = ALIGN(16);
 		__prom_end = .;
+		/* Align MP section to the same as the MAX size of the MP section */
+		. = ALIGN(512);
+		__mp_start = .;
+		*(.mp.data)
+		*(.mp.text)
+		. = ALIGN(16);
+		__mp_end = .;
 		*(.text)
 		*(.fixup)
 		*(.gnu.warning)
diff --git a/board/gaisler/gr_ep2s60/u-boot.lds b/board/gaisler/gr_ep2s60/u-boot.lds
index 99aa0ad..c02a6d2 100644
--- a/board/gaisler/gr_ep2s60/u-boot.lds
+++ b/board/gaisler/gr_ep2s60/u-boot.lds
@@ -72,6 +72,13 @@ SECTIONS
 		*(.prom.text)
 		. = ALIGN(16);
 		__prom_end = .;
+		/* Align MP section to the same as the MAX size of the MP section */
+		. = ALIGN(512);
+		__mp_start = .;
+		*(.mp.data)
+		*(.mp.text)
+		. = ALIGN(16);
+		__mp_end = .;
 		*(.text)
 		*(.fixup)
 		*(.gnu.warning)
diff --git a/board/gaisler/gr_xc3s_1500/u-boot.lds b/board/gaisler/gr_xc3s_1500/u-boot.lds
index 3b13190..de7ea6b 100644
--- a/board/gaisler/gr_xc3s_1500/u-boot.lds
+++ b/board/gaisler/gr_xc3s_1500/u-boot.lds
@@ -72,6 +72,13 @@ SECTIONS
 		*(.prom.text)
 		. = ALIGN(16);
 		__prom_end = .;
+		/* Align MP section to the same as the MAX size of the MP section */
+		. = ALIGN(512);
+		__mp_start = .;
+		*(.mp.data)
+		*(.mp.text)
+		. = ALIGN(16);
+		__mp_end = .;
 		*(.text)
 		*(.fixup)
 		*(.gnu.warning)
diff --git a/board/gaisler/grsim/u-boot.lds b/board/gaisler/grsim/u-boot.lds
index 0fa6627..ac7dbec 100644
--- a/board/gaisler/grsim/u-boot.lds
+++ b/board/gaisler/grsim/u-boot.lds
@@ -71,6 +71,13 @@ SECTIONS
 		*(.prom.text)
 		. = ALIGN(16);
 		__prom_end = .;
+		/* Align MP section to the same as the MAX size of the MP section */
+		. = ALIGN(512);
+		__mp_start = .;
+		*(.mp.data)
+		*(.mp.text)
+		. = ALIGN(16);
+		__mp_end = .;
 		*(.text)
 		*(.fixup)
 		*(.gnu.warning)
diff --git a/cpu/leon3/Makefile b/cpu/leon3/Makefile
index f1bb808..4d36061 100644
--- a/cpu/leon3/Makefile
+++ b/cpu/leon3/Makefile
@@ -28,7 +28,7 @@ LIB	= $(obj)lib$(CPU).a
 START	= start.o
 SOBJS	= ambapp_low.o ambapp_low_c.o memcfg_low.o
 COBJS	= cpu_init.o serial.o cpu.o ambapp.o interrupts.o prom.o usb_uhci.o \
-	memcfg.o
+	memcfg.o cpu_mp.o
 
 SRCS	:= $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
 OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
diff --git a/cpu/leon3/cpu.c b/cpu/leon3/cpu.c
index 5cc9513..13d3dd7 100644
--- a/cpu/leon3/cpu.c
+++ b/cpu/leon3/cpu.c
@@ -83,8 +83,14 @@ int checkcpu(void)
 
 /* ------------------------------------------------------------------------- */
 
-void cpu_reset(void)
+int cpu_reset(int nr)
 {
+	if ( nr > 0 ) {
+		puts(" CPU[N] RESET NOT SUPPORTED BY ARCHITECTURE (N>0), "
+		     "SYSTEM RESET IS POSSIBLE.");
+		return -1;
+	}
+
 	/* Interrupts off */
 	disable_interrupts();
 
@@ -94,7 +100,7 @@ void cpu_reset(void)
 
 int do_reset(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
 {
-	cpu_reset();
+	cpu_reset(0);
 
 	return 1;
 
diff --git a/cpu/leon3/cpu_mp.c b/cpu/leon3/cpu_mp.c
new file mode 100644
index 0000000..5cd5a6a
--- /dev/null
+++ b/cpu/leon3/cpu_mp.c
@@ -0,0 +1,80 @@
+/* Interface implementation for cmd_mp.c on multi processor LEON
+ * CPUs
+ *
+ * (C) Copyright 2010
+ * Daniel Hellstrom, Gaisler Research, daniel at gaisler.com
+ *
+ * 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 <config.h>
+
+#ifdef CONFIG_MP
+
+#include <grlib/irqmp.h>
+
+extern int leon_cpu_cnt;
+extern ambapp_dev_irqmp *irqmp;
+
+int cpu_numcores(void)
+{
+	return leon_cpu_cnt;
+}
+
+int cpu_status(int nr)
+{
+	printf("LEON CPUs available: %d\n", leon_cpu_cnt);
+
+	return 0;
+}
+
+int cpu_release(int nr, int argc, char *argv[])
+{
+	unsigned int ep, stack, arg0, arg1;
+
+	/* Get entry point, stack and argument */
+	if ( argc < 2 ) {
+		printf(	" At least 5 arguments must be given.\n"
+			" Argument 4 is entry point\n"
+			" Argument 5 is stack\n"
+			" Argument 6-7 is kernel arg 0 and 1 (OPTIONAL)\n");
+		return -1;
+	}
+	ep = simple_strtoul(argv[0], NULL, 16);
+	stack = simple_strtoul(argv[1], NULL, 16);
+	arg0 = arg1 = 0;
+
+	if ( argc > 2 ) {
+		arg0 = simple_strtoul(argv[2], NULL, 16);
+	}
+	if ( argc > 3 ) {
+		arg1 = simple_strtoul(argv[3], NULL, 16);
+	}
+
+	/* Register CPU start up options into MP table */
+	boot_mp_cpu_setup(nr, ep, stack, (void *)arg0, (void *)arg1);
+
+	/* Release CPU by writing to IRQ controller MP register */
+	irqmp->mstatus = (1<<nr);
+
+	return 0;
+}
+
+#endif
diff --git a/cpu/leon3/prom.c b/cpu/leon3/prom.c
index 6cd2281..2a4fc2d 100644
--- a/cpu/leon3/prom.c
+++ b/cpu/leon3/prom.c
@@ -31,6 +31,7 @@
 #include <asm/processor.h>
 #include <asm/irq.h>
 #include <asm/leon.h>
+#include <asm/boot_mp.h>
 #include <ambapp.h>
 #include <grlib/apbuart.h>
 #include <grlib/irqmp.h>
@@ -931,21 +932,9 @@ void leon_prom_init(struct leon_prom_info *pspi)
 	/* Set the pointer to the Console UART in romvec */
 	pspi->reloc_funcs.leon3_apbuart = leon3_apbuart;
 
-	{
-		int j = 1;
-#ifdef CONFIG_SMP
-		ambapp_dev_irqmp *b;
-		b = (ambapp_dev_irqmp *) leon3_getapbbase(VENDOR_GAISLER,
-							  GAISLER_IRQMP);
-		if (b) {
-			j = 1 + ((LEON3_BYPASS_LOAD_PA(&(b->mpstatus))
-				  >> LEON3_IRQMPSTATUS_CPUNR) & 0xf);
-		}
-#endif
 #undef nodes
-		pspi->nodes[2 + j].level = -1;
-		pspi->nodes[2 + j].properties = __va(spi.root_properties + 3);
-	}
+	pspi->nodes[2 + leon_cpu_cnt].level = -1;
+	pspi->nodes[2 + leon_cpu_cnt].properties = __va(spi.root_properties + 3);
 
 	/* Set Ethernet MAC address from environment */
 	if ((addr_str = getenv("ethaddr")) != NULL) {
@@ -1024,7 +1013,7 @@ void prepare_bootargs(char *bootargs)
 	}
 }
 
-void srmmu_init_cpu(unsigned int entry)
+void srmmu_init(unsigned int entry)
 {
 	sparc_srmmu_setup *psrmmu_tables = (void *)
 	    ((((unsigned int)&srmmu_tables) & PROM_SIZE_MASK) +
@@ -1079,6 +1068,19 @@ void srmmu_init_cpu(unsigned int entry)
 	/* convert rom vec pointer to virtual address */
 	kernel_arg_promvec = (struct linux_romvec *)
 	    (((unsigned int)kernel_arg_promvec & 0x0fffffff) | 0xf0000000);
+}
+
+#ifdef CONFIG_MP
+/* This function must be located in the MP or PROM part of the application because
+ * it will be called from CPU1, CPU2 ...  after CPU0 has made it into the kernel 
+ * and started the other CPUs
+ */
+void MP_TEXT boot_mp_linux_cpu_preinit(int cpu)
+#else
+void boot_mp_linux_cpu_preinit(int cpu)
+#endif
+{
+	sparc_srmmu_setup *psrmmu_tables = (void *)CONFIG_SYS_PROM_OFFSET;
 
 	/* Set Context pointer to point to context table
 	 * 256 contexts supported.
diff --git a/cpu/leon3/start.S b/cpu/leon3/start.S
index d9faa86..1f30150 100644
--- a/cpu/leon3/start.S
+++ b/cpu/leon3/start.S
@@ -27,6 +27,7 @@
 #include <asm/psr.h>
 #include <asm/stack.h>
 #include <asm/leon.h>
+#include <asm/boot_mp.h>
 #include <timestamp.h>
 #include <version.h>
 #include <ambapp.h>
@@ -258,6 +259,20 @@ wininit:
 	set	WIM_INIT, %g3
 	mov	%g3, %wim
 
+#ifdef CONFIG_MP
+/* In a multi CPU system (and the slave CPUs have been started) the slaves
+ * have a special boot up sequence. It is expected that CPU0 has already run
+ * u-boot and it has loaded an OS which now have activated one or more slave 
+ * CPUs.
+ */
+multi_cpu_detect:
+	rd	%asr17, %g3
+	srl	%g3, 28, %g3
+	cmp	%g3, %g0
+	bne	slave_cpu_init
+	 nop
+#endif
+
 stackp:
 	set	CONFIG_SYS_INIT_SP_OFFSET, %fp
 	andn	%fp, 0x0f, %fp
@@ -386,6 +401,23 @@ prom_relocate_loop:
 	bne	prom_relocate_loop
 	inc	16,%g4
 
+#ifdef CONFIG_MP
+mp_relocate:
+	set	__mp_start, %g2
+	set	__mp_end, %g3
+	set	CONFIG_SYS_MP_OFFSET, %g4
+
+mp_relocate_loop:
+	ldd	[%g2],%l0
+	ldd	[%g2+8],%l2
+	std	%l0,[%g4]
+	std	%l2,[%g4+8]
+	inc	16,%g2
+	subcc	%g3,%g2,%g0
+	bne	mp_relocate_loop
+	inc	16,%g4
+#endif
+
 /* Trap table has been moved, lets tell CPU about
  * the new trap table address
  */
@@ -651,3 +683,41 @@ _reset_reloc:
 	set	start, %l0
 	call	%l0
 	nop
+
+#ifdef CONFIG_MP
+/* Slave CPUs reach here */
+slave_cpu_init:
+
+	/* Get Index into cpu slave struct */
+	sll	%g3, 4, %i0
+
+	set	(CONFIG_SYS_MP_OFFSET+0x4), %o1	/* cpu_table is mp_data+0x4 */
+	add	%i0, %o1, %i0
+
+	/* Setup Stack Pointer from config */
+	ld	[%i0 + BOOT_MP_CPU_STACK], %fp
+	andn	%fp, 0x0f, %fp
+	sub	%fp, 64, %sp
+
+	/* Call OS-dependent CPU init routine */
+	set	CONFIG_SYS_MP_OFFSET, %o1	/* cpu_table is mp_data+0x0 */
+	ld	[%o1], %o1
+	cmp	%o1, 0
+	beq	slave_cpu_boot_kernel
+	 nop
+	call	%o1
+	 clr	%o0
+
+	/* Call Kernel */
+slave_cpu_boot_kernel:
+	ld	[%i0 + BOOT_MP_CPU_ARG0], %o0	/* ARG0 */
+	ld	[%i0 + BOOT_MP_CPU_ARG1], %o1	/* ARG1 */
+	ld	[%i0 + BOOT_MP_CPU_EP], %o3	/* ENTRY POINT */
+	call	%o3
+	 clr	%o2
+
+dead_slave:
+	/* Kernel Failed or no support for MP */
+	ta 0x1
+	 nop
+#endif
diff --git a/include/asm-sparc/boot_mp.h b/include/asm-sparc/boot_mp.h
new file mode 100644
index 0000000..e033b9c
--- /dev/null
+++ b/include/asm-sparc/boot_mp.h
@@ -0,0 +1,70 @@
+/* Multiprocessor boot setup functions.
+ *
+ * (C) Copyright 2010
+ * Daniel Hellstrom, Gaisler Research, daniel at gaisler.com.
+ *
+ * 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
+ *
+ */
+
+#ifndef __ASM_SPARC_BOOT_MP_H__
+#define __ASM_SPARC_BOOT_MP_H__
+
+#define MP_TEXT __attribute__ ((__section__ (".mp.text")))
+#define MP_DATA __attribute__ ((__section__ (".mp.data")))
+
+#define BOOT_MP_CPU_EP 0x00
+#define BOOT_MP_CPU_STACK 0x04
+#define BOOT_MP_CPU_ARG0 0x08
+#define BOOT_MP_CPU_ARG1 0x0C
+
+#ifndef __ASSEMBLER__
+
+/* Allow for arch specific CPU initialization before RTEMS boot */
+extern void boot_mp_rtems_cpu_preinit(int cpu);
+
+/* Allow for arch specific CPU initialization before VxWorks boot */
+extern void boot_mp_vxworks_cpu_preinit(int cpu);
+
+/* Allow for arch specific CPU initialization before Linux boot */
+extern void boot_mp_linux_cpu_preinit(int cpu);
+
+struct boot_mp_cpu {
+	unsigned int entry_point;
+	unsigned int stack;
+	void *arg0;
+	void *arg1;
+};
+
+/* All CPU entry points and stacks */
+extern struct boot_mp_cpu boot_mp_cpu_table[];
+
+extern void boot_mp_os_setup(int os);
+
+extern void boot_mp_cpu_setup(
+	int cpu,
+	unsigned int entry_point,
+	unsigned int stack,
+	void *arg0,
+	void *arg1
+	);
+
+/* Init a CPU before entering the kernel */
+extern void boot_mp_cpu_preinit(int cpu);
+
+#endif
+
+#endif
diff --git a/include/configs/gr_cpci_ax2000.h b/include/configs/gr_cpci_ax2000.h
index b9d45dd..a6d669d 100644
--- a/include/configs/gr_cpci_ax2000.h
+++ b/include/configs/gr_cpci_ax2000.h
@@ -264,8 +264,16 @@
 #define CONFIG_SYS_GBL_DATA_SIZE	128	/* size in bytes reserved for initial data */
 #define CONFIG_SYS_GBL_DATA_OFFSET	(CONFIG_SYS_RAM_END - CONFIG_SYS_GBL_DATA_SIZE)
 
-#define CONFIG_SYS_PROM_SIZE		(8192-CONFIG_SYS_GBL_DATA_SIZE)
-#define CONFIG_SYS_PROM_OFFSET		(CONFIG_SYS_GBL_DATA_OFFSET-CONFIG_SYS_PROM_SIZE)
+#ifdef CONFIG_MP
+#define CONFIG_SYS_MP_SIZE		512
+#define CONFIG_SYS_MP_OFFSET		(CONFIG_SYS_GBL_DATA_OFFSET-CONFIG_SYS_MP_SIZE)
+#else
+#define CONFIG_SYS_MP_SIZE		0
+#define CONFIG_SYS_MP_OFFSET		CONFIG_SYS_GBL_DATA_OFFSET
+#endif
+
+#define CONFIG_SYS_PROM_SIZE		(8192-CONFIG_SYS_MP_SIZE-CONFIG_SYS_GBL_DATA_SIZE)
+#define CONFIG_SYS_PROM_OFFSET		(CONFIG_SYS_MP_OFFSET-CONFIG_SYS_PROM_SIZE)
 
 #define CONFIG_SYS_INIT_SP_OFFSET	(CONFIG_SYS_PROM_OFFSET-32)
 #define CONFIG_SYS_STACK_SIZE		(0x10000-32)
diff --git a/include/configs/gr_ep2s60.h b/include/configs/gr_ep2s60.h
index 6edb92c..10afca2 100644
--- a/include/configs/gr_ep2s60.h
+++ b/include/configs/gr_ep2s60.h
@@ -232,8 +232,16 @@
 #define CONFIG_SYS_GBL_DATA_SIZE	128	/* size in bytes reserved for initial data */
 #define CONFIG_SYS_GBL_DATA_OFFSET	(CONFIG_SYS_SDRAM_END - CONFIG_SYS_GBL_DATA_SIZE)
 
-#define CONFIG_SYS_PROM_SIZE		(8192-CONFIG_SYS_GBL_DATA_SIZE)
-#define CONFIG_SYS_PROM_OFFSET		(CONFIG_SYS_GBL_DATA_OFFSET-CONFIG_SYS_PROM_SIZE)
+#ifdef CONFIG_MP
+#define CONFIG_SYS_MP_SIZE		512
+#define CONFIG_SYS_MP_OFFSET		(CONFIG_SYS_GBL_DATA_OFFSET-CONFIG_SYS_MP_SIZE)
+#else
+#define CONFIG_SYS_MP_SIZE		0
+#define CONFIG_SYS_MP_OFFSET		CONFIG_SYS_GBL_DATA_OFFSET
+#endif
+
+#define CONFIG_SYS_PROM_SIZE		(8192-CONFIG_SYS_MP_SIZE-CONFIG_SYS_GBL_DATA_SIZE)
+#define CONFIG_SYS_PROM_OFFSET		(CONFIG_SYS_MP_OFFSET-CONFIG_SYS_PROM_SIZE)
 
 #define CONFIG_SYS_INIT_SP_OFFSET	(CONFIG_SYS_PROM_OFFSET-32)
 #define CONFIG_SYS_STACK_SIZE		(0x10000-32)
diff --git a/include/configs/gr_xc3s_1500.h b/include/configs/gr_xc3s_1500.h
index 1f9dd4a..b57640a 100644
--- a/include/configs/gr_xc3s_1500.h
+++ b/include/configs/gr_xc3s_1500.h
@@ -54,6 +54,8 @@
 #define CONFIG_DOS_PARTITION
 #define CONFIG_MAC_PARTITION
 #define CONFIG_ISO_PARTITION
+#define CONFIG_MP
+#define CONFIG_MP_MAX_CPUS 4
 
 /*
  * Supported commands
@@ -209,8 +211,16 @@
 #define CONFIG_SYS_GBL_DATA_SIZE	128	/* size in bytes reserved for initial data */
 #define CONFIG_SYS_GBL_DATA_OFFSET	(CONFIG_SYS_RAM_END - CONFIG_SYS_GBL_DATA_SIZE)
 
-#define CONFIG_SYS_PROM_SIZE		(8192-CONFIG_SYS_GBL_DATA_SIZE)
-#define CONFIG_SYS_PROM_OFFSET		(CONFIG_SYS_GBL_DATA_OFFSET-CONFIG_SYS_PROM_SIZE)
+#ifdef CONFIG_MP
+#define CONFIG_SYS_MP_SIZE		512
+#define CONFIG_SYS_MP_OFFSET		(CONFIG_SYS_GBL_DATA_OFFSET-CONFIG_SYS_MP_SIZE)
+#else
+#define CONFIG_SYS_MP_SIZE		0
+#define CONFIG_SYS_MP_OFFSET		CONFIG_SYS_GBL_DATA_OFFSET
+#endif
+
+#define CONFIG_SYS_PROM_SIZE		(8192-CONFIG_SYS_MP_SIZE-CONFIG_SYS_GBL_DATA_SIZE)
+#define CONFIG_SYS_PROM_OFFSET		(CONFIG_SYS_MP_OFFSET-CONFIG_SYS_PROM_SIZE)
 
 #define CONFIG_SYS_INIT_SP_OFFSET	(CONFIG_SYS_PROM_OFFSET-32)
 #define CONFIG_SYS_STACK_SIZE		(0x10000-32)
diff --git a/include/configs/grsim.h b/include/configs/grsim.h
index f815672..9e177e6 100644
--- a/include/configs/grsim.h
+++ b/include/configs/grsim.h
@@ -234,8 +234,16 @@
 #define CONFIG_SYS_GBL_DATA_SIZE	128	/* size in bytes reserved for initial data */
 #define CONFIG_SYS_GBL_DATA_OFFSET	(CONFIG_SYS_RAM_END - CONFIG_SYS_GBL_DATA_SIZE)
 
-#define CONFIG_SYS_PROM_SIZE		(8192-CONFIG_SYS_GBL_DATA_SIZE)
-#define CONFIG_SYS_PROM_OFFSET		(CONFIG_SYS_GBL_DATA_OFFSET-CONFIG_SYS_PROM_SIZE)
+#ifdef CONFIG_MP
+#define CONFIG_SYS_MP_SIZE		512
+#define CONFIG_SYS_MP_OFFSET		(CONFIG_SYS_GBL_DATA_OFFSET-CONFIG_SYS_MP_SIZE)
+#else
+#define CONFIG_SYS_MP_SIZE		0
+#define CONFIG_SYS_MP_OFFSET		CONFIG_SYS_GBL_DATA_OFFSET
+#endif
+
+#define CONFIG_SYS_PROM_SIZE		(8192-CONFIG_SYS_MP_SIZE-CONFIG_SYS_GBL_DATA_SIZE)
+#define CONFIG_SYS_PROM_OFFSET		(CONFIG_SYS_MP_OFFSET-CONFIG_SYS_PROM_SIZE)
 
 #define CONFIG_SYS_INIT_SP_OFFSET	(CONFIG_SYS_PROM_OFFSET-32)
 #define CONFIG_SYS_STACK_SIZE		(0x10000-32)
diff --git a/lib_sparc/Makefile b/lib_sparc/Makefile
index 040ca10..3860fdc 100644
--- a/lib_sparc/Makefile
+++ b/lib_sparc/Makefile
@@ -27,7 +27,7 @@ LIB	= $(obj)lib$(ARCH).a
 
 SOBJS	=
 
-COBJS	= board.o cache.o interrupts.o time.o bootm.o
+COBJS	= board.o cache.o interrupts.o time.o bootm.o boot_mp.o
 
 SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
 OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
diff --git a/lib_sparc/boot_mp.c b/lib_sparc/boot_mp.c
new file mode 100644
index 0000000..3154fd1
--- /dev/null
+++ b/lib_sparc/boot_mp.c
@@ -0,0 +1,177 @@
+/* SPARC Multi-Processor initialization
+ *
+ * (C) Copyright 2010
+ * Daniel Hellstrom, Aeroflex Gaisler, daniel at gaisler.com.
+ *
+ * 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/boot_mp.h>
+#include <config.h>
+
+#ifdef CONFIG_MP
+
+#ifndef CONFIG_MP_MAX_CPUS
+ #error CONFIG_MP_MAX_CPUS must be defined
+#endif
+
+typedef int (*cpu_preinit_func) (int cpu);
+
+/* Structure of all MP DATA section */
+struct boot_mp_data {
+	/* Function called for each CPU before entering kernel */
+	cpu_preinit_func func;
+
+	/* All CPU entry points and so on */
+	struct boot_mp_cpu cpu_table[CONFIG_MP_MAX_CPUS];
+
+	/* OS to boot */
+	int os;
+};
+
+struct boot_mp_data MP_DATA mp_data;
+
+/* Allow for specific RTEMS CPU initialization before RTEMS AMP boot */
+void MP_TEXT __boot_mp_rtems_cpu_preinit(int cpu)
+{
+
+}
+void boot_mp_rtems_cpu_preinit(int cpu)
+	__attribute__((weak, alias("__boot_mp_rtems_cpu_preinit")));
+
+/* Allow for specific VxWorks CPU initialization before slave CPUs boot */
+void MP_TEXT __boot_mp_vxworks_cpu_preinit(int cpu)
+{
+
+}
+void boot_mp_vxworks_cpu_preinit(int cpu)
+	__attribute__((weak, alias("__boot_mp_vxworks_cpu_preinit")));
+
+/* Allow for specific Linux CPU initialization before slave CPUs boot */
+void MP_TEXT __boot_mp_linux_cpu_preinit(int cpu)
+{
+
+}
+void boot_mp_linux_cpu_preinit(int cpu)
+	__attribute__((weak, alias("__boot_mp_linux_cpu_preinit")));
+
+static cpu_preinit_func os_cpu_preinit[] =
+{
+	[IH_OS_LINUX] = boot_mp_linux_cpu_preinit,
+	[IH_OS_RTEMS] = boot_mp_rtems_cpu_preinit,
+	[IH_OS_VXWORKS] = boot_mp_vxworks_cpu_preinit,
+};
+
+void boot_mp_os_setup(int os)
+{
+	struct boot_mp_data *mpd = (void *)CONFIG_SYS_MP_OFFSET;
+	unsigned int func;
+
+	mpd->os = os;
+
+	func = (unsigned int)os_cpu_preinit[os];
+	if ( func == 0 ) {
+		/* We assume that the OS booting does not support MP and will 
+		 * therefore not start the other CPUs.
+		 */
+		mpd->func = 0;
+	} else {
+		mpd->func = CONFIG_SYS_MP_OFFSET + (func & (CONFIG_SYS_MP_SIZE-1));
+	}
+
+	debug("boot_mp_os_setup:  0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x\n",
+		os,
+		os_cpu_preinit,
+		&os_cpu_preinit[os],
+		(unsigned int)os_cpu_preinit[os],
+		CONFIG_SYS_MP_SIZE,
+		((unsigned int)os_cpu_preinit[os] & (CONFIG_SYS_MP_SIZE-1))
+		);
+}
+
+void boot_mp_cpu_setup(
+	int cpu,
+	unsigned int entry_point,
+	unsigned int stack,
+	void *arg0,
+	void *arg1
+	)
+{
+	struct boot_mp_data *mpd = (void *)CONFIG_SYS_MP_OFFSET;
+
+	if ( cpu >= CONFIG_MP_MAX_CPUS )
+		return;
+
+	mpd->cpu_table[cpu].entry_point = entry_point;
+	mpd->cpu_table[cpu].stack = stack;
+	mpd->cpu_table[cpu].arg0 = arg0;
+	mpd->cpu_table[cpu].arg1 = arg1;
+
+	debug("boot_mp_cpu_setup(%d): ep=0x%x stack=0x%x, arg=[0x%x,0x%x]\n",
+		cpu, entry_point, stack, arg0, arg1);
+}
+
+/* In a RTEMS AMP system all CPUs have different entry points and stacks,
+ * the addresses are taken from the environment variables:
+ * cpu0_entry and cpu0_stack
+ */
+void boot_mp_rtems_setup(void)
+{
+	char *str;
+	char env_str[16];
+	int cpu;
+	unsigned int entry, stack;
+
+	for(cpu=0; cpu<CONFIG_MP_MAX_CPUS; cpu++) {
+
+		entry = 0;
+		stack = 0;
+
+		strcpy(env_str, "cpuX_entry");
+		env_str[3] = '0' + cpu;
+		if ( (str = getenv(env_str)) != NULL ) {
+			entry = simple_strtoul(str, NULL, 16);
+		}
+
+		strcpy(env_str, "cpuX_stack");
+		env_str[3] = '0' + cpu;
+		if ( (str = getenv(env_str)) != NULL ) {
+			stack = simple_strtoul(str, NULL, 16);
+		}
+
+		boot_mp_cpu_setup(
+			cpu,
+			(unsigned int)entry,
+			(unsigned int)stack,
+			NULL,
+			NULL);
+	}
+}
+
+/* Prepare boot, called from bootm */
+void arch_preboot_os(int os)
+{
+	boot_mp_os_setup(os);
+
+	if ( os == IH_OS_RTEMS )
+		boot_mp_rtems_setup();
+}
+
+#endif
diff --git a/lib_sparc/bootm.c b/lib_sparc/bootm.c
index f517325..428ad97 100644
--- a/lib_sparc/bootm.c
+++ b/lib_sparc/bootm.c
@@ -28,11 +28,12 @@
 #include <asm/prom.h>
 #include <asm/cache.h>
 #include <image.h>
+#include <asm-sparc/boot_mp.h>
 
 #define PRINT_KERNEL_HEADER
 
 extern image_header_t header;
-extern void srmmu_init_cpu(unsigned int entry);
+extern void srmmu_init(unsigned int entry);
 extern void prepare_bootargs(char *bootargs);
 
 /* sparc kernel argument (the ROM vector) */
@@ -43,7 +44,8 @@ struct linux_romvec *kernel_arg_promvec;
 #define RAMDISK_IMAGE_START_MASK	0x07FF
 #define RAMDISK_PROMPT_FLAG		0x8000
 #define RAMDISK_LOAD_FLAG		0x4000
-struct __attribute__ ((packed)) {
+/* Linux Single CPU Header */
+struct linux_up_hdr {
 	char traptable[PAGE_SIZE];
 	char swapper_pg_dir[PAGE_SIZE];
 	char pg0[PAGE_SIZE];
@@ -73,7 +75,13 @@ struct __attribute__ ((packed)) {
 			unsigned int end;
 		} ver_0203;
 	} hdr_input;
-} *linux_hdr;
+} __attribute__ ((packed)) ;
+
+/* Linux SMP Header */
+struct linux_smp_hdr {
+	char traptable[3][PAGE_SIZE];
+	struct linux_up_hdr single_hdr;
+} __attribute__ ((packed));
 
 /* temporary initrd image holder */
 image_header_t ihdr;
@@ -98,23 +106,34 @@ int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t * images)
 	void (*kernel) (struct linux_romvec *, void *);
 	struct lmb *lmb = &images->lmb;
 	int ret;
+	int i;
+	struct linux_up_hdr *linux_hdr;
+	struct linux_smp_hdr *linux_smp_hdr;
 
 	if ((flag != 0) && (flag != BOOTM_STATE_OS_GO))
 		return 1;
 
-	/* Get virtual address of kernel start */
-	linux_hdr = (void *)images->os.load;
-
-	/* */
+	/* Kernel Entry Point */
 	kernel = (void (*)(struct linux_romvec *, void *))images->ep;
 
+	/* Get virtual address of kernel start */
+	linux_hdr = (struct linux_up_hdr *)images->os.load;
+
 	/* check for a SPARC kernel */
 	if ((linux_hdr->hdr[0] != 'H') ||
 	    (linux_hdr->hdr[1] != 'd') ||
 	    (linux_hdr->hdr[2] != 'r') || (linux_hdr->hdr[3] != 'S')) {
-		puts("Error reading header of SPARC Linux kernel, aborting\n");
-		goto error;
+		/* Not a valid Linux Header, check if Linux SMP header */
+		linux_smp_hdr = (struct linux_smp_hdr *)images->os.load;
+		linux_hdr = (struct linux_up_hdr *)&linux_smp_hdr->single_hdr;
+		if ((linux_hdr->hdr[0] != 'H') ||
+		    (linux_hdr->hdr[1] != 'd') ||
+		    (linux_hdr->hdr[2] != 'r') || (linux_hdr->hdr[3] != 'S')) {
+			puts("Error reading header of SPARC Linux kernel, aborting\n");
+			goto error;
+   		}
 	}
+
 #ifdef PRINT_KERNEL_HEADER
 	printf("## Found SPARC Linux kernel %d.%d.%d ...\n",
 	       linux_hdr->linuxver_major,
@@ -164,8 +183,24 @@ int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t * images)
 	bootargs = getenv("bootargs");
 	prepare_bootargs(bootargs);
 
-	/* turn on mmu & setup context table & page table for process 0 (kernel) */
-	srmmu_init_cpu((unsigned int)kernel);
+	/* Init MMU table of SRMMU and more */
+	srmmu_init((unsigned int)kernel);
+
+#ifdef CONFIG_MP
+	for(i=0; i<CONFIG_MP_MAX_CPUS; i++) {
+		boot_mp_cpu_setup(
+			i,
+			(unsigned int)kernel,
+			(unsigned int)CONFIG_SYS_INIT_SP_OFFSET,
+			kernel_arg_promvec,
+			NULL);
+	}
+#endif
+
+	/* turn on mmu & setup context table & page table for process 0 (kernel).
+	 * This function is later called by each CPU in a multiprocessor system.
+	 */	
+	boot_mp_linux_cpu_preinit(0);
 
 	/* Enter SPARC Linux kernel
 	 * From now on the only code in u-boot that will be
-- 
1.5.4

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [U-Boot] [PATCH 01/17] SPARC: added unaligned definitions, patch supplied by Magnus Sjalander.
  2010-01-28 12:16 [U-Boot] [PATCH 01/17] SPARC: added unaligned definitions, patch supplied by Magnus Sjalander Daniel Hellstrom
                   ` (15 preceding siblings ...)
  2010-01-28 12:16 ` [U-Boot] [PATCH 17/17] SPARC, LEON3: added support for multiprocessing, tested Linux 2.6.21.1 SMP and RTEMS-4.10 AMP Daniel Hellstrom
@ 2010-01-28 20:41 ` Mike Frysinger
  2010-02-01 17:08   ` Daniel Hellstrom
  2010-05-05 21:35 ` Wolfgang Denk
  17 siblings, 1 reply; 26+ messages in thread
From: Mike Frysinger @ 2010-01-28 20:41 UTC (permalink / raw)
  To: u-boot

On Thursday 28 January 2010 07:16:20 Daniel Hellstrom wrote:
> Signed-off-by: Daniel Hellstrom <daniel@gaisler.com>
> ---
>  include/asm-sparc/unaligned.h |   17 +++++++++++++++++
>  1 files changed, 17 insertions(+), 0 deletions(-)
>  create mode 100644 include/asm-sparc/unaligned.h
> 
> diff --git a/include/asm-sparc/unaligned.h b/include/asm-sparc/unaligned.h
> new file mode 100644
> index 0000000..4e604c1
> --- /dev/null
> +++ b/include/asm-sparc/unaligned.h
> @@ -0,0 +1,17 @@
> +#ifndef _ASM_SPARC_UNALIGNED_H
> +#define _ASM_SPARC_UNALIGNED_H
> +
> +#ifdef __KERNEL__
> +
> +/*
> + * The SPARC can not do unaligned accesses, it must be split into multiple
> + * byte accesses. The SPARC is in big endian mode.
> + */
> +#include <linux/unaligned/be_byteshift.h>
> +#include <linux/unaligned/generic.h>
> +
> +#define get_unaligned	__get_unaligned_be
> +#define put_unaligned	__put_unaligned_be
> +
> +#endif	/* __KERNEL__ */
> +#endif	/* _ASM_SPARC_UNALIGNED_H */

there is a proposed asm-generic/unaligned.h on the mailing list which i think 
you could use.  you'd just need:
#include <asm-generic/unaligned.h>
-mike
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part.
Url : http://lists.denx.de/pipermail/u-boot/attachments/20100128/329f0c76/attachment.pgp 

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [U-Boot] [PATCH 01/17] SPARC: added unaligned definitions, patch supplied by Magnus Sjalander.
  2010-01-28 20:41 ` [U-Boot] [PATCH 01/17] SPARC: added unaligned definitions, patch supplied by Magnus Sjalander Mike Frysinger
@ 2010-02-01 17:08   ` Daniel Hellstrom
  2010-03-16 20:44     ` Mike Frysinger
  0 siblings, 1 reply; 26+ messages in thread
From: Daniel Hellstrom @ 2010-02-01 17:08 UTC (permalink / raw)
  To: u-boot


Mike Frysinger wrote:

>On Thursday 28 January 2010 07:16:20 Daniel Hellstrom wrote:
>  
>
>>Signed-off-by: Daniel Hellstrom <daniel@gaisler.com>
>>---
>> include/asm-sparc/unaligned.h |   17 +++++++++++++++++
>> 1 files changed, 17 insertions(+), 0 deletions(-)
>> create mode 100644 include/asm-sparc/unaligned.h
>>
>>diff --git a/include/asm-sparc/unaligned.h b/include/asm-sparc/unaligned.h
>>new file mode 100644
>>index 0000000..4e604c1
>>--- /dev/null
>>+++ b/include/asm-sparc/unaligned.h
>>@@ -0,0 +1,17 @@
>>+#ifndef _ASM_SPARC_UNALIGNED_H
>>+#define _ASM_SPARC_UNALIGNED_H
>>+
>>+#ifdef __KERNEL__
>>+
>>+/*
>>+ * The SPARC can not do unaligned accesses, it must be split into multiple
>>+ * byte accesses. The SPARC is in big endian mode.
>>+ */
>>+#include <linux/unaligned/be_byteshift.h>
>>+#include <linux/unaligned/generic.h>
>>+
>>+#define get_unaligned	__get_unaligned_be
>>+#define put_unaligned	__put_unaligned_be
>>+
>>+#endif	/* __KERNEL__ */
>>+#endif	/* _ASM_SPARC_UNALIGNED_H */
>>    
>>
>
>there is a proposed asm-generic/unaligned.h on the mailing list which i think 
>you could use.  you'd just need:
>#include <asm-generic/unaligned.h>
>-mike
>  
>
Thank you for your comment, I will update this patch.

Daniel

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [U-Boot] [PATCH 01/17] SPARC: added unaligned definitions, patch supplied by Magnus Sjalander.
  2010-02-01 17:08   ` Daniel Hellstrom
@ 2010-03-16 20:44     ` Mike Frysinger
  0 siblings, 0 replies; 26+ messages in thread
From: Mike Frysinger @ 2010-03-16 20:44 UTC (permalink / raw)
  To: u-boot

On Monday 01 February 2010 12:08:51 Daniel Hellstrom wrote:
> Mike Frysinger wrote:
> >there is a proposed asm-generic/unaligned.h on the mailing list which i
> >think you could use.  you'd just need:
> >#include <asm-generic/unaligned.h>
> 
> Thank you for your comment, I will update this patch.

the generic unaligned.h has been merged if you want to post your one-line 
patch now ...
-mike
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part.
Url : http://lists.denx.de/pipermail/u-boot/attachments/20100316/e8073a90/attachment.pgp 

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [U-Boot] [PATCH 01/17] SPARC: added unaligned definitions, patch supplied by Magnus Sjalander.
  2010-01-28 12:16 [U-Boot] [PATCH 01/17] SPARC: added unaligned definitions, patch supplied by Magnus Sjalander Daniel Hellstrom
                   ` (16 preceding siblings ...)
  2010-01-28 20:41 ` [U-Boot] [PATCH 01/17] SPARC: added unaligned definitions, patch supplied by Magnus Sjalander Mike Frysinger
@ 2010-05-05 21:35 ` Wolfgang Denk
  2010-05-06  6:37   ` Daniel Hellstrom
  17 siblings, 1 reply; 26+ messages in thread
From: Wolfgang Denk @ 2010-05-05 21:35 UTC (permalink / raw)
  To: u-boot

Dear Daniel Hellstrom,

In message <1264680996-13804-1-git-send-email-daniel@gaisler.com> you wrote:
> Signed-off-by: Daniel Hellstrom <daniel@gaisler.com>
> ---
>  include/asm-sparc/unaligned.h |   17 +++++++++++++++++
>  1 files changed, 17 insertions(+), 0 deletions(-)
>  create mode 100644 include/asm-sparc/unaligned.h

This whole patch series has been out there for many months, but I'm
still waiting for a pull request from you.

Do you have any such plans?

Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
Sorry, but my karma just ran over your dogma.

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [U-Boot] [PATCH 01/17] SPARC: added unaligned definitions, patch supplied by Magnus Sjalander.
  2010-05-05 21:35 ` Wolfgang Denk
@ 2010-05-06  6:37   ` Daniel Hellstrom
  2010-05-06 10:57     ` Wolfgang Denk
  0 siblings, 1 reply; 26+ messages in thread
From: Daniel Hellstrom @ 2010-05-06  6:37 UTC (permalink / raw)
  To: u-boot

Dear Wolfgang,

I had some minor remarks on patch 1 and 2 as I recall, and a minor 
change on another patch I discovered myself. Unfortunately I have been 
very busy, I am really sorry for that. I will try to pull my self 
together and finish them in the weekend.

Do I have to repost the patches, now that they are so delayed?

Thank you for your interest, that really helps,
Daniel Hellstrom


Wolfgang Denk wrote:

>Dear Daniel Hellstrom,
>
>In message <1264680996-13804-1-git-send-email-daniel@gaisler.com> you wrote:
>  
>
>>Signed-off-by: Daniel Hellstrom <daniel@gaisler.com>
>>---
>> include/asm-sparc/unaligned.h |   17 +++++++++++++++++
>> 1 files changed, 17 insertions(+), 0 deletions(-)
>> create mode 100644 include/asm-sparc/unaligned.h
>>    
>>
>
>This whole patch series has been out there for many months, but I'm
>still waiting for a pull request from you.
>
>Do you have any such plans?
>
>Best regards,
>
>Wolfgang Denk
>
>  
>

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [U-Boot] [PATCH 01/17] SPARC: added unaligned definitions, patch supplied by Magnus Sjalander.
  2010-05-06  6:37   ` Daniel Hellstrom
@ 2010-05-06 10:57     ` Wolfgang Denk
  0 siblings, 0 replies; 26+ messages in thread
From: Wolfgang Denk @ 2010-05-06 10:57 UTC (permalink / raw)
  To: u-boot

Dear Daniel Hellstrom,

In message <4BE263AD.7020006@gaisler.com> you wrote:
> 
> I had some minor remarks on patch 1 and 2 as I recall, and a minor 
> change on another patch I discovered myself. Unfortunately I have been 
> very busy, I am really sorry for that. I will try to pull my self 
> together and finish them in the weekend.
> 
> Do I have to repost the patches, now that they are so delayed?

You will probably have to rebase these anyway, so please also repost.

Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
"A fractal is by definition a set for which the Hausdorff Besicovitch
dimension strictly exceeds the topological dimension."
- Mandelbrot, _The Fractal Geometry of Nature_

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [U-Boot] [PATCH 01/17] SPARC: added unaligned definitions, patch supplied by Magnus Sjalander.
  2010-05-19 22:01 ` Mike Frysinger
@ 2010-05-26 11:29   ` Daniel Hellstrom
  0 siblings, 0 replies; 26+ messages in thread
From: Daniel Hellstrom @ 2010-05-26 11:29 UTC (permalink / raw)
  To: u-boot

Hi,

Thank you for the input, I will resend the patch with Magnus as author.

Daniel


Mike Frysinger wrote:

>the subject line is incorrect.  you dont credit people via summary/changelogs, 
>you do it via the tags.  so if Magnus wrote this patch, he should be credited 
>with authorship (so use --author when committing).  if he gave tips or 
>something, then perhaps use Reported-by.
>-mike
>  
>

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [U-Boot] [PATCH 01/17] SPARC: added unaligned definitions, patch supplied by Magnus Sjalander.
  2010-05-18 14:47 Daniel Hellstrom
@ 2010-05-19 22:01 ` Mike Frysinger
  2010-05-26 11:29   ` Daniel Hellstrom
  0 siblings, 1 reply; 26+ messages in thread
From: Mike Frysinger @ 2010-05-19 22:01 UTC (permalink / raw)
  To: u-boot

the subject line is incorrect.  you dont credit people via summary/changelogs, 
you do it via the tags.  so if Magnus wrote this patch, he should be credited 
with authorship (so use --author when committing).  if he gave tips or 
something, then perhaps use Reported-by.
-mike
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part.
Url : http://lists.denx.de/pipermail/u-boot/attachments/20100519/89a69174/attachment.pgp 

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [U-Boot] [PATCH 01/17] SPARC: added unaligned definitions, patch supplied by Magnus Sjalander.
@ 2010-05-18 14:47 Daniel Hellstrom
  2010-05-19 22:01 ` Mike Frysinger
  0 siblings, 1 reply; 26+ messages in thread
From: Daniel Hellstrom @ 2010-05-18 14:47 UTC (permalink / raw)
  To: u-boot

Signed-off-by: Daniel Hellstrom <daniel@gaisler.com>
---
 arch/sparc/include/asm/byteorder.h |    1 +
 arch/sparc/include/asm/unaligned.h |   10 ++++++++++
 2 files changed, 11 insertions(+), 0 deletions(-)
 create mode 100644 arch/sparc/include/asm/unaligned.h

diff --git a/arch/sparc/include/asm/byteorder.h b/arch/sparc/include/asm/byteorder.h
index b9fc656..e3b3dec 100644
--- a/arch/sparc/include/asm/byteorder.h
+++ b/arch/sparc/include/asm/byteorder.h
@@ -32,6 +32,7 @@
 
 #if defined(__GNUC__) && !defined(__STRICT_ANSI__)
 #define __BYTEORDER_HAS_U64__
+#define __SWAB_64_THRU_32__
 #endif
 #include <linux/byteorder/big_endian.h>
 #endif				/* _SPARC_BYTEORDER_H */
diff --git a/arch/sparc/include/asm/unaligned.h b/arch/sparc/include/asm/unaligned.h
new file mode 100644
index 0000000..0e646f7
--- /dev/null
+++ b/arch/sparc/include/asm/unaligned.h
@@ -0,0 +1,10 @@
+#ifndef _ASM_SPARC_UNALIGNED_H
+#define _ASM_SPARC_UNALIGNED_H
+
+/*
+ * The SPARC can not do unaligned accesses, it must be split into multiple
+ * byte accesses. The SPARC is in big endian mode.
+ */
+#include <asm-generic/unaligned.h>
+
+#endif	/* _ASM_SPARC_UNALIGNED_H */
-- 
1.5.4

^ permalink raw reply related	[flat|nested] 26+ messages in thread

end of thread, other threads:[~2010-05-26 11:29 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-01-28 12:16 [U-Boot] [PATCH 01/17] SPARC: added unaligned definitions, patch supplied by Magnus Sjalander Daniel Hellstrom
2010-01-28 12:16 ` [U-Boot] [PATCH 02/17] GRETH: Added support for selecting PHY address from config, PHY address was always set to zero before Daniel Hellstrom
2010-01-28 12:16 ` [U-Boot] [PATCH 03/17] GRETH: Added extra RESET, this is needed if GRETH was stopped during an ethernet frame reception Daniel Hellstrom
2010-01-28 12:16 ` [U-Boot] [PATCH 04/17] LEON3: reimplemented AMBA Plug&Play scanning routines Daniel Hellstrom
2010-01-28 12:16 ` [U-Boot] [PATCH 05/17] LEON3: added memory controller initialization using the new AMBA PnP routines Daniel Hellstrom
2010-01-28 12:16 ` [U-Boot] [PATCH 06/17] LEON3: Moved GRLIB core header files to common include/grlib directory Daniel Hellstrom
2010-01-28 12:16 ` [U-Boot] [PATCH 07/17] LEON3: serial baud rate register support multiple buses with different frequency Daniel Hellstrom
2010-01-28 12:16 ` [U-Boot] [PATCH 08/17] SPARC: added function that checks if IRQ is on or off Daniel Hellstrom
2010-01-28 12:16 ` [U-Boot] [PATCH 09/17] LEON3: added busy wait function, made wait_ms() work when IRQ is disabled Daniel Hellstrom
2010-01-28 12:16 ` [U-Boot] [PATCH 10/17] LEON3: added CPU count and frequency detection Daniel Hellstrom
2010-01-28 12:16 ` [U-Boot] [PATCH 11/17] SPARC: removed USB stop from linux bootm, arch-independent bootm stop USB Daniel Hellstrom
2010-01-28 12:16 ` [U-Boot] [PATCH 12/17] SPARC: added optional cpu_late_init routine Daniel Hellstrom
2010-01-28 12:16 ` [U-Boot] [PATCH 13/17] LEON3: Added GRETH EDCL debug link IP address initialization Daniel Hellstrom
2010-01-28 12:16 ` [U-Boot] [PATCH 14/17] LEON: added support for GRLIB SPI Memory controller, spi command interface Daniel Hellstrom
2010-01-28 12:16 ` [U-Boot] [PATCH 15/17] LEON3: fixed MMU table for systems with larger memory than 128MB Daniel Hellstrom
2010-01-28 12:16 ` [U-Boot] [PATCH 16/17] bootm command: added argument to arch_preboot_os, function may depend on OS type Daniel Hellstrom
2010-01-28 12:16 ` [U-Boot] [PATCH 17/17] SPARC, LEON3: added support for multiprocessing, tested Linux 2.6.21.1 SMP and RTEMS-4.10 AMP Daniel Hellstrom
2010-01-28 20:41 ` [U-Boot] [PATCH 01/17] SPARC: added unaligned definitions, patch supplied by Magnus Sjalander Mike Frysinger
2010-02-01 17:08   ` Daniel Hellstrom
2010-03-16 20:44     ` Mike Frysinger
2010-05-05 21:35 ` Wolfgang Denk
2010-05-06  6:37   ` Daniel Hellstrom
2010-05-06 10:57     ` Wolfgang Denk
2010-05-18 14:47 Daniel Hellstrom
2010-05-19 22:01 ` Mike Frysinger
2010-05-26 11:29   ` Daniel Hellstrom

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.