]> git.sur5r.net Git - u-boot/commitdiff
Add support for EXBITGEN board
authorwdenk <wdenk>
Fri, 27 Jun 2003 23:19:19 +0000 (23:19 +0000)
committerwdenk <wdenk>
Fri, 27 Jun 2003 23:19:19 +0000 (23:19 +0000)
13 files changed:
CHANGELOG
MAINTAINERS
MAKEALL
Makefile
board/exbitgen/Makefile [new file with mode: 0644]
board/exbitgen/config.mk [new file with mode: 0644]
board/exbitgen/exbitgen.c [new file with mode: 0644]
board/exbitgen/exbitgen.h [new file with mode: 0644]
board/exbitgen/flash.c [new file with mode: 0644]
board/exbitgen/init.S [new file with mode: 0644]
board/exbitgen/u-boot.lds [new file with mode: 0644]
include/configs/EXBITGEN.h [new file with mode: 0644]
include/flash.h

index edc38857f469b1877e2a72f1fdab3b280f30b67a..eaa5cc326c87e3159ec2e6d5b52ce61c813e2c9e 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -2,6 +2,8 @@
 Changes since U-Boot 0.4.0:
 ======================================================================
 
+* Add support for EXBITGEN board
+
 * Add support for SL8245 board
 
 ======================================================================
index 1dd62bd8bd586c39c7111ad4237aff7c66f6990e..6b312adfce2038f9db32001f543c8606cf2f5977 100644 (file)
@@ -94,6 +94,8 @@ Wolfgang Denk <wd@denx.de>
        PCIPPC2                 MPC750
        PCIPPC6                 MPC750
 
+       EXBITGEN                PPC405GP
+
 Jon Diekema <jon.diekema@smiths-aerospace.com>
 
        sbc8260                 MPC8260
diff --git a/MAKEALL b/MAKEALL
index 9d75d5816f2b3bc175f4eae3fdc1fe36bcf2f69f..577f3ff755a2615ecf576f5862942d2a55aafd2a 100644 (file)
--- a/MAKEALL
+++ b/MAKEALL
@@ -37,7 +37,7 @@ LIST_8xx="    \
        SM850           SPD823TS        svm_sc8xx       SXNI855T        \
        TOP860          TQM823L         TQM823L_LCD     TQM850L         \
        TQM855L         TQM860L         TTTech          v37             \
-"
+
 
 #########################################################################
 ## PPC4xx Systems
@@ -47,10 +47,10 @@ LIST_4xx="  \
        ADCIOP          AR405           ASH405          BUBINGA405EP    \
         CANBT          CPCI405         CPCI4052        CPCI405AB       \
         CPCI440         CPCIISER4      CRAYL1          DASA_SIM        \
-        DU405          EBONY           ERIC            MIP405          \
-        MIP405T                ML2             OCRTC           ORSG            \
-       PCI405          PIP405          PMC405          W7OLMC          \
-       W7OLMG          WALNUT405       \
+        DU405          EBONY           ERIC            EXBITGEN        \
+       MIP405          MIP405T         ML2             OCRTC           \
+       ORSG            PCI405          PIP405          PMC405          \
+       W7OLMC          W7OLMG          WALNUT405                       \
 "
 
 #########################################################################
index ef7b38b3aeb3e42f390014a8d75a255d645d4521..6ac1b083331256d73a86d4cf6e2bb298924b5638 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -466,6 +466,9 @@ EBONY_config:unconfig
 ERIC_config:unconfig
        @./mkconfig $(@:_config=) ppc ppc4xx eric
 
+EXBITGEN_config:unconfig
+       @./mkconfig $(@:_config=) ppc ppc4xx exbitgen
+
 MIP405_config:unconfig
        @./mkconfig $(@:_config=) ppc ppc4xx mip405 mpl
 
diff --git a/board/exbitgen/Makefile b/board/exbitgen/Makefile
new file mode 100644 (file)
index 0000000..34bd4b2
--- /dev/null
@@ -0,0 +1,49 @@
+#
+# (C) Copyright 2000
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB    = lib$(BOARD).a
+
+OBJS   = $(BOARD).o flash.o
+
+SOBJS  = init.o
+
+
+$(LIB):        $(OBJS) $(SOBJS)
+       $(AR) crv $@ $^
+
+clean:
+       rm -f $(SOBJS) $(OBJS)
+
+distclean:     clean
+       rm -f $(LIB) core *.bak .depend
+
+#########################################################################
+
+.depend:       Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c)
+               $(CC) -M $(CFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@
+
+sinclude .depend
+
+#########################################################################
diff --git a/board/exbitgen/config.mk b/board/exbitgen/config.mk
new file mode 100644 (file)
index 0000000..42ea0c6
--- /dev/null
@@ -0,0 +1,33 @@
+#
+# (C) Copyright 2000
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+#
+# ExbitGen board
+#
+
+LDFLAGS += $(LINKER_UNDEFS)
+
+TEXT_BASE := 0xFFF80000
+#TEXT_BASE := 0x00100000
+
+PLATFORM_RELFLAGS := $(PLATFORM_RELFLAGS)
diff --git a/board/exbitgen/exbitgen.c b/board/exbitgen/exbitgen.c
new file mode 100644 (file)
index 0000000..f2cd8ca
--- /dev/null
@@ -0,0 +1,117 @@
+#include <asm/u-boot.h>
+#include <asm/processor.h>
+#include <common.h>
+#include "exbitgen.h"
+
+/* ************************************************************************ */
+int board_pre_init (void)
+/* ------------------------------------------------------------------------ --
+ * Purpose     :
+ * Remarks     :
+ * Restrictions:
+ * See also    :
+ * Example     :
+ * ************************************************************************ */
+{
+       unsigned long i;
+
+   /*-------------------------------------------------------------------------+
+   | Interrupt controller setup for the Walnut board.
+   | Note: IRQ 0-15  405GP internally generated; active high; level sensitive
+   |       IRQ 16    405GP internally generated; active low; level sensitive
+   |       IRQ 17-24 RESERVED
+   |       IRQ 25 (EXT IRQ 0) FPGA; active high; level sensitive
+   |       IRQ 26 (EXT IRQ 1) SMI; active high; level sensitive
+   |       IRQ 27 (EXT IRQ 2) Not Used
+   |       IRQ 28 (EXT IRQ 3) PCI SLOT 3; active low; level sensitive
+   |       IRQ 29 (EXT IRQ 4) PCI SLOT 2; active low; level sensitive
+   |       IRQ 30 (EXT IRQ 5) PCI SLOT 1; active low; level sensitive
+   |       IRQ 31 (EXT IRQ 6) PCI SLOT 0; active low; level sensitive
+   | Note for Walnut board:
+   |       An interrupt taken for the FPGA (IRQ 25) indicates that either
+   |       the Mouse, Keyboard, IRDA, or External Expansion caused the
+   |       interrupt. The FPGA must be read to determine which device
+   |       caused the interrupt. The default setting of the FPGA clears
+   |
+   +-------------------------------------------------------------------------*/
+
+       mtdcr (uicsr, 0xFFFFFFFF);      /* clear all ints */
+       mtdcr (uicer, 0x00000000);      /* disable all ints */
+       mtdcr (uiccr, 0x00000020);      /* set all but FPGA SMI to be non-critical */
+       mtdcr (uicpr, 0xFFFFFF90);      /* set int polarities */
+       mtdcr (uictr, 0x10000000);      /* set int trigger levels */
+       mtdcr (uicvcr, 0x00000001);     /* set vect base=0,INT0 highest priority */
+       mtdcr (uicsr, 0xFFFFFFFF);      /* clear all ints */
+
+       /* Perform reset of PHY connected to PPC via register in CPLD */
+       out8 (PHY_CTRL_ADDR, 0x2e);     /* activate nRESET,FDX,F100,ANEN, enable output */
+       for (i = 0; i < 10000000; i++) {
+               ;
+       }
+       out8 (PHY_CTRL_ADDR, 0x2f);     /* deactivate nRESET */
+
+       return 0;
+}
+
+
+/* ************************************************************************ */
+int checkboard (void)
+/* ------------------------------------------------------------------------ --
+ * Purpose     :
+ * Remarks     :
+ * Restrictions:
+ * See also    :
+ * Example     :
+ * ************************************************************************ */
+{
+       printf ("Exbit H/W id: %d\n", in8 (HW_ID_ADDR));
+       return (0);
+}
+
+/* ************************************************************************ */
+long int initdram (int board_type)
+/* ------------------------------------------------------------------------ --
+ * Purpose     : Determines size of mounted DRAM.
+ * Remarks     : Size is determined by reading SDRAM configuration registers as
+ *               set up by sdram_init.
+ * Restrictions:
+ * See also    :
+ * Example     :
+ * ************************************************************************ */
+{
+       ulong tot_size;
+       ulong bank_size;
+       ulong tmp;
+
+       tot_size = 0;
+
+       mtdcr (memcfga, mem_mb0cf);
+       tmp = mfdcr (memcfgd);
+       if (tmp & 0x00000001) {
+               bank_size = 0x00400000 << ((tmp >> 17) & 0x7);
+               tot_size += bank_size;
+       }
+
+       mtdcr (memcfga, mem_mb1cf);
+       tmp = mfdcr (memcfgd);
+       if (tmp & 0x00000001) {
+               bank_size = 0x00400000 << ((tmp >> 17) & 0x7);
+               tot_size += bank_size;
+       }
+
+       mtdcr (memcfga, mem_mb2cf);
+       tmp = mfdcr (memcfgd);
+       if (tmp & 0x00000001) {
+               bank_size = 0x00400000 << ((tmp >> 17) & 0x7);
+               tot_size += bank_size;
+       }
+
+       mtdcr (memcfga, mem_mb3cf);
+       tmp = mfdcr (memcfgd);
+       if (tmp & 0x00000001) {
+               bank_size = 0x00400000 << ((tmp >> 17) & 0x7);
+               tot_size += bank_size;
+       }
+
+       return tot_size;
+}
diff --git a/board/exbitgen/exbitgen.h b/board/exbitgen/exbitgen.h
new file mode 100644 (file)
index 0000000..058ad48
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * (C) Copyright 2003
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#define GPIO_CPU_LED           GPIO_3
+
+
+#define CPLD_BASE              0x10000000              /* t.b.m. */
+#define DEBUG_LEDS_ADDR        CPLD_BASE + 0x01
+#define HW_ID_ADDR             CPLD_BASE + 0x02
+#define DIP_SWITCH_ADDR        CPLD_BASE + 0x04
+#define PHY_CTRL_ADDR          CPLD_BASE + 0x05
+#define SPI_OUT_ADDR           CPLD_BASE + 0x07
+#define SPI_IN_ADDR            CPLD_BASE + 0x08
+#define MDIO_OUT_ADDR          CPLD_BASE + 0x09
+#define MDIO_IN_ADDR           CPLD_BASE + 0x0A
+#define MISC_OUT_ADDR          CPLD_BASE + 0x0B
+
+/* Addresses used on I2C bus */
+#define LM75_CHIP_ADDR         0x9C
+#define LM75_CPU_ADDR          0x9E
+#define SDRAM_SPD_ADDR         0xA0
+
+#define SDRAM_SPD_WRITE_ADDRESS        (SDRAM_SPD_ADDR)
+#define SDRAM_SPD_READ_ADDRESS (SDRAM_SPD_ADDR+1)
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#ifndef TRUE
+#define TRUE 1
+#endif
diff --git a/board/exbitgen/flash.c b/board/exbitgen/flash.c
new file mode 100644 (file)
index 0000000..f687ea3
--- /dev/null
@@ -0,0 +1,597 @@
+/*
+ * (C) Copyright 2003
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * Modified 4/5/2001
+ * Wait for completion of each sector erase command issued
+ * 4/5/2001
+ * Chris Hallinan - DS4.COM, Inc. - clh@net1plus.com
+ */
+
+#include <asm/u-boot.h>
+#include <asm/processor.h>
+#include <ppc4xx.h>
+#include <common.h>
+
+flash_info_t   flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips        */
+
+/*-----------------------------------------------------------------------
+ * Functions
+ */
+static ulong flash_get_size (vu_long *addr, flash_info_t *info);
+static int write_word (flash_info_t *info, ulong dest, ulong data);
+
+#ifdef MEIGSBOARD_ONBOARD_FLASH /* onboard = 2MB */
+#  ifdef CONFIG_EXBITGEN
+#     define FLASH_WORD_SIZE unsigned long
+#  endif
+#else /* Meigsboard socket flash = 512KB */
+#  ifdef CONFIG_EXBITGEN
+#    define FLASH_WORD_SIZE unsigned char
+#  endif
+#endif
+
+#ifdef CONFIG_EXBITGEN
+#define ADDR0           0x5555
+#define ADDR1           0x2aaa
+#define FLASH_WORD_SIZE unsigned char
+#endif
+
+/*-----------------------------------------------------------------------
+ */
+
+unsigned long flash_init (void)
+{
+       unsigned long bank_size;
+       unsigned long tot_size;
+       unsigned long bank_addr;
+       int i;
+
+       /* Init: no FLASHes known */
+       for (i = 0; i < CFG_MAX_FLASH_BANKS; ++i) {
+               flash_info[i].flash_id = FLASH_UNKNOWN;
+               flash_info[i].size = 0;
+       }
+
+       tot_size = 0;
+
+       /* Detect Boot Flash */
+       bank_addr = CFG_FLASH0_BASE;
+       bank_size = flash_get_size((vu_long *)bank_addr, &flash_info[0]);
+       if (bank_size > 0) {
+               (void)flash_protect(FLAG_PROTECT_CLEAR,
+                       bank_addr,
+                       bank_addr + bank_size - 1,
+                       &flash_info[0]);
+       }
+       if (flash_info[0].flash_id == FLASH_UNKNOWN) {
+               printf ("## Unknown FLASH on Boot Flash Bank\n");
+       }
+       flash_info[0].size = bank_size;
+       tot_size += bank_size;
+
+       /* Detect Application Flash */
+       bank_addr = CFG_FLASH1_BASE;
+       for (i = 1; i < CFG_MAX_FLASH_BANKS; ++i) {
+               bank_size = flash_get_size((vu_long *)bank_addr, &flash_info[i]);
+               if (flash_info[i].flash_id == FLASH_UNKNOWN) {
+                       break;
+               }
+               if (bank_size > 0) {
+                       (void)flash_protect(FLAG_PROTECT_CLEAR,
+                               bank_addr,
+                               bank_addr + bank_size - 1,
+                               &flash_info[i]);
+               }
+               flash_info[i].size = bank_size;
+               tot_size += bank_size;
+               bank_addr += bank_size;
+       }
+       if (flash_info[1].flash_id == FLASH_UNKNOWN) {
+               printf ("## Unknown FLASH on Application Flash Bank\n");
+       }
+
+       /* Protect monitor and environment sectors */
+#if CFG_MONITOR_BASE >= CFG_FLASH0_BASE
+       flash_protect(FLAG_PROTECT_SET,
+               CFG_MONITOR_BASE,
+               CFG_MONITOR_BASE + monitor_flash_len - 1,
+               &flash_info[0]);
+#if 0xfffffffc >= CFG_FLASH0_BASE
+#if 0xfffffffc <= CFG_FLASH0_BASE + CFG_FLASH0_SIZE - 1
+       flash_protect(FLAG_PROTECT_SET,
+               0xfffffffc, 0xffffffff,
+               &flash_info[0]);
+#endif
+#endif
+#endif
+
+#if (CFG_ENV_IS_IN_FLASH == 1) && defined(CFG_ENV_ADDR)
+       flash_protect(FLAG_PROTECT_SET,
+               CFG_ENV_ADDR,
+               CFG_ENV_ADDR + CFG_ENV_SIZE - 1,
+               &flash_info[0]);
+#endif
+
+       return tot_size;
+}
+
+/*-----------------------------------------------------------------------
+ */
+void flash_print_info  (flash_info_t *info)
+{
+       int i;
+
+       if (info->flash_id == FLASH_UNKNOWN) {
+               printf ("missing or unknown FLASH type\n");
+               return;
+       }
+
+       switch (info->flash_id & FLASH_VENDMASK) {
+       case FLASH_MAN_AMD:     printf ("AMD ");                break;
+       case FLASH_MAN_FUJ:     printf ("FUJITSU ");            break;
+       case FLASH_MAN_SST:     printf ("SST ");                break;
+       default:                printf ("Unknown Vendor ");     break;
+       }
+
+       switch (info->flash_id & FLASH_TYPEMASK) {
+       case FLASH_AM040:       printf ("AM29F040 (512 Kbit, uniform sector size)\n");
+                               break;
+       case FLASH_AM400B:      printf ("AM29LV400B (4 Mbit, bottom boot sect)\n");
+                               break;
+       case FLASH_AM400T:      printf ("AM29LV400T (4 Mbit, top boot sector)\n");
+                               break;
+       case FLASH_AM800B:      printf ("AM29LV800B (8 Mbit, bottom boot sect)\n");
+                               break;
+       case FLASH_AM800T:      printf ("AM29LV800T (8 Mbit, top boot sector)\n");
+                               break;
+       case FLASH_AM160B:      printf ("AM29LV160B (16 Mbit, bottom boot sect)\n");
+                               break;
+       case FLASH_AM160T:      printf ("AM29LV160T (16 Mbit, top boot sector)\n");
+                               break;
+       case FLASH_AM320B:      printf ("AM29LV320B (32 Mbit, bottom boot sect)\n");
+                               break;
+       case FLASH_AM320T:      printf ("AM29LV320T (32 Mbit, top boot sector)\n");
+                               break;
+       case FLASH_AMDLV033C:   printf ("AM29LV033C (32 Mbit, uniform sector size)\n");
+                               break;
+       case FLASH_AMDLV065D:   printf ("AM29LV065D (64 Mbit, uniform sector size)\n");
+                               break;
+       case FLASH_SST800A:     printf ("SST39LF/VF800 (8 Mbit, uniform sector size)\n");
+                               break;
+       case FLASH_SST160A:     printf ("SST39LF/VF160 (16 Mbit, uniform sector size)\n");
+                               break;
+       case FLASH_SST040:      printf ("SST39LF/VF040 (4 Mbit, uniform sector size)\n");
+                               break;
+       default:                printf ("Unknown Chip Type\n");
+                               break;
+       }
+
+       printf ("  Size: %ld KB in %d Sectors\n",
+               info->size >> 10, info->sector_count);
+
+       printf ("  Sector Start Addresses:");
+       for (i=0; i<info->sector_count; ++i) {
+               if ((i % 5) == 0)
+                       printf ("\n   ");
+               printf (" %08lX%s",
+                       info->start[i],
+                       info->protect[i] ? " (RO)" : "     "
+               );
+       }
+       printf ("\n");
+}
+
+/*-----------------------------------------------------------------------
+ */
+
+
+/*-----------------------------------------------------------------------
+ */
+
+/*
+ * The following code cannot be run from FLASH!
+ */
+static ulong flash_get_size (vu_long *addr, flash_info_t *info)
+{
+       short i;
+       FLASH_WORD_SIZE value;
+       ulong base = (ulong)addr;
+        volatile FLASH_WORD_SIZE *addr2 = (FLASH_WORD_SIZE *)addr;
+
+       /* Write auto select command: read Manufacturer ID */
+       addr2[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA;
+       addr2[ADDR1] = (FLASH_WORD_SIZE)0x00550055;
+       addr2[ADDR0] = (FLASH_WORD_SIZE)0x00900090;
+
+       value = addr2[0];
+
+       switch (value) {
+       case (FLASH_WORD_SIZE)AMD_MANUFACT:
+               info->flash_id = FLASH_MAN_AMD;
+               break;
+       case (FLASH_WORD_SIZE)FUJ_MANUFACT:
+               info->flash_id = FLASH_MAN_FUJ;
+               break;
+       case (FLASH_WORD_SIZE)SST_MANUFACT:
+               info->flash_id = FLASH_MAN_SST;
+               break;
+       default:
+               info->flash_id = FLASH_UNKNOWN;
+               info->sector_count = 0;
+               info->size = 0;
+               return (0);                     /* no or unknown flash  */
+       }
+
+       value = addr2[1];                       /* device ID            */
+
+       switch (value) {
+       case (FLASH_WORD_SIZE)AMD_ID_F040B:
+               info->flash_id += FLASH_AM040;
+               info->sector_count = 8;
+               info->size = 0x0080000; /* => 512 ko */
+               break;
+       case (FLASH_WORD_SIZE)AMD_ID_LV400T:
+               info->flash_id += FLASH_AM400T;
+               info->sector_count = 11;
+               info->size = 0x00080000;
+               break;                          /* => 0.5 MB            */
+
+       case (FLASH_WORD_SIZE)AMD_ID_LV400B:
+               info->flash_id += FLASH_AM400B;
+               info->sector_count = 11;
+               info->size = 0x00080000;
+               break;                          /* => 0.5 MB            */
+
+       case (FLASH_WORD_SIZE)AMD_ID_LV800T:
+               info->flash_id += FLASH_AM800T;
+               info->sector_count = 19;
+               info->size = 0x00100000;
+               break;                          /* => 1 MB              */
+
+       case (FLASH_WORD_SIZE)AMD_ID_LV800B:
+               info->flash_id += FLASH_AM800B;
+               info->sector_count = 19;
+               info->size = 0x00100000;
+               break;                          /* => 1 MB              */
+
+       case (FLASH_WORD_SIZE)AMD_ID_LV160T:
+               info->flash_id += FLASH_AM160T;
+               info->sector_count = 35;
+               info->size = 0x00200000;
+               break;                          /* => 2 MB              */
+
+       case (FLASH_WORD_SIZE)AMD_ID_LV160B:
+               info->flash_id += FLASH_AM160B;
+               info->sector_count = 35;
+               info->size = 0x00200000;
+               break;                          /* => 2 MB              */
+
+       case (FLASH_WORD_SIZE)AMD_ID_LV033C:
+               info->flash_id += FLASH_AMDLV033C;
+               info->sector_count = 64;
+               info->size = 0x00400000;
+               break;                          /* => 4 MB              */
+
+       case (FLASH_WORD_SIZE)AMD_ID_LV065D:
+               info->flash_id += FLASH_AMDLV065D;
+               info->sector_count = 128;
+               info->size = 0x00800000;
+               break;                          /* => 8 MB              */
+
+       case (FLASH_WORD_SIZE)AMD_ID_LV320T:
+               info->flash_id += FLASH_AM320T;
+               info->sector_count = 67;
+               info->size = 0x00400000;
+               break;                          /* => 4 MB              */
+
+       case (FLASH_WORD_SIZE)AMD_ID_LV320B:
+               info->flash_id += FLASH_AM320B;
+               info->sector_count = 67;
+               info->size = 0x00400000;
+               break;                          /* => 4 MB              */
+
+       case (FLASH_WORD_SIZE)SST_ID_xF800A:
+               info->flash_id += FLASH_SST800A;
+               info->sector_count = 16;
+               info->size = 0x00100000;
+               break;                          /* => 1 MB              */
+
+       case (FLASH_WORD_SIZE)SST_ID_xF160A:
+               info->flash_id += FLASH_SST160A;
+               info->sector_count = 32;
+               info->size = 0x00200000;
+               break;                          /* => 2 MB              */
+       case (FLASH_WORD_SIZE)SST_ID_xF040:
+               info->flash_id += FLASH_SST040;
+               info->sector_count = 128;
+               info->size = 0x00080000;
+               break;                          /* => 512KB             */
+
+       default:
+               info->flash_id = FLASH_UNKNOWN;
+               return (0);                     /* => no or unknown flash */
+
+       }
+
+       /* set up sector start address table */
+        if (((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) ||
+               (info->flash_id  == FLASH_AM040) ||
+               (info->flash_id == FLASH_AMDLV033C) ||
+               (info->flash_id == FLASH_AMDLV065D)) {
+               ulong sectsize = info->size / info->sector_count;
+               for (i = 0; i < info->sector_count; i++)
+                       info->start[i] = base + (i * sectsize);
+        } else {
+           if (info->flash_id & FLASH_BTYPE) {
+               /* set sector offsets for bottom boot block type        */
+               info->start[0] = base + 0x00000000;
+               info->start[1] = base + 0x00004000;
+               info->start[2] = base + 0x00006000;
+               info->start[3] = base + 0x00008000;
+               for (i = 4; i < info->sector_count; i++) {
+                       info->start[i] = base + (i * 0x00010000) - 0x00030000;
+               }
+           } else {
+               /* set sector offsets for top boot block type           */
+               i = info->sector_count - 1;
+               info->start[i--] = base + info->size - 0x00004000;
+               info->start[i--] = base + info->size - 0x00006000;
+               info->start[i--] = base + info->size - 0x00008000;
+               for (; i >= 0; i--) {
+                       info->start[i] = base + i * 0x00010000;
+               }
+           }
+       }
+
+       /* check for protected sectors */
+       for (i = 0; i < info->sector_count; i++) {
+               /* read sector protection at sector address, (A7 .. A0) = 0x02 */
+               /* D0 = 1 if protected */
+
+               addr2 = (volatile FLASH_WORD_SIZE *)(info->start[i]);
+                if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST)
+                       info->protect[i] = 0;
+                else
+                       info->protect[i] = addr2[2] & 1;
+       }
+
+       /* switch to the read mode */
+       if (info->flash_id != FLASH_UNKNOWN) {
+               addr2 = (FLASH_WORD_SIZE *)info->start[0];
+               *addr2 = (FLASH_WORD_SIZE)0x00F000F0;   /* reset bank */
+       }
+
+       return (info->size);
+}
+
+/*-----------------------------------------------------------------------
+ */
+
+int flash_erase (flash_info_t *info, int s_first, int s_last)
+{
+       volatile FLASH_WORD_SIZE *addr = (FLASH_WORD_SIZE *)(info->start[0]);
+       volatile FLASH_WORD_SIZE *addr2;
+       int flag, prot, sect;
+       ulong start, now, last;
+
+       if ((s_first < 0) || (s_first > s_last)) {
+               if (info->flash_id == FLASH_UNKNOWN) {
+                       printf ("- missing\n");
+               } else {
+                       printf ("- no sectors to erase\n");
+               }
+               return 1;
+       }
+
+       if (info->flash_id == FLASH_UNKNOWN) {
+               printf ("Can't erase unknown flash type - aborted\n");
+               return 1;
+       }
+
+       prot = 0;
+       for (sect=s_first; sect<=s_last; ++sect) {
+               if (info->protect[sect]) {
+                       prot++;
+               }
+       }
+
+       if (prot) {
+               printf ("- Warning: %d protected sectors will not be erased!\n",
+                       prot);
+       } else {
+               printf ("\n");
+       }
+
+       start = get_timer (0);
+       last  = start;
+       /* Start erase on unprotected sectors */
+       for (sect = s_first; sect <= s_last; sect++) {
+               if (info->protect[sect] == 0) { /* not protected */
+                       addr2 = (FLASH_WORD_SIZE *)(info->start[sect]);
+
+                       /* Disable interrupts which might cause a timeout here */
+                       flag = disable_interrupts();
+
+                       addr[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA;
+                       addr[ADDR1] = (FLASH_WORD_SIZE)0x00550055;
+                       addr[ADDR0] = (FLASH_WORD_SIZE)0x00800080;
+                       addr[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA;
+                       addr[ADDR1] = (FLASH_WORD_SIZE)0x00550055;
+                       addr2[0] = (FLASH_WORD_SIZE)0x00300030;
+
+                       /* re-enable interrupts if necessary */
+                       if (flag)
+                               enable_interrupts();
+
+                       /* wait at least 80us - let's wait 1 ms */
+                       udelay (1000);
+
+                       while ((addr2[0] & 0x00800080) !=
+                               (FLASH_WORD_SIZE) 0x00800080) {
+                               if ((now=get_timer(start)) >
+                                          CFG_FLASH_ERASE_TOUT) {
+                                       printf ("Timeout\n");
+                                       addr[0] = (FLASH_WORD_SIZE)0x00F000F0;
+                                       return 1;
+                               }
+
+                               /* show that we're waiting */
+                               if ((now - last) > 1000) {  /* every second  */
+                                       putc ('.');
+                                       last = now;
+                               }
+                       }
+
+                       addr[0] = (FLASH_WORD_SIZE)0x00F000F0;
+               }
+       }
+
+       printf (" done\n");
+
+       return 0;
+}
+
+/*-----------------------------------------------------------------------
+ * Copy memory to flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ */
+
+int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
+{
+       ulong cp, wp, data;
+       int i, l, rc;
+
+       wp = (addr & ~3);       /* get lower word aligned address */
+
+       /*
+        * handle unaligned start bytes
+        */
+       if ((l = addr - wp) != 0) {
+               data = 0;
+               for (i=0, cp=wp; i<l; ++i, ++cp) {
+                       data = (data << 8) | (*(uchar *)cp);
+               }
+               for (; i<4 && cnt>0; ++i) {
+                       data = (data << 8) | *src++;
+                       --cnt;
+                       ++cp;
+               }
+               for (; cnt==0 && i<4; ++i, ++cp) {
+                       data = (data << 8) | (*(uchar *)cp);
+               }
+
+               if ((rc = write_word(info, wp, data)) != 0) {
+                       return (rc);
+               }
+               wp += 4;
+       }
+
+       /*
+        * handle word aligned part
+        */
+       while (cnt >= 4) {
+               data = 0;
+               for (i=0; i<4; ++i) {
+                       data = (data << 8) | *src++;
+               }
+               if ((rc = write_word(info, wp, data)) != 0) {
+                       return (rc);
+               }
+               wp  += 4;
+               cnt -= 4;
+       }
+
+       if (cnt == 0) {
+               return (0);
+       }
+
+       /*
+        * handle unaligned tail bytes
+        */
+       data = 0;
+       for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) {
+               data = (data << 8) | *src++;
+               --cnt;
+       }
+       for (; i<4; ++i, ++cp) {
+               data = (data << 8) | (*(uchar *)cp);
+       }
+
+       return (write_word(info, wp, data));
+}
+
+/*-----------------------------------------------------------------------
+ * Write a word to Flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ */
+static int write_word (flash_info_t *info, ulong dest, ulong data)
+{
+        volatile FLASH_WORD_SIZE *addr2 = (FLASH_WORD_SIZE *)(info->start[0]);
+        volatile FLASH_WORD_SIZE *dest2 = (FLASH_WORD_SIZE *)dest;
+        volatile FLASH_WORD_SIZE *data2 = (FLASH_WORD_SIZE *)&data;
+       ulong start;
+       int flag;
+        int i;
+
+       /* Check if Flash is (sufficiently) erased */
+       if ((*((volatile ulong *)dest) & data) != data) {
+               printf("dest = %08lx, *dest = %08lx, data = %08lx\n",
+                       dest, *(volatile ulong *)dest, data);
+               return 2;
+       }
+
+        for (i=0; i < 4/sizeof(FLASH_WORD_SIZE); i++) {
+               /* Disable interrupts which might cause a timeout here */
+               flag = disable_interrupts();
+
+               addr2[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA;
+               addr2[ADDR1] = (FLASH_WORD_SIZE)0x00550055;
+               addr2[ADDR0] = (FLASH_WORD_SIZE)0x00A000A0;
+               dest2[i] = data2[i];
+
+               /* re-enable interrupts if necessary */
+               if (flag)
+                       enable_interrupts();
+
+               /* data polling for D7 */
+               start = get_timer (0);
+               while ((dest2[i] & 0x00800080) != (data2[i] & 0x00800080)) {
+                       if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
+                               addr2[0] = (FLASH_WORD_SIZE)0x00F000F0;
+                               return (1);
+                       }
+               }
+       }
+
+       addr2[0] = (FLASH_WORD_SIZE)0x00F000F0;
+
+       return (0);
+}
+
+/*-----------------------------------------------------------------------
+ */
diff --git a/board/exbitgen/init.S b/board/exbitgen/init.S
new file mode 100644 (file)
index 0000000..96b0aba
--- /dev/null
@@ -0,0 +1,1009 @@
+/*----------------------------------------------------------------------+
+ *
+ *       This source code has been made available to you by IBM on an AS-IS
+ *       basis.  Anyone receiving this source is licensed under IBM
+ *       copyrights to use it in any way he or she deems fit, including
+ *       copying it, modifying it, compiling it, and redistributing it either
+ *       with or without modifications.  No license under IBM patents or
+ *       patent applications is to be implied by the copyright license.
+ *
+ *       Any user of this software should understand that IBM cannot provide
+ *       technical support for this software and will not be responsible for
+ *       any consequences resulting from the use of this software.
+ *
+ *       Any person who transfers this source code or any derivative work
+ *       must include the IBM copyright notice, this paragraph, and the
+ *       preceding two paragraphs in the transferred software.
+ *
+ *       COPYRIGHT   I B M   CORPORATION 1995
+ *       LICENSED MATERIAL  -  PROGRAM PROPERTY OF I B M
+ *-----------------------------------------------------------------------
+ */
+
+#include <config.h>
+#include <ppc4xx.h>
+#include "config.h"
+
+#define _LINUX_CONFIG_H 1      /* avoid reading Linux autoconf.h file  */
+#define FPGA_BRDC       0xF0300004
+
+#include <ppc_asm.tmpl>
+#include <ppc_defs.h>
+
+#include <asm/cache.h>
+#include <asm/mmu.h>
+
+#include "exbitgen.h"
+               
+/* IIC declarations (This is an extract from 405gp_i2c.h, which also contains some */
+/* c-code declarations and consequently can't be included here). */
+/* (Possibly to be solved somehow else). */
+/*--------------------------------------------------------------------- */
+#define           I2C_REGISTERS_BASE_ADDRESS 0xEF600500
+#define    IIC_MDBUF   (I2C_REGISTERS_BASE_ADDRESS+IICMDBUF)
+#define    IIC_SDBUF   (I2C_REGISTERS_BASE_ADDRESS+IICSDBUF)
+#define    IIC_LMADR   (I2C_REGISTERS_BASE_ADDRESS+IICLMADR)
+#define    IIC_HMADR   (I2C_REGISTERS_BASE_ADDRESS+IICHMADR)
+#define    IIC_CNTL    (I2C_REGISTERS_BASE_ADDRESS+IICCNTL)
+#define    IIC_MDCNTL  (I2C_REGISTERS_BASE_ADDRESS+IICMDCNTL)
+#define    IIC_STS     (I2C_REGISTERS_BASE_ADDRESS+IICSTS)
+#define    IIC_EXTSTS  (I2C_REGISTERS_BASE_ADDRESS+IICEXTSTS)
+#define    IIC_LSADR   (I2C_REGISTERS_BASE_ADDRESS+IICLSADR)
+#define    IIC_HSADR   (I2C_REGISTERS_BASE_ADDRESS+IICHSADR)
+#define    IIC_CLKDIV  (I2C_REGISTERS_BASE_ADDRESS+IICCLKDIV)
+#define    IIC_INTRMSK (I2C_REGISTERS_BASE_ADDRESS+IICINTRMSK)
+#define    IIC_XFRCNT  (I2C_REGISTERS_BASE_ADDRESS+IICXFRCNT)
+#define    IIC_XTCNTLSS        (I2C_REGISTERS_BASE_ADDRESS+IICXTCNTLSS)
+#define    IIC_DIRECTCNTL (I2C_REGISTERS_BASE_ADDRESS+IICDIRECTCNTL)
+
+/* MDCNTL Register Bit definition */
+#define    IIC_MDCNTL_HSCL 0x01
+#define    IIC_MDCNTL_EUBS 0x02
+#define    IIC_MDCNTL_FMDB 0x40
+#define    IIC_MDCNTL_FSDB 0x80
+
+/* CNTL Register Bit definition */
+#define    IIC_CNTL_PT     0x01
+#define    IIC_CNTL_READ   0x02
+#define    IIC_CNTL_CHT    0x04
+
+/* STS Register Bit definition */
+#define    IIC_STS_PT     0X01
+#define    IIC_STS_ERR    0X04
+#define    IIC_STS_MDBS    0X20
+
+/* EXTSTS Register Bit definition */
+#define    IIC_EXTSTS_XFRA 0X01
+#define    IIC_EXTSTS_ICT  0X02
+#define    IIC_EXTSTS_LA   0X04
+
+/* LED codes used for inditing progress and errors during read of DIMM SPD.  */
+/*--------------------------------------------------------------------- */
+#define LED_SDRAM_CODE_1  0xef
+#define LED_SDRAM_CODE_2  0xee
+#define LED_SDRAM_CODE_3  0xed
+#define LED_SDRAM_CODE_4  0xec
+#define LED_SDRAM_CODE_5  0xeb
+#define LED_SDRAM_CODE_6  0xea
+#define LED_SDRAM_CODE_7  0xe9
+#define LED_SDRAM_CODE_8  0xe8
+#define LED_SDRAM_CODE_9  0xe7
+#define LED_SDRAM_CODE_10 0xe6
+#define LED_SDRAM_CODE_11 0xe5
+#define LED_SDRAM_CODE_12 0xe4
+#define LED_SDRAM_CODE_13 0xe3
+#define LED_SDRAM_CODE_14 0xe2
+#define LED_SDRAM_CODE_15 0xe1
+#define LED_SDRAM_CODE_16 0xe0
+
+
+#define TIMEBASE_10PS (1000000000 / CONFIG_SYS_CLK_FREQ) * 100
+
+#define FLASH_8bit_AP   0x9B015480
+#define FLASH_8bit_CR   0xFFF18000 /* 1MB(min), 8bit, R/W */ 
+
+#define FLASH_32bit_AP  0x9B015480
+#define FLASH_32bit_CR  0xFFE3C000 /* 2MB, 32bit, R/W */
+
+
+#define WDCR_EBC(reg,val) addi    r4,0,reg;\
+        mtdcr   ebccfga,r4;\
+        addis   r4,0,val@h;\
+        ori     r4,r4,val@l;\
+        mtdcr   ebccfgd,r4
+
+/*---------------------------------------------------------------------
+ * Function:     ext_bus_cntlr_init
+ * Description:  Initializes the External Bus Controller for the external 
+ *             peripherals. IMPORTANT: For pass1 this code must run from 
+ *             cache since you can not reliably change a peripheral banks
+ *             timing register (pbxap) while running code from that bank.
+ *             For ex., since we are running from ROM on bank 0, we can NOT 
+ *             execute the code that modifies bank 0 timings from ROM, so
+ *             we run it from cache.
+ *     Bank 0 - Boot flash
+ *     Bank 1-4 - application flash
+ *     Bank 5 - CPLD
+ *     Bank 6 - not used
+ *     Bank 7 - Heathrow chip
+ *---------------------------------------------------------------------        
+ */
+       .globl  ext_bus_cntlr_init
+ext_bus_cntlr_init:
+        mflr    r4                      /* save link register */
+        bl      ..getAddr
+..getAddr:
+        mflr    r3                      /* get address of ..getAddr */
+        mtlr    r4                      /* restore link register */
+        addi    r4,0,14                 /* set ctr to 10; used to prefetch */
+        mtctr   r4                      /* 10 cache lines to fit this function */
+                                        /* in cache (gives us 8x10=80 instrctns) */
+..ebcloop:
+        icbt    r0,r3                   /* prefetch cache line for addr in r3 */
+        addi    r3,r3,32               /* move to next cache line */
+        bdnz    ..ebcloop               /* continue for 10 cache lines */
+
+       mflr    r31                     /* save link register */
+       
+        /*-----------------------------------------------------------
+         * Delay to ensure all accesses to ROM are complete before changing
+        * bank 0 timings. 200usec should be enough.
+         *   200,000,000 (cycles/sec) X .000200 (sec) = 0x9C40 cycles
+         *-----------------------------------------------------------
+        */
+
+       addis   r3,0,0x0
+        ori     r3,r3,0xA000          /* ensure 200usec have passed since reset */
+        mtctr   r3
+..spinlp:
+        bdnz    ..spinlp                /* spin loop */
+
+        /*---------------------------------------------------------------
+         * Memory Bank 0 (Boot Flash) initialization
+         *---------------------------------------------------------------
+        */
+       WDCR_EBC(pb0ap, FLASH_32bit_AP)
+       WDCR_EBC(pb0cr, 0xffe38000)
+/*pnc  WDCR_EBC(pb0cr, FLASH_32bit_CR) */
+       
+        /*---------------------------------------------------------------
+         * Memory Bank 5 (CPLD) initialization
+         *---------------------------------------------------------------
+        */
+       WDCR_EBC(pb5ap, 0x01010040)
+/*jsa recommendation:          WDCR_EBC(pb5ap, 0x00010040) */
+       WDCR_EBC(pb5cr, 0x10038000)
+
+        /*--------------------------------------------------------------- */
+        /* Memory Bank 6 (not used) initialization */
+        /*--------------------------------------------------------------- */
+       WDCR_EBC(pb6cr, 0x00000000)
+
+       /* Read HW ID to determine whether old H2 board or new generic CPU board */
+       addis   r3, 0,  HW_ID_ADDR@h
+       ori     r3, r3, HW_ID_ADDR@l
+        lbz     r3,0x0000(r3)
+       cmpi    0, r3, 1          /* if (HW_ID==1) */
+       beq     setup_h2evalboard /* then jump */
+       cmpi    0, r3, 2          /* if (HW_ID==2) */
+       beq     setup_genieboard  /* then jump */
+       cmpi    0, r3, 3          /* if (HW_ID==3) */
+       beq     setup_genieboard  /* then jump */
+
+setup_genieboard:
+        /*--------------------------------------------------------------- */
+        /* Memory Bank 1 (Application Flash) initialization for generic CPU board */
+        /*--------------------------------------------------------------- */
+/*     WDCR_EBC(pb1ap, 0x7b015480)     /###* T.B.M. */
+/*     WDCR_EBC(pb1ap, 0x7F8FFE80)     /###* T.B.M. */
+       WDCR_EBC(pb1ap, 0x9b015480)     /* hlb-20020207: burst 8 bit 6 cycles  */
+
+/*     WDCR_EBC(pb1cr, 0x20098000)     /###* 16 MB */
+       WDCR_EBC(pb1cr, 0x200B8000)     /* 32 MB */
+
+        /*--------------------------------------------------------------- */
+        /* Memory Bank 4 (Onboard FPGA) initialization for generic CPU board */
+        /*--------------------------------------------------------------- */
+       WDCR_EBC(pb4ap, 0x01010000)     /*  */
+       WDCR_EBC(pb4cr, 0x1021c000)     /*  */
+
+        /*--------------------------------------------------------------- */
+        /* Memory Bank 7 (Heathrow chip on Reference board) initialization */
+        /*--------------------------------------------------------------- */
+       WDCR_EBC(pb7ap, 0x200ffe80)     /* No Ready, many wait states (let reflections die out) */
+       WDCR_EBC(pb7cr, 0X4001A000)
+
+       bl      setup_continue
+
+       
+setup_h2evalboard:
+        /*--------------------------------------------------------------- */
+        /* Memory Bank 1 (Application Flash) initialization */
+        /*--------------------------------------------------------------- */
+       WDCR_EBC(pb1ap, 0x7b015480)     /* T.B.M. */
+/*3010 WDCR_EBC(pb1ap, 0x7F8FFE80)     /###* T.B.M. */
+       WDCR_EBC(pb1cr, 0x20058000) 
+
+        /*--------------------------------------------------------------- */
+        /* Memory Bank 2 (Application Flash) initialization */
+        /*--------------------------------------------------------------- */
+       WDCR_EBC(pb2ap, 0x7b015480)     /* T.B.M. */
+/*3010 WDCR_EBC(pb2ap, 0x7F8FFE80)     /###* T.B.M. */
+       WDCR_EBC(pb2cr, 0x20458000) 
+
+       /*--------------------------------------------------------------- */
+        /* Memory Bank 3 (Application Flash) initialization */
+        /*--------------------------------------------------------------- */
+       WDCR_EBC(pb3ap, 0x7b015480)     /* T.B.M. */
+/*3010 WDCR_EBC(pb3ap, 0x7F8FFE80)     /###* T.B.M. */
+       WDCR_EBC(pb3cr, 0x20858000) 
+
+        /*--------------------------------------------------------------- */
+        /* Memory Bank 4 (Application Flash) initialization */
+        /*--------------------------------------------------------------- */
+       WDCR_EBC(pb4ap, 0x7b015480)     /* T.B.M. */
+/*3010 WDCR_EBC(pb4ap, 0x7F8FFE80)     /###* T.B.M. */
+       WDCR_EBC(pb4cr, 0x20C58000)
+
+        /*--------------------------------------------------------------- */
+        /* Memory Bank 7 (Heathrow chip) initialization */
+        /*--------------------------------------------------------------- */
+       WDCR_EBC(pb7ap, 0x02000280)     /* No Ready, 4 wait states */
+       WDCR_EBC(pb7cr, 0X4001A000)
+
+setup_continue:
+
+       
+        mtlr    r31                     /* restore lr   */
+       nop                             /* pass2 DCR errata #8 */
+        blr
+
+/*--------------------------------------------------------------------- */
+/* Function:     sdram_init */
+/* Description:  Configures SDRAM memory banks. */
+/*--------------------------------------------------------------------- */
+        .globl  sdram_init
+
+sdram_init:
+#if CFG_MONITOR_BASE < CFG_FLASH_BASE
+       blr
+#else
+       mflr    r31
+
+       /* output SDRAM code  on LEDs */
+       addi    r4, 0, LED_SDRAM_CODE_1
+       addis   r5, 0, 0x1000
+       ori     r5, r5, 0x0001
+       stb     r4,0(r5)
+       eieio
+
+       /* Read contents of spd */
+       /*--------------------- */
+       bl      read_spd
+
+       /*----------------------------------------------------------- */
+       /* */
+       /* */
+       /* Update SDRAM timing register */
+       /* */
+       /* */
+       /*----------------------------------------------------------- */
+
+       /* Read  PLL feedback divider and calculate clock period of local bus in */
+       /* granularity of 10 ps. Save clock period in r30 */
+       /*-------------------------------------------------------------- */
+       mfdcr   r4, pllmd
+       addi    r9, 0, 25
+       srw     r4, r4, r9
+       andi.   r4, r4, 0x07
+       addis   r5, 0,  TIMEBASE_10PS@h
+       ori     r5, r5, TIMEBASE_10PS@l
+       divwu   r30, r5, r4
+
+       /* Determine CASL */
+       /*--------------- */
+       bl      find_casl       /* Returns CASL in r3 */
+
+       /* Calc trp_clocks = (trp * 100 + (clk - 1)) / clk */
+       /* (trp read from byte 27 in granularity of 1 ns) */
+       /*------------------------------------------------ */
+       mulli   r16, r16, 100
+       add     r16, r16, r30
+       addi    r6, 0, 1
+       subf    r16, r6, r16
+       divwu   r16, r16, r30
+
+       /* Calc trcd_clocks = (trcd * 100 + (clk - 1) ) / clk */
+       /* (trcd read from byte 29 in granularity of 1 ns) */
+       /*--------------------------------------------------- */
+       mulli   r17, r17, 100
+       add     r17, r17, r30
+       addi    r6, 0, 1
+       subf    r17, r6, r17
+       divwu   r17, r17, r30
+
+       /* Calc tras_clocks = (tras * 100 + (clk - 1) ) / clk */
+       /* (tras read from byte 30 in granularity of 1 ns) */
+       /*--------------------------------------------------- */
+       mulli   r18, r18, 100
+       add     r18, r18, r30
+       addi    r6, 0, 1
+       subf    r18, r6, r18
+       divwu   r18, r18, r30
+
+       /* Calc trc_clocks = trp_clocks + tras_clocks */
+       /*------------------------------------------- */
+       add     r18, r18, r16
+
+       /* CASL value */
+       /*----------- */
+       addi    r9, 0, 23
+       slw     r4, r3, r9
+
+       /* PTA = trp_clocks - 1 */
+       /*--------------------- */
+       addi    r6, 0, 1
+       subf    r5, r6, r16
+       addi    r9, 0, 18
+       slw     r5, r5, r9
+       or      r4, r4, r5
+
+       /* CTP = trc_clocks - trp_clocks - trcd_clocks - 1 */
+       /*------------------------------------------------ */
+       addi    r5, r18, 0
+       subf    r5, r16, r5
+       subf    r5, r17, r5
+       addi    r6, 0, 1
+       subf    r5, r6, r5
+       addi    r9, 0, 16
+       slw     r5, r5, r9
+       or      r4, r4, r5
+
+       /* LDF = 1 */
+       /*-------- */
+       ori     r4, r4, 0x4000
+
+       /* RFTA = trc_clocks - 4 */
+       /*---------------------- */
+       addi    r6, 0, 4
+       subf    r5, r6, r18
+       addi    r9, 0, 2
+       slw     r5, r5, r9
+       or      r4, r4, r5
+
+       /* RCD = trcd_clocks - 1 */
+       /*---------------------- */
+       addi    r6, 0, 1
+       subf    r5, r6, r17
+       or      r4, r4, r5
+
+        /*----------------------------------------------------------- */
+        /* Set SDTR1  */
+        /*----------------------------------------------------------- */
+        addi    r5,0,mem_sdtr1
+        mtdcr   memcfga,r5
+        mtdcr   memcfgd,r4
+
+       /*----------------------------------------------------------- */
+       /* */
+       /* */
+       /* Update memory bank 0-3 configuration registers */
+       /* */
+       /* */
+       /*----------------------------------------------------------- */
+
+       /* Build contents of configuration register for bank 0 into r6 */
+       /*------------------------------------------------------------ */
+       bl      find_mode       /* returns addressing mode in r3 */
+       addi    r29, r3, 0      /* save mode temporarily in r29 */
+       bl      find_size_code  /* returns size code in r3 */
+       addi    r9, 0, 17       /* bit offset of size code in configuration register */
+       slw     r3, r3, r9      /* */
+       addi    r9, 0, 13       /* bit offset of addressing mode in configuration register  */
+       slw     r29, r29, r9    /*  */
+       or      r3, r29, r3     /* merge size code and addressing mode */
+       ori     r6, r3, CFG_SDRAM_BASE + 1 /* insert base address and enable bank */
+
+       /* Calculate banksize r15 = (density << 22) / 2 */
+       /*--------------------------------------------- */
+       addi    r9, 0, 21
+       slw     r15, r15, r9
+
+       /* Set SDRAM bank 0 register and adjust r6 for next bank */
+       /*------------------------------------------------------ */
+       addi    r7,0,mem_mb0cf
+       mtdcr   memcfga,r7
+       mtdcr   memcfgd,r6
+
+       add     r6, r6, r15     /* add bank size to base address for next bank */
+
+       /* If two rows/banks then set SDRAM bank 1 register and adjust r6 for next bank */
+       /*---------------------------------------------------------------------------- */
+       cmpi    0, r12, 2
+       bne     b1skip
+
+       addi    r7,0,mem_mb1cf
+       mtdcr   memcfga,r7
+       mtdcr   memcfgd,r6
+
+       add     r6, r6, r15     /* add bank size to base address for next bank */
+
+       /* Set SDRAM bank 2 register and adjust r6 for next bank */
+       /*------------------------------------------------------ */
+b1skip:        addi    r7,0,mem_mb2cf
+       mtdcr   memcfga,r7
+       mtdcr   memcfgd,r6
+
+       add     r6, r6, r15     /* add bank size to base address for next bank */
+
+       /* If two rows/banks then set SDRAM bank 3 register */
+       /*------------------------------------------------ */
+       cmpi    0, r12, 2
+       bne     b3skip
+
+       addi    r7,0,mem_mb3cf
+       mtdcr   memcfga,r7
+       mtdcr   memcfgd,r6
+b3skip:        
+
+        /*----------------------------------------------------------- */
+        /* Set RTR */
+        /*----------------------------------------------------------- */
+       cmpi    0, r30, 1600
+       bge     rtr_1
+        addis   r7, 0, 0x05F0  /* RTR value for 100Mhz */
+       bl      rtr_2
+rtr_1: addis   r7, 0, 0x03F8
+rtr_2: addi    r4,0,mem_rtr
+       mtdcr   memcfga,r4
+       mtdcr   memcfgd,r7
+
+        /*----------------------------------------------------------- */
+        /* Delay to ensure 200usec have elapsed since reset. Assume worst */
+        /* case that the core is running 200Mhz: */
+        /*   200,000,000 (cycles/sec) X .000200 (sec) = 0x9C40 cycles */
+        /*----------------------------------------------------------- */
+        addis   r3,0,0x0000
+        ori     r3,r3,0xA000          /* ensure 200usec have passed since reset */
+        mtctr   r3
+..spinlp2:
+        bdnz    ..spinlp2               /* spin loop */
+
+        /*----------------------------------------------------------- */
+        /* Set memory controller options reg, MCOPT1. */
+       /* Set DC_EN to '1' and BRD_PRF to '01' for 16 byte PLB Burst  */
+       /* read/prefetch. */
+        /*----------------------------------------------------------- */
+       addi    r4,0,mem_mcopt1
+       mtdcr   memcfga,r4
+       addis   r4,0,0x80C0             /* set DC_EN=1 */
+       ori     r4,r4,0x0000
+       mtdcr   memcfgd,r4
+
+
+        /*----------------------------------------------------------- */
+        /* Delay to ensure 10msec have elapsed since reset. This is */
+        /* required for the MPC952 to stabalize. Assume worst */
+        /* case that the core is running 200Mhz: */
+        /*   200,000,000 (cycles/sec) X .010 (sec) = 0x1E8480 cycles */
+        /* This delay should occur before accessing SDRAM. */
+        /*----------------------------------------------------------- */
+       addis   r3,0,0x001E
+       ori     r3,r3,0x8480          /* ensure 10msec have passed since reset */
+       mtctr   r3
+..spinlp3:
+       bdnz    ..spinlp3                /* spin loop */
+
+       /* output SDRAM code  on LEDs */
+       addi    r4, 0, LED_SDRAM_CODE_16
+       addis   r5, 0, 0x1000
+       ori     r5, r5, 0x0001
+       stb     r4,0(r5)
+       eieio
+
+        mtlr    r31                     /* restore lr */
+        blr
+
+/*--------------------------------------------------------------------- */
+/* Function:    read_spd */
+/* Description: Reads contents of SPD and saves parameters to be used for */
+/*             configuration in dedicated registers (see code below). */
+/*---------------------------------------------------------------------         */
+
+#define WRITE_I2C(reg,val) \
+       addi    r3,0,val;\
+        addis   r4, 0, 0xef60;\
+        ori     r4, r4, 0x0500 + reg;\
+        stb     r3, 0(r4);\
+        eieio
+
+#define READ_I2C(reg) \
+        addis   r3, 0, 0xef60;\
+        ori     r3, r3, 0x0500 + reg;\
+        lbz     r3, 0x0000(r3);\
+        eieio
+
+read_spd:
+
+       mflr    r5
+       
+       /* Initialize i2c */
+       /*--------------- */
+       WRITE_I2C(IICLMADR, 0x00)       /* clear lo master address */
+       WRITE_I2C(IICHMADR, 0x00)       /* clear hi master address */
+       WRITE_I2C(IICLSADR, 0x00)       /* clear lo slave address */
+       WRITE_I2C(IICHSADR, 0x00)       /* clear hi slave address */
+       WRITE_I2C(IICSTS, 0x08)         /* update status register */
+       WRITE_I2C(IICEXTSTS, 0x8f)
+       WRITE_I2C(IICCLKDIV, 0x05)
+       WRITE_I2C(IICINTRMSK, 0x00)     /* no interrupts */
+       WRITE_I2C(IICXFRCNT, 0x00)      /* clear transfer count */
+       WRITE_I2C(IICXTCNTLSS, 0xf0)    /* clear extended control & stat */
+       WRITE_I2C(IICMDCNTL, IIC_MDCNTL_FSDB | IIC_MDCNTL_FMDB) /* mode control */
+       READ_I2C(IICMDCNTL)
+       ori     r3, r3, IIC_MDCNTL_EUBS | IIC_MDCNTL_HSCL
+       WRITE_I2C(IICMDCNTL, r3)        /* mode control */
+       WRITE_I2C(IICCNTL, 0x00)        /* clear control reg */
+
+       /* Wait until initialization completed */
+       /*------------------------------------ */
+       bl      wait_i2c_transfer_done
+
+       WRITE_I2C(IICHMADR, 0x00)       /* 7-bit addressing */
+       WRITE_I2C(IICLMADR, SDRAM_SPD_WRITE_ADDRESS)
+
+       /* Write 0 into buffer(start address) */
+       /*----------------------------------- */
+       WRITE_I2C(IICMDBUF, 0x00);
+
+       /* Wait a little */
+       /*-------------- */
+        addis   r3,0,0x0000
+        ori     r3,r3,0xA000
+        mtctr   r3
+in02:  bdnz    in02
+
+       /* Issue write command */
+       /*-------------------- */
+       WRITE_I2C(IICCNTL, IIC_CNTL_PT)
+       bl      wait_i2c_transfer_done
+
+       /* Read 128 bytes */
+       /*--------------- */
+       addi    r7, 0, 0        /* byte counter in r7 */
+       addi    r8, 0, 0        /* checksum in r8 */
+rdlp:  
+       /* issue read command */
+       /*------------------- */
+       cmpi    0, r7, 127
+       blt     rd01
+       WRITE_I2C(IICCNTL, IIC_CNTL_READ | IIC_CNTL_PT) 
+       bl      rd02
+rd01:  WRITE_I2C(IICCNTL, IIC_CNTL_READ | IIC_CNTL_CHT | IIC_CNTL_PT)
+rd02:  bl      wait_i2c_transfer_done
+
+       /* Fetch byte from buffer */
+       /*----------------------- */
+       READ_I2C(IICMDBUF)
+       
+       /* Retrieve parameters that are going to be used during configuration. */
+       /* Save them in dedicated registers. */
+       /*------------------------------------------------------------ */
+       cmpi    0, r7, 3        /* Save byte 3 in r10 */
+       bne     rd10
+       addi    r10, r3, 0      
+rd10:  cmpi    0, r7, 4        /* Save byte 4 in r11 */
+       bne     rd11
+       addi    r11, r3, 0      
+rd11:  cmpi    0, r7, 5        /* Save byte 5 in r12 */
+       bne     rd12
+       addi    r12, r3, 0      
+rd12:  cmpi    0, r7, 17       /* Save byte 17 in r13 */
+       bne     rd13
+       addi    r13, r3, 0      
+rd13:  cmpi    0, r7, 18       /* Save byte 18 in r14 */
+       bne     rd14
+       addi    r14, r3, 0      
+rd14:  cmpi    0, r7, 31       /* Save byte 31 in r15 */
+       bne     rd15
+       addi    r15, r3, 0      
+rd15:  cmpi    0, r7, 27       /* Save byte 27 in r16 */
+       bne     rd16
+       addi    r16, r3, 0      
+rd16:  cmpi    0, r7, 29       /* Save byte 29 in r17 */
+       bne     rd17
+       addi    r17, r3, 0      
+rd17:  cmpi    0, r7, 30       /* Save byte 30 in r18 */
+       bne     rd18
+       addi    r18, r3, 0      
+rd18:  cmpi    0, r7, 9        /* Save byte 9 in r19 */
+       bne     rd19
+       addi    r19, r3, 0      
+rd19:  cmpi    0, r7, 23       /* Save byte 23 in r20 */
+       bne     rd20
+       addi    r20, r3, 0      
+rd20:  cmpi    0, r7, 25       /* Save byte 25 in r21 */
+       bne     rd21
+       addi    r21, r3, 0      
+rd21:
+
+       /* Calculate checksum of the first 63 bytes */
+       /*----------------------------------------- */
+       cmpi    0, r7, 63
+       bgt     rd31
+       beq     rd30
+       add     r8, r8, r3
+       bl      rd31
+
+       /* Verify checksum at byte 63 */
+       /*--------------------------- */
+rd30:  andi.   r8, r8, 0xff            /* use only 8 bits */
+       cmp     0, r8, r3
+       beq     rd31
+       addi    r4, 0, LED_SDRAM_CODE_8
+       addis   r5, 0, 0x1000
+       ori     r5, r5, 0x0001
+       stb     r4,0(r5)
+       eieio
+rderr: bl      rderr
+
+rd31:  
+       
+       /* Increment byte counter and check whether all bytes have been read. */
+       /*------------------------------------------------------------------- */
+       addi    r7, r7, 1
+       cmpi    0, r7, 127
+       bgt     rd05
+       bl      rdlp
+rd05:  
+        mtlr    r5                     /* restore lr */
+       blr
+
+wait_i2c_transfer_done:
+       mflr    r6
+wt01:  READ_I2C(IICSTS)
+       andi.   r4, r3, IIC_STS_PT
+       cmpi    0, r4, IIC_STS_PT
+       beq     wt01    
+        mtlr    r6                     /* restore lr */
+       blr
+
+/*--------------------------------------------------------------------- */
+/* Function:    find_mode */
+/* Description: Determines addressing mode to be used dependent on   */
+/*             number of rows (r10 = byte 3 from SPD), number of columns (r11 = */
+/*             byte 4 from SPD) and number of banks (r13 = byte 17 from SPD). */
+/*             mode is returned in r3. */
+/* (It would be nicer having a table, pnc). */
+/*---------------------------------------------------------------------         */
+find_mode:
+
+       mflr    r5
+
+       cmpi    0, r10, 11
+       bne     fm01
+       cmpi    0, r11, 9
+       bne     fm01
+       cmpi    0, r13, 2
+       bne     fm01
+       addi    r3, 0, 1
+       bl      fmfound
+
+fm01:  cmpi    0, r10, 11
+       bne     fm02
+       cmpi    0, r11, 10
+       bne     fm02
+       cmpi    0, r13, 2
+       bne     fm02
+       addi    r3, 0, 1
+       bl      fmfound 
+
+fm02:  cmpi    0, r10, 12
+       bne     fm03
+       cmpi    0, r11, 9
+       bne     fm03
+       cmpi    0, r13, 4
+       bne     fm03
+       addi    r3, 0, 2
+       bl      fmfound
+
+fm03:  cmpi    0, r10, 12
+       bne     fm04
+       cmpi    0, r11, 10
+       bne     fm04
+       cmpi    0, r13, 4
+       bne     fm04
+       addi    r3, 0, 2
+       bl      fmfound
+
+fm04:  cmpi    0, r10, 13
+       bne     fm05
+       cmpi    0, r11, 9
+       bne     fm05
+       cmpi    0, r13, 4
+       bne     fm05
+       addi    r3, 0, 3
+       bl      fmfound
+
+fm05:  cmpi    0, r10, 13
+       bne     fm06
+       cmpi    0, r11, 10
+       bne     fm06
+       cmpi    0, r13, 4
+       bne     fm06
+       addi    r3, 0, 3
+       bl      fmfound
+
+fm06:  cmpi    0, r10, 13
+       bne     fm07
+       cmpi    0, r11, 11
+       bne     fm07
+       cmpi    0, r13, 4
+       bne     fm07
+       addi    r3, 0, 3
+       bl      fmfound
+
+fm07:  cmpi    0, r10, 12
+       bne     fm08
+       cmpi    0, r11, 8
+       bne     fm08
+       cmpi    0, r13, 2
+       bne     fm08
+       addi    r3, 0, 4
+       bl      fmfound
+
+fm08:  cmpi    0, r10, 12
+       bne     fm09
+       cmpi    0, r11, 8
+       bne     fm09
+       cmpi    0, r13, 4
+       bne     fm09
+       addi    r3, 0, 4
+       bl      fmfound
+
+fm09:  cmpi    0, r10, 11
+       bne     fm10
+       cmpi    0, r11, 8
+       bne     fm10
+       cmpi    0, r13, 2
+       bne     fm10
+       addi    r3, 0, 5
+       bl      fmfound
+
+fm10:  cmpi    0, r10, 11
+       bne     fm11
+       cmpi    0, r11, 8
+       bne     fm11
+       cmpi    0, r13, 4
+       bne     fm11
+       addi    r3, 0, 5
+       bl      fmfound
+
+fm11:  cmpi    0, r10, 13
+       bne     fm12
+       cmpi    0, r11, 8
+       bne     fm12
+       cmpi    0, r13, 2
+       bne     fm12
+       addi    r3, 0, 6
+       bl      fmfound
+
+fm12:  cmpi    0, r10, 13
+       bne     fm13
+       cmpi    0, r11, 8
+       bne     fm13
+       cmpi    0, r13, 4
+       bne     fm13
+       addi    r3, 0, 6
+       bl      fmfound
+
+fm13:  cmpi    0, r10, 13
+       bne     fm14
+       cmpi    0, r11, 9
+       bne     fm14
+       cmpi    0, r13, 2
+       bne     fm14
+       addi    r3, 0, 7
+       bl      fmfound
+
+fm14:  cmpi    0, r10, 13
+       bne     fm15
+       cmpi    0, r11, 10
+       bne     fm15
+       cmpi    0, r13, 2
+       bne     fm15
+       addi    r3, 0, 7
+       bl      fmfound
+
+fm15:  
+       /* not found, error code to be issued on LEDs */
+       addi    r7, 0, LED_SDRAM_CODE_2
+       addis   r6, 0, 0x1000
+       ori     r6, r6, 0x0001
+       stb     r7,0(r6)
+       eieio
+fmerr: bl      fmerr
+
+fmfound:addi   r6, 0, 1
+       subf    r3, r6, r3
+
+        mtlr    r5                     /* restore lr */
+       blr
+
+/*--------------------------------------------------------------------- */
+/* Function:    find_size_code */
+/* Description: Determines size code to be used in configuring SDRAM controller */
+/*             dependent on density (r15 = byte 31 from SPD) */
+/*--------------------------------------------------------------------- */
+find_size_code:
+
+       mflr    r5
+       
+       addi    r3, r15, 0      /* density */
+       addi    r7, 0, 0
+fs01:  andi.   r6, r3, 0x01
+       cmpi    0, r6, 1
+       beq     fs04
+       
+       addi    r7, r7, 1
+       cmpi    0, r7, 7
+       bge     fs02
+       addi    r9, 0, 1
+       srw     r3, r3, r9
+       bl      fs01
+
+       /* not found, error code to be issued on LEDs */
+fs02:  addi    r4, 0, LED_SDRAM_CODE_3
+       addis   r8, 0, 0x1000
+       ori     r8, r8, 0x0001
+       stb     r4,0(r8)
+       eieio
+fs03:  bl      fs03
+
+fs04:  addi    r3, r7, 0
+       cmpi    0, r3, 0
+       beq     fs05
+       addi    r6, 0, 1
+       subf    r3, r6, r3
+fs05:
+        mtlr    r5                     /* restore lr */
+       blr
+
+/*--------------------------------------------------------------------- */
+/* Function:    find_casl */
+/* Description: Determines CAS latency */
+/*--------------------------------------------------------------------- */
+find_casl:
+
+       mflr    r5
+
+       andi.   r14, r14, 0x7f  /* r14 holds supported CAS latencies */
+       addi    r3, 0, 0xff     /* preset determined CASL */
+       addi    r4, 0, 6        /* Start at bit 6 of supported CAS latencies */
+       addi    r2, 0, 0        /* Start finding highest CAS latency */
+
+fc01:  srw     r6, r14, r4     /*  */
+       andi.   r6, r6, 0x01    /*  */
+       cmpi    0, r6, 1        /* Check bit for current latency */
+       bne     fc06            /* If not supported, go to next */
+
+       cmpi    0, r2, 2        /* Check if third-highest latency */
+       bge     fc04            /* If so, go calculate with another format */
+
+       cmpi    0, r2, 0        /* Check if highest latency */
+       bgt     fc02            /* */
+       addi    r7, r19, 0      /* SDRAM cycle time for highest CAS latenty */
+
+       bl      fc03
+fc02:  
+       addi    r7, r20, 0      /* SDRAM cycle time for next-highest CAS latenty */
+fc03:  
+       addi    r8, r7, 0
+       addi    r9, 0, 4
+       srw     r7, r7, r9
+       andi.   r7, r7, 0x0f
+       mulli   r7, r7, 100
+       andi.   r8, r8, 0x0f
+       mulli   r8, r8, 10
+       add     r7, r7, r8
+       cmp     0, r7, r30
+       bgt     fc05
+       addi    r3, r2, 0
+       bl      fc05
+fc04:  
+       addi    r7, r21, 0      /* SDRAM cycle time for third-highest CAS latenty */
+       addi    r8, r7, 0
+       addi    r9, 0, 2
+       srw     r7, r7, r9
+       andi.   r7, r7, 0x3f
+       mulli   r7, r7, 100
+       andi.   r8, r8, 0x03
+       mulli   r8, r8, 25
+       add     r7, r7, r8
+
+       cmp     0, r7, r30
+       bgt     fc05
+       addi    r3, r2, 0
+
+fc05:  addi    r2, r2, 1       /* next latency */
+       cmpi    0, r2, 3
+       bge     fc07
+fc06:  addi    r6, 0, 1
+       subf    r4, r6, r4
+       cmpi    0, r4, 0
+       bne     fc01
+
+fc07:  
+
+        mtlr    r5             /* restore lr */
+       blr
+#endif
+
+
+/*  Peripheral Bank 1 Access Parameters */
+/*     0       BME = 1 ; burstmode enabled */
+/*    " 1:8"   TWT=00110110    ;Transfer wait (details below) */
+/*     1:5     FWT=00110       ; first wait = 6 cycles */
+/*     6:8     BWT=110 ; burst wait = 6 cycles */
+/*     9:11    000     ; reserved */
+/*     12:13   CSN=00  ; chip select on timing = 0 */
+/*     14:15   OEN=01  ; output enable  */
+/*     16:17   WBN=01  ; write byte enable on timing 1 cycle */
+/*     18:19   WBF=01  ; write byte enable off timing 1 cycle */
+/*     20:22   TH=010  ; transfer hold = 2 cycles */
+/*     23      RE=0    ; ready enable = disabled */
+/*     24      SOR=1   ; sample on ready = same PerClk */
+/*     25      BEM=0   ; byte enable mode = only for write cycles */
+/*     26      PEN=0   ; parity enable = disable */
+/*     27:31   00000   ;reserved */
+/* */
+/* 1 + 00110 + 110 + 000 + 00 + 01 + 01 + 01 + 010 + 0 + 1 + 0 + 0 + 00000 = 0x9b015480 */
+/* */
+/* */
+/*     Code for BDI probe: */
+/* */
+/* WDCR    18      0x00000011      ;Select PB1AP */
+/* WDCR    19      0x1b015480      ;PB1AP: Flash */
+/* */
+/* Peripheral Bank 0 Access Parameters */
+/* 0:11        BAS=0x200       ; base address select = 0x200 * 0x100000 (1MB) =  */
+/* 12:14       BS=100  ; bank size =  16MB (100) / 32MB (101) */
+/* 15:16       BU=11   ; bank usage = read/write */
+/* 17:18       BW=00   ; bus width = 8-bit */
+/* 19:31               ; reserved */
+/* */
+/* 0x200 + 100 + 11 + 00 + 0 0000 0000 0000 = 0x20098000 */
+/* WDCR    18      0x00000001      ;Select PB1CR */
+/* WDCR    19      0x20098000      ;PB1CR: 1MB at 0x00100000, r/w, 8bit */
+
+/* For CPLD */
+/* 0 + 00000 + 010 + 000 + 00 + 01 + 00 + 00 + 000 + 0 + 0 + 1 + 0 + 00000 */
+/*     WDCR_EBC(pb5ap, 0x01010040) */
+/*jsa recommendation:          WDCR_EBC(pb5ap, 0x00010040) */
+/*     WDCR_EBC(pb5cr, 0X10018000) */
+/* Access parms */
+/*   100   3      8          0    0    0 */
+/* 0x100 + 001 + 11 + 00 + 0 0000 0000 0000 = 0x10038000 */
+/* Address :   0x10000000 */
+/* Size:       2 MB */
+/* Usage:      read/write */
+/* Width:      32 bit */
+
+/* For Genie onboard fpga 32 bit interface */
+/* 0      1      0         1         0         0         0            0 */
+/* 0 + 00000 + 010 + 000 + 00 + 01 + 00 + 00 + 000 + 0 + 0 + 0 + 0 + 00000 */
+/* 0x01010000 */
+/* Access parms */
+/*   102   1      c          0    0    0 */
+/* 0x102 + 000 + 11 + 10 + 0 0000 0000 0000 = 0x1021c000 */
+/* Address :   0x10200000 */
+/* Size:       2 MB */
+/* Usage:      read/write */
+/* Width:      32 bit */
+       
+/* Walnut fpga pb7ap */
+/* 0      1      8         1         5         2         8            0 */
+/* 0 + 00000 + 011 + 000 + 00 + 01 + 01 + 01 + 001 + 0 + 1 + 0 + 0 + 00000 */
+/* Walnut fpga pb7cr */
+/* 0xF0318000 */
+/*  */
diff --git a/board/exbitgen/u-boot.lds b/board/exbitgen/u-boot.lds
new file mode 100644 (file)
index 0000000..863a7e4
--- /dev/null
@@ -0,0 +1,144 @@
+/*
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+OUTPUT_ARCH(powerpc)
+SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
+/* Do we need any of these for elf?
+   __DYNAMIC = 0;    */
+SECTIONS
+{
+  .resetvec 0xFFFFFFFC :
+  {
+    *(.resetvec)
+  } = 0xffff
+
+  /* Read-only sections, merged into text segment: */
+  . = + SIZEOF_HEADERS;
+  .interp : { *(.interp) }
+  .hash          : { *(.hash)          }
+  .dynsym        : { *(.dynsym)                }
+  .dynstr        : { *(.dynstr)                }
+  .rel.text      : { *(.rel.text)              }
+  .rela.text     : { *(.rela.text)     }
+  .rel.data      : { *(.rel.data)              }
+  .rela.data     : { *(.rela.data)     }
+  .rel.rodata    : { *(.rel.rodata)    }
+  .rela.rodata   : { *(.rela.rodata)   }
+  .rel.got       : { *(.rel.got)               }
+  .rela.got      : { *(.rela.got)              }
+  .rel.ctors     : { *(.rel.ctors)     }
+  .rela.ctors    : { *(.rela.ctors)    }
+  .rel.dtors     : { *(.rel.dtors)     }
+  .rela.dtors    : { *(.rela.dtors)    }
+  .rel.bss       : { *(.rel.bss)               }
+  .rela.bss      : { *(.rela.bss)              }
+  .rel.plt       : { *(.rel.plt)               }
+  .rela.plt      : { *(.rela.plt)              }
+  .init          : { *(.init)  }
+  .plt : { *(.plt) }
+  .text      :
+  {
+    /* WARNING - the following is hand-optimized to fit within */
+    /* the sector layout of our flash chips!   XXX FIXME XXX   */
+
+    cpu/ppc4xx/start.o (.text)
+    board/exbitgen/init.o      (.text)
+    cpu/ppc4xx/kgdb.o  (.text)
+    cpu/ppc4xx/traps.o (.text)
+    cpu/ppc4xx/interrupts.o    (.text)
+    cpu/ppc4xx/serial.o        (.text)
+    cpu/ppc4xx/cpu_init.o      (.text)
+    cpu/ppc4xx/speed.o (.text)
+    common/dlmalloc.o  (.text)
+    lib_generic/crc32.o                (.text)
+    lib_ppc/extable.o  (.text)
+    lib_generic/zlib.o         (.text)
+
+/*    . = env_offset;*/
+    common/environment.o(.text)
+
+    *(.text)
+    *(.fixup)
+    *(.got1)
+  }
+  _etext = .;
+  PROVIDE (etext = .);
+  .rodata    :
+  {
+    *(.rodata)
+    *(.rodata1)
+  }
+  .fini      : { *(.fini)    } =0
+  .ctors     : { *(.ctors)   }
+  .dtors     : { *(.dtors)   }
+
+  /* Read-write section, merged into data segment: */
+  . = (. + 0x00FF) & 0xFFFFFF00;
+  _erotext = .;
+  PROVIDE (erotext = .);
+  .reloc   :
+  {
+    *(.got) 
+    _GOT2_TABLE_ = .;
+    *(.got2)
+    _FIXUP_TABLE_ = .;
+    *(.fixup)
+  }
+  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+  __fixup_entries = (. - _FIXUP_TABLE_)>>2;
+
+  .data    :
+  {
+    *(.data)
+    *(.data1)
+    *(.sdata)
+    *(.sdata2)
+    *(.dynamic)
+    CONSTRUCTORS
+  }
+  _edata  =  .;
+  PROVIDE (edata = .);
+
+  __start___ex_table = .;
+  __ex_table : { *(__ex_table) }
+  __stop___ex_table = .;
+
+  . = ALIGN(256);
+  __init_begin = .;
+  .text.init : { *(.text.init) }
+  .data.init : { *(.data.init) }
+  . = ALIGN(256);
+  __init_end = .;
+
+  __bss_start = .;
+  .bss       :
+  {
+   *(.sbss) *(.scommon)
+   *(.dynbss)
+  . = ALIGN(4);
+   *(.bss)
+   *(COMMON)
+  }
+  _end = . ;
+  PROVIDE (end = .);
+}
diff --git a/include/configs/EXBITGEN.h b/include/configs/EXBITGEN.h
new file mode 100644 (file)
index 0000000..f1ffcb3
--- /dev/null
@@ -0,0 +1,213 @@
+/*
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * board/config.h - configuration options, board specific
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/*
+ * High Level Configuration Options
+ * (easy to change)
+ */
+
+#define CONFIG_405GP           1       /* This is a PPC405GP CPU       */
+#define CONFIG_4xx             1       /* ...member of PPC4xx family   */
+#define CONFIG_EXBITGEN                1       /* on a Exbit Generic board     */
+
+#define CONFIG_BOARD_PRE_INIT  1       /* Call board_pre_init          */
+
+#define CONFIG_SYS_CLK_FREQ     25000000 /* external frequency to pll   */
+
+/* I2C configuration */
+#define CONFIG_HARD_I2C                1       /* I2C with hardware support    */
+#define CFG_I2C_SPEED          40000   /* I2C speed                    */
+#define CFG_I2C_SLAVE          0x7F    /* I2C slave address            */
+
+/* environment is in EEPROM */
+#define CFG_ENV_IS_IN_EEPROM    1
+#undef CFG_ENV_IS_IN_FLASH
+#undef CFG_ENV_IS_IN_NVRAM
+
+#ifdef CFG_ENV_IS_IN_EEPROM
+#define CFG_I2C_EEPROM_ADDR            0x56    /* 1010110 */
+#define CFG_I2C_EEPROM_ADDR_LEN                1       /* 8-bit internal addressing */
+#define CFG_I2C_EEPROM_ADDR_OVERFLOW   1       /* ... and 1 bit in I2C address */
+#define CFG_EEPROM_PAGE_WRITE_BITS     3       /* 4 bytes per page */
+#define CFG_EEPROM_PAGE_WRITE_DELAY_MS 40      /* write takes up to 40 msec */
+#define CFG_ENV_OFFSET         4       /* Offset of Environment Sector */
+#define        CFG_ENV_SIZE            350     /* that is 350 bytes only!      */
+#endif
+
+#define CONFIG_BOOTDELAY       10      /* autoboot after 10 seconds    */
+/* Explanation:
+   autbooting is altogether disabled and cannot be
+   enabled if CONFIG_BOOTDELAY is negative.
+   If you want shorter bootdelay, then 
+   - "setenv bootdelay <delay>" to the proper value
+*/
+
+#define CONFIG_BOOTCOMMAND     "bootm 20400000 20800000"
+
+#define CONFIG_BOOTARGS                "root=/dev/ram "  \
+                               "ramdisk_size=32768 " \
+                               "console=ttyS0,115200 " \
+                               "ram=128M debug"
+
+#define CONFIG_LOADS_ECHO      1       /* echo on for serial download  */
+#define CFG_LOADS_BAUD_CHANGE  1       /* allow baudrate change        */
+
+#define CONFIG_MII             1       /* MII PHY management           */
+#define CONFIG_PHY_ADDR                0       /* PHY address                  */
+
+#define CONFIG_COMMANDS                (CONFIG_CMD_DFL)
+
+/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
+#include <cmd_confdefs.h>
+
+#undef CONFIG_WATCHDOG                 /* watchdog disabled            */
+
+/*
+ * Miscellaneous configurable options
+ */
+#define CFG_LONGHELP                   /* undef to save memory         */
+#define CFG_PROMPT     "=> "           /* Monitor Command Prompt       */
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#define        CFG_CBSIZE      1024            /* Console I/O Buffer Size      */
+#else
+#define        CFG_CBSIZE      256             /* Console I/O Buffer Size      */
+#endif
+#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */
+#define CFG_MAXARGS    16              /* max number of command args   */
+#define CFG_BARGSIZE   CFG_CBSIZE      /* Boot Argument Buffer Size    */
+
+#define CFG_MEMTEST_START      0x0400000       /* memtest works on     */
+#define CFG_MEMTEST_END                0x0C00000       /* 4 ... 12 MB in DRAM  */
+
+/* UART configuration */
+#define CFG_BASE_BAUD          691200
+
+/* Default baud rate */
+#define CONFIG_BAUDRATE                115200
+       
+/* The following table includes the supported baudrates */
+#define CFG_BAUDRATE_TABLE      \
+        { 300, 600, 1200, 2400, 4800, 9600, 19200, 38400,     \
+         57600, 115200, 230400, 460800, 921600 }
+
+#define CFG_CLKS_IN_HZ         1       /* everything, incl board info, in Hz */
+
+#define CFG_LOAD_ADDR          0x100000        /* default load address */
+#define CFG_EXTBDINFO          1       /* To use extended board_into (bd_t) */
+
+#define        CFG_HZ                  1000    /* decrementer freq: 1 ms ticks */
+
+/*-----------------------------------------------------------------------
+ * PCI stuff
+ *-----------------------------------------------------------------------
+ */
+#undef CONFIG_PCI                      /* no pci support               */
+
+/*-----------------------------------------------------------------------
+ * External peripheral base address
+ *-----------------------------------------------------------------------
+ */
+#undef  CONFIG_IDE_PCMCIA               /* no pcmcia interface required */
+#undef  CONFIG_IDE_LED                  /* no led for ide supported     */
+#undef  CONFIG_IDE_RESET                /* no reset for ide supported   */
+
+#define        CFG_KEY_REG_BASE_ADDR   0xF0100000
+#define        CFG_IR_REG_BASE_ADDR    0xF0200000
+#define        CFG_FPGA_REG_BASE_ADDR  0xF0300000
+
+/*-----------------------------------------------------------------------
+ * Start addresses for the final memory configuration
+ * (Set up by the startup code)
+ * Please note that CFG_SDRAM_BASE _must_ start at 0
+ */
+#define CFG_SDRAM_BASE         0x00000000
+#define CFG_FLASH0_BASE                0xFFF80000
+#define CFG_FLASH0_SIZE                0x00080000
+#define CFG_FLASH1_BASE                0x20000000
+#define CFG_FLASH1_SIZE                0x02000000
+#define CFG_FLASH_BASE         CFG_FLASH0_BASE
+#define CFG_FLASH_SIZE         CFG_FLASH0_SIZE
+#define CFG_MONITOR_BASE       TEXT_BASE
+#define CFG_MONITOR_LEN                (192 * 1024)    /* Reserve 196 kB for Monitor   */
+#define CFG_MALLOC_LEN         (128 * 1024)    /* Reserve 128 kB for malloc()  */
+
+#if CFG_MONITOR_BASE < CFG_FLASH0_BASE
+#define CFG_RAMSTART
+#endif
+
+/*
+ * For booting Linux, the board info and command line data
+ * have to be in the first 8 MB of memory, since this is
+ * the maximum mapped by the Linux kernel during initialization.
+ */
+#define CFG_BOOTMAPSZ          (8 << 20)       /* Initial Memory map for Linux */
+/*-----------------------------------------------------------------------
+ * FLASH organization
+ */
+#define CFG_MAX_FLASH_BANKS    5       /* max number of memory banks           */
+#define CFG_MAX_FLASH_SECT     128     /* max number of sectors on one chip    */
+
+#define CFG_FLASH_ERASE_TOUT   120000  /* Timeout for Flash Erase (in ms)      */
+#define CFG_FLASH_WRITE_TOUT   500     /* Timeout for Flash Write (in ms)      */
+
+#ifdef CFG_ENV_IS_IN_FLASH 
+#define CFG_ENV_OFFSET         0x00060000 /* Offset of Environment Sector      */
+#define        CFG_ENV_SIZE            0x00010000 /* Total Size of Environment Sector  */
+#define CFG_ENV_SECT_SIZE      0x00010000 /* see README - env sector total size */
+#endif
+
+/* On Chip Memory location/size */
+#define CFG_OCM_DATA_ADDR      0xF8000000
+#define CFG_OCM_DATA_SIZE      0x1000
+
+/* Global info and initial stack */
+#define CFG_INIT_RAM_ADDR      CFG_OCM_DATA_ADDR /* inside of on-chip SRAM     */
+#define CFG_INIT_RAM_END       CFG_OCM_DATA_SIZE /* End of used area in RAM    */
+#define CFG_GBL_DATA_SIZE      128 /* size in bytes reserved for initial data */
+#define CFG_GBL_DATA_OFFSET    (CFG_INIT_RAM_END - CFG_GBL_DATA_SIZE)
+#define CFG_INIT_SP_OFFSET     CFG_GBL_DATA_OFFSET
+
+/* Cache configuration */
+#define CFG_DCACHE_SIZE                8192
+#define CFG_CACHELINE_SIZE     32
+
+/*
+ * Internal Definitions
+ *
+ * Boot Flags
+ */
+#define BOOTFLAG_COLD  0x01            /* Normal Power-On: Boot from FLASH     */
+#define BOOTFLAG_WARM  0x02            /* Software reboot                      */
+
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#define CONFIG_KGDB_BAUDRATE   230400  /* speed to run kgdb serial port */
+#define CONFIG_KGDB_SER_INDEX  2       /* which serial port to use */
+#endif
+#endif /* __CONFIG_H */
index 7223f59e8da9ba53d8e96213236c65f2a916165f..282a204904b66a791d60cc052ffc3b69e2a39876 100644 (file)
@@ -139,7 +139,8 @@ extern int flash_real_protect(flash_info_t *info, long sector, int prot);
 #define AMD_ID_LV400T  0x22B922B9      /* 29LV400T ID ( 4 M, top boot sector)  */
 #define AMD_ID_LV400B  0x22BA22BA      /* 29LV400B ID ( 4 M, bottom boot sect) */
 
-#define AMD_ID_LV033C  0xA3            /* 29LV033C ID ( 4M x 8 )               */
+#define AMD_ID_LV033C  0xA3            /* 29LV033C ID ( 4 M x 8)               */
+#define AMD_ID_LV065D  0x93            /* 29LV065D ID ( 8 M x 8)               */
 
 #define AMD_ID_LV800T  0x22DA22DA      /* 29LV800T ID ( 8 M, top boot sector)  */
 #define AMD_ID_LV800B  0x225B225B      /* 29LV800B ID ( 8 M, bottom boot sect) */
@@ -174,6 +175,7 @@ extern int flash_real_protect(flash_info_t *info, long sector, int prot);
 #define SST_ID_xF400A  0x27802780      /* 39xF400A ID ( 4M = 256K x 16 )       */
 #define SST_ID_xF800A  0x27812781      /* 39xF800A ID ( 8M = 512K x 16 )       */
 #define SST_ID_xF160A  0x27822782      /* 39xF800A ID (16M =   1M x 16 )       */
+#define SST_ID_xF040   0xBFD7BFD7      /* 39xF040 ID (512KB = 4Mbit x 8)       */
 
 #define STM_ID_F040B   0xE2            /* M29F040B ID ( 4M = 512K x 8  )       */
                                        /* 8 64K x 8 uniform sectors            */
@@ -255,6 +257,9 @@ extern int flash_real_protect(flash_info_t *info, long sector, int prot);
 #define FLASH_AMDL324T 0x0014          /* AMD AM29DL324                        */
 #define FLASH_AMDL324B 0x0015
 
+#define FLASH_AMDLV033C        0x0018
+#define FLASH_AMDLV065D        0x001A
+
 #define FLASH_AMDL640  0x0016          /* AMD AM29DL640D                       */
 #define FLASH_AMD016   0x0018          /* AMD AM29F016D                        */
 
@@ -262,6 +267,7 @@ extern int flash_real_protect(flash_info_t *info, long sector, int prot);
 #define FLASH_SST400A  0x0042          /* SST 39xF400A ID (  4M = 256K x 16 )  */
 #define FLASH_SST800A  0x0044          /* SST 39xF800A ID (  8M = 512K x 16 )  */
 #define FLASH_SST160A  0x0046          /* SST 39xF160A ID ( 16M =   1M x 16 )  */
+#define FLASH_SST040   0x000E          /* SST 39xF040 ID (512KB = 4Mbit x 8 )  */
 
 #define FLASH_STM800AB 0x0051          /* STM M29WF800AB  (  8M = 512K x 16 )  */
 #define FLASH_STMW320DT 0x0052         /* STM M29W320DT   (32 M, top boot sector)      */