]> git.karo-electronics.de Git - karo-tx-uboot.git/commitdiff
Merge branch 'series1_v2' of git://git.denx.de/u-boot-sparc
authorTom Rini <trini@konsulko.com>
Fri, 13 Nov 2015 15:04:34 +0000 (10:04 -0500)
committerTom Rini <trini@konsulko.com>
Fri, 13 Nov 2015 15:04:34 +0000 (10:04 -0500)
39 files changed:
MAINTAINERS
arch/sparc/config.mk
arch/sparc/cpu/leon2/serial.c
arch/sparc/cpu/leon2/start.S
arch/sparc/cpu/leon3/Makefile
arch/sparc/cpu/leon3/ambapp.c
arch/sparc/cpu/leon3/ambapp_low.S [new file with mode: 0644]
arch/sparc/cpu/leon3/ambapp_low_c.S [new file with mode: 0644]
arch/sparc/cpu/leon3/cpu_init.c
arch/sparc/cpu/leon3/interrupts.c
arch/sparc/cpu/leon3/memcfg.c [new file with mode: 0644]
arch/sparc/cpu/leon3/memcfg.h [new file with mode: 0644]
arch/sparc/cpu/leon3/memcfg_low.S [new file with mode: 0644]
arch/sparc/cpu/leon3/prom.c
arch/sparc/cpu/leon3/serial.c
arch/sparc/cpu/leon3/start.S
arch/sparc/cpu/leon3/usb_uhci.c
arch/sparc/include/asm/global_data.h
arch/sparc/include/asm/io.h
arch/sparc/include/asm/winmacro.h
common/Kconfig
common/board_r.c
common/cmd_ambapp.c
configs/grsim_defconfig
doc/git-mailrc
drivers/net/greth.c
drivers/serial/Kconfig
include/ambapp.h
include/ambapp_ids.h [new file with mode: 0644]
include/config_cmd_all.h
include/configs/gr_cpci_ax2000.h
include/configs/gr_ep2s60.h
include/configs/gr_xc3s_1500.h
include/configs/grsim.h
include/configs/grsim_leon2.h
include/grlib/apbuart.h [new file with mode: 0644]
include/grlib/gptimer.h [new file with mode: 0644]
include/grlib/greth.h [new file with mode: 0644]
include/grlib/irqmp.h [new file with mode: 0644]

index bf60c67668b1281a583d98c13432a3c0974d26af..b3a45ccbac65957dfa2d029c3df229790ff2fbff 100644 (file)
@@ -370,7 +370,7 @@ T:  git git://git.denx.de/u-boot-sh.git
 F:     arch/sh/
 
 SPARC
-M:     Daniel Hellstrom <daniel@gaisler.com>
+M:     Francois Retief <fgretief@spaceteq.co.za>
 S:     Maintained
 T:     git git://git.denx.de/u-boot-sparc.git
 F:     arch/sparc/
index d615f294fed48cb60d9141ee338bff1d944214aa..43faad48ceb1c4e8fad7141fb79415c78b974b11 100644 (file)
@@ -1,19 +1,25 @@
 #
-# (C) Copyright 2007
-# Daniel Hellstrom, Gaisler Research, daniel@gaisler.com
+# (C) Copyright 2015
+# Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com.
 #
 # SPDX-License-Identifier:     GPL-2.0+
 #
 
 ifeq ($(CROSS_COMPILE),)
-CROSS_COMPILE := sparc-elf-
+CROSS_COMPILE := sparc-linux-
 endif
 
+# This GCC compiler is known to work:
+#  https://www.kernel.org/pub/tools/crosstool/files/bin/x86_64/4.9.0/
+
 gcclibdir := $(shell dirname `$(CC) -print-libgcc-file-name`)
 
 CONFIG_STANDALONE_LOAD_ADDR ?= 0x00000000 -L $(gcclibdir) \
                               -T $(srctree)/examples/standalone/sparc.lds
 
-PLATFORM_CPPFLAGS += -D__sparc__
+cpuflags-$(CONFIG_LEON2) := -mcpu=leon
+cpuflags-$(CONFIG_LEON3) := -mcpu=leon3
+
+PLATFORM_CPPFLAGS += $(cpuflags-y)
 
 PLATFORM_RELFLAGS += -fPIC
index 5cfbb9ed15951ef7d6189ce20f401fdfac7d555f..603364ee0bd9d0c6a4c5703befa26e1d3b3a29ed 100644 (file)
@@ -1,72 +1,78 @@
 /* GRLIB APBUART Serial controller driver
  *
- * (C) Copyright 2008
- * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com.
+ * (C) Copyright 2008, 2015
+ * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com.
  *
  * SPDX-License-Identifier:    GPL-2.0+
  */
 
 #include <common.h>
-#include <asm/processor.h>
-#include <asm/leon.h>
+#include <asm/io.h>
 #include <serial.h>
-#include <linux/compiler.h>
+#include <watchdog.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
+static unsigned leon2_serial_calc_scaler(unsigned freq, unsigned baud)
+{
+       return (((freq*10) / (baud*8)) - 5) / 10;
+}
+
 static int leon2_serial_init(void)
 {
-       LEON2_regs *leon2 = (LEON2_regs *) LEON2_PREGS;
+       LEON2_regs *leon2 = (LEON2_regs *)LEON2_PREGS;
        LEON2_Uart_regs *regs;
        unsigned int tmp;
 
-       /* Init LEON2 UART
-        *
-        * Set scaler / baud rate
-        *
-        * Receiver & transmitter enable
-        */
 #if LEON2_CONSOLE_SELECT == LEON_CONSOLE_UART1
-       regs = (LEON2_Uart_regs *) & leon2->UART_Channel_1;
+       regs = (LEON2_Uart_regs *)&leon2->UART_Channel_1;
 #else
-       regs = (LEON2_Uart_regs *) & leon2->UART_Channel_2;
+       regs = (LEON2_Uart_regs *)&leon2->UART_Channel_2;
 #endif
 
-       regs->UART_Scaler = CONFIG_SYS_LEON2_UART1_SCALER;
+       /* Set scaler / baud rate */
+       tmp = leon2_serial_calc_scaler(CONFIG_SYS_CLK_FREQ, CONFIG_BAUDRATE);
+       writel(tmp, &regs->UART_Scaler);
 
        /* Let bit 11 be unchanged (debug bit for GRMON) */
-       tmp = READ_WORD(regs->UART_Control);
+       tmp = readl(&regs->UART_Control) & LEON2_UART_CTRL_DBG;
+       tmp |= (LEON2_UART1_LOOPBACK_ENABLE << 7);
+       tmp |= (LEON2_UART1_FLOWCTRL_ENABLE << 6);
+       tmp |= (LEON2_UART1_PARITY_ENABLE << 5);
+       tmp |= (LEON2_UART1_ODDPAR_ENABLE << 4);
+       /* Receiver & transmitter enable */
+       tmp |= (LEON2_UART_CTRL_RE | LEON2_UART_CTRL_TE);
+       writel(tmp, &regs->UART_Control);
+
+       gd->arch.uart = regs;
+       return 0;
+}
 
-       regs->UART_Control = ((tmp & LEON2_UART_CTRL_DBG) |
-                             (LEON2_UART1_LOOPBACK_ENABLE << 7) |
-                             (LEON2_UART1_FLOWCTRL_ENABLE << 6) |
-                             (LEON2_UART1_PARITY_ENABLE << 5) |
-                             (LEON2_UART1_ODDPAR_ENABLE << 4) |
-                             LEON2_UART_CTRL_RE | LEON2_UART_CTRL_TE);
+static inline LEON2_Uart_regs *leon2_get_uart_regs(void)
+{
+       LEON2_Uart_regs *uart = gd->arch.uart;
 
-       return 0;
+       return uart;
 }
 
 static void leon2_serial_putc_raw(const char c)
 {
-       LEON2_regs *leon2 = (LEON2_regs *) LEON2_PREGS;
-       LEON2_Uart_regs *regs;
+       LEON2_Uart_regs *uart = leon2_get_uart_regs();
 
-#if LEON2_CONSOLE_SELECT == LEON_CONSOLE_UART1
-       regs = (LEON2_Uart_regs *) & leon2->UART_Channel_1;
-#else
-       regs = (LEON2_Uart_regs *) & leon2->UART_Channel_2;
-#endif
+       if (!uart)
+               return;
 
        /* Wait for last character to go. */
-       while (!(READ_WORD(regs->UART_Status) & LEON2_UART_STAT_THE)) ;
+       while (!(readl(&uart->UART_Status) & LEON2_UART_STAT_THE))
+               WATCHDOG_RESET();
 
        /* Send data */
-       regs->UART_Channel = c;
+       writel(c, &uart->UART_Channel);
 
 #ifdef LEON_DEBUG
        /* Wait for data to be sent */
-       while (!(READ_WORD(regs->UART_Status) & LEON2_UART_STAT_TSE)) ;
+       while (!(readl(&uart->UART_Status) & LEON2_UART_STAT_TSE))
+               WATCHDOG_RESET();
 #endif
 }
 
@@ -80,56 +86,43 @@ static void leon2_serial_putc(const char c)
 
 static int leon2_serial_getc(void)
 {
-       LEON2_regs *leon2 = (LEON2_regs *) LEON2_PREGS;
-       LEON2_Uart_regs *regs;
+       LEON2_Uart_regs *uart = leon2_get_uart_regs();
 
-#if LEON2_CONSOLE_SELECT == LEON_CONSOLE_UART1
-       regs = (LEON2_Uart_regs *) & leon2->UART_Channel_1;
-#else
-       regs = (LEON2_Uart_regs *) & leon2->UART_Channel_2;
-#endif
+       if (!uart)
+               return 0;
 
        /* Wait for a character to arrive. */
-       while (!(READ_WORD(regs->UART_Status) & LEON2_UART_STAT_DR)) ;
+       while (!(readl(&uart->UART_Status) & LEON2_UART_STAT_DR))
+               WATCHDOG_RESET();
 
-       /* read data */
-       return READ_WORD(regs->UART_Channel);
+       /* Read character data */
+       return readl(&uart->UART_Channel);
 }
 
 static int leon2_serial_tstc(void)
 {
-       LEON2_regs *leon2 = (LEON2_regs *) LEON2_PREGS;
-       LEON2_Uart_regs *regs;
+       LEON2_Uart_regs *uart = leon2_get_uart_regs();
 
-#if LEON2_CONSOLE_SELECT == LEON_CONSOLE_UART1
-       regs = (LEON2_Uart_regs *) & leon2->UART_Channel_1;
-#else
-       regs = (LEON2_Uart_regs *) & leon2->UART_Channel_2;
-#endif
+       if (!uart)
+               return 0;
 
-       return (READ_WORD(regs->UART_Status) & LEON2_UART_STAT_DR);
+       return readl(&uart->UART_Status) & LEON2_UART_STAT_DR;
 }
 
-/* set baud rate for uart */
 static void leon2_serial_setbrg(void)
 {
-       /* update baud rate settings, read it from gd->baudrate */
+       LEON2_Uart_regs *uart = leon2_get_uart_regs();
        unsigned int scaler;
-       LEON2_regs *leon2 = (LEON2_regs *) LEON2_PREGS;
-       LEON2_Uart_regs *regs;
 
-#if LEON2_CONSOLE_SELECT == LEON_CONSOLE_UART1
-       regs = (LEON2_Uart_regs *) & leon2->UART_Channel_1;
-#else
-       regs = (LEON2_Uart_regs *) & leon2->UART_Channel_2;
-#endif
+       if (!uart)
+               return;
+
+       if (!gd->baudrate)
+               gd->baudrate = CONFIG_BAUDRATE;
+
+       scaler = leon2_serial_calc_scaler(CONFIG_SYS_CLK_FREQ, CONFIG_BAUDRATE);
 
-       if (gd->baudrate > 0) {
-               scaler =
-                   (((CONFIG_SYS_CLK_FREQ * 10) / (gd->baudrate * 8)) -
-                    5) / 10;
-               regs->UART_Scaler = scaler;
-       }
+       writel(scaler, &uart->UART_Scaler);
 }
 
 static struct serial_device leon2_serial_drv = {
index e43097cf9b17622bd8e6cad78f64f90c3d505b93..974de76852e5f74c18fe38c6b53992383ec699bc 100644 (file)
@@ -57,6 +57,27 @@ MINFRAME = (WINDOWSIZE + ARGPUSHSIZE + 4)
 #error Must define number of SPARC register windows, default is 8
 #endif
 
+/* Macros to load address into a register. Uses GOT table for PIC */
+#ifdef __PIC__
+
+#define SPARC_PIC_THUNK_CALL(reg) \
+       sethi   %pc22(_GLOBAL_OFFSET_TABLE_-4), %##reg; \
+       call    __sparc_get_pc_thunk.reg; \
+        add    %##reg, %pc10(_GLOBAL_OFFSET_TABLE_+4), %##reg;
+
+#define SPARC_LOAD_ADDRESS(sym, got, reg) \
+       sethi   %gdop_hix22(sym), %##reg; \
+       xor     %##reg, %gdop_lox10(sym), %##reg; \
+       ld      [%##got + %##reg], %##reg, %gdop(sym);
+
+#else
+
+#define SPARC_PIC_THUNK_CALL(reg)
+#define SPARC_LOAD_ADDRESS(sym, got, tmp) \
+       set     sym, %##reg;
+
+#endif
+
 #define STACK_ALIGN    8
 #define SA(X)  (((X)+(STACK_ALIGN-1)) & ~(STACK_ALIGN-1))
 
@@ -278,7 +299,7 @@ leon2_init_mctrl:
        srl     %g2, 30, %g2
        andcc   %g2, 3, %g6
        bne,a   leon2_init_wim
-       mov     %g0, %asr16             ! clear err_reg
+        mov    %g0, %asr16             ! clear err_reg
 
 leon2_init_wim:
        set     WIM_INIT, %g3
@@ -299,7 +320,7 @@ leon2_init_stackp:
 
 cpu_init_unreloc:
        call    cpu_init_f
-       nop
+        nop
 
 /* un relocated start address of monitor */
 #define TEXT_START _text
@@ -307,9 +328,10 @@ cpu_init_unreloc:
 /* un relocated end address of monitor */
 #define DATA_END __init_end
 
+       SPARC_PIC_THUNK_CALL(l7)
 reloc:
-       set     TEXT_START,%g2
-       set     DATA_END,%g3
+       SPARC_LOAD_ADDRESS(TEXT_START, l7, g2)
+       SPARC_LOAD_ADDRESS(DATA_END, l7, g3)
        set     CONFIG_SYS_RELOC_MONITOR_BASE,%g4
 reloc_loop:
        ldd     [%g2],%l0
@@ -319,7 +341,7 @@ reloc_loop:
        inc     16,%g2
        subcc   %g3,%g2,%g0
        bne     reloc_loop
-       inc     16,%g4
+        inc    16,%g4
 
        clr     %l0
        clr     %l1
@@ -336,8 +358,8 @@ reloc_loop:
 
 clr_bss:
 /* clear bss area (the relocated) */
-       set     __bss_start,%g2
-       set     __bss_end,%g3
+       SPARC_LOAD_ADDRESS(__bss_start, l7, g2)
+       SPARC_LOAD_ADDRESS(__bss_end, l7, g3)
        sub     %g3,%g2,%g3
        add     %g3,%g4,%g3
        clr     %g1     /* std %g0 uses g0 and g1 */
@@ -348,19 +370,19 @@ clr_bss_16:
        inc     16,%g4
        cmp     %g3,%g4
        bne     clr_bss_16
-       nop
+        nop
 
 /* add offsets to GOT table */
 fixup_got:
-       set     __got_start,%g4
-       set     __got_end,%g3
+       SPARC_LOAD_ADDRESS(__got_start, l7, g4)
+       SPARC_LOAD_ADDRESS(__got_end, l7, g3)
 /*
  * new got offset = (old GOT-PTR (read with ld) -
  *   CONFIG_SYS_RELOC_MONITOR_BASE(from define) ) +
  *   Destination Address (from define)
  */
        set     CONFIG_SYS_RELOC_MONITOR_BASE,%g2
-       set     TEXT_START, %g1
+       SPARC_LOAD_ADDRESS(TEXT_START, l7, g1)
        add     %g4,%g2,%g4
        sub     %g4,%g1,%g4
        add     %g3,%g2,%g3
@@ -375,11 +397,11 @@ got_loop:
        inc     4,%g4
        cmp     %g3,%g4
        bne     got_loop
-       nop
+        nop
 
 prom_relocate:
-       set     __prom_start, %g2
-       set     __prom_end, %g3
+       SPARC_LOAD_ADDRESS(__prom_start, l7, g2)
+       SPARC_LOAD_ADDRESS(__prom_end, l7, g3)
        set     CONFIG_SYS_PROM_OFFSET, %g4
 
 prom_relocate_loop:
@@ -390,7 +412,7 @@ prom_relocate_loop:
        inc     16,%g2
        subcc   %g3,%g2,%g0
        bne     prom_relocate_loop
-       inc     16,%g4
+        inc    16,%g4
 
 /* Trap table has been moved, lets tell CPU about
  * the new trap table address
@@ -403,19 +425,19 @@ prom_relocate_loop:
        nop
 /* Call relocated init functions */
 jump:
-       set     cpu_init_f2,%o1
+       SPARC_LOAD_ADDRESS(cpu_init_f2, l7, o1)
        set     CONFIG_SYS_RELOC_MONITOR_BASE,%o2
        add     %o1,%o2,%o1
        sub     %o1,%g1,%o1
        call    %o1
-       clr     %o0
+        clr    %o0
 
-       set     board_init_f,%o1
+       SPARC_LOAD_ADDRESS(board_init_f, l7, o1)
        set     CONFIG_SYS_RELOC_MONITOR_BASE,%o2
        add     %o1,%o2,%o1
        sub     %o1,%g1,%o1
        call    %o1
-       clr     %o0
+        clr    %o0
 
 dead:  ta 0                            ! if call returns...
        nop
index 4f13ec30715a994c3da3ee5ead013c155b545d5c..f4cf43cfec32eddaff9f885cefd40297e3a1dac3 100644 (file)
@@ -6,4 +6,5 @@
 #
 
 extra-y        = start.o
-obj-y  = cpu_init.o serial.o cpu.o ambapp.o interrupts.o prom.o usb_uhci.o
+obj-y  = cpu_init.o serial.o cpu.o ambapp.o ambapp_low.o ambapp_low_c.o \
+       interrupts.o prom.o usb_uhci.o memcfg.o memcfg_low.o
index a30d1f2a99b35c4060b435d5416f72efb2ca8a62..b8ac05faf12c50c1bbe3ed3e8d94020d3d0ed231 100644 (file)
-/* 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@gaisler.com
+ * (C) Copyright 2010, 2015
+ * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com.
  *
  * SPDX-License-Identifier:    GPL-2.0+
  */
 
+/* #define DEBUG */
+
 #include <common.h>
-#include <command.h>
+#include <malloc.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
-
-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.
-                                        */
-    )
-{
-       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;
-       }
+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;
+};
 
-       /* Get APB CTRL Plug&Play info area */
-       apbmst_base = apbmst.address[0] & LEON3_IO_AREA;
-       apb = (apbctrl_pp_dev *) (apbmst_base | LEON3_CONF_AREA);
+extern void ambapp_find_buses(unsigned int ioarea, struct ambapp_bus *abus);
 
-       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;
-}
+extern int ambapp_find_apb(struct ambapp_bus *abus, unsigned int dev_vend,
+       int index, struct ambapp_find_apb_info *result);
 
-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)
-{
-       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);
-               }
-               /* Get next Plug&Play entry */
-               apb++;
-       }
-       return 0;
-}
+extern int ambapp_find_ahb(struct ambapp_bus *abus, unsigned int dev_vend,
+       int index, int type, struct ambapp_find_ahb_info *result);
 
-/****************************** APB SLAVES ******************************/
+/************ C ROUTINES USED BY U-BOOT AMBA CORE DRIVERS ************/
+struct ambapp_bus ambapp_plb;
 
-int ambapp_apb_count(unsigned int vendor, unsigned int driver)
+void ambapp_bus_init(
+       unsigned int ioarea,
+       unsigned int freq,
+       struct ambapp_bus *abus)
 {
-       return ambapp_apb_scan(vendor, driver, NULL, 0, LEON3_APB_SLAVES);
+       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;
 }
 
-int ambapp_apb_first(unsigned int vendor,
-                    unsigned int driver, ambapp_apbdev * dev)
+/* Parse APB PnP Information */
+void ambapp_apb_parse(struct ambapp_find_apb_info *info, ambapp_apbdev *dev)
 {
-       return ambapp_apb_scan(vendor, driver, dev, 0, 1);
+       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;
 }
 
-int ambapp_apb_next(unsigned int vendor,
-                   unsigned int driver, ambapp_apbdev * dev, int index)
+/* Parse AHB PnP information */
+void ambapp_ahb_parse(struct ambapp_find_ahb_info *info, ambapp_ahbdev *dev)
 {
-       return ambapp_apb_scan(vendor, driver, dev, index, 1);
+       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;
+               }
+               dev->address[i] = addr;
+               dev->mask[i] = mask;
+               dev->type[i] = type;
+       }
 }
 
-int ambapp_apbs_first(unsigned int vendor,
-                     unsigned int driver, ambapp_apbdev * dev, int max_cnt)
+int ambapp_apb_find(struct ambapp_bus *abus, int vendor, int device,
+       int index, ambapp_apbdev *dev)
 {
-       return ambapp_apb_scan(vendor, driver, dev, 0, max_cnt);
-}
+       unsigned int devid = AMBA_PNP_ID(vendor, device);
+       int found;
+       struct ambapp_find_apb_info apbdev;
 
-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 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;
-       }
+       found = ambapp_find_apb(abus, devid, index, &apbdev);
+       if (found == 1)
+               ambapp_apb_parse(&apbdev, dev);
 
-       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++;
-       }
-       return cnt;
+       return found;
 }
 
-unsigned int ambapp_ahb_get_info(ahbctrl_pp_dev * ahb, int info)
+int ambapp_apb_count(struct ambapp_bus *abus, int vendor, int device)
 {
-       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;
-
+       unsigned int devid = AMBA_PNP_ID(vendor, device);
+       int found;
+       struct ambapp_find_apb_info apbdev;
+
+       found = ambapp_find_apb(abus, devid, 63, &apbdev);
+       if (found == 1)
+               return 64;
+       else
+               return 63 - apbdev.dec_index;
 }
 
-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_find(struct ambapp_bus *abus, int vendor, int device,
+       int index, ambapp_ahbdev *dev, 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++;
-       }
-       return 0;
+       found = ambapp_find_ahb(abus, devid, index, type, &ahbdev);
+       if (found == 1)
+               ambapp_ahb_parse(&ahbdev, dev);
+
+       return found;
 }
 
-/****************************** AHB MASTERS ******************************/
-int ambapp_ahbmst_count(unsigned int vendor, unsigned int driver)
+int ambapp_ahbmst_find(struct ambapp_bus *abus, int vendor, int device,
+       int index, ambapp_ahbdev *dev)
 {
-       /* 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_find(abus, vendor, device, index, dev, DEV_AHB_MST);
 }
 
-int ambapp_ahbmst_first(unsigned int vendor, unsigned int driver,
-                       ambapp_ahbdev * dev)
+int ambapp_ahbslv_find(struct ambapp_bus *abus, int vendor, int device,
+       int index, ambapp_ahbdev *dev)
 {
-       /* find first device of this */
-       return ambapp_ahb_scan(vendor, driver, dev, 0, 1, AHB_SCAN_MASTER);
+       return ambapp_ahb_find(abus, vendor, device, index, dev, DEV_AHB_SLV);
 }
 
-int ambapp_ahbmst_next(unsigned int vendor,
-                      unsigned int driver, ambapp_ahbdev * dev, int index)
+int ambapp_ahb_count(struct ambapp_bus *abus, int vendor, int device, int type)
 {
-       /* find first device of this */
-       return ambapp_ahb_scan(vendor, driver, dev, index, 1, AHB_SCAN_MASTER);
+       int found;
+       struct ambapp_find_ahb_info ahbdev;
+       unsigned int devid = AMBA_PNP_ID(vendor, device);
+
+       found = ambapp_find_ahb(abus, devid, 63, type, &ahbdev);
+       if (found == 1)
+               return 64;
+       else
+               return 63 - ahbdev.dec_index;
 }
 
-int ambapp_ahbmsts_first(unsigned int vendor,
-                        unsigned int driver, ambapp_ahbdev * dev, int max_cnt)
+int ambapp_ahbmst_count(struct ambapp_bus *abus, int vendor, int device)
 {
-       /* find first device of this */
-       return ambapp_ahb_scan(vendor, driver, dev, 0, max_cnt,
-                              AHB_SCAN_MASTER);
+       return ambapp_ahb_count(abus, vendor, device, DEV_AHB_MST);
 }
 
-/****************************** AHB SLAVES ******************************/
-int ambapp_ahbslv_count(unsigned int vendor, unsigned int driver)
+int ambapp_ahbslv_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_SLAVES,
-                              AHB_SCAN_SLAVE);
+       return ambapp_ahb_count(abus, vendor, device, DEV_AHB_SLV);
 }
 
-int ambapp_ahbslv_first(unsigned int vendor, unsigned int driver,
-                       ambapp_ahbdev * dev)
+/* 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.
+ */
+
+#ifndef CONFIG_SYS_GRLIB_SINGLE_BUS
+
+/* 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 */
+
+/* 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);
+       panic("gaisler_ahb2ahb_v2_freq: AHB2AHB ver 2 not supported\n");
+       return -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];
+
+               debug("  IOAREA: 0x%08x\n", ioarea);
+
+               /* Get parent bus */
+               parent = (ioarea & 0x7);
+               if (parent == 0) {
+                       panic("%s: parent=0 indicates no parent! Stopping.\n",
+                               __func__);
+                       return -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%p\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 {
+                       panic("%s: unsupported AMBA bridge\n", __func__);
+                       return -1;
+               }
+
+               /* Step upwards towards system top bus */
+               ahb_bus_index = parent;
+       }
+#endif
+
+       debug("ambapp_bus_freq: %dHz\n", freq);
+
+       return freq;
 }
diff --git a/arch/sparc/cpu/leon3/ambapp_low.S b/arch/sparc/cpu/leon3/ambapp_low.S
new file mode 100644 (file)
index 0000000..2863586
--- /dev/null
@@ -0,0 +1,784 @@
+/* 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, 2015
+ * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com.
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#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 the 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/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/arch/sparc/cpu/leon3/ambapp_low_c.S b/arch/sparc/cpu/leon3/ambapp_low_c.S
new file mode 100644 (file)
index 0000000..42288fa
--- /dev/null
@@ -0,0 +1,113 @@
+/* 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, 2015
+ * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com.
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+
+       .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
index 2f41d8847bdc2749901a91afe7415a7e6f0d0893..b140da31b13bfe6077464190a514eb0a3e81ecae 100644 (file)
@@ -1,8 +1,8 @@
 /* Initializes CPU and basic hardware such as memory
  * controllers, IRQ controller and system timer 0.
  *
- * (C) Copyright 2007
- * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com
+ * (C) Copyright 2007, 2015
+ * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com
  *
  * SPDX-License-Identifier:    GPL-2.0+
  */
 #include <asm/asi.h>
 #include <asm/leon.h>
 #include <ambapp.h>
+#include <grlib/irqmp.h>
+#include <grlib/gptimer.h>
+#include <debug_uart.h>
 
 #include <config.h>
 
+/* Default Plug&Play I/O area */
+#ifndef CONFIG_AMBAPP_IOAREA
+#define CONFIG_AMBAPP_IOAREA AMBA_DEFAULT_IOAREA
+#endif
+
 #define TIMER_BASE_CLK 1000000
 #define US_PER_TICK (1000000 / CONFIG_SYS_HZ)
 
@@ -22,11 +30,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;
@@ -39,64 +43,32 @@ 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 available
+ *  - memory controller has already been setup up, stack can be used
  *  - no global variables available for writing
  *  - constants available
  */
-
 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 */
+#ifdef CONFIG_DEBUG_UART
+       debug_uart_init();
+#endif
 }
 
+/* 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);
 }
 
 /*
@@ -105,95 +77,58 @@ 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) {
+               panic("%s: IRQ controller not found\n", __func__);
+               return -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("%s: gptimer not found!\n", __func__);
+               return 1;
        }
-
-       /* failed to find any memory controller */
-       return not_found_mctrl;
+       return 0;
 }
 
 /* Uses Timer 0 to get accurate
@@ -216,8 +151,8 @@ int timer_interrupt_init_cpu(void)
        gptimer->e[0].val = 0;
        gptimer->e[0].rld = (TIMER_BASE_CLK / CONFIG_SYS_HZ) - 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;
 }
index a834aa024b23b6a1df511c9ac64d5579942813ad..2312b58d29b11237f4a58e2f28a3f947e42902b2 100644 (file)
@@ -23,6 +23,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
@@ -125,9 +127,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/arch/sparc/cpu/leon3/memcfg.c b/arch/sparc/cpu/leon3/memcfg.c
new file mode 100644 (file)
index 0000000..b9eda44
--- /dev/null
@@ -0,0 +1,237 @@
+/* GRLIB Memory controller setup. The register values are used
+ * from the associated low level assembler routine implemented
+ * in memcfg_low.S.
+ *
+ * (C) Copyright 2010, 2015
+ * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com.
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#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/arch/sparc/cpu/leon3/memcfg.h b/arch/sparc/cpu/leon3/memcfg.h
new file mode 100644 (file)
index 0000000..a524896
--- /dev/null
@@ -0,0 +1,90 @@
+/* GRLIB Memory controller setup structures
+ *
+ * (C) Copyright 2010, 2015
+ * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com.
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#ifndef __MEMCFG_H__
+#define __MEMCFG_H__
+
+/*********** Low Level Memory Controller Initalization ***********/
+
+#ifndef __ASSEMBLER__
+
+struct grlib_mctrl_handler;
+
+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_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/arch/sparc/cpu/leon3/memcfg_low.S b/arch/sparc/cpu/leon3/memcfg_low.S
new file mode 100644 (file)
index 0000000..84a81a9
--- /dev/null
@@ -0,0 +1,253 @@
+/* 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, 2015
+ * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com.
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#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
index b83776bc06de69ded10557de09c6f21d2c1ae241..c391be7420cfd9558fc66fcd445462922e41b8fe 100644 (file)
 #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>
 /*
 #define PRINT_ROM_VEC
 */
 extern struct linux_romvec *kernel_arg_promvec;
-extern ambapp_dev_apbuart *leon3_apbuart;
+
+DECLARE_GLOBAL_DATA_PTR;
 
 #define PROM_PGT __attribute__ ((__section__ (".prom.pgt")))
 #define PROM_TEXT __attribute__ ((__section__ (".prom.text")))
@@ -740,14 +744,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;
 }
@@ -909,7 +913,7 @@ void leon_prom_init(struct leon_prom_info *pspi)
        pspi->avail.num_bytes = pspi->totphys.num_bytes;
 
        /* Set the pointer to the Console UART in romvec */
-       pspi->reloc_funcs.leon3_apbuart = leon3_apbuart;
+       pspi->reloc_funcs.leon3_apbuart = gd->arch.uart;
 
        {
                int j = 1;
index bca6b6548b9aa9efbbcd448bdb75c344e5dee03b..66b377302700f39a93755ecebd186ab93012cd3f 100644 (file)
@@ -1,66 +1,79 @@
 /* GRLIB APBUART Serial controller driver
  *
- * (C) Copyright 2007
- * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com.
+ * (C) Copyright 2007, 2015
+ * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com.
  *
  * SPDX-License-Identifier:    GPL-2.0+
  */
 
 #include <common.h>
-#include <asm/processor.h>
-#include <asm/leon.h>
+#include <asm/io.h>
 #include <ambapp.h>
+#include <grlib/apbuart.h>
 #include <serial.h>
-#include <linux/compiler.h>
+#include <watchdog.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
-ambapp_dev_apbuart *leon3_apbuart = NULL;
+/* Select which UART that will become u-boot console */
+#ifndef CONFIG_SYS_GRLIB_APBUART_INDEX
+#define CONFIG_SYS_GRLIB_APBUART_INDEX 0
+#endif
 
 static int leon3_serial_init(void)
 {
+       ambapp_dev_apbuart *uart;
        ambapp_apbdev apbdev;
        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) {
+               panic("%s: apbuart not found!\n", __func__);
+               return -1; /* didn't find hardware */
+       }
 
-               leon3_apbuart = (ambapp_dev_apbuart *) apbdev.address;
+       /* found apbuart, let's init .. */
+       uart = (ambapp_dev_apbuart *) apbdev.address;
 
-               /* found apbuart, let's init...
-                *
-                * Set scaler / baud rate
-                *
-                * Receiver & transmitter enable
-                */
-               leon3_apbuart->scaler = CONFIG_SYS_GRLIB_APBUART_SCALER;
+       /* Set scaler / baud rate */
+       tmp = (((CONFIG_SYS_CLK_FREQ*10) / (CONFIG_BAUDRATE*8)) - 5)/10;
+       writel(tmp, &uart->scaler);
 
-               /* Let bit 11 be unchanged (debug bit for GRMON) */
-               tmp = READ_WORD(leon3_apbuart->ctrl);
+       /* Let bit 11 be unchanged (debug bit for GRMON) */
+       tmp = readl(&uart->ctrl) & APBUART_CTRL_DBG;
+       /* Receiver & transmitter enable */
+       tmp |= APBUART_CTRL_RE | APBUART_CTRL_TE;
+       writel(tmp, &uart->ctrl);
 
-               leon3_apbuart->ctrl = ((tmp & LEON_REG_UART_CTRL_DBG) |
-                                      LEON_REG_UART_CTRL_RE |
-                                      LEON_REG_UART_CTRL_TE);
+       gd->arch.uart = uart;
+       return 0;
+}
 
-               return 0;
-       }
-       return -1;              /* didn't find hardware */
+static inline ambapp_dev_apbuart *leon3_get_uart_regs(void)
+{
+       ambapp_dev_apbuart *uart = gd->arch.uart;
+       return uart;
 }
 
 static void leon3_serial_putc_raw(const char c)
 {
-       if (!leon3_apbuart)
+       ambapp_dev_apbuart * const uart = leon3_get_uart_regs();
+
+       if (!uart)
                return;
 
        /* Wait for last character to go. */
-       while (!(READ_WORD(leon3_apbuart->status) & LEON_REG_UART_STATUS_THE)) ;
+       while (!(readl(&uart->status) & APBUART_STATUS_THE))
+               WATCHDOG_RESET();
 
        /* Send data */
-       leon3_apbuart->data = c;
+       writel(c, &uart->data);
 
 #ifdef LEON_DEBUG
        /* Wait for data to be sent */
-       while (!(READ_WORD(leon3_apbuart->status) & LEON_REG_UART_STATUS_TSE)) ;
+       while (!(readl(&uart->status) & APBUART_STATUS_TSE))
+               WATCHDOG_RESET();
 #endif
 }
 
@@ -74,36 +87,44 @@ static void leon3_serial_putc(const char c)
 
 static int leon3_serial_getc(void)
 {
-       if (!leon3_apbuart)
+       ambapp_dev_apbuart * const uart = leon3_get_uart_regs();
+
+       if (!uart)
                return 0;
 
        /* Wait for a character to arrive. */
-       while (!(READ_WORD(leon3_apbuart->status) & LEON_REG_UART_STATUS_DR)) ;
+       while (!(readl(&uart->status) & APBUART_STATUS_DR))
+               WATCHDOG_RESET();
 
-       /* read data */
-       return READ_WORD(leon3_apbuart->data);
+       /* Read character data */
+       return readl(&uart->data);
 }
 
 static int leon3_serial_tstc(void)
 {
-       if (leon3_apbuart)
-               return (READ_WORD(leon3_apbuart->status) &
-                       LEON_REG_UART_STATUS_DR);
-       return 0;
+       ambapp_dev_apbuart * const uart = leon3_get_uart_regs();
+
+       if (!uart)
+               return 0;
+
+       return readl(&uart->status) & APBUART_STATUS_DR;
 }
 
 /* set baud rate for uart */
 static void leon3_serial_setbrg(void)
 {
-       /* update baud rate settings, read it from gd->baudrate */
+       ambapp_dev_apbuart * const uart = leon3_get_uart_regs();
        unsigned int scaler;
-       if (leon3_apbuart && (gd->baudrate > 0)) {
-               scaler =
-                   (((CONFIG_SYS_CLK_FREQ * 10) / (gd->baudrate * 8)) -
-                    5) / 10;
-               leon3_apbuart->scaler = scaler;
-       }
-       return;
+
+       if (!uart)
+               return;
+
+       if (!gd->baudrate)
+               gd->baudrate = CONFIG_BAUDRATE;
+
+       scaler = (((CONFIG_SYS_CLK_FREQ*10) / (gd->baudrate*8)) - 5)/10;
+
+       writel(scaler, &uart->scaler);
 }
 
 static struct serial_device leon3_serial_drv = {
@@ -126,3 +147,26 @@ __weak struct serial_device *default_serial_console(void)
 {
        return &leon3_serial_drv;
 }
+
+#ifdef CONFIG_DEBUG_UART_APBUART
+
+#include <debug_uart.h>
+
+static inline void _debug_uart_init(void)
+{
+       ambapp_dev_apbuart *uart = (ambapp_dev_apbuart *)CONFIG_DEBUG_UART_BASE;
+       uart->scaler = (((CONFIG_DEBUG_UART_CLOCK*10) / (CONFIG_BAUDRATE*8)) - 5)/10;
+       uart->ctrl = APBUART_CTRL_RE | APBUART_CTRL_TE;
+}
+
+static inline void _debug_uart_putc(int ch)
+{
+       ambapp_dev_apbuart *uart = (ambapp_dev_apbuart *)CONFIG_DEBUG_UART_BASE;
+       while (!(readl(&uart->status) & APBUART_STATUS_THE))
+               WATCHDOG_RESET();
+       writel(ch, &uart->data);
+}
+
+DEBUG_UART_FUNCS
+
+#endif
index cf897f6877726e6f2d17ba4330b071529f72bf7c..203114970b2966615d0789c025e9d82656929a89 100644 (file)
@@ -2,9 +2,6 @@
  * Copyright (C) 2007,
  * Daniel Hellstrom, daniel@gaisler.com
  *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
  * SPDX-License-Identifier:    GPL-2.0+
  */
 
 #include <asm/stack.h>
 #include <asm/leon.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)  \
@@ -60,6 +63,27 @@ MINFRAME = (WINDOWSIZE + ARGPUSHSIZE + 4)
 #error Must define number of SPARC register windows, default is 8
 #endif
 
+/* Macros to load address into a register. Uses GOT table for PIC */
+#ifdef __PIC__
+
+#define SPARC_PIC_THUNK_CALL(reg) \
+       sethi   %pc22(_GLOBAL_OFFSET_TABLE_-4), %##reg; \
+       call    __sparc_get_pc_thunk.reg; \
+        add    %##reg, %pc10(_GLOBAL_OFFSET_TABLE_+4), %##reg;
+
+#define SPARC_LOAD_ADDRESS(sym, got, reg) \
+       sethi   %gdop_hix22(sym), %##reg; \
+       xor     %##reg, %gdop_lox10(sym), %##reg; \
+       ld      [%##got + %##reg], %##reg, %gdop(sym);
+
+#else
+
+#define SPARC_PIC_THUNK_CALL(reg)
+#define SPARC_LOAD_ADDRESS(sym, got, tmp) \
+       set     sym, %##reg;
+
+#endif
+
 #define STACK_ALIGN    8
 #define SA(X)  (((X)+(STACK_ALIGN-1)) & ~(STACK_ALIGN-1))
 
@@ -190,6 +214,7 @@ version_string:
        .ascii U_BOOT_VERSION_STRING, "\0"
 
        .section        ".text"
+       .extern _nomem_amba_init, _nomem_memory_ctrl_init
        .align 4
 
 _hardreset:
@@ -232,7 +257,7 @@ clear_window:
        bge     clear_window
        save
 
-wininit:
+wiminit:
        set     WIM_INIT, %g3
        mov     %g3, %wim
 
@@ -241,9 +266,41 @@ stackp:
        andn    %fp, 0x0f, %fp
        sub     %fp, 64, %sp
 
+/* Obtain the address of _GLOBAL_OFFSET_TABLE_ */
+       SPARC_PIC_THUNK_CALL(l7)
+
+/* 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:
+       SPARC_LOAD_ADDRESS(grlib_mctrl_handlers, l7, o0)
+
+       call    _nomem_memory_ctrl_init
+        nop
+
+/* 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
+        nop
 
 /* un relocated start address of monitor */
 #define TEXT_START _text
@@ -252,8 +309,8 @@ cpu_init_unreloc:
 #define DATA_END __init_end
 
 reloc:
-       set     TEXT_START,%g2
-       set     DATA_END,%g3
+       SPARC_LOAD_ADDRESS(TEXT_START, l7, g2)
+       SPARC_LOAD_ADDRESS(DATA_END, l7, g3)
        set     CONFIG_SYS_RELOC_MONITOR_BASE,%g4
 reloc_loop:
        ldd     [%g2],%l0
@@ -263,7 +320,7 @@ reloc_loop:
        inc     16,%g2
        subcc   %g3,%g2,%g0
        bne     reloc_loop
-       inc     16,%g4
+        inc    16,%g4
 
        clr     %l0
        clr     %l1
@@ -280,8 +337,8 @@ reloc_loop:
 
 clr_bss:
 /* clear bss area (the relocated) */
-       set     __bss_start,%g2
-       set     __bss_end,%g3
+       SPARC_LOAD_ADDRESS(__bss_start, l7, g2)
+       SPARC_LOAD_ADDRESS(__bss_end, l7, g3)
        sub     %g3,%g2,%g3
        add     %g3,%g4,%g3
        clr     %g1     /* std %g0 uses g0 and g1 */
@@ -292,19 +349,19 @@ clr_bss_16:
        inc     16,%g4
        cmp     %g3,%g4
        bne     clr_bss_16
-       nop
+        nop
 
 /* add offsets to GOT table */
 fixup_got:
-       set     __got_start,%g4
-       set     __got_end,%g3
+       SPARC_LOAD_ADDRESS(__got_start, l7, g4)
+       SPARC_LOAD_ADDRESS(__got_end, l7, g3)
 /*
  * new got offset = (old GOT-PTR (read with ld) -
  *   CONFIG_SYS_RELOC_MONITOR_BASE(from define) ) +
  *   Destination Address (from define)
  */
        set     CONFIG_SYS_RELOC_MONITOR_BASE,%g2
-       set     TEXT_START, %g1
+       SPARC_LOAD_ADDRESS(TEXT_START, l7, g1)
        add     %g4,%g2,%g4
        sub     %g4,%g1,%g4
        add     %g3,%g2,%g3
@@ -319,11 +376,11 @@ got_loop:
        inc     4,%g4
        cmp     %g3,%g4
        bne     got_loop
-       nop
+        nop
 
 prom_relocate:
-       set     __prom_start, %g2
-       set     __prom_end, %g3
+       SPARC_LOAD_ADDRESS(__prom_start, l7, g2)
+       SPARC_LOAD_ADDRESS(__prom_end, l7, g3)
        set     CONFIG_SYS_PROM_OFFSET, %g4
 
 prom_relocate_loop:
@@ -334,7 +391,7 @@ prom_relocate_loop:
        inc     16,%g2
        subcc   %g3,%g2,%g0
        bne     prom_relocate_loop
-       inc     16,%g4
+        inc    16,%g4
 
 /* Trap table has been moved, lets tell CPU about
  * the new trap table address
@@ -361,19 +418,20 @@ snoop_detect:
        nop
 /* Call relocated init functions */
 jump:
-       set     cpu_init_f2,%o1
+       SPARC_LOAD_ADDRESS(cpu_init_f2, l7, o1)
        set     CONFIG_SYS_RELOC_MONITOR_BASE,%o2
        add     %o1,%o2,%o1
        sub     %o1,%g1,%o1
        call    %o1
-       clr     %o0
+        clr    %o0
 
-       set     board_init_f,%o1
+       SPARC_LOAD_ADDRESS(board_init_f, l7, o1)
        set     CONFIG_SYS_RELOC_MONITOR_BASE,%o2
+       SPARC_LOAD_ADDRESS(TEXT_START, l7, g1)
        add     %o1,%o2,%o1
        sub     %o1,%g1,%o1
        call    %o1
-       clr     %o0
+        clr    %o0
 
 dead:  ta 0                            ! if call returns...
        nop
index ca7d6e86f0b81b458269dbe946899b9eb2d5f20f..1be84c646b8f164574cf28d005ddf9e7e5beda71 100644 (file)
@@ -690,11 +690,11 @@ void handle_usb_interrupt(void)
  */
 int usb_lowlevel_init(int index, enum usb_init_type init, void **controller)
 {
-       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;
        }
index 667e7d6d3b1e9e442d710a507b62adb798dce75f..0680a56758dcbcbd63e3f737d0c7ca2eff0286c1 100644 (file)
@@ -15,6 +15,7 @@
 
 /* Architecture-specific global data */
 struct arch_global_data {
+       void *uart;
 };
 
 #include <asm-generic/global_data.h>
index f7b89c890fc14640c8403d9d26d515112bb7a8ce..a317d132be28e9df7cdf39208940516f38096d07 100644 (file)
@@ -1,7 +1,7 @@
 /* SPARC I/O definitions
  *
- * (C) Copyright 2007
- * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com.
+ * (C) Copyright 2007, 2015
+ * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com.
  *
  * SPDX-License-Identifier:    GPL-2.0+
  */
 /* Nothing to sync, total store ordering (TSO)... */
 #define sync()
 
+/*
+ * Generic virtual read/write.
+ */
+
+#ifndef CONFIG_SYS_HAS_NO_CACHE
+
 /* Forces a cache miss on read/load.
  * On some architectures we need to bypass the cache when reading
  * I/O registers so that we are not reading the same status word
  * over and over again resulting in a hang (until an IRQ if lucky)
- *
  */
-#ifndef CONFIG_SYS_HAS_NO_CACHE
-#define READ_BYTE(var)  SPARC_NOCACHE_READ_BYTE((unsigned int)(var))
-#define READ_HWORD(var) SPARC_NOCACHE_READ_HWORD((unsigned int)(var))
-#define READ_WORD(var)  SPARC_NOCACHE_READ((unsigned int)(var))
-#define READ_DWORD(var) SPARC_NOCACHE_READ_DWORD((unsigned int)(var))
+
+#define __arch_getb(a)         SPARC_NOCACHE_READ_BYTE((unsigned int)(a))
+#define __arch_getw(a)         SPARC_NOCACHE_READ_HWORD((unsigned int)(a))
+#define __arch_getl(a)         SPARC_NOCACHE_READ((unsigned int)(a))
+#define __arch_getq(a)         SPARC_NOCACHE_READ_DWORD((unsigned int)(a))
+
 #else
-#define READ_BYTE(var)  (var)
-#define READ_HWORD(var) (var)
-#define READ_WORD(var)  (var)
-#define READ_DWORD(var) (var)
-#endif
 
-/*
- * Generic virtual read/write.
- */
-#define __arch_getb(a)                 (READ_BYTE(a))
-#define __arch_getw(a)                 (READ_HWORD(a))
-#define __arch_getl(a)                 (READ_WORD(a))
-#define __arch_getq(a)                 (READ_DWORD(a))
+#define __arch_getb(a)         (*(volatile unsigned char *)(a))
+#define __arch_getw(a)         (*(volatile unsigned short *)(a))
+#define __arch_getl(a)         (*(volatile unsigned int *)(a))
+#define __arch_getq(a)         (*(volatile unsigned long long *)(a))
+
+#endif /* CONFIG_SYS_HAS_NO_CACHE */
 
-#define __arch_putb(v,a)               (*(volatile unsigned char *)(a) = (v))
-#define __arch_putw(v,a)               (*(volatile unsigned short *)(a) = (v))
-#define __arch_putl(v,a)               (*(volatile unsigned int *)(a) = (v))
+#define __arch_putb(v, a)      (*(volatile unsigned char *)(a) = (v))
+#define __arch_putw(v, a)      (*(volatile unsigned short *)(a) = (v))
+#define __arch_putl(v, a)      (*(volatile unsigned int *)(a) = (v))
+#define __arch_putq(v, a)      (*(volatile unsigned long long *)(a) = (v))
 
-#define __raw_writeb(v,a)              __arch_putb(v,a)
-#define __raw_writew(v,a)              __arch_putw(v,a)
-#define __raw_writel(v,a)              __arch_putl(v,a)
+#define __raw_writeb(v, a)             __arch_putb(v, a)
+#define __raw_writew(v, a)             __arch_putw(v, a)
+#define __raw_writel(v, a)             __arch_putl(v, a)
+#define __raw_writeq(v, a)             __arch_putq(v, a)
 
 #define __raw_readb(a)                 __arch_getb(a)
 #define __raw_readw(a)                 __arch_getw(a)
 #define __raw_readl(a)                 __arch_getl(a)
 #define __raw_readq(a)                 __arch_getq(a)
 
+#define writeb                         __raw_writeb
+#define writew                         __raw_writew
+#define writel                         __raw_writel
+#define writeq                         __raw_writeq
+
+#define readb                          __raw_readb
+#define readw                          __raw_readw
+#define readl                          __raw_readl
+#define readq                          __raw_readq
+
 /*
  * Given a physical address and a length, return a virtual address
  * that can be used to access the memory range with the caching
index 65e4561e7d5c817415b2f51f1bf7765d1fe5c509..4f68fbda6993240e85457801e190ceb9cc711ff3 100644 (file)
        ld      [reg + FW_FSR], %fsr;
 
 #endif
-
-#ifndef __SPARC_WINMACRO_H__
-#define __SPARC_WINMACRO_H__
-
-#include <asm/asmmacro.h>
-#include <asm/stack.h>
-
-/* Store the register window onto the 8-byte aligned area starting
- * at %reg.  It might be %sp, it might not, we don't care.
- */
-#define RW_STORE(reg) \
-       std     %l0, [%reg + RW_L0]; \
-       std     %l2, [%reg + RW_L2]; \
-       std     %l4, [%reg + RW_L4]; \
-       std     %l6, [%reg + RW_L6]; \
-       std     %i0, [%reg + RW_I0]; \
-       std     %i2, [%reg + RW_I2]; \
-       std     %i4, [%reg + RW_I4]; \
-       std     %i6, [%reg + RW_I6];
-
-/* Load a register window from the area beginning at %reg. */
-#define RW_LOAD(reg) \
-       ldd     [%reg + RW_L0], %l0; \
-       ldd     [%reg + RW_L2], %l2; \
-       ldd     [%reg + RW_L4], %l4; \
-       ldd     [%reg + RW_L6], %l6; \
-       ldd     [%reg + RW_I0], %i0; \
-       ldd     [%reg + RW_I2], %i2; \
-       ldd     [%reg + RW_I4], %i4; \
-       ldd     [%reg + RW_I6], %i6;
-
-/* Loading and storing struct pt_reg trap frames. */
-#define PT_LOAD_INS(base_reg) \
-       ldd     [%base_reg + SF_REGS_SZ + PT_I0], %i0; \
-       ldd     [%base_reg + SF_REGS_SZ + PT_I2], %i2; \
-       ldd     [%base_reg + SF_REGS_SZ + PT_I4], %i4; \
-       ldd     [%base_reg + SF_REGS_SZ + PT_I6], %i6;
-
-#define PT_LOAD_GLOBALS(base_reg) \
-       ld      [%base_reg + SF_REGS_SZ + PT_G1], %g1; \
-       ldd     [%base_reg + SF_REGS_SZ + PT_G2], %g2; \
-       ldd     [%base_reg + SF_REGS_SZ + PT_G4], %g4; \
-       ldd     [%base_reg + SF_REGS_SZ + PT_G6], %g6;
-
-#define PT_LOAD_YREG(base_reg, scratch) \
-       ld      [%base_reg + SF_REGS_SZ + PT_Y], %scratch; \
-       wr      %scratch, 0x0, %y;
-
-#define PT_LOAD_PRIV(base_reg, pt_psr, pt_pc, pt_npc) \
-       ld      [%base_reg + SF_REGS_SZ + PT_PSR], %pt_psr; \
-       ld      [%base_reg + SF_REGS_SZ + PT_PC], %pt_pc; \
-       ld      [%base_reg + SF_REGS_SZ + PT_NPC], %pt_npc;
-
-#define PT_LOAD_ALL(base_reg, pt_psr, pt_pc, pt_npc, scratch) \
-       PT_LOAD_YREG(base_reg, scratch) \
-       PT_LOAD_INS(base_reg) \
-       PT_LOAD_GLOBALS(base_reg) \
-       PT_LOAD_PRIV(base_reg, pt_psr, pt_pc, pt_npc)
-
-#define PT_STORE_INS(base_reg) \
-       std     %i0, [%base_reg + SF_REGS_SZ + PT_I0]; \
-       std     %i2, [%base_reg + SF_REGS_SZ + PT_I2]; \
-       std     %i4, [%base_reg + SF_REGS_SZ + PT_I4]; \
-       std     %i6, [%base_reg + SF_REGS_SZ + PT_I6];
-
-#define PT_STORE_GLOBALS(base_reg) \
-       st      %g1, [%base_reg + SF_REGS_SZ + PT_G1]; \
-       std     %g2, [%base_reg + SF_REGS_SZ + PT_G2]; \
-       std     %g4, [%base_reg + SF_REGS_SZ + PT_G4]; \
-       std     %g6, [%base_reg + SF_REGS_SZ + PT_G6];
-
-#define PT_STORE_YREG(base_reg, scratch) \
-       rd      %y, %scratch; \
-       st      %scratch, [%base_reg + SF_REGS_SZ + PT_Y];
-
-#define PT_STORE_PRIV(base_reg, pt_psr, pt_pc, pt_npc) \
-       st      %pt_psr, [%base_reg + SF_REGS_SZ + PT_PSR]; \
-       st      %pt_pc,  [%base_reg + SF_REGS_SZ + PT_PC]; \
-       st      %pt_npc, [%base_reg + SF_REGS_SZ + PT_NPC];
-
-#define PT_STORE_ALL(base_reg, reg_psr, reg_pc, reg_npc, g_scratch) \
-       PT_STORE_PRIV(base_reg, reg_psr, reg_pc, reg_npc) \
-       PT_STORE_GLOBALS(base_reg) \
-       PT_STORE_YREG(base_reg, g_scratch) \
-       PT_STORE_INS(base_reg)
-
-/* Store the fpu register window*/
-#define FW_STORE(reg) \
-       std     %f0, [reg + FW_F0]; \
-       std     %f2, [reg + FW_F2]; \
-       std     %f4, [reg + FW_F4]; \
-       std     %f6, [reg + FW_F6]; \
-       std     %f8, [reg + FW_F8]; \
-       std     %f10, [reg + FW_F10]; \
-       std     %f12, [reg + FW_F12]; \
-       std     %f14, [reg + FW_F14]; \
-       std     %f16, [reg + FW_F16]; \
-       std     %f18, [reg + FW_F18]; \
-       std     %f20, [reg + FW_F20]; \
-       std     %f22, [reg + FW_F22]; \
-       std     %f24, [reg + FW_F24]; \
-       std     %f26, [reg + FW_F26]; \
-       std     %f28, [reg + FW_F28]; \
-       std     %f30, [reg + FW_F30]; \
-       st      %fsr, [reg + FW_FSR];
-
-/* Load a fpu register window from the area beginning at reg. */
-#define FW_LOAD(reg) \
-       ldd     [reg + FW_F0], %f0; \
-       ldd     [reg + FW_F2], %f2; \
-       ldd     [reg + FW_F4], %f4; \
-       ldd     [reg + FW_F6], %f6; \
-       ldd     [reg + FW_F8], %f8; \
-       ldd     [reg + FW_F10], %f10; \
-       ldd     [reg + FW_F12], %f12; \
-       ldd     [reg + FW_F14], %f14; \
-       ldd     [reg + FW_F16], %f16; \
-       ldd     [reg + FW_F18], %f18; \
-       ldd     [reg + FW_F20], %f20; \
-       ldd     [reg + FW_F22], %f22; \
-       ldd     [reg + FW_F24], %f24; \
-       ldd     [reg + FW_F26], %f26; \
-       ldd     [reg + FW_F28], %f28; \
-       ldd     [reg + FW_F30], %f30; \
-       ld      [reg + FW_FSR], %fsr;
-
-#endif
index 0388a6c34d452de8549835be0e8ecc3a9ec0ba80..440cb372a13e159da8033df10bca9cf9e7bb47bc 100644 (file)
@@ -455,6 +455,20 @@ endmenu
 
 menu "Misc commands"
 
+config CMD_AMBAPP
+       bool "ambapp"
+       depends on LEON3
+       default y
+       help
+         Lists AMBA Plug-n-Play information.
+
+config SYS_AMBAPP_PRINT_ON_STARTUP
+       bool "Show AMBA PnP info on startup"
+       depends on CMD_AMBAPP
+       default n
+       help
+         Show AMBA Plug-n-Play information on startup.
+
 config CMD_TIME
        bool "time"
        help
index 2270e2ed0f27f578d26feffa79b38b44d1717362..c6aa7e5224ab77b8b1cbf7fc2c51d1d9df09fc2b 100644 (file)
@@ -46,6 +46,9 @@
 #include <stdio_dev.h>
 #include <trace.h>
 #include <watchdog.h>
+#ifdef CONFIG_CMD_AMBAPP
+#include <ambapp.h>
+#endif
 #ifdef CONFIG_ADDR_MAP
 #include <asm/mmu.h>
 #endif
@@ -559,6 +562,18 @@ static int initr_status_led(void)
 }
 #endif
 
+#if defined(CONFIG_CMD_AMBAPP) && defined(CONFIG_SYS_AMBAPP_PRINT_ON_STARTUP)
+extern int do_ambapp_print(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
+
+static int initr_ambapp_print(void)
+{
+       puts("AMBA:\n");
+       do_ambapp_print(NULL, 0, 0, NULL);
+
+       return 0;
+}
+#endif
+
 #if defined(CONFIG_CMD_SCSI)
 static int initr_scsi(void)
 {
@@ -850,6 +865,12 @@ init_fnc_t init_sequence_r[] = {
 #ifdef CONFIG_BOARD_LATE_INIT
        board_late_init,
 #endif
+#if defined(CONFIG_CMD_AMBAPP)
+       ambapp_init_reloc,
+#if defined(CONFIG_SYS_AMBAPP_PRINT_ON_STARTUP)
+       initr_ambapp_print,
+#endif
+#endif
 #ifdef CONFIG_CMD_SCSI
        INIT_FUNC_WATCHDOG_RESET
        initr_scsi,
index 2a1995a76135d2cef65e41162acb8c5b49b7b094..4b6d1741e9bf41182461e1f4ad78e43ef9ab01be 100644 (file)
 
 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_L4STAT, "L4STAT", "Leon4 Statistics Module"},
+       {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", "64-bit PC133 SDRAM Controller"},
+       {GAISLER_GR1553B, "GR1553B", "MIL-STD-1553B Interface"},
+       {GAISLER_1553TST, "1553TST", "MIL-STD-1553B Test Device"},
+       {GAISLER_GRIOMMU, "GRIOMMU", "I/O Memory Management Unit"},
+       {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_MEMSCRUB, "MEMSCRUB", "AHB Memory Scrubber"},
+       {GAISLER_FTSDCTRL64, "FTSDCTRL64", "64-bit FT SDRAM Controller"},
+       {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_AESDMA, "AESDMA", "AES 256 DMA"},
+       {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", "General Purpose Register"},
+       {GAISLER_GRTMPAHB, "GRTMPAHB", "CCSDS Telemetry VC AHB Input"},
+       {GAISLER_SPWCUC, "SPWCUC", "CCSDS CUC / SpaceWire I/F"},
+       {GAISLER_SPW2_DMA, "SPW2_DMA", "GRSPW Router DMA interface"},
+       {GAISLER_SPWROUTER, "SPWROUTER", "GRSPW Router"},
+       {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;
 
+/** Vendor CONTRIB devices */
+static ambapp_device_name CONTRIB_devices[] = {
+       {CONTRIB_CORE1, "CORE1", "Contributed core 1"},
+       {CONTRIB_CORE2, "CORE2", "Contributed core 2"},
+       {0, NULL, NULL}
+};
+
+
+/** 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 S3 devices */
+static ambapp_device_name S3_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, "VENDOR_GAISLER", gaisler_devices},
-       {VENDOR_ESA, "VENDOR_ESA", esa_devices},
-       {VENDOR_OPENCORES, "VENDOR_OPENCORES", opencores_devices},
-       {0, NULL, 0}
+       {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_S3, "S3", "S3 Group", S3_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 char *ambapp_get_devname(ambapp_device_name * devs, int id)
+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;
@@ -109,10 +392,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++;
        }
@@ -134,101 +438,106 @@ 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);
+       unsigned int freq;
 
-       mask = amba_membar_mask(apb->bar) << 8;
-       mask = ((~mask) & 0x000fffff) + 1;
-
-       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"
+       /* Get Frequency of Core */
+       freq = ambapp_bus_freq(&ambapp_plb, dev->ahb_bus_index);
+
+       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;
+       char *dev_str, *ven_str, *type_str;
+       int i;
+       unsigned int freq;
 
-       vendor = amba_vendor(ahb->conf);
-       deviceid = amba_device(ahb->conf);
-       irq = amba_irq(ahb->conf);
-       ver = amba_ver(ahb->conf);
-
-       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);
+
+       printf("0x%02x:0x%02x:0x%02x: %s  %s  (%dkHz)\n",
+              index, dev->vendor, dev->device, ven_str, dev_str, freq / 1000);
 
-       for (j = 0; j < 4; j++) {
-               addr = amba_membar_start(ahb->bars[j]);
-               if (amba_membar_type(ahb->bars[j]) == 0)
+       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 * const 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;
 }
@@ -240,16 +549,18 @@ int ambapp_init_reloc(void)
 
        while (vend->vendor_id && vend->name) {
                vend->name = (char *)((unsigned int)vend->name + gd->reloc_off);
-               vend->devices =
-                   (ambapp_device_name *) ((unsigned int)vend->devices +
-                                           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);
                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++;
                }
        }
index f0fa23f810646a0eba94fc0d520161f504b7fea5..d2f709f834efffd6f88f64e17b8d63f0ca337853 100644 (file)
@@ -11,4 +11,10 @@ CONFIG_SYS_TEXT_BASE=0x00000000
 # CONFIG_CMD_MEMORY is not set
 # CONFIG_CMD_FLASH is not set
 # CONFIG_CMD_SETEXPR is not set
+# CONFIG_CMD_NET is not set
 # CONFIG_CMD_NFS is not set
+CONFIG_SYS_AMBAPP_PRINT_ON_STARTUP=y
+CONFIG_DEBUG_UART=y
+CONFIG_DEBUG_UART_APBUART=y
+CONFIG_DEBUG_UART_BASE=0x80000100
+CONFIG_DEBUG_UART_CLOCK=40000000
index 6fe78a1d084b391784acf48986d44fc483894b45..1b26e232d2f22b197b5195d588aafc1e4a0cc292 100644 (file)
@@ -106,7 +106,7 @@ alias ppc4xx         uboot, stroese
 alias sandbox        sjg
 alias sb             sandbox
 
-alias sparc          uboot, Daniel Hellstrom <daniel@gaisler.com>
+alias sparc          uboot, Francois Retief <fgretief@spaceteq.co.za>
 
 alias superh         uboot, iwamatsu
 alias sh             superh
index 9bc8a8d1aa1543a74923f90f605684e6281cc18a..0624eb8cac33a5c2348fa4a55aff346090f2d568 100644 (file)
@@ -20,7 +20,7 @@
 #include <ambapp.h>
 #include <asm/leon.h>
 
-#include "greth.h"
+#include <grlib/greth.h>
 
 /* Default to 3s timeout on autonegotiation */
 #ifndef GRETH_PHY_TIMEOUT_MS
 #define GRETH_PHY_ADR_DEFAULT 0
 #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 */
@@ -593,8 +600,12 @@ int greth_initialize(bd_t * bis)
 
        debug("Scanning for GRETH\n");
 
-       /* 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 */
        }
 
index d462244a04555de761b122a4f59c0a2a2e1021e3..eba96f4a80d328b05cd2b6332b4550b176ca3061 100644 (file)
@@ -98,6 +98,14 @@ config DEBUG_UART_ZYNQ
          will need to provide parameters to make this work. The driver will
          be available until the real driver-model serial is running.
 
+config DEBUG_UART_APBUART
+       depends on LEON3
+       bool "Gaisler APBUART"
+       help
+         Select this to enable a debug UART using the serial_leon3 driver. You
+         will need to provide parameters to make this work. The driver will
+         be available until the real driver model serial is running.
+
 endchoice
 
 config DEBUG_UART_BASE
index 405637d8cd6db809dc6f6b44fbebda8540b8bf65..d79fcedb4139a059fb650dcb626270be8c27ebf3 100644 (file)
@@ -3,8 +3,8 @@
  * the APB bus, also freely available in GRLIB at
  * www.gaisler.com.
  *
- * (C) Copyright 2007
- * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com.
+ * (C) Copyright 2009, 2015
+ * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com.
  *
  * SPDX-License-Identifier:    GPL-2.0+
  */
 #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)) )
-
-#define amba_irq(conf) ((conf) & 0xf)
-
-#define amba_ver(conf) (((conf)>>5) & 0x1f)
-
-#define amba_membar_type(mbar) ((mbar) & 0xf)
-
-#define amba_membar_mask(mbar) (((mbar)>>4) & 0xfff)
-
-#define AMBA_TYPE_APBIO 0x1
-#define AMBA_TYPE_MEM   0x2
-#define AMBA_TYPE_AHBIO 0x3
-
-#define AMBA_TYPE_AHBIO_ADDR(addr) (LEON3_IO_AREA | ((addr) >> 12))
+#include <ambapp_ids.h>
 
 #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 */
+};
 
-#ifdef CONFIG_CMD_AMBAPP
-
-/* AMBA Plug&Play relocation & initialization */
-int ambapp_init_reloc(void);
-
-/* AMBA Plug&Play Name of Vendors and devices */
-
-/* Return name of device */
-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
- */
-
-/* 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)
+/* AMBA Plug&Play AHB Masters & Slaves information locations
+ * Max devices is 64 supported by HW, however often only 16
+ * are used.
  */
-
-typedef struct {
+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;
 
+/* 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;
 
-/* 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;
+/* Scan AMBA Bus for AHB Bridges */
+extern void ambapp_bus_init(
+       unsigned int ioarea,
+       unsigned int freq,
+       struct ambapp_bus *abus);
 
-/* AMBA Plug&Play AHB information layout */
-typedef struct {
-       unsigned int conf;
-       unsigned int bar;
-} apbctrl_pp_dev;
-
-/* All functions return the number of found devices
- * 0 = no devices found
+/* 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);
 
-/****************************** 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);
-
-int ambapp_ahbmst_next(unsigned int vendor,
-                      unsigned int driver, ambapp_ahbdev * dev, int index);
+/* 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);
 
-int ambapp_ahbmsts_first(unsigned int vendor,
-                        unsigned int driver, ambapp_ahbdev * dev, int max_cnt);
+/* 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);
 
-/****************************** AHB SLAVES ******************************/
-int ambapp_ahbslv_count(unsigned int vendor, unsigned int driver);
+#ifdef CONFIG_CMD_AMBAPP
 
-int ambapp_ahbslv_first(unsigned int vendor,
-                       unsigned int driver, ambapp_ahbdev * dev);
+/* AMBA Plug&Play relocation & initialization */
+int ambapp_init_reloc(void);
 
-int ambapp_ahbslv_next(unsigned int vendor,
-                      unsigned int driver, ambapp_ahbdev * dev, int index);
+/* AMBA Plug&Play Name of Vendors and devices */
 
-int ambapp_ahbslvs_first(unsigned int vendor,
-                        unsigned int driver, ambapp_ahbdev * dev, int max_cnt);
+/* Return name of device */
+char *ambapp_device_id2str(int vendor, int id);
 
-/*************************** 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);
+/* Return name of vendor */
+char *ambapp_vendor_id2str(int vendor);
 
-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);
+/* Return description of a device */
+char *ambapp_device_id2desc(int vendor, int id);
 
-unsigned int ambapp_ahb_get_info(ahbctrl_pp_dev * ahb, int info);
+#endif
 
-/*************************** AMBA Plug&Play device register MAPS *****************/
+#endif /* defined(__ASSEMBLER__) */
 
-/*
- *  The following defines the bits in the LEON UART Status Registers.
- */
+#define AMBA_DEFAULT_IOAREA 0xfff00000
+#define AMBA_CONF_AREA 0xff000
+#define AMBA_AHB_SLAVE_CONF_AREA 0x800
 
-#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 DEV_NONE       0
+#define DEV_AHB_MST    1
+#define DEV_AHB_SLV    2
+#define DEV_APB_SLV    3
 
-#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 */
+#define AMBA_TYPE_APBIO 0x1
+#define AMBA_TYPE_MEM 0x2
+#define AMBA_TYPE_AHBIO 0x3
 
-/*
- *  The following defines the bits in the LEON PS/2 Ctrl Registers.
+/* 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.
  */
 
-#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 */
-
-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;
+#define amba_vendor(x) (((x) >> 24) & 0xff)
 
-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 */
+#define amba_device(x) (((x) >> 12) & 0xfff)
 
-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;
+#define amba_irq(conf) ((conf) & 0x1f)
 
-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;
+#define amba_ver(conf) (((conf)>>5) & 0x1f)
 
-typedef struct {
-       volatile unsigned int data;
-       volatile unsigned int status;
-       volatile unsigned int ctrl;
-} ambapp_dev_apbps2;
+#define amba_iobar_start(base, iobar) \
+       ((base) | ((((iobar) & 0xfff00000)>>12) & (((iobar) & 0xfff0)<<4)))
 
-typedef struct {
-       unsigned int mcfg1, mcfg2, mcfg3;
-} ambapp_dev_mctrl;
+#define amba_membar_start(mbar) \
+       (((mbar) & 0xfff00000) & (((mbar) & 0xfff0) << 16))
 
-typedef struct {
-       unsigned int sdcfg;
-} ambapp_dev_sdctrl;
+#define amba_membar_type(mbar) ((mbar) & 0xf)
 
-typedef struct {
-       unsigned int cfg1;
-       unsigned int cfg2;
-       unsigned int cfg3;
-} ambapp_dev_ddr2spa;
+#define amba_membar_mask(mbar) (((mbar) >> 4) & 0xfff)
 
-typedef struct {
-       unsigned int ctrl;
-       unsigned int cfg;
-} ambapp_dev_ddrspa;
+#define amba_ahbio_adr(addr, base_ioarea) \
+       ((unsigned int)(base_ioarea) | ((addr) >> 12))
 
-#endif
+#define amba_apb_mask(iobar) ((~(amba_membar_mask(iobar)<<8) & 0x000fffff) + 1)
 
 #endif
diff --git a/include/ambapp_ids.h b/include/ambapp_ids.h
new file mode 100644 (file)
index 0000000..1eae34e
--- /dev/null
@@ -0,0 +1,250 @@
+/* AMBA Plug & Play Bus Vendor and Device IDs.
+ *
+ * (C) Copyright 2010, 2015
+ * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com.
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+
+#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_S3            0x31
+#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_L4STAT       0x047
+#define GAISLER_LEON4        0x048
+#define GAISLER_LEON4DSU     0x049
+#define GAISLER_PWM          0x04a
+#define GAISLER_L2CACHE      0x04b
+#define GAISLER_SDCTRL64     0x04c
+#define GAISLER_GR1553B      0x04d
+#define GAISLER_1553TST      0x04e
+#define GAISLER_GRIOMMU      0x04f
+#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_MEMSCRUB     0x057
+#define GAISLER_FTSDCTRL64   0x058
+#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_AESDMA       0x07b
+#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
+#define GAISLER_SPWCUC       0x089
+#define GAISLER_SPW2_DMA     0x08a
+#define GAISLER_SPWROUTER    0x08b
+
+/* 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
index 8832552f318e8a8ccb3116b62dd9a358c62c3b3a..424721b7e746f3be981e998e2e9073f3774ad38b 100644 (file)
@@ -13,7 +13,6 @@
  * Alphabetical list of all possible commands.
  */
 
-#define CONFIG_CMD_AMBAPP      /* AMBA Plug & Play Bus print utility */
 #define CONFIG_CMD_ASKENV      /* ask for env variable         */
 #define CONFIG_CMD_BEDBUG      /* Include BedBug Debugger      */
 #define CONFIG_CMD_BMP         /* BMP support                  */
index 782746e4e02aa873d4afde46d91776591326545a..5bbf1aaae80903d2b921b9f8b66877934e801072 100644 (file)
@@ -60,7 +60,6 @@
  * Supported commands
  */
 #define CONFIG_CMD_REGINFO
-#define CONFIG_CMD_AMBAPP
 #define CONFIG_CMD_PING
 #define CONFIG_CMD_DIAG
 #define CONFIG_CMD_IRQ
 
 /***** Gaisler GRLIB IP-Cores Config ********/
 
-/* 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
-
-/* Calculate scaler register value from default baudrate */
-#define CONFIG_SYS_GRLIB_APBUART_SCALER \
- ((((CONFIG_SYS_CLK_FREQ*10)/(CONFIG_BAUDRATE*8))-5)/10)
+#undef CONFIG_SYS_GRLIB_GAISLER_DDR2SPA1
 
 /* Identification string */
 #define CONFIG_IDENT_STRING "GAISLER LEON3 GR-CPCI-AX2000"
index 5c466f29293f238af790ef61262d13adaff306e8..b55ca77a87a510b8a7c60639d6bc355131b63ab1 100644 (file)
@@ -54,7 +54,6 @@
  * Supported commands
  */
 #define CONFIG_CMD_REGINFO
-#define CONFIG_CMD_AMBAPP
 #define CONFIG_CMD_PING
 #define CONFIG_CMD_DIAG
 #define CONFIG_CMD_IRQ
 
 /***** Gaisler GRLIB IP-Cores Config ********/
 
-/* 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
-
-/* Calculate scaler register value from default baudrate */
-#define CONFIG_SYS_GRLIB_APBUART_SCALER \
- ((((CONFIG_SYS_CLK_FREQ*10)/(CONFIG_BAUDRATE*8))-5)/10)
+#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
 
 /* Identification string */
 #define CONFIG_IDENT_STRING "GAISLER LEON3 EP2S60"
index e01578cbb2bce5aa9cab8678ff94309df1fe0938..d086b694c208b1f89bd2f2b49ffe89792ba29a0a 100644 (file)
@@ -41,7 +41,6 @@
  * Supported commands
  */
 #define CONFIG_CMD_REGINFO
-#define CONFIG_CMD_AMBAPP
 #define CONFIG_CMD_PING
 #define CONFIG_CMD_DIAG
 #define CONFIG_CMD_IRQ
 
 /***** Gaisler GRLIB IP-Cores Config ********/
 
-/* 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
-
-/* Calculate scaler register value from default baudrate */
-#define CONFIG_SYS_GRLIB_APBUART_SCALER \
- ((((CONFIG_SYS_CLK_FREQ*10)/(CONFIG_BAUDRATE*8))-5)/10)
+#undef CONFIG_SYS_GRLIB_GAISLER_DDR2SPA1
 
 /* Identification string */
 #define CONFIG_IDENT_STRING "GAISLER LEON3 GR-XC3S-1500"
index f54919eaae6f77d525fbab52bdfcbad46649c647..e1f7dc3bf6dc0d7aa2912c37440c79be948672e5 100644 (file)
  *
  * Select between TSIM or GRSIM by setting CONFIG_GRSIM or CONFIG_TSIM to 1.
  *
- * TSIM command
- *  tsim-leon3 -sdram 0 -ram 32000 -rom 8192 -mmu
+ * TSIM command:
+ * $ tsim-leon3 -sdram 32768 -ram 4096 -rom 2048 -mmu -cas
  *
+ * In the evaluation version of TSIM, the -sdram/-ram/-rom arguments are
+ * hard-coded to these values and need not be specified. (see below)
+ *
+ * Get TSIM from http://www.gaisler.com/index.php/downloads/simulators
  */
 
 #define CONFIG_GRSIM           0       /* ... not running on GRSIM */
@@ -47,7 +51,6 @@
 /*
  * Supported commands
  */
-#define CONFIG_CMD_AMBAPP      /* AMBA Plyg&Play information   */
 #define CONFIG_CMD_DIAG
 #define CONFIG_CMD_FPGA_LOADMK
 #define CONFIG_CMD_IRQ
 /*
  * Memory map
  */
-#define CONFIG_SYS_SDRAM_BASE          0x40000000
-#define CONFIG_SYS_SDRAM_SIZE          0x02000000
-#define CONFIG_SYS_SDRAM_END           (CONFIG_SYS_SDRAM_BASE+CONFIG_SYS_SDRAM_SIZE)
+#define CONFIG_SYS_SDRAM_BASE          0x60000000
+#define CONFIG_SYS_SDRAM_SIZE          0x02000000 /* 32MiB SDRAM */
+#define CONFIG_SYS_SDRAM_END           (CONFIG_SYS_SDRAM_BASE + CONFIG_SYS_SDRAM_SIZE)
 
-/* no SRAM available */
-#undef CONFIG_SYS_SRAM_BASE
-#undef CONFIG_SYS_SRAM_SIZE
+#define CONFIG_SYS_SRAM_BASE           0x40000000
+#define CONFIG_SYS_SRAM_SIZE           0x00400000 /* 4MiB SRAM */
+#define CONFIG_SYS_SRAM_END            (CONFIG_SYS_SRAM_BASE + CONFIG_SYS_SRAM_SIZE)
 
 /* Always Run U-Boot from SDRAM */
-#define CONFIG_SYS_RAM_BASE CONFIG_SYS_SDRAM_BASE
-#define CONFIG_SYS_RAM_SIZE CONFIG_SYS_SDRAM_SIZE
-#define CONFIG_SYS_RAM_END CONFIG_SYS_SDRAM_END
+#define CONFIG_SYS_RAM_BASE            CONFIG_SYS_SDRAM_BASE
+#define CONFIG_SYS_RAM_SIZE            CONFIG_SYS_SDRAM_SIZE
+#define CONFIG_SYS_RAM_END             CONFIG_SYS_SDRAM_END
 
 #define CONFIG_SYS_GBL_DATA_OFFSET     (CONFIG_SYS_RAM_END - GENERATED_GBL_DATA_SIZE)
 
 /* make un relocated address from relocated address */
 #define UN_RELOC(address) (address-(CONFIG_SYS_RELOC_MONITOR_BASE-CONFIG_SYS_TEXT_BASE))
 
+#ifdef CONFIG_CMD_NET
 /*
  * Ethernet configuration
  */
 /* #define CONFIG_GRETH_10MBIT 1 */
 #define CONFIG_PHY_ADDR                0x00
 
+#endif /* CONFIG_CMD_NET */
+
 /*
  * Miscellaneous configurable options
  */
 
 /***** Gaisler GRLIB IP-Cores Config ********/
 
-/* 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   0x81805220
 #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
-
-#define CONFIG_SYS_GRLIB_APBUART_SCALER \
- ((((CONFIG_SYS_CLK_FREQ*10)/(CONFIG_BAUDRATE*8))-5)/10)
+#undef CONFIG_SYS_GRLIB_GAISLER_DDR2SPA1
 
 /* default kernel command line */
 #define CONFIG_DEFAULT_KERNEL_COMMAND_LINE "console=ttyS0,38400\0\0"
 
 #define CONFIG_IDENT_STRING "Gaisler GRSIM"
 
+/* TSIM command:
+ * $ ./tsim-leon3 -mmu -cas
+ *
+ *  This TSIM evaluation version will expire 2015-04-02
+ *
+ *
+ *  TSIM/LEON3 SPARC simulator, version 2.0.35 (evaluation version)
+ *
+ *  Copyright (C) 2014, Aeroflex Gaisler - all rights reserved.
+ *  This software may only be used with a valid license.
+ *  For latest updates, go to http://www.gaisler.com/
+ *  Comments or bug-reports to support@gaisler.com
+ *
+ * serial port A on stdin/stdout
+ * allocated 4096 K SRAM memory, in 1 bank
+ * allocated 32 M SDRAM memory, in 1 bank
+ * allocated 2048 K ROM memory
+ * icache: 1 * 4 kbytes, 16 bytes/line (4 kbytes total)
+ * dcache: 1 * 4 kbytes, 16 bytes/line (4 kbytes total)
+ * tsim> leon
+ * 0x80000000   Memory configuration register 1   0x000002ff
+ * 0x80000004   Memory configuration register 2   0x81805220
+ * 0x80000008   Memory configuration register 3   0x00000000
+ */
+
 #endif                         /* __CONFIG_H */
index bd2eaa9fdaa7d03f4c68adefb3d6bb8d2ed72bd7..83fd7fae5000ed70c469f4adf9ede83f07a24e5e 100644 (file)
 #define CONFIG_SYS_GRLIB_MEMCFG3  0x00136000
 
 /*** LEON2 UART 1 ***/
-#define CONFIG_SYS_LEON2_UART1_SCALER \
-       ((((CONFIG_SYS_CLK_FREQ*10)/(CONFIG_BAUDRATE*8))-5)/10)
 
 /* UART1 Define to 1 or 0 */
 #define LEON2_UART1_LOOPBACK_ENABLE 0
 
 /*** LEON2 UART 2 ***/
 
-#define CONFIG_SYS_LEON2_UART2_SCALER \
-       ((((CONFIG_SYS_CLK_FREQ*10)/(CONFIG_BAUDRATE*8))-5)/10)
-
 /* UART2 Define to 1 or 0 */
 #define LEON2_UART2_LOOPBACK_ENABLE 0
 #define LEON2_UART2_FLOWCTRL_ENABLE 0
diff --git a/include/grlib/apbuart.h b/include/grlib/apbuart.h
new file mode 100644 (file)
index 0000000..1e1eb9a
--- /dev/null
@@ -0,0 +1,47 @@
+/* GRLIB APBUART definitions
+ *
+ * (C) Copyright 2010, 2015
+ * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#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 (file)
index 0000000..8b2b165
--- /dev/null
@@ -0,0 +1,34 @@
+/* GRLIB GPTIMER (General Purpose Timer) definitions
+ *
+ * (C) Copyright 2010, 2015
+ * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#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 (file)
index 0000000..89c1e49
--- /dev/null
@@ -0,0 +1,87 @@
+/* Gaisler.com GRETH 10/100/1000 Ethernet MAC definitions
+ *
+ * (C) Copyright 2010, 2015
+ * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#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 (file)
index 0000000..0354d5c
--- /dev/null
@@ -0,0 +1,23 @@
+/* GRLIB IRQMP (IRQ Multi-processor controller) definitions
+ *
+ * (C) Copyright 2010, 2015
+ * Daniel Hellstrom, Cobham Gaisler, daniel@gaisler.com
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#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