]> www.infradead.org Git - users/rw/ppcboot.git/commitdiff
* Add CPU Support for MPC 75x;
authorwdenk <wdenk>
Fri, 23 Nov 2001 17:38:33 +0000 (17:38 +0000)
committerwdenk <wdenk>
Fri, 23 Nov 2001 17:38:33 +0000 (17:38 +0000)
  add board support for Eltec BAB750 board
  Patch by Andreas Heppel, 22 Nov 2001

44 files changed:
CHANGELOG
CREDITS
MAKEALL
Makefile
board/eltec/bab750/Makefile [new file with mode: 0644]
board/eltec/bab750/bab750.c [new file with mode: 0644]
board/eltec/bab750/config.mk [new file with mode: 0644]
board/eltec/bab750/dc2114x.c [new file with mode: 0644]
board/eltec/bab750/flash.c [new file with mode: 0644]
board/eltec/bab750/mpc106.c [new file with mode: 0644]
board/eltec/bab750/mpc106_init.S [new file with mode: 0644]
board/eltec/bab750/mpc106_pci.c [new file with mode: 0644]
board/eltec/bab750/ns16550.c [new file with mode: 0644]
board/eltec/bab750/ns16550.h [new file with mode: 0644]
board/eltec/bab750/ns87308.c [new file with mode: 0644]
board/eltec/bab750/ns87308.h [new file with mode: 0644]
board/eltec/bab750/ppcboot.lds [new file with mode: 0644]
board/eltec/bab750/ppcboot.lds.mw.debug [new file with mode: 0644]
board/eltec/bab750/serial.c [new file with mode: 0644]
board/eltec/bab750/serial.h [new file with mode: 0644]
board/eltec/bab750/speed.c [new file with mode: 0644]
board/eltec/bab750/sym53c8xx.c [new file with mode: 0644]
board/eltec/bab750/sym53c8xx.h [new file with mode: 0644]
board/eltec/bab750/w83c553f.c [new file with mode: 0644]
common/board.c
common/cmd_ide.c
common/cmd_nvedit.c
cpu/mpc75x/Makefile [new file with mode: 0644]
cpu/mpc75x/config.mk [new file with mode: 0644]
cpu/mpc75x/cpu.c [new file with mode: 0644]
cpu/mpc75x/cpu_init.c [new file with mode: 0644]
cpu/mpc75x/interrupts.c [new file with mode: 0644]
cpu/mpc75x/kgdb.S [new file with mode: 0644]
cpu/mpc75x/speed.c [new file with mode: 0644]
cpu/mpc75x/start.S [new file with mode: 0644]
cpu/mpc75x/traps.c [new file with mode: 0644]
include/config_BAB750.h [new file with mode: 0644]
include/mk48t59.h [new file with mode: 0644]
include/mpc106.h [new file with mode: 0644]
include/mpc75x.h [new file with mode: 0644]
include/ppcboot.h
include/w83c553f.h [new file with mode: 0644]
rtc/Makefile
rtc/mk48t59.c [new file with mode: 0644]

index 6d7b918c7e59045ff8b9c6e7b66a0b28f5106fc4..0dab9d848e017ce4bf4caefc1c6449bebf264a3d 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -56,6 +56,10 @@ To do:
 Modifications for 1.1.1:
 ======================================================================
 
+* Add CPU Support for MPC 75x;
+  add board support for Eltec BAB750 board
+  Patch by Andreas Heppel, 22 Nov 2001
+
 * Fix problem with TFTP server in different subnet, or with
   "gatewayip" set when not needed.
   Patch by Nye Liu, 21 Nov 2001
diff --git a/CREDITS b/CREDITS
index abd686b4df2c4a075b0b4541d78924334bc0652b..56247a0ea2ff541066468cbb9e2e6ddfd8c38fa8 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -84,6 +84,10 @@ N: Anne-Sophie Harnois
 E: Anne-Sophie.Harnois@nextream.fr
 D: Port to Walnut405 board
 
+N: Andreas Heppel
+E: aheppel@sysgo.de
+D: CPU Support for MPC 75x; board support for Eltec BAB750
+
 N: Josh Huber
 E: huber@alum.wpi.edu
 D: Port to the Galileo Evaluation Board, and the MPC74xx cpu series.
diff --git a/MAKEALL b/MAKEALL
index 60b8c98369cf12b473c50c84c04848e2a177abfd..c7907e5c87b43881cf424cf4517e61745589252e 100755 (executable)
--- a/MAKEALL
+++ b/MAKEALL
@@ -72,7 +72,16 @@ LIST_74xx="  \
        EVB64260        \
 "
 
-LIST_all="${LIST_8xx} ${LIST_8240} ${LIST_8260} ${LIST_4xx}"
+#########################################################################
+## MPC7xx Systems
+#########################################################################
+
+LIST_7xx="     \
+       BAB750          \
+"
+
+LIST_all="${LIST_8xx} ${LIST_8240} ${LIST_8260} \
+         ${LIST_4xx} ${LIST_74xx} ${LIST_7xx}"
 
 [ $# = 0 ] && set $LIST_all
 
index 19ebc736a6b206bc4fbf87c50d99530c620c86d3..d7d3433081ecae3434f8458d650c643eaae584ab 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -593,6 +593,19 @@ EVB64260_config: unconfig
        echo "CPU   = mpc74xx"  >>config.mk ;   \
        echo "#include <config_$(@:_config=).h>" >config.h
 
+#########################################################################
+## MPC7xx Systems
+#########################################################################  
+
+BAB750_config: unconfig
+       @echo "Configuring for $(@:_config=) Board..." ; \
+       cd include ;                            \
+       echo "ARCH  = ppc"      > config.mk ;   \
+       echo "VENDOR= eltec"    >>config.mk ;   \
+       echo "BOARD = bab750"   >>config.mk ;   \
+       echo "CPU   = mpc75x"   >>config.mk ;   \
+       echo "#include <config_$(@:_config=).h>" >config.h                              
+
 #########################################################################
 
 clean:
diff --git a/board/eltec/bab750/Makefile b/board/eltec/bab750/Makefile
new file mode 100644 (file)
index 0000000..0b448bf
--- /dev/null
@@ -0,0 +1,48 @@
+#
+# (C) Copyright 2001
+# 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 ns16550.o ns87308.o serial.o speed.o \
+         dc2114x.o w83c553f.o mpc106_pci.o mpc106.o sym53c8xx.o
+SOBJS  = mpc106_init.o
+
+$(LIB):        .depend $(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/eltec/bab750/bab750.c b/board/eltec/bab750/bab750.c
new file mode 100644 (file)
index 0000000..bac9fa6
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ * (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Andreas Heppel <aheppel@sysgo.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 <ppcboot.h>
+#include <command.h>
+#include <config.h>
+#include <mpc106.h>
+#include <mk48t59.h>
+
+
+int checkboard (void)
+{
+    printf("BAB 750\n");
+    return 0;
+}
+
+int checkflash (void)
+{
+    /* TODO: XXX XXX XXX */
+    printf ("2 MB ## Test not implemented yet ##\n");
+
+    return (0);
+}
+
+long int dram_size (int board_type)
+{
+    /* No actual initialisation to do - done when setting up PICRs MCCRs ME/SARs etc
+     * in ram_init.S.
+     */
+     #if defined(CFG_MEMTEST)
+
+     register unsigned long reg;
+
+     printf("Testing DRAM\n");
+     
+     /* write each mem addr with it's address */
+     for (reg = CFG_MEMTEST_START; reg < CFG_MEMTEST_END; reg+=4
+         *reg = reg;
+
+     for (reg = CFG_MEMTEST_START; reg < CFG_MEMTEST_END; reg+=4
+     {
+         if (*reg != reg)
+           return -1;
+     }
+     #endif
+
+     /* TODO: calculate amount of dram..for now just return MEMTEST_END */
+     return CFG_MEMTEST_END;
+
+}
+
+long int initdram(int board_type)
+{
+       return dram_size(board_type);
+}
+/* ------------------------------------------------------------------------- */
+
+/*
+ * do_reset is done here because in this case it is board specific, since the
+ * 7xx CPUs can only be reset by external HW (the RTC in this case).
+ */
+void
+do_reset (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
+{
+#if defined(CONFIG_RTC_MK48T59)
+       /* trigger watchdog immediately */
+       rtc_set_watchdog(1, RTC_WD_RB_16TH);
+#else
+       #error "You must define the macro CONFIG_RTC_MK48T59."
+#endif
+}
+
+/* ------------------------------------------------------------------------- */
+
+#if defined(CONFIG_WATCHDOG)
+
+/*
+ * Since the 7xx CPUs don't have an internal watchdog, this function is board specific.
+ * We use the RTC here.
+ */
+void watchdog_reset(void)
+{
+#if defined(CONFIG_RTC_MK48T59)
+       /* we use a 32 sec watchdog timer */
+       rtc_set_watchdog(8, RTC_WD_RB_4);
+#else
+       #error "You must define the macro CONFIG_RTC_MK48T59."
+#endif
+}
+#endif /* CONFIG_WATCHDOG */
+
+
diff --git a/board/eltec/bab750/config.mk b/board/eltec/bab750/config.mk
new file mode 100644 (file)
index 0000000..50f480d
--- /dev/null
@@ -0,0 +1,31 @@
+#
+# (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
+#
+
+#
+# BAB740 boards
+#
+
+TEXT_BASE = 0xFFC00000
+#TEXT_BASE = 0x400000
+
+PLATFORM_CPPFLAGS += -DTEXT_BASE=$(TEXT_BASE)
diff --git a/board/eltec/bab750/dc2114x.c b/board/eltec/bab750/dc2114x.c
new file mode 100644 (file)
index 0000000..cf8464c
--- /dev/null
@@ -0,0 +1,540 @@
+/*
+ * 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 <ppcboot.h>
+#include <net.h>
+#include <mpc106.h>
+
+
+/* PCI Registers.
+ */
+#define PCI_CFDA_PSM           0x43
+
+#define CFRV_RN                0x000000f0      /* Revision Number */
+#define CBIO_MASK      0xffffff80
+
+#define WAKEUP         0x00            /* Power Saving Wakeup */
+#define SLEEP          0x80            /* Power Saving Sleep Mode */
+
+
+#define DC2114x_VID    0x1011          /* DC2114[23] Manufacturer */
+#define DC2114x_DID    0x0019          /* Unique Device ID # */
+#define DC2114x_BRK    0x0020          /* CFRV break between DC21142 & DC21143 */
+#define DC21142                (DC2114x_DID << 8 | 0x0010)
+#define DC21143                (DC2114x_DID << 8 | 0x0030)
+
+#define is_DC2114x ((vendor == DC2114x_VID) && (device == DC2114x_DID))
+
+/* Ethernet chip registers.
+        */
+#define DE4X5_BMR      iobase + 0x000  /* Bus Mode Register */
+#define DE4X5_TPD      iobase + 0x008  /* Transmit Poll Demand Reg */
+#define DE4X5_RRBA     iobase + 0x018  /* RX Ring Base Address Reg */
+#define DE4X5_TRBA     iobase + 0x020  /* TX Ring Base Address Reg */
+#define DE4X5_STS      iobase + 0x028  /* Status Register */
+#define DE4X5_OMR      iobase + 0x030  /* Operation Mode Register */
+#define DE4X5_SICR     iobase + 0x068  /* SIA Connectivity Register */
+#define DE4X5_APROM    iobase + 0x048  /* Ethernet Address PROM */
+
+/* Register bits.
+        */
+#define BMR_SWR                0x00000001      /* Software Reset */
+#define STS_TS         0x00700000      /* Transmit Process State */
+#define STS_RS         0x000e0000      /* Receive Process State */
+#define OMR_ST         0x00002000      /* Start/Stop Transmission Command */
+#define OMR_SR         0x00000002      /* Start/Stop Receive */
+#define OMR_PS         0x00040000      /* Port Select */
+#define OMR_SDP                0x02000000      /* SD Polarity - MUST BE ASSERTED */
+#define OMR_PM         0x00000080      /* Pass All Multicast */
+
+/* Descriptor bits.
+        */
+#define R_OWN          0x80000000      /* Own Bit */
+#define RD_RER         0x02000000      /* Receive End Of Ring */
+#define RD_LS          0x00000100      /* Last Descriptor */
+#define RD_ES          0x00008000      /* Error Summary */
+#define TD_TER         0x02000000      /* Transmit End Of Ring */
+#define T_OWN          0x80000000      /* Own Bit */
+#define TD_LS          0x40000000      /* Last Segment */
+#define TD_FS          0x20000000      /* First Segment */
+#define TD_ES          0x00008000      /* Error Summary */
+#define TD_SET         0x08000000      /* Setup Packet */
+
+
+#define SROM_HWADD         0x0014      /* Hardware Address offset in SROM */
+#define SROM_RD                0x00004000      /* Read from Boot ROM */
+#define SROM_SR                0x00000800      /* Select Serial ROM when set */
+
+#define DT_IN          0x00000004      /* Serial Data In */
+#define DT_CLK         0x00000002      /* Serial ROM Clock */
+#define DT_CS          0x00000001      /* Serial ROM Chip Select */
+
+#define POLL_DEMAND    1
+
+#define RESET_DE4X5 {\
+    int i;\
+    i=inl(DE4X5_BMR);\
+    udelay(1000);\
+    outl(i | BMR_SWR, DE4X5_BMR);\
+    udelay(1000);\
+    outl(i, DE4X5_BMR);\
+    udelay(1000);\
+    for (i=0;i<5;i++) {inl(DE4X5_BMR); udelay(10000);}\
+    udelay(1000);\
+}
+
+#define START_DE4X5 {\
+    s32 omr; \
+    omr = inl(DE4X5_OMR);\
+    omr |= OMR_ST | OMR_SR;\
+    outl(omr, DE4X5_OMR);              /* Enable the TX and/or RX */\
+}
+
+#define STOP_DE4X5 {\
+    s32 omr; \
+    omr = inl(DE4X5_OMR);\
+    omr &= ~(OMR_ST|OMR_SR);\
+    outl(omr, DE4X5_OMR);              /* Disable the TX and/or RX */ \
+}
+
+#define NUM_RX_DESC PKTBUFSRX
+#define NUM_TX_DESC 1                  /* Number of TX descriptors   */
+#define RX_BUFF_SZ  PKTSIZE_ALIGN
+
+#define TOUT_LOOP   1000000
+
+#define SETUP_FRAME_LEN 192
+#define ETH_ALEN       6
+
+
+struct de4x5_desc {
+       volatile s32 status;
+       u32 des1;
+       u32 buf;
+       u32 next;
+};
+
+static struct de4x5_desc rx_ring[NUM_RX_DESC]; /* RX descriptor ring         */
+static struct de4x5_desc tx_ring[NUM_TX_DESC]; /* TX descriptor ring         */
+static int rx_new;                             /* RX descriptor ring pointer */
+static int tx_new;                             /* TX descriptor ring pointer */
+
+static char rxRingSize;
+static char txRingSize;
+
+static u_long iobase;
+
+unsigned int     PCI_Read_CFG_Reg(int BusDevFunc, int Reg, int Width);
+int    PCI_Write_CFG_Reg(int BusDevFunc, int Reg, unsigned int Value, int Width);
+
+static void  send_setup_frame(bd_t * bis);
+static void  check_hw_addr(bd_t * bis);
+static short srom_rd(u_long address, u_char offset);
+static void  srom_latch(u_int command, u_long address);
+static void  srom_command(u_int command, u_long address);
+static void  srom_address(u_int command, u_long address, u_char offset);
+static short srom_data(u_int command, u_long address);
+static void  sendto_srom(u_int command, u_long addr);
+static int   getfrom_srom(u_long addr);
+
+static int inl(u_long addr)
+{
+       return le32_to_cpu(*(volatile u_long *)(addr));
+}
+
+static void outl (int command, u_long addr)
+{
+       *(volatile u_long *)(addr) = cpu_to_le32(command);
+}
+
+
+int    devbusfn = 0;
+
+int eth_init(bd_t *bis)
+{
+       int             i, status          = 0;
+       int             device;
+       int             cfrv;
+       unsigned char   timer;
+
+       devbusfn = PCI_Find_Device(DC2114x_VID, DC2114x_DID);
+       if (devbusfn == -1)
+       {
+               printf("Error: Cannot find an ethernet card on any PCI bus.");
+       goto Done;
+       }
+
+       /* Get the chip configuration revision register. */
+       cfrv = PCI_Read_CFG_Reg(devbusfn, PCI_CFG_REVISION, 4);
+
+       device = ((cfrv & CFRV_RN) < DC2114x_BRK ? DC21142 : DC21143);
+
+       if (device != DC21143)
+    {
+       printf("Error: The chip is not DC21143.\n");
+       goto Done;
+    }
+
+       status = PCI_Read_CFG_Reg(devbusfn, PCI_CFG_COMMAND, 2);
+       status |= PCI_CMD_MASTER | PCI_CMD_IOEN | PCI_CMD_MEMEN;
+       PCI_Write_CFG_Reg(devbusfn, PCI_CFG_COMMAND, status, 2);
+
+       /* Check the latency timer for values >= 0x60. */
+       timer = PCI_Read_CFG_Reg(devbusfn, PCI_CFG_LATENCY_TIMER, 1);
+       
+       if (timer < 0x60)
+    {
+               PCI_Write_CFG_Reg(devbusfn, PCI_CFG_LATENCY_TIMER, 0x60, 1);
+    }
+
+       /* read BAR for memory space access */
+       iobase = PCI_Read_CFG_Reg(devbusfn, PCI_CFG_BASE_ADDRESS_1, 4);
+
+       iobase &= CBIO_MASK;
+       iobase |= CFG_60X_PCI_MEM_OFFSET;
+       
+       /* Ensure we're not sleeping. */
+       PCI_Write_CFG_Reg(devbusfn, PCI_CFDA_PSM, WAKEUP, 1);
+
+       udelay(10 * 1000);
+
+       check_hw_addr(bis);
+
+       RESET_DE4X5;
+
+       if ((inl(DE4X5_STS) & (STS_TS | STS_RS)) != 0)
+       {
+               printf("Error: Cannot reset ethernet controller.\n");
+               goto Done;
+       }
+
+       outl(OMR_SDP | OMR_PS | OMR_PM, DE4X5_OMR);
+
+       for (i = 0; i < NUM_RX_DESC; i++)
+       {
+               rx_ring[i].status = cpu_to_le32(R_OWN);
+               rx_ring[i].des1 = cpu_to_le32(RX_BUFF_SZ);
+               rx_ring[i].buf = cpu_to_le32(phys_to_bus((void*)NetRxPackets[i]));
+               rx_ring[i].next = 0;
+       }
+
+       for (i=0; i < NUM_TX_DESC; i++)
+       {
+               tx_ring[i].status = 0;
+               tx_ring[i].des1 = 0;
+               tx_ring[i].buf = 0;
+               tx_ring[i].next = 0;
+       }
+
+       rxRingSize = NUM_RX_DESC;
+       txRingSize = NUM_TX_DESC;
+
+       /* Write the end of list marker to the descriptor lists. */
+       rx_ring[rxRingSize - 1].des1 |= cpu_to_le32(RD_RER);
+       tx_ring[txRingSize - 1].des1 |= cpu_to_le32(TD_TER);
+
+       /* Tell the adapter where the TX/RX rings are located. */
+       outl(phys_to_bus(&rx_ring), DE4X5_RRBA);
+       outl(phys_to_bus(&tx_ring), DE4X5_TRBA);
+
+       START_DE4X5;
+
+       tx_new = 0;
+       rx_new = 0;
+
+       send_setup_frame(bis);
+
+Done:
+ return 0;
+}
+
+int eth_send(volatile void *packet, int length)
+{
+  int    status = 0;
+  int i;
+
+  if (length <= 0)
+    {
+      printf("eth: bad packet size: %d\n", length);
+      goto out;
+    }
+
+  for(i = 0; tx_ring[tx_new].status & cpu_to_le32(T_OWN); i++)
+    {
+      if (i >= TOUT_LOOP)
+        {
+          printf("eth: tx error buffer not ready\n");
+          goto out;
+        }
+    }
+
+  tx_ring[tx_new].buf = cpu_to_le32(phys_to_bus((void*)packet));
+  tx_ring[tx_new].des1 = cpu_to_le32(TD_TER | TD_LS | TD_FS | length);
+  tx_ring[tx_new].status = cpu_to_le32(T_OWN);
+
+  outl(POLL_DEMAND, DE4X5_TPD);
+
+  for(i = 0; tx_ring[tx_new].status & cpu_to_le32(T_OWN); i++)
+    {
+      if (i >= TOUT_LOOP)
+        {
+          printf("eth: tx buffer not ready\n");
+          goto out;
+        }
+    }
+
+#if 0 /* test-only */
+  if (le32_to_cpu(tx_ring[tx_new].status) & TD_ES)
+    {
+      printf("TX error status = 0x%08X\n",
+             le32_to_cpu(tx_ring[tx_new].status));
+      status++;
+    }
+#endif
+
+ out:
+  return status;
+}
+
+int eth_rx(void)
+{
+       s32 status;
+       int length    = 0;
+
+       for ( ; ; ) {
+               status = (s32)le32_to_cpu(rx_ring[rx_new].status);
+
+               if (status & R_OWN) {
+                       break;
+               }
+
+               if (status & RD_LS) {
+                       /* Valid frame status.
+                        */
+                       if (status & RD_ES) {
+              /* There was an error.
+               */
+              printf("RX error status = 0x%08X\n", status);
+                       }
+                       else {
+                               /* A valid frame received.
+                                */
+                               length = (le32_to_cpu(rx_ring[rx_new].status) >>
+                        16);
+
+                               /* Pass the packet up to the protocol
+                                * layers.
+                                */
+                               NetReceive(NetRxPackets[rx_new], length - 4);
+                       }
+
+                       /* Change buffer ownership for this frame, back
+                        * to the adapter.
+                        */
+                       rx_ring[rx_new].status = cpu_to_le32(R_OWN);
+               }
+
+               /* Update entry information.
+                */
+               rx_new = (++rx_new) % rxRingSize;
+       }
+
+       return length;
+}
+
+void eth_halt(void)
+{
+#if 1
+       STOP_DE4X5;
+       outl(0, DE4X5_SICR);
+       if (devbusfn > 0)
+               PCI_Write_CFG_Reg(devbusfn, PCI_CFDA_PSM, SLEEP, 1);
+#endif
+}
+
+static void check_hw_addr(bd_t *bis)
+{
+       unsigned char hw_addr[ETH_ALEN];
+       u_short tmp, *p = (short *)(&hw_addr[0]);
+       int i, j = 0;
+       
+       for (i = 0; i < (ETH_ALEN >> 1); i++) {
+               tmp = srom_rd(DE4X5_APROM, (SROM_HWADD >> 1) + i);
+               *p = le16_to_cpu(tmp);
+               j += *p++;
+       }
+
+       if ((j == 0) || (j == 0x2fffd)) {
+               printf("Warning: can't read HW address from SROM.\n");
+               goto Done;
+       }
+
+       for (i = 0; i < ETH_ALEN; i++) {
+               if (hw_addr[i] != bis->bi_enetaddr[i]) {
+                       printf("Warning: HW addresses don't match:\n");
+                       printf("Address in SROM is         "
+                 "%02X:%02X:%02X:%02X:%02X:%02X\n",
+                 hw_addr[0], hw_addr[1], hw_addr[2],
+                 hw_addr[3], hw_addr[4], hw_addr[5]);
+                       printf("Address used by ppcboot is "
+                 "%02X:%02X:%02X:%02X:%02X:%02X\n",
+                 bis->bi_enetaddr[0], bis->bi_enetaddr[1],
+                 bis->bi_enetaddr[2], bis->bi_enetaddr[3],
+                 bis->bi_enetaddr[4], bis->bi_enetaddr[5]);
+                       goto Done;
+               }
+       }
+
+Done:
+}
+
+static void send_setup_frame(bd_t *bis)
+{
+       int             i;
+       char    setup_frame[SETUP_FRAME_LEN];
+       char    *pa = &setup_frame[0];
+
+       memset(pa, 0xff, SETUP_FRAME_LEN);
+
+       for (i = 0; i < ETH_ALEN; i++) {
+               *(pa + (i & 1)) = bis->bi_enetaddr[i];
+               if (i & 0x01)
+               {
+                       pa += 4;
+               }
+       }
+
+       for(i = 0; tx_ring[tx_new].status & cpu_to_le32(T_OWN); i++) {
+               if (i >= TOUT_LOOP) {
+                       printf("eth: tx error buffer not ready\n");
+                       goto out;
+               }
+       }
+
+       tx_ring[tx_new].buf = cpu_to_le32(phys_to_bus(&setup_frame[0]));
+       tx_ring[tx_new].des1 = cpu_to_le32(TD_TER | TD_SET| SETUP_FRAME_LEN);
+       tx_ring[tx_new].status = cpu_to_le32(T_OWN);
+
+       outl(POLL_DEMAND, DE4X5_TPD);
+
+       for(i = 0; tx_ring[tx_new].status & cpu_to_le32(T_OWN); i++) {
+               if (i >= TOUT_LOOP) {
+                       printf("eth: tx buffer not ready\n");
+                       goto out;
+               }
+       }
+
+       if (le32_to_cpu(tx_ring[tx_new].status) != 0x7FFFFFFF) {
+               printf("TX error status2 = 0x%08X\n", le32_to_cpu(tx_ring[tx_new].status));
+       }
+out:
+}
+
+/* SROM Read.
+ */
+static short
+srom_rd(u_long addr, u_char offset)
+{
+       sendto_srom(SROM_RD | SROM_SR, addr);
+
+       srom_latch(SROM_RD | SROM_SR | DT_CS, addr);
+       srom_command(SROM_RD | SROM_SR | DT_IN | DT_CS, addr);
+       srom_address(SROM_RD | SROM_SR | DT_CS, addr, offset);
+
+       return srom_data(SROM_RD | SROM_SR | DT_CS, addr);
+}
+
+static void
+srom_latch(u_int command, u_long addr)
+{
+  sendto_srom(command, addr);
+  sendto_srom(command | DT_CLK, addr);
+  sendto_srom(command, addr);
+
+  return;
+}
+
+static void
+srom_command(u_int command, u_long addr)
+{
+  srom_latch(command, addr);
+  srom_latch(command, addr);
+  srom_latch((command & 0x0000ff00) | DT_CS, addr);
+
+  return;
+}
+
+static void
+srom_address(u_int command, u_long addr, u_char offset)
+{
+  int i;
+  signed char a;
+
+  a = (char)(offset << 2);
+  for (i=0; i<6; i++, a <<= 1) {
+    srom_latch(command | ((a < 0) ? DT_IN : 0), addr);
+  }
+  udelay(1);
+
+  i = (getfrom_srom(addr) >> 3) & 0x01;
+
+  return;
+}
+
+static short
+srom_data(u_int command, u_long addr)
+{
+  int i;
+  short word = 0;
+  s32 tmp;
+
+  for (i=0; i<16; i++) {
+    sendto_srom(command  | DT_CLK, addr);
+    tmp = getfrom_srom(addr);
+    sendto_srom(command, addr);
+
+    word = (word << 1) | ((tmp >> 3) & 0x01);
+  }
+
+  sendto_srom(command & 0x0000ff00, addr);
+
+  return word;
+}
+
+static void
+sendto_srom(u_int command, u_long addr)
+{
+       outl(command, addr);
+       udelay(1);
+
+       return;
+}
+
+static int
+getfrom_srom(u_long addr)
+{
+  s32 tmp;
+
+  tmp = inl(addr);
+  udelay(1);
+
+  return tmp;
+}
+
diff --git a/board/eltec/bab750/flash.c b/board/eltec/bab750/flash.c
new file mode 100644 (file)
index 0000000..42943f8
--- /dev/null
@@ -0,0 +1,489 @@
+/*
+ * (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
+ */
+
+/*
+ * 09-18-2001, Andreas Heppel: Reduced the code in here to the usage
+ *             of AMD's 29F040 and 29F016 flashes, since the BAB750 does use
+ *             any other.
+ */
+#include <ppcboot.h>
+#include <asm/processor.h>
+#include <asm/pci_io.h>
+
+flash_info_t    flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips    */
+
+/*-----------------------------------------------------------------------
+ * Functions
+ */
+ulong flash_get_size (vu_long *addr, flash_info_t *info);
+static int write_word (flash_info_t *info, ulong dest, ulong data);
+
+/*flash command address offsets*/
+
+#define ADDR0           (0x555)
+#define ADDR1           (0x2AA)
+#define ADDR3           (0x001)
+
+#define FLASH_WORD_SIZE unsigned char
+
+/*-----------------------------------------------------------------------
+ */
+
+unsigned long flash_init (void)
+{
+    unsigned long size1, size2;
+    int i;
+    unsigned long base;
+    
+       
+    /* Init: no FLASHes known */
+    for (i=0; i<CFG_MAX_FLASH_BANKS; ++i) {
+        flash_info[i].flash_id = FLASH_UNKNOWN;
+    }
+
+       /* initialise 1st flash */
+    size1 = flash_get_size((vu_long *)FLASH_BASE0_PRELIM, &flash_info[0]);
+
+    if (flash_info[0].flash_id == FLASH_UNKNOWN) {
+        printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
+            size1, size1<<20);
+    }
+
+    /* monitor protection ON by default */
+    flash_protect(FLAG_PROTECT_SET,
+                 base + size1 - CFG_MONITOR_LEN,
+                 base + size1 - 1,
+                 &flash_info[0]);
+
+       /* initialise 2nd flash */
+    size2 = flash_get_size((vu_long *)FLASH_BASE1_PRELIM, &flash_info[1]);
+
+    if (flash_info[0].flash_id == FLASH_UNKNOWN) {
+        printf ("## Unknown FLASH on Bank 1 - Size = 0x%08lx = %ld MB\n",
+            size2, size2<<20);
+    }
+
+    return (size1 + size2);
+}
+
+/*-----------------------------------------------------------------------
+ */
+void flash_print_info  (flash_info_t *info)
+{
+    int i;
+    int k;
+    int size;
+    int erased;
+    volatile unsigned long *flash;
+
+    if (info->flash_id == FLASH_UNKNOWN) {
+        printf ("missing or unknown FLASH type\n");
+       flash_init();
+    }
+    
+    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;
+    default:
+       printf ("Unknown Vendor ");
+               break;
+    }
+
+    switch (info->flash_id & FLASH_TYPEMASK) {
+    case AMD_ID_F040B:
+       printf ("AM29F040B (4 Mbit)\n");
+        break;
+    case AMD_ID_F016D:
+       printf ("AM29F016D (16 Mbit)\n");
+        break;
+    default:
+       printf ("Unknown Chip Type\n");
+        break;
+    }
+
+    if (info->size >= (1 << 20)) {
+           printf ("  Size: %ld MB in %d Sectors\n", info->size >> 20, info->sector_count);
+       } else {
+           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) {
+               /*
+               * Check if whole sector is erased
+               */
+               if (i != (info->sector_count-1))
+                       size = info->start[i+1] - info->start[i];
+               else
+                       size = info->start[0] + info->size - info->start[i];
+                       
+               erased = 1;
+               flash = (volatile unsigned long *)info->start[i];
+               size = size >> 2;        /* divide by 4 for longword access */
+               for (k=0; k<size; k++) {
+                       if (*flash++ != 0xffffffff) {
+                               erased = 0;
+                               break;
+                       }
+               }
+
+        if ((i % 5) == 0)
+            printf ("\n   ");
+           
+        printf (" %08lX%s%s",
+            info->start[i],
+            erased ? " E" : "  ",
+            info->protect[i] ? "RO " : "   ");
+    }
+    printf ("\n");
+}
+
+
+/*-----------------------------------------------------------------------
+ */
+
+/*
+ * The following code cannot be run from FLASH!
+ */
+ulong flash_get_size (vu_long *addr, flash_info_t *info)
+{
+       short i;
+    ulong vendor, devid;
+    ulong base = (ulong)addr;
+       volatile unsigned char *caddr = (unsigned char *)addr;
+       
+#ifdef DEBUG
+    printf("flash_get_size for address 0x%lx: \n", (unsigned long)caddr);
+#endif
+
+    /* Write auto select command: read Manufacturer ID */
+       caddr[0] = 0xF0;   /* reset bank */
+    udelay(10);
+
+       eieio();
+    caddr[0x555] = 0xAA;
+    udelay(10);
+    caddr[0x2AA] = 0x55;
+    udelay(10);
+    caddr[0x555] = 0x90;
+    
+    udelay(10);
+    
+    vendor = caddr[0];
+       devid = caddr[1];
+       
+#ifdef DEBUG
+    printf("Manufacturer: 0x%lx\n", vendor);
+#endif
+
+    vendor &= 0xff;
+    devid &= 0xff;
+
+       /* We accept only two AMD types */
+    switch (vendor) {
+    case (FLASH_WORD_SIZE)AMD_MANUFACT:
+        info->flash_id = FLASH_MAN_AMD;
+        break;
+    default:
+        info->flash_id = FLASH_UNKNOWN;
+        info->sector_count = 0;
+        info->size = 0;
+        return (0);         /* no or unknown flash  */
+    }
+
+    switch (devid) {
+    case (FLASH_WORD_SIZE)AMD_ID_F040B:
+        info->flash_id |= AMD_ID_F040B;
+        info->sector_count = 8;
+        info->size = 0x00080000;
+        break;              /* => 0.5 MB      */
+
+    case (FLASH_WORD_SIZE)AMD_ID_F016D:
+               info->flash_id |= AMD_ID_F016D;
+               info->sector_count = 32;
+               info->size         = 0x00200000;
+               break;              /* => 2 MB      */
+               
+    default:
+        info->flash_id = FLASH_UNKNOWN;
+        return (0);         /* => no or unknown flash */
+
+    }
+
+#ifdef DEBUG
+    printf("flash id 0x%lx; sector count 0x%x, size 0x%lx\n", info->flash_id, info->sector_count, info->size);
+#endif
+
+    /* check for protected sectors */
+    for (i = 0; i < info->sector_count; i++) {
+               /* sector base address */
+               info->start[i] = base + i * (info->size / info->sector_count);
+               /* read sector protection at sector address, (A7 .. A0) = 0x02 */
+               /* D0 = 1 if protected */
+               caddr = (volatile unsigned char *)(info->start[i]);
+               info->protect[i] = caddr[2] & 1;
+    }
+
+    /*
+     * Prevent writes to uninitialized FLASH.
+     */
+    if (info->flash_id != FLASH_UNKNOWN) {
+       caddr = (volatile unsigned char *)info->start[0];
+       caddr[0] = 0xF0;   /* 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]);
+       int flag, prot, sect, l_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 ERR_NOT_ERASED;
+       }
+
+       if ((info->flash_id == FLASH_UNKNOWN) || (info->flash_id > FLASH_AMD_COMP)) {
+               printf ("Can't erase unknown flash type - aborted\n");
+               return ERR_NOT_ERASED;
+       }
+
+       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");
+       }
+
+       l_sect = -1;
+
+       /* 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;
+
+       /* Start erase on unprotected sectors */
+       for (sect = s_first; sect<=s_last; sect++) {
+               if (info->protect[sect] == 0) { /* not protected */
+                       addr = (FLASH_WORD_SIZE *)(info->start[sect]);
+                       if (info->flash_id & FLASH_MAN_SST) {
+                               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;
+                               addr[0] = (FLASH_WORD_SIZE)0x00500050;  /* block erase */
+                               udelay(30000);  /* wait 30 ms */
+                       }
+                       else
+                               addr[0] = (FLASH_WORD_SIZE)0x00300030;  /* sector erase */
+                       l_sect = sect;
+               }
+       }
+
+       /* re-enable interrupts if necessary */
+       if (flag)
+               enable_interrupts();
+
+       /* wait at least 80us - let's wait 1 ms */
+       udelay (1000);
+
+       /*
+        * We wait for the last triggered sector
+        */
+       if (l_sect < 0)
+               goto DONE;
+
+       start = get_timer (0);
+       last  = start;
+       addr = (FLASH_WORD_SIZE *)(info->start[l_sect]);
+       while ((addr[0] & (FLASH_WORD_SIZE)0x00800080) != (FLASH_WORD_SIZE)0x00800080) {
+               if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
+                       printf ("Timeout\n");
+                       return ERR_TIMOUT;
+               }
+               /* show that we're waiting */
+               if ((now - last) > 1000) {  /* every second */
+                       serial_putc ('.');
+                       last = now;
+               }
+       }
+
+DONE:
+       /* reset to read mode */
+       addr = (FLASH_WORD_SIZE *)info->start[0];
+       addr[0] = (FLASH_WORD_SIZE)0x00F000F0;  /* reset bank */
+
+       printf (" done\n");
+       return ERR_OK;
+}
+
+/*-----------------------------------------------------------------------
+ * 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 FLASH_WORD_SIZE *)dest) &
+             (FLASH_WORD_SIZE)data) != (FLASH_WORD_SIZE)data) {
+        return (2);
+    }
+    /* Disable interrupts which might cause a timeout here */
+    flag = disable_interrupts();
+
+        for (i=0; i<4/sizeof(FLASH_WORD_SIZE); i++)
+          {
+            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] & (FLASH_WORD_SIZE)0x00800080) !=
+                   (data2[i] & (FLASH_WORD_SIZE)0x00800080)) {
+              if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
+                return (1);
+              }
+            }
+          }
+
+    return (0);
+}
+
+/*-----------------------------------------------------------------------
+ */
diff --git a/board/eltec/bab750/mpc106.c b/board/eltec/bab750/mpc106.c
new file mode 100644 (file)
index 0000000..bfa9c30
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Andreas Heppel <aheppel@sysgo.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
+ */
+
+/*
+ * memory routines for the MPC106 CPU.
+ */
+#include <ppcboot.h>
+#include <config.h>
+#include <mpc106.h>
+
+/*
+ * The local DRAM may have a different address from the PCI
+ * point of view, thus buffer addresses have to be modified
+ * [mapped] appropriately.
+ */
+unsigned long phys_to_bus(void * address)
+{
+       if (address == (void *)0)
+               return 0;
+       return (unsigned long)address + CFG_PCI_DRAM_OFFSET;
+}
+void * bus_to_phys(unsigned long address)
+{
+       if (address == 0)
+               return 0;
+       return (void *)(address - CFG_PCI_DRAM_OFFSET);
+}
diff --git a/board/eltec/bab750/mpc106_init.S b/board/eltec/bab750/mpc106_init.S
new file mode 100644 (file)
index 0000000..3b34fb1
--- /dev/null
@@ -0,0 +1,1331 @@
+#include <config.h>
+#include <mpc75x.h>
+#include <version.h>
+
+#include <ppc_asm.tmpl>
+#include <ppc_defs.h>
+
+#define DEFS_ONLY
+
+#include <mpc106.h>
+
+
+
+       .globl set_address_map
+set_address_map:
+       /*
+        * Switch to address map A if necessary.
+        */
+#ifdef CFG_ADDRESS_MAP_A
+       lis     r1, 0xfec0
+       ori     r1, r1, 0x0cf8
+       lis     r2, 0xfee0
+       ori     r2, r2, 0xcfc
+
+       lis     r3, MPC106_REG@h
+       ori     r3, r3, PCI_PICR1
+       stwbrx  r3, 0, r1
+       sync    
+       lwbrx   r4, 0, r2
+       sync
+       lis     r0, PICR1_XIO_MODE@h
+       ori     r0, r0, PICR1_XIO_MODE@l
+       andc    r4, r4, r0
+       lis     r0, PICR1_ADDRESS_MAP@h
+       ori     r0, r0, PICR1_ADDRESS_MAP@l
+       or      r4, r4, r0
+       stwbrx  r4, 0, r2
+       
+       sync
+#endif
+       blr
+
+
+       /*
+        * This following contains the entry code for the initialization code
+        * for the MPC 106, a PCI Bridge/Memory Controller.
+        * Register usage:
+        * r0  = ramtest scratch register, toggleError loop counter
+        * r1 = CONFIG_ADDRESS
+        * r2 = CONFIG_DATA
+        * r3  = scratch register, subroutine argument and return value, ramtest size
+        * r4  = scratch register, spdRead clock mask, OutHex loop count
+        * r5  = ramtest scratch register
+        * r6  = toggleError 1st value, spdRead port mask
+        * r7  = toggleError 2nd value, ramtest scratch register, spdRead scratch register (0x00)
+        * r8  = ramtest scratch register, spdRead scratch register (0x80)
+        * r9  = ramtest scratch register, toggleError loop end, OutHex digit
+        * r10 = ramtest scratch register, spdWriteByte parameter, spdReadByte return value, printf pointer to COM1
+        * r11 = startType
+        * r12 = ramtest scratch register, spdRead data mask 
+        * r14 = pointer to GOT
+        * r15 = scratch register, SPD save
+        * r16 = bank0 size, total memory size
+        * r17 = bank1 size
+        * r18 = bank2 size
+        * r19 = bank3 size
+        * r20 = MCCR1, MSAR1
+        * r21 = MCCR3, MEAR1
+        * r22 = MCCR4, MBER
+        * r23 = EMSAR1
+        * r24 = EMEAR1
+        * r25 = save link register 1st level
+        * r26 = save link register 2nd level
+        * r27 = save link register 3rd level
+        * r30 = pointer to GPIO for spdRead
+        * r31 = pointer to message block
+        */
+
+       .globl ram_init
+ram_init:
+       mflr    r25 /* save away link register */
+       
+       /* set pointer to message block */
+       lis     r4, CFG_MONITOR_BASE@h
+       ori     r4, r4, CFG_MONITOR_BASE@l
+       addi    r4, r4, EXC_OFF_SYS_RESET
+       bl get_startaddr
+       sub r4, r4,r3
+       bl get_msgblk
+       add     r4, r4,r3
+       mr      r31, r4
+
+       /* 
+        * Do the init for the SIO.
+        */
+       bl .sioInit
+
+       addi    r3, r31, (MinitLogo-MessageBlock)
+       bl      Printf
+
+       addi    r3, r31, (Mspd01-MessageBlock)
+       bl      Printf
+
+       /*
+        * Memory cofiguration using SPD information stored on the SODIMMs
+        */
+
+       li      r17,0
+       li      r18,0
+       li      r19,0
+
+       li      r3, 0x0002              /* get RAM type from spd for bank0/1 */
+       bl      spdRead
+       
+       cmpi    0, 0, r3, -1            /* error ? */
+       bne     noSpdError
+
+       addi    r3, r31, (Mfail-MessageBlock)
+       bl      Printf
+
+       li      r6, 0xe0                /* error codes in r6 and r7  */
+       li      r7, 0x00
+       b       toggleError             /* fail - loop forever */
+
+noSpdError:
+       mr      r15, r3                 /* save r3 (RAM type) */
+
+       addi    r3, r31, (Mok-MessageBlock)
+       bl      Printf
+
+       cmpli   0, 0, r15, 0x0001       /* FPM ? */
+       beq     configFPM
+       cmpli   0, 0, r15, 0x0002       /* EDO ? */
+       beq     configEDO
+       cmpli   0, 0, r15, 0x0004       /* SDRAM ? */
+       beq     configSDRAM
+
+       li      r6, 0xe0                /* error codes in r6 and r7  */
+       li      r7, 0x01
+       b       toggleError             /* fail - loop forever */
+
+configSDRAM:
+       addi    r3, r31, (MsdRam-MessageBlock)
+       bl      Printf
+
+       /* set the Memory Configuration Reg. 1 */
+       li      r3, 0x001f              /* get bank size from spd for bank0/1 */
+       bl      spdRead
+
+       li      r20, 0x00ff             /* 16-Mbit SDRAM 2 banks */
+
+       andi.   r3,r3,0x0038            /* not 32MB, 64MB or 128MB */
+       beq     sizeofSDRAM
+
+       li      r3, 0x0011              /* get number of internal banks from spd for bank0/1 */
+       bl      spdRead
+
+       li      r20, 0x0055             /* 64-Mbit SDRAM 2 banks */
+       
+       cmpli   0, 0, r3, 0x02          /* 2 banks */
+       beq     sizeofSDRAM
+
+       li      r20, 0x0000             /* 64-Mbit SDRAM 4 banks */
+       
+       cmpli   0, 0, r3, 0x04          /* 4 banks */
+       beq     sizeofSDRAM
+
+       li      r6, 0xe0                /* error codes in r6 and r7  */
+       li      r7, 0x02
+       b       toggleError             /* fail - loop forever */
+
+sizeofSDRAM:
+       /* set the Memory Configuration Reg. 3 */
+       lis     r21, 0x8630             /* BSTOPRE = 0x80, REFREC = 6, RDLAT = 3 */
+
+       /* set the Memory Configuration Reg. 4 */
+       lis     r22, 0x2430             /* PRETOACT = 2, ACTOPRE = 4, WCBUF = 1, RCBUF = 1 */
+       ori     r22, r22, 0x2220        /* SDMODE = 0x022, ACTORW = 2 */
+
+       /* get the size of bank 0-3 */
+
+       li      r3, 0x001f              /* get bank size from spd for bank0/1 */
+       bl      spdRead
+
+       rlwinm  r16, r3, 2, 24, 29      /* calculate size in MByte (128 MB max.) */             
+
+       li      r3, 0x0005              /* get number of banks from spd for bank0/1 */
+       bl      spdRead
+
+       cmpi    0, 0, r3, 2             /* 2 banks on module ? */
+       bne     SDRAMnobank1
+
+       mr      r17, r16                /* save size of bank 1 */
+
+SDRAMnobank1:
+       addi    r3, r31, (Mspd23-MessageBlock)
+       bl      Printf
+
+       li      r3, 0x0102              /* get RAM type spd for bank2/3 */
+       bl      spdRead
+
+       cmpli   0, 0, r3, 0x0001        /* FPM ? */
+       bne     1f
+       addi    r3, r31, (Mok-MessageBlock)
+       bl      Printf
+       addi    r3, r31, (MfpmRam-MessageBlock)
+       bl      Printf
+       b       configRAMcommon
+1:
+       cmpli   0, 0, r3, 0x0002        /* EDO ? */
+       bne     2f
+       addi    r3, r31, (Mok-MessageBlock)
+       bl      Printf
+       addi    r3, r31, (MedoRam-MessageBlock)
+       bl      Printf
+       b       configRAMcommon
+2:
+       cmpli   0, 0, r3, 0x0004        /* SDRAM ? */
+       bne     3f
+       addi    r3, r31, (Mok-MessageBlock)
+       bl      Printf
+       addi    r3, r31, (MsdRam-MessageBlock)
+       bl      Printf
+       b       configSDRAM23
+3:
+       addi    r3, r31, (Mfail-MessageBlock)
+       bl      Printf
+       b       configRAMcommon         /* bank2/3 is not present or no SDRAM */
+
+configSDRAM23:
+       li      r3, 0x011f              /* get bank size from spd for bank2/3 */
+       bl      spdRead
+
+       rlwinm  r18, r3, 2, 24, 29      /* calculate size in MByte (128 MB max.) */
+
+       li      r3, 0x0105              /* get number of banks from spd for bank2/3 */
+       bl      spdRead
+
+       cmpi    0, 0, r3, 2             /* 2 banks ? */
+       bne     configRAMcommon
+
+       mr      r19, r18                /* save size of bank 3 */
+       b       configRAMcommon
+
+configFPM:
+       addi    r3, r31, (MfpmRam-MessageBlock)
+       bl      Printf
+       b       configEDO0
+configEDO:
+       addi    r3, r31, (MedoRam-MessageBlock)
+       bl      Printf
+
+configEDO0:
+       /* set the Memory Configuration Reg. 1 */
+       /* set RAM type to not SDRAM */
+       lis     r20, MCCR1_TYPE_EDO@h
+
+       li      r3, 0x0003              /* get # of row bits from spd for bank0/1 */
+       bl      spdRead
+       
+       ori     r20, r20, (MCCR1_BK0_9BITS | MCCR1_BK1_9BITS)
+       cmpli   0, 0, r3, 0x0009        /* bank0 -  9 row bits */
+       beq     sizeofEDO
+       
+       ori     r20, r20, (MCCR1_BK0_10BITS | MCCR1_BK1_10BITS)
+       cmpli   0, 0, r3, 0x000a        /* bank0 -  10 row bits */
+       beq     sizeofEDO
+       
+       ori     r20, r20, (MCCR1_BK0_11BITS | MCCR1_BK1_11BITS)
+       cmpli   0, 0, r3, 0x000b        /* bank0 -  11 row bits */
+       beq     sizeofEDO
+       
+       ori     r20, r20, (MCCR1_BK0_12BITS | MCCR1_BK1_12BITS)
+       cmpli   0, 0, r3, 0x000c        /* bank0 -  12 row bits */
+       beq     sizeofEDO
+       
+       cmpli   0, 0, r3, 0x000d        /* bank0 -  13 row bits */
+       beq     sizeofEDO
+
+       li      r6, 0xe0                /* error codes in r6 and r7  */
+       li      r7, 0x10
+       b       toggleError             /* fail - loop forever */
+
+sizeofEDO:
+       /* set the Memory Configuration Reg. 3 */
+       lis     r21, 0x000a                     /* CPX = 1, RAS6P = 4 */
+       ori     r21, r21, 0x2293        /* CAS5 = 2, CP4 = 1, CAS3 = 2, RCD2 = 2, RP = 3 */
+
+       /* set the Memory Configuration Reg. 4 */
+       lis     r22, 0x0010             /* all SDRAM parameter 0, WCBUF flow through, RCBUF registered */
+
+       /* get the size of bank 0-3 */
+       li      r3, 0x0003              /* get row bits from spd for bank0/1 */
+       bl      spdRead
+
+       li      r16, 0                  /* bank size is (8 * 2^row * 2^column) / 0x100000 MB */
+       ori     r16, r16, 0x8000
+       rlwnm   r16, r16, r3, 0, 31             
+
+       li      r3, 0x0004              /* get column bits from spd for bank0/1 */
+       bl      spdRead
+
+       rlwnm   r16, r16, r3, 0, 31             
+
+       li      r3, 0x0005              /* get number of banks from spd for bank0/1 */
+       bl      spdRead
+
+       cmpi    0, 0, r3, 2             /* 2 banks on module ? */
+       bne     EDOnobank1
+
+       mr      r17, r16                /* save size of bank 1 */
+
+EDOnobank1:
+       addi    r3, r31, (Mspd23-MessageBlock)
+       bl      Printf
+
+       li      r3, 0x0102              /* get RAM type spd for bank2/3 */
+       bl      spdRead
+
+       cmpli   0, 0, r3, 0x0001        /* FPM ? */
+       bne     1f
+       addi    r3, r31, (Mok-MessageBlock)
+       bl      Printf
+       addi    r3, r31, (MfpmRam-MessageBlock)
+       bl      Printf
+       b       configEDO23
+1:
+       cmpli   0, 0, r3, 0x0002        /* EDO ? */
+       bne     2f
+       addi    r3, r31, (Mok-MessageBlock)
+       bl      Printf
+       addi    r3, r31, (MedoRam-MessageBlock)
+       bl      Printf
+       b       configEDO23
+2:
+       cmpli   0, 0, r3, 0x0004        /* SDRAM ? */
+       bne     3f
+       addi    r3, r31, (Mok-MessageBlock)
+       bl      Printf
+       addi    r3, r31, (MsdRam-MessageBlock)
+       bl      Printf
+       b       configRAMcommon
+3:
+       addi    r3, r31, (Mfail-MessageBlock)
+       bl      Printf
+       b       configRAMcommon         /* bank2/3 is not present or no SDRAM */
+
+configEDO23:
+       li      r3, 0x0103              /* get row bits from spd for bank2/3 */
+       bl      spdRead
+
+       li      r18, 0                  /* bank size is (8 * 2^row * 2^column) / 0x100000 MB */
+       ori     r18, r18, 0x8000
+       rlwnm   r18, r18, r3, 0, 31             
+
+       li      r3, 0x0104              /* get column bits from spd for bank2/3 */
+       bl      spdRead
+
+       rlwnm   r18, r18, r3, 0, 31
+
+       li      r3, 0x0105              /* get number of banks from spd for bank2/3 */
+       bl      spdRead
+
+       cmpi    0, 0, r3, 2             /* 2 banks ? */
+       bne     configRAMcommon
+
+       mr      r19, r18                /* save size of bank 3 */
+
+configRAMcommon:
+       lis     r1, MPC106_REG_ADDR@h
+       ori r1, r1, MPC106_REG_ADDR@l
+       lis     r2, MPC106_REG_DATA@h
+       ori r2, r2, MPC106_REG_DATA@l
+
+       li r0, 0
+
+/*
+ * If we are already running in RAM (debug mode), we should
+ * NOT reset the MEMGO flag. Otherwise we will stop all memory
+ * accesses.
+ */
+#ifdef IN_RAM
+       lis     r4, MCCR1_MEMGO@h
+       ori r4,r4, MCCR1_MEMGO@l
+       or r20,r20,r4
+#endif
+
+       /* set the Memory Configuration Reg. 1 */
+       lis     r3, MPC106_REG@h        /* start building new reg number */
+       ori     r3, r3, MPC106_MCCR1    /* register number 0xf0 */
+       stwbrx  r3, r0, r1              /* write this value to CONFIG_ADDR */
+       eieio                           /* make sure mem. access is complete */
+
+       stwbrx  r20, r0, r2             /* write data to CONFIG_DATA */
+
+       /* set the Memory Configuration Reg. 3 */
+       lis     r3, MPC106_REG@h        /* start building new reg number */
+       ori     r3, r3, MPC106_MCCR3    /* register number 0xf8 */
+       stwbrx  r3, r0, r1              /* write this value to CONFIG_ADDR */
+       eieio                           /* make sure mem. access is complete */
+
+       stwbrx  r21, r0, r2             /* write data to CONFIG_DATA */
+
+       /* set the Memory Configuration Reg. 4 */
+       lis     r3, MPC106_REG@h        /* start building new reg number */
+       ori     r3, r3, MPC106_MCCR4    /* register number 0xfc */
+       stwbrx  r3, r0, r1              /* write this value to CONFIG_ADDR */
+       eieio                           /* make sure mem. access is complete */
+
+       stwbrx  r22, r0, r2             /* write data to CONFIG_DATA */
+
+       /* set the memory boundary registers for bank 0-3 */
+       li      r20, 0
+       li      r23, 0
+       li      r24, 0
+       subi    r21, r16, 1             /* calculate end address bank0 */
+       li      r22, MBER_BANK0
+
+       cmpi    0, 0, r17, 0            /* bank1 present ? */
+       beq     nobank1
+
+       rlwinm  r3, r16, 8, 16, 23      /* calculate start address of bank1 */
+       or      r20, r20, r3
+               
+       add     r16, r16, r17           /* add to total memory size */          
+
+       subi    r3, r16, 1              /* calculate end address of bank1 */
+       rlwinm  r3, r3, 8, 16, 23
+       or      r21, r21, r3
+
+       ori     r22, r22, MBER_BANK1    /* enable bank1 */
+       b       bank2
+
+nobank1:
+       ori     r23,r23,0x0300          /* set bank1 start to unused area */
+       ori     r24,r24,0x0300          /* set bank1 end to unused area */
+
+bank2:
+       cmpi    0, 0, r18, 0            /* bank2 present ? */
+       beq     nobank2
+  
+       andi.   r3, r16, 0x00ff         /* calculate start address of bank2 */
+       andi.   r4, r16, 0x0300
+       rlwinm  r3, r3, 16, 8, 15
+       or      r20, r20, r3
+       rlwinm  r3, r4, 8, 8, 15
+       or      r23, r23, r3
+               
+       add     r16, r16, r18           /* add to total memory size */          
+
+       subi    r3, r16, 1              /* calculate end address of bank2 */
+       andi.   r4, r3, 0x0300
+       andi.   r3, r3, 0x00ff
+       rlwinm  r3, r3, 16, 8, 15
+       or      r21, r21, r3
+       rlwinm  r3, r4, 8, 8, 15
+       or      r24, r24, r3
+
+       ori     r22, r22, (MBER_BANK2)  /* enable bank2 */
+       b       bank3
+
+nobank2:
+       lis     r3,0x0003
+       or      r23,r23,r3              /* set bank2 start to unused area */
+       or      r24,r24,r3              /* set bank2 end to unused area */
+
+bank3:
+       cmpi    0, 0, r19, 0            /* bank3 present ? */
+       beq     nobank3
+
+       andi.   r3, r16, 0x00ff         /* calculate start address of bank3 */
+       andi.   r4, r16, 0x0300
+       rlwinm  r3, r3, 24, 0, 7
+       or      r20, r20, r3
+       rlwinm  r3, r4, 16, 0, 7
+       or      r23, r23, r3
+               
+       add     r16, r16, r19           /* add to total memory size */          
+
+       subi    r3, r16, 1              /* calculate end address of bank3 */
+       andi.   r4, r3, 0x0300
+       andi.   r3, r3, 0x00ff
+       rlwinm  r3, r3, 24, 0, 7
+       or      r21, r21, r3
+       rlwinm  r3, r4, 16, 0, 7
+       or      r24, r24, r3
+
+       ori     r22, r22, (MBER_BANK3)  /* enable bank3 */
+       b       writebound
+
+nobank3:
+       lis     r3,0x0300
+       or      r23,r23,r3              /* set bank3 start to unused area */
+       or      r24,r24,r3              /* set bank3 end to unused area */
+
+writebound:
+       lis     r3, MPC106_REG@h        /* start building new reg number */
+       ori     r3, r3, MPC106_MSAR1    /* register number 0x80 */
+       stwbrx  r3, r0, r1              /* write this value to CONFIG_ADDR */
+       eieio                                           /* make sure mem. access is complete */
+       stwbrx  r20, r0, r2             /* write data to CONFIG_DATA */
+
+       lis     r3, MPC106_REG@h        /* start building new reg number */
+       ori     r3, r3, MPC106_MEAR1    /* register number 0x90 */
+       stwbrx  r3, r0, r1              /* write this value to CONFIG_ADDR */
+       eieio                           /* make sure mem. access is complete */
+       stwbrx  r21, r0, r2             /* write data to CONFIG_DATA */
+
+       lis     r3, MPC106_REG@h        /* start building new reg number */
+       ori     r3, r3, MPC106_EMSAR1   /* register number 0x88 */
+       stwbrx  r3, r0, r1              /* write this value to CONFIG_ADDR */
+       eieio                           /* make sure mem. access is complete */
+       stwbrx  r23, r0, r2             /* write data to CONFIG_DATA */
+
+       lis     r3, MPC106_REG@h        /* start building new reg number */
+       ori     r3, r3, MPC106_EMEAR1   /* register number 0x98 */
+       stwbrx  r3, r0, r1              /* write this value to CONFIG_ADDR */
+       eieio                           /* make sure mem. access is complete */
+       stwbrx  r24, r0, r2             /* write data to CONFIG_DATA */
+
+       /* set boundaries of unused banks to unused address space */
+       lis     r4, 0x0303
+       ori     r4, r4, 0x0303          /* bank 4-7 start and end adresses */
+       lis     r3, MPC106_REG@h        /* start building new reg number */
+       ori     r3, r3, MPC106_EMSAR2   /* register number 0x8C */
+       stwbrx  r3, r0, r1              /* write this value to CONFIG_ADDR */
+       eieio                           /* make sure mem. access is complete */
+       stwbrx  r4, r0, r2              /* write data to CONFIG_DATA */
+
+       lis     r3, MPC106_REG@h        /* start building new reg number */
+       ori     r3, r3, MPC106_EMEAR2   /* register number 0x9C */
+       stwbrx  r3, r0, r1              /* write this value to CONFIG_ADDR */
+       eieio                           /* make sure mem. access is complete */
+       stwbrx  r4, r0, r2              /* write data to CONFIG_DATA */
+
+
+       /* set the Memory Configuration Reg. 2 */
+       lis     r3, MPC106_REG@h        /* start building new reg number */
+       ori     r3, r3, MPC106_MCCR2    /* register number 0xf4 */
+       stwbrx  r3, r0, r1              /* write this value to CONFIG_ADDR */
+       eieio                           /* make sure mem. access is complete */
+
+       li      r3, 0x000c              /* get refresh from spd for bank0/1 */
+       bl      spdRead
+
+       cmpi    0, 0, r3, -1            /* error ? */
+       bne     common1
+
+       li      r6, 0xe0                /* error codes in r6 and r7  */
+       li      r7, 0x20
+       b       toggleError             /* fail - loop forever */
+
+common1:
+       andi.   r15, r3, 0x007f         /* mask selfrefresh bit */
+       li      r3, 0x010c              /* get refresh from spd for bank2/3 */
+       bl      spdRead
+
+       cmpi    0, 0, r3, -1            /* error ? */
+       beq     common2
+       andi.   r3, r3, 0x007f          /* mask selfrefresh bit */
+       cmp     0, 0, r3, r15           /* find the lower */
+       blt     common3
+common2:
+       mr      r3, r15
+common3:
+       li      r4, 0x1010              /* refesh cycle 1028 clocks left shifted 2 */
+       cmpli   0, 0, r3, 0x0000        /* 15.6 us ? */
+       beq     writeRefresh
+
+       li      r4, 0x0808              /* refesh cycle 514 clocks left shifted 2 */
+       cmpli   0, 0, r3, 0x0002        /* 7.8 us ? */
+       beq     writeRefresh
+
+       li      r4, 0x2020              /* refesh cycle 2056 clocks left shifted 2 */
+       cmpli   0, 0, r3, 0x0003        /* 31.3 us ? */
+       beq     writeRefresh
+
+       li      r4, 0x4040              /* refesh cycle 4112 clocks left shifted 2 */
+       cmpli   0, 0, r3, 0x0004        /* 62.5 us ? */
+       beq     writeRefresh
+
+       li      r4, 0
+       ori     r4, r4, 0x8080          /* refesh cycle 8224 clocks left shifted 2 */
+       cmpli   0, 0, r3, 0x0005        /* 125 us ? */
+       beq     writeRefresh
+
+       li      r6, 0xe0                /* error codes in r6 and r7  */
+       li      r7, 0x21
+       b       toggleError             /* fail - loop forever */
+
+writeRefresh:
+       stwbrx  r4, r0, r2              /* write data to CONFIG_DATA */
+
+       /* DRAM BANKS SHOULD BE ENABLED */
+       addi    r3, r31, (Mactivate-MessageBlock)
+       bl      Printf
+       mr      r3, r16
+       bl      OutDec
+       addi    r3, r31, (Mmbyte-MessageBlock)
+       bl      Printf
+
+       lis     r3, MPC106_REG@h        /* start building new reg number */
+       ori     r3, r3, MPC106_MBER     /* register number 0xa0 */
+       stwbrx  r3, r0, r1              /* write this value to CONFIG_ADDR */
+       eieio                           /* make sure mem. access is complete */
+       stb     r22, 0(r2)              /* write data to CONFIG_DATA */
+
+       li      r8, 0x63                /* PGMAX = 99 */
+
+       stb     r8, 3(r2)               /* write data to CONFIG_DATA */
+       
+       /* 
+          DRAM SHOULD NOW BE CONFIGURED AND ENABLED - 
+          MUST WAIT 200us BEFORE ACCESSING 
+       */
+
+       li      r0, 0x3800
+       mtctr   r0
+       
+wait200us:     
+       bdnz    wait200us
+
+       lis     r3, MPC106_REG@h        /* start building new reg number */
+       ori     r3, r3, MPC106_MCCR1    /* register number 0xf0 */
+       stwbrx  r3, r0, r1              /* write this value to CONFIG_ADDR */
+       eieio                           /* make sure mem. access is complete */
+
+       lwbrx   r4, r0, r2              /* load r4 from CONFIG_DATA */
+
+       lis     r0, MCCR1_MEMGO@h       /* MEMGO=1 */
+       ori     r0, r0, MCCR1_MEMGO@l
+       or      r4, r4, r0              /* set the MEMGO bit */
+       stwbrx  r4, r0, r2              /* write mdfd data to CONFIG_DATA */
+
+       li      r0, 0x7000
+       mtctr   r0
+wait8ref:      
+       bdnz    wait8ref
+
+       addi    r3, r31, (Mok-MessageBlock)
+       bl      Printf
+
+       mtlr    r25
+       blr
+       
+/*
+ * Infinite loop called in case of an error during RAM initialisation.
+ * error codes in r6 and r7.
+ */
+toggleError:
+       li      r0,0
+       lis     r9,127
+       ori     r9,r9,65535
+toggleError1:
+       addic   r0,r0,1
+       cmpw    cr1,r0,r9
+       ble     cr1,toggleError1
+       li      r0,0
+       lis     r9,127
+       ori     r9,r9,65535
+toggleError2:
+       addic   r0,r0,1
+       cmpw    cr1,r0,r9
+       ble     cr1,toggleError2
+       b       toggleError
+
+
+/****************************************************************************/
+
+       .set    SIO_LUNINDEX,0x07       /* SIO LUN index register */
+       .set    SIO_CNFG1,0x21          /* SIO configuration #1 register */
+       .set    SIO_PCSCI,0x23          /* SIO PCS configuration index reg */
+       .set    SIO_PCSCD,0x24          /* SIO PCS configuration data reg */
+       .set    SIO_ACTIVATE,0x30       /* SIO activate register */
+       .set    SIO_IOBASEHI,0x60       /* SIO I/O port base address, 15:8 */
+       .set    SIO_IOBASELO,0x61       /* SIO I/O port base address,  7:0 */
+       .set    SIO_LUNENABLE,0x01      /* SIO LUN enable */
+
+/*
+ * This function performs a basic initialisation of the superio chip
+ * to enable basic console output and SPD access during RAM initialisation.
+ *
+ * Upon completion, SIO resource registers are mapped as follows:
+ * Resource    Enabled         Address
+ * UART1       Yes                     COM1    3F8-3FF
+ * UART2       Yes                     COM2    2F8-2FF
+ * GPIO                Yes                     220-227
+ */
+
+.sioInit:
+       mfspr   r7,8                    /* save link register */
+
+.sioInit_87308:
+
+       /*
+        *      Get base addr of ISA I/O space
+        */
+       lis     r6,CFG_ISA_IO@h
+       ori     r6,r6,CFG_ISA_IO@l
+
+       /*
+        * Set offset to base address for config registers.
+        */
+#if defined(CFG_NS87308_BADDR_0x)
+       addi r4,r0,0x0279
+#elif defined(CFG_NS87308_BADDR_10)
+       addi r4,r0,0x015C
+#elif defined(CFG_NS87308_BADDR_11)
+       addi r4,r0,0x002E
+#endif
+
+       add     r6,r6,r4                /* add offset to base */
+       or      r3,r6,r6                /* make a copy */
+
+/*
+ * PMC (LUN 8)
+ */
+       addi    r4,r0,SIO_LUNINDEX      /* select PMC LUN */
+       addi    r5,r0,0x8
+       bl      .sio_bw
+       addi    r4,r0,SIO_IOBASEHI      /* initialize PMC address to 0x460 */
+       addi    r5,r0,0x04
+       bl      .sio_bw
+       addi    r4,r0,SIO_IOBASELO
+       addi    r5,r0,0x60
+       bl      .sio_bw
+       addi    r4,r0,SIO_ACTIVATE      /* enable PMC */
+       addi    r5,r0,SIO_LUNENABLE
+       bl      .sio_bw
+
+       lis     r8,CFG_ISA_IO@h
+       ori     r8,r8,0x0460
+       li      r9,0x03
+       stb     r9,0(r8)                /* select PMC2 register */
+       eieio
+       li      r9,0x00
+       stb     r9,1(r8)                /* SuperI/O clock source is 24MHz via X1 */
+       eieio
+
+/*
+ * map UART1 (LUN 6) or UART2 (LUN 5) to COM1 (0x3F8)
+ */
+       addi    r4,r0,SIO_LUNINDEX      /* select COM1 LUN */
+       addi    r5,r0,0x6
+       bl      .sio_bw
+       addi    r4,r0,SIO_IOBASEHI      /* initialize COM1 address to 0x3F8 */
+       addi    r5,r0,0x03
+       bl      .sio_bw
+       addi    r4,r0,SIO_IOBASELO
+       addi    r5,r0,0xF8
+       bl      .sio_bw
+       addi    r4,r0,SIO_ACTIVATE      /* enable COM1 */
+       addi    r5,r0,SIO_LUNENABLE
+       bl      .sio_bw
+/* 
+ * Init COM1 for polled output 
+ * 
+ */
+       lis     r8,CFG_ISA_IO@h
+       ori     r8,r8,0x03f8
+       li      r9,0x00
+       stb     r9,1(r8)                /* int disabled */
+       eieio
+       li      r9,0x00
+       stb     r9,4(r8)                /* modem ctrl */
+       eieio
+       li      r9,0x80
+       stb     r9,3(r8)                /* link ctrl, bank select */
+       eieio
+       li      r9,115200/CONFIG_BAUDRATE
+       stb     r9,0(r8)                /* baud rate (LSB)*/
+       eieio
+       rotrwi  r9,r9,8
+       stb     r9,1(r8)                /* baud rate (MSB) */
+       eieio
+       li      r9,0x03
+       stb     r9,3(r8)                /*  8 data bits, 1 stop bit, no parity */
+       eieio
+       li      r9,0x0b
+       stb     r9,4(r8)                /* enable the receiver and transmitter (modem ctrl) */
+       eieio
+waitEmpty:
+       lbz     r9,5(r8)                /* transmit empty */
+       andi.   r9,r9,0x40
+       beq     waitEmpty
+       li      r9,0x47
+       stb     r9,3(r8)                /*  send break; 8 data bits, 2 stop bit, no parity */
+       eieio
+
+       lis     r0, 0x0001              /*  */
+       mtctr   r0
+waitCOM1:      
+       lwz     r0, 5(r8)               /* load from port for delay */
+       bdnz    waitCOM1
+
+waitEmpty1:
+       lbz     r9,5(r8)                /* transmit empty */
+       andi.   r9,r9,0x40
+       beq     waitEmpty1
+       li      r9,0x07
+       stb     r9,3(r8)                /*  8 data bits, 2 stop bit, no parity */
+       eieio
+
+/*
+;      GPIO (LUN 7)
+*/
+       addi    r4,r0,SIO_LUNINDEX      /* select GPIO LUN */
+       addi    r5,r0,0x7
+       bl      .sio_bw
+       addi    r4,r0,SIO_IOBASEHI      /* initialize GPIO address to 0x220 */
+       addi    r5,r0,0x02
+       bl      .sio_bw
+       addi    r4,r0,SIO_IOBASELO
+       addi    r5,r0,0x20
+       bl      .sio_bw
+       addi    r4,r0,SIO_ACTIVATE      /* enable GPIO */
+       addi    r5,r0,SIO_LUNENABLE
+       bl      .sio_bw
+
+.sioInit_done:
+
+       /*
+        *      Get base addr of ISA I/O space
+        */
+       lis     r3,CFG_ISA_IO@h
+       ori     r3,r3,CFG_ISA_IO@l
+
+       addi    r3,r3,0x015C            /* adjust to superI/O 87308 base */
+       or      r6,r3,r3                /* make a copy */
+/*
+;      CS0
+*/
+       addi    r4,r0,SIO_PCSCI         /* select PCSCIR */
+       addi    r5,r0,0x00
+       bl      .sio_bw
+       addi    r4,r0,SIO_PCSCD         /* select PCSCDR */
+       addi    r5,r0,0x00
+       bl      .sio_bw
+       addi    r4,r0,SIO_PCSCI         /* select PCSCIR */
+       addi    r5,r0,0x01
+       bl      .sio_bw
+       addi    r4,r0,SIO_PCSCD         /* select PCSCDR */
+       addi    r5,r0,0x76
+       bl      .sio_bw
+       addi    r4,r0,SIO_PCSCI         /* select PCSCIR */
+       addi    r5,r0,0x02
+       bl      .sio_bw
+       addi    r4,r0,SIO_PCSCD         /* select PCSCDR */
+       addi    r5,r0,0x40
+       bl      .sio_bw
+/*
+;      CS1
+*/
+       addi    r4,r0,SIO_PCSCI         /* select PCSCIR */
+       addi    r5,r0,0x05
+       bl      .sio_bw
+       addi    r4,r0,SIO_PCSCD         /* select PCSCDR */
+       addi    r5,r0,0x00
+       bl      .sio_bw
+       addi    r4,r0,SIO_PCSCI         /* select PCSCIR */
+       addi    r5,r0,0x05
+       bl      .sio_bw
+       addi    r4,r0,SIO_PCSCD         /* select PCSCDR */
+       addi    r5,r0,0x70
+       bl      .sio_bw
+       addi    r4,r0,SIO_PCSCI         /* select PCSCIR */
+       addi    r5,r0,0x06
+       bl      .sio_bw
+       addi    r4,r0,SIO_PCSCD         /* select PCSCDR */
+       addi    r5,r0,0x1C
+       bl      .sio_bw
+/*
+;      CS2
+*/
+       addi    r4,r0,SIO_PCSCI         /* select PCSCIR */
+       addi    r5,r0,0x08
+       bl      .sio_bw
+       addi    r4,r0,SIO_PCSCD         /* select PCSCDR */
+       addi    r5,r0,0x00
+       bl      .sio_bw
+       addi    r4,r0,SIO_PCSCI         /* select PCSCIR */
+       addi    r5,r0,0x09
+       bl      .sio_bw
+       addi    r4,r0,SIO_PCSCD         /* select PCSCDR */
+       addi    r5,r0,0x71
+       bl      .sio_bw
+       addi    r4,r0,SIO_PCSCI         /* select PCSCIR */
+       addi    r5,r0,0x0A
+       bl      .sio_bw
+       addi    r4,r0,SIO_PCSCD         /* select PCSCDR */
+       addi    r5,r0,0x1C
+       bl      .sio_bw
+
+       mtspr   8,r7                    /* restore link register */
+       bclr    20,0                    /* return to caller */
+
+/*
+; routine: sio_bw
+;      this function writes a register to the SIO chip
+; call:
+;      sio_bw(sioaddr, regnum, value)
+; return:
+;      none
+*/
+.sio_bw:
+       stb     r4,0(r3)        /* write index register with register offset */
+       eieio
+       sync
+       stb     r5,1(r3)        /* 1st write */
+       eieio
+       sync
+       stb     r5,1(r3)        /* 2nd write */
+       eieio
+       sync
+       bclr    20,0            /* return to caller */
+/*
+; routine: sio_br
+;      this function reads a register from the SIO chip
+; call:
+;      sioInit(sioaddr, regnum)
+; return:
+;      register value
+*/
+.sio_br:
+       stb     r4,0(r3)        /* write index register with register offset */
+       eieio
+       sync
+       lbz     r3,1(r3)        /* retrieve specified reg offset contents */
+       eieio
+       sync
+       bclr    20,0            /* return to caller */
+
+/*
+ *     Print a message to COM1 in polling mode
+ *     r10=COM1 port, r3=(char*)string
+ */
+       .globl Printf
+Printf:
+       lis     r10,CFG_ISA_IO@h                /* COM1 port */
+       ori     r10,r10,0x03f8
+       
+WaitChr:
+       lbz     r0,5(r10)               /* read link status */
+       eieio
+       andi.   r0,r0,0x40              /* mask transmitter empty bit */
+       beq     cr0,WaitChr             /* wait till empty */
+       lbzx    r0,r0,r3                /* get char */
+       stb     r0,0(r10)               /* write to transmit reg */
+       eieio
+       addi    r3,r3,1                 /* next char */
+       lbzx    r0,r0,r3                /* get char */
+       cmpwi   cr1,r0,0                /* end of string ? */
+       bne     cr1,WaitChr
+       blr
+/*
+ *      Print 8/4/2 digits hex value to COM1 in polling mode
+ *      r10=COM1 port, r3=val
+ */
+OutHex2:
+        li      r9,4                    /* shift reg for 2 digits */
+        b       OHstart
+OutHex4:
+        li      r9,12                   /* shift reg for 4 digits */
+        b       OHstart
+               .globl OutHex
+OutHex:
+        li      r9,28                   /* shift reg for 8 digits */
+OHstart:
+        lis     r10,CFG_ISA_IO@h                /* COM1 port */
+        ori     r10,r10,0x03f8
+OutDig:
+        lbz     r0,0(r29)               /* slow down dummy read */
+        lbz     r0,5(r10)               /* read link status */
+        eieio
+        andi.   r0,r0,0x40              /* mask transmitter empty bit */
+        beq     cr0,OutDig
+        sraw    r0,r3,r9
+        clrlwi  r0,r0,28
+        cmpwi   cr1,r0,9
+        ble     cr1,digIsNum
+        addic   r0,r0,55
+        b       nextDig
+digIsNum:
+        addic   r0,r0,48
+nextDig:
+        stb     r0,0(r10)               /* write to transmit reg */
+        eieio
+        addic.  r9,r9,-4
+        bge     OutDig
+        blr                                                                                                    
+
+/*
+ *     Print 3 digits hdec value to COM1 in polling mode
+ *     r10=COM1 port, r3=val, r7=x00, r8=x0, r9=x, r0,r6=scratch
+ */
+       .globl OutDec
+OutDec:
+       li      r6, 10
+       divwu   r0, r3, r6              /* r0 = r3 / 10, r9 = r3 mod 10 */
+       mullw   r10, r0, r6
+       subf    r9, r10, r3
+
+       mr      r3, r0
+       divwu   r0, r3, r6              /* r0 = r3 / 10, r8 = r3 mod 10 */
+       mullw   r10, r0, r6
+       subf    r8, r10, r3
+
+       mr      r3, r0
+       divwu   r0, r3, r6              /* r0 = r3 / 10, r7 = r3 mod 10 */
+       mullw   r10, r0, r6
+       subf    r7, r10, r3
+
+       lis     r10,CFG_ISA_IO@h                /* COM1 port */
+       ori     r10,r10,0x03f8
+
+       or.     r7, r7, r7
+       bne     noblank1
+       li      r3, 0x20
+       b       OutDec4
+noblank1:
+       addi    r3, r7, 48              /* convert to ASCII */
+OutDec4:
+       lbz     r0,0(r31)               /* slow down dummy read */
+       lbz     r0,5(r10)               /* read link status */
+       eieio
+       andi.   r0,r0,0x40              /* mask transmitter empty bit */
+       beq     cr0,OutDec4
+       stb     r3,0(r10)               /* x00 to transmit */
+       eieio
+
+       or.     r7, r7, r8
+       beq     OutDec5
+
+       addi    r3, r8, 48              /* convert to ASCII */
+OutDec5:
+       lbz     r0,0(r31)               /* slow down dummy read */
+       lbz     r0,5(r10)               /* read link status */
+       eieio
+       andi.   r0,r0,0x40              /* mask transmitter empty bit */
+       beq     cr0,OutDec5
+       stb     r3,0(r10)               /* x0  to transmit */
+       eieio
+
+       addi    r3, r9, 48              /* convert to ASCII */
+OutDec6:
+       lbz     r0,0(r31)               /* slow down dummy read */
+       lbz     r0,5(r10)               /* read link status */
+       eieio
+       andi.   r0,r0,0x40              /* mask transmitter empty bit */
+       beq     cr0,OutDec6
+       stb     r3,0(r10)               /* x   to transmit */
+       eieio
+
+       blr
+
+/*
+ *     Print a char to COM1 in polling mode
+ *     r10=COM1 port, r3=char
+ */
+       .globl  OutChr
+OutChr:
+       lis     r10,CFG_ISA_IO@h                /* COM1 port */
+       ori     r10,r10,0x03f8
+       
+OutChr1:
+       lbz     r0,5(r10)               /* read link status */
+       eieio
+       andi.   r0,r0,0x40      /* mask transmitter empty bit */
+       beq     cr0,OutChr1             /* wait till empty */
+       stb     r3,0(r10)               /* write to transmit reg */
+       eieio
+       blr
+
+
+/*
+ *  IN:  r3 adr to read
+ *     OUT: r3 val or -1 for error
+ */
+spdRead:
+       mfspr   r26,8                   /* save link register */
+
+       lis     r30, CFG_ISA_IO@h
+       ori     r30, r30, 0x220         /* GPIO Port 1 */
+       li      r7, 0x00
+       li      r8, 0x100
+       and.    r5,r3,r8
+       beq     spdbank0
+       li      r12, 0x08
+       li      r4, 0x10
+       li      r6, 0x18
+       b       spdRead1
+spdbank0:
+       li      r12, 0x20               /* set I2C data */
+       li      r4, 0x40                /* set I2C clock */
+       li      r6, 0x60                /* set I2C clock and data */
+spdRead1:
+       li      r8, 0x80
+
+       bl      spdStart                /* access I2C bus as master */
+
+       li      r10,0xa0                /* write to SPD */
+       bl      spdWriteByte
+       bl      spdReadAck              /* ACK returns in r10 */
+       cmpw    cr0,r10,r7
+       bne     AckErr                  /* r10 must be 0, if ACK received */
+       mr      r10,r3                  /* adr to read */
+       bl      spdWriteByte
+       bl      spdReadAck
+       cmpw    cr0,r10,r7
+       bne     AckErr
+       bl      spdStart
+       li      r10,0xa1                /* read from SPD */
+       bl      spdWriteByte
+       bl      spdReadAck
+       cmpw    cr0,r10,r7
+       bne     AckErr
+       bl      spdReadByte             /* return val in r10 */
+       bl      spdWriteAck
+       bl      spdStop                 /* release I2C bus */
+
+       mr      r3,r10
+
+       mtspr   8,r26           /* restore link register */
+       blr
+
+/*
+ * ACK error occurred
+ */
+AckErr:
+       bl      spdStop
+       orc     r3,r0,r0                /* return -1 */
+       mtspr   8,r26           /* restore link register */
+       blr
+
+/*
+ * Routines to read from RAM spd.
+ * r30 - GPIO Port1 address in all cases.
+ * r4 - clock mask for SPD
+ * r6 - port mask for SPD
+ * r12 - data mask for SPD
+ */
+waitSpd:
+       li      r0,0x1000
+       mtctr   r0
+wSpd:  bdnz    wSpd
+       bclr    20,0            /* return to caller */
+
+/*
+ * establish START condition on I2C bus
+ */
+spdStart:
+       mfspr   r27,8           /* save link register */
+       stb     r6,0(r30)               /* set SDA and SCL */
+       eieio
+       stb     r6,1(r30)               /* switch GPIO to output */
+       eieio
+       bl      waitSpd
+       stb     r4,0(r30)               /* reset SDA */
+       eieio
+       bl      waitSpd
+       stb     r7,0(r30)               /* reset SCL */
+       eieio
+       bl      waitSpd
+       mtspr   8,r27
+       bclr    20,0            /* return to caller */
+
+/*
+ * establish STOP condition on I2C bus
+ */
+spdStop:
+       mfspr   r27,8           /* save link register */
+       stb     r7,0(r30)               /* reset SCL and SDA */
+       eieio
+       stb     r6,1(r30)               /* switch GPIO to output */
+       eieio
+       bl      waitSpd
+       stb     r4,0(r30)               /* set SCL */
+       eieio
+       bl      waitSpd
+       stb     r6,0(r30)               /* set SDA and SCL */
+       eieio
+       bl      waitSpd
+       stb     r7,1(r30)               /* switch GPIO to input */
+       eieio
+       mtspr   8,r27
+       bclr    20,0            /* return to caller */
+
+spdReadByte:
+       mfspr   r27,8
+       stb     r4,1(r30)               /* set GPIO for SCL output */
+       eieio
+       li      r9,0x08
+       li      r10,0x00
+loopRB:
+       stb     r7,0(r30)               /* reset SDA and SCL */
+       eieio
+       bl      waitSpd
+       stb     r4,0(r30)               /* set SCL */
+       eieio
+       bl      waitSpd
+       lbz     r5,0(r30)               /* read from GPIO Port1*/
+       rlwinm  r10, r10, 1, 0, 31
+       and.    r5,r5,r12
+       beq     clearBit
+       ori     r10,r10,0x01    /* append _1_ */
+clearBit:
+       stb     r7,0(r30)               /* reset SCL */
+       eieio
+       bl      waitSpd
+       addic.  r9,r9,-1
+       bne     loopRB
+       mtspr   8,r27
+       bclr    20,0            /* return (r10) to caller */
+
+/*
+ * spdWriteByte writes bits 24 - 31 of r10 to I2C.
+ * r8 contains bit mask 0x80
+ */
+spdWriteByte:
+       mfspr r27,8                     /* save link register */
+       li r9,0x08                      /* write octet */
+       and. r5,r10,r8
+       bne sWB1
+       stb r7,0(r30)           /* set SDA to _0_ */
+       eieio
+       b       sWB2
+sWB1:  stb     r12,0(r30)      /* set SDA to _1_ */
+       eieio
+sWB2:  stb     r6,1(r30)       /* set GPIO to output */
+       eieio
+loopWB:
+       and.    r5,r10,r8
+       bne     sWB3
+       stb     r7,0(r30)               /* set SDA to _0_ */
+       eieio
+       b       sWB4
+sWB3:  stb     r12,0(r30)      /* set SDA to _1_ */
+       eieio
+sWB4:  bl      waitSpd
+       and.    r5,r10,r8
+       bne     sWB5
+       stb     r4,0(r30)               /* set SDA to _0_ and SCL */
+       eieio
+       b       sWB6
+sWB5:  stb     r6,0(r30)       /* set SDA to _1_ and SCL */
+       eieio
+sWB6:  bl      waitSpd
+       and.    r5,r10,r8
+       bne     sWB7
+       stb     r7,0(r30)               /* set SDA to _0_ and reset SCL */
+       eieio
+       b       sWB8
+sWB7:  stb     r12,0(r30)      /* set SDA to _1_ and reset SCL */
+       eieio
+sWB8:  bl      waitSpd
+       rlwinm  r10, r10, 1, 0, 31              /* next bit */
+       addic.  r9,r9,-1
+       bne     loopWB
+       mtspr   8,r27
+       bclr    20,0            /* return to caller */
+
+/*
+ * Read ACK from SPD, return value in r10
+ */
+spdReadAck:
+       mfspr   r27,8           /* save link register */
+       stb     r4,1(r30)               /* set GPIO to output */
+       eieio
+       stb     r7,0(r30)               /* reset SDA and SCL */
+       eieio
+       bl      waitSpd
+       stb     r4,0(r30)               /* set SCL */
+       eieio
+       bl      waitSpd
+       lbz     r10,0(r30)              /* read GPIO Port 1 and mask SDA */
+       and     r10,r10,r12
+       bl      waitSpd
+       stb     r7,0(r30)               /* reset SDA and SCL */
+       eieio
+       bl      waitSpd
+       mtspr   8,r27
+       bclr    20,0            /* return (r10) to caller */
+
+spdWriteAck:
+       mfspr   r27,8
+       stb     r12,0(r30)              /* set SCL */
+       eieio
+       stb     r6,1(r30)               /* set GPIO to output */
+       eieio
+       bl      waitSpd
+       stb     r6,0(r30)               /* SDA and SCL */
+       eieio
+       bl      waitSpd
+       stb     r12,0(r30)              /* reset SCL */
+       eieio
+       bl      waitSpd
+       mtspr   8,r27
+       bclr    20,0            /* return to caller */
+
+
+
+/*
+ * Message for outport to console.
+ */
+       .globl MessageBlock
+MessageBlock:
+Mok:
+       .ascii   "....... OK \015\012\000"
+Mfail:
+       .ascii   "... FAILED \015\012\000"
+MinitLogo:
+       .ascii  "*** ELTEC Elektronik, Mainz ***\015\012"
+       .ascii  "\015\012"
+       .ascii  "BAB 750\015\012"
+       .ascii  "\015\012"
+       .ascii  "Initialising RAM\015\012\000"
+Mspd01:
+       .ascii  "  Reading SPD of bank 0/1 ........\000"
+Mspd23:
+       .ascii  "  Reading SPD of bank 2/3 ........\000"
+MfpmRam:
+       .ascii  "  RAM-Type: FPM\015\012\000"
+MedoRam:
+       .ascii  "  RAM-Type: EDO\015\012\000"
+MsdRam:
+       .ascii  "  RAM-Type: SDRAM\015\012\000"
+Mactivate:
+       .ascii  "  Activating \000"
+Mmbyte:
+       .ascii  " MB ....\000"
diff --git a/board/eltec/bab750/mpc106_pci.c b/board/eltec/bab750/mpc106_pci.c
new file mode 100644 (file)
index 0000000..5086381
--- /dev/null
@@ -0,0 +1,1005 @@
+/*
+ * (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Andreas Heppel <aheppel@sysgo.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
+ */
+
+/*
+ * PCI routines for the MPC106 CPU.
+ */
+
+#include <ppcboot.h>
+#include <command.h>
+#include <cmd_boot.h>
+#include <mpc106.h>
+#include <asm/processor.h>
+
+#ifdef CONFIG_PCI
+
+/*
+ * These are the lowest addresses allowed for PCI configuration.
+ * They correspond to lowest available I/O and Memory addresses.
+ * In the case where where multiple PMM regs are being used to map
+ * different PLB to PCI regions, each region should have it's own
+ * minimum address.
+ */
+unsigned long    LowestMemAddr1 = CFG_MIN_PCI_MEMADDR1;
+unsigned long    LowestMemAddr2 = CFG_MIN_PCI_MEMADDR2;
+unsigned long    LowestIOAddr   = CFG_PCI_PCI_IOADDR;
+
+unsigned long    MaxBusNum = 0;
+
+unsigned char          ShortPCIListing = 0;
+
+/*
+ * Subroutine:  pci_init
+ *
+ * Description: Initialises the MPC106 PCI Configuration regs.
+ *
+ * Inputs:      bd  board info structure
+ *
+ * Return:             None
+ *
+ */
+void pci_init(bd_t *bd)
+{
+       unsigned int pcicmd;
+       unsigned int pcistat;
+       unsigned int picr1;
+       unsigned int picr2;
+       unsigned int pvr = get_pvr();
+
+       puts("PCI:   ");
+
+       picr2  = PCI_Read_CFG_Reg(PCIDEVID_MPC106, PCI_PICR2, 4);
+       picr2 |= PICR2_CF_SNOOP_WS(3) |
+                PICR2_CF_FLUSH_L2 |
+                PICR2_CF_L2_HIT_DELAY(3) |
+                PICR2_CF_APHASE_WS(3);
+       picr2 &= ~(PICR2_L2_EN | PICR2_L2_UPDATE_EN);
+       PCI_Write_CFG_Reg(PCIDEVID_MPC106, PCI_PICR2, picr2, 4);
+
+       pcicmd = PCI_Read_CFG_Reg(PCIDEVID_MPC106, PCI_CFG_COMMAND, 2);
+       pcicmd |= (CMD_SERR | PCI_CMD_MASTER | PCI_CMD_MEMEN);
+       PCI_Write_CFG_Reg(PCIDEVID_MPC106, PCI_CFG_COMMAND, pcicmd, 2);
+
+       /* clear non-reserved bits in status register */
+       pcistat = PCI_Read_CFG_Reg(PCIDEVID_MPC106, PCI_CFG_STATUS, 2);
+       pcistat |= PCI_STAT_NO_RSV_BITS;
+       PCI_Write_CFG_Reg(PCIDEVID_MPC106, PCI_CFG_STATUS, pcistat, 2);
+
+       picr1 = PCI_Read_CFG_Reg(PCIDEVID_MPC106, PCI_PICR1, 4);
+       if (PVR_VER(pvr) == 0x0008)
+               picr1 |= PICR1_PROC_TYPE_603;
+       else
+               picr1 |= PICR1_PROC_TYPE_604;
+
+       picr1 |= PICR1_CF_CBA(63) | PICR1_CF_BREAD_WS(2);
+       picr1 |= PICR1_MCP_EN | PICR1_CF_DPARK |
+                PICR1_CF_LOOP_SNOOP | PICR1_CF_APARK;
+       PCI_Write_CFG_Reg(PCIDEVID_MPC106, PCI_PICR1, picr1, 4);
+
+#ifdef CONFIG_PCI_PNP
+       /*
+        * Scan the PCI bus and configure devices found.
+        */
+       puts("scanning bus for devices ...");
+
+    PCI_Scan(0);
+#endif  /* CONFIG_PCI_PNP */
+       puts("OK\n");
+}
+
+/*
+ * Subroutine:  PCI_Scan
+ *
+ * Description: Scan through all allowable PCI IDs and configure
+ *              those for which the vendor ID indicates there is a
+ *              device present. Routine scans only function 0.
+ *
+ * Inputs:      BusNum  Bus number where scanning begins
+ *
+ * Return:      Number of devices found on the bus.
+ *
+ */
+int PCI_Scan(int BusNum)
+{
+       int     Device;
+       int Function;
+       int     BusDevFunc;
+       int Found = 0;
+       unsigned int HeaderType = 0;
+       unsigned int VendorID = 0;
+
+#ifdef DEBUG
+       printf("Scanning PCI bus %d\n", BusNum);
+#endif
+
+       /*
+        * Start with device 0, the MPC106 is device 0.  sr: 09-07-2001
+        */
+       for (Device = 0; Device < CFG_MAX_PCI_DEVICES; Device++) {
+               HeaderType = 0;
+               VendorID = 0;
+               for (Function = 0; Function < CFG_MAX_PCI_FUNCTIONS; Function++) {
+                       /*
+                        * If this is not a multi-function device, we skip the rest
+                        */
+                       if (Function && !(HeaderType & 0x80))
+                               break;
+
+                       BusDevFunc = (BusNum << 16) |
+                                    (Device << 11) |
+                                    (Function << 8);
+
+                       VendorID = PCI_Read_CFG_Reg (BusDevFunc,
+                                                    PCI_CFG_VENDOR_ID, 2);
+                       if ((VendorID == 0xFFFF) || (VendorID == 0x0000))
+                               continue;
+
+                       HeaderType = PCI_Read_CFG_Reg(BusDevFunc,
+                                                     PCI_CFG_HEADER_TYPE, 1);
+#ifdef DEBUG
+                       printf("\nPCI Device %d Funtion %d is present\n",
+                               Device, Function);
+#endif
+                       if (HeaderType & 0x01) {
+                               /*  PCI-PCI Bridge */
+                               PCI_Config_Bridge(BusDevFunc);
+                       } else {
+                               PCI_Config_Device(BusDevFunc, 6);
+                       }
+                       Found++;
+               }
+       }
+       return Found;
+}
+
+/*
+ * Subroutine:  PCI_Read_CFG_Reg
+ *
+ * Description: Read a PCI configuration register
+ *
+ * Inputs:      BusDevFunc      PCI Bus+Device+Function number
+ *              Reg             Configuration register number
+ *              Width           Number of bytes to read (1, 2, or 4)
+ *
+ * Return:      Value of the configuration register read.
+ *              For reads shorter than 4 bytes, return value
+ *              is LSB-justified
+ */
+unsigned int PCI_Read_CFG_Reg(int BusDevFunc, int Reg, int Width)
+{
+       unsigned int RegAddr;
+
+       /*
+        * bit 31 must be 1 and bits 1:0 must be 0 (note Little Endian bit notation)
+        */
+       RegAddr = MPC106_REG | ((Reg|BusDevFunc) & 0xFFFFFFFC);
+
+       /*
+        * Write reg to PCI Config Address
+        */
+       out32r(MPC106_REG_ADDR, RegAddr);
+
+       /*
+        * Read reg value from PCI Config Data
+       */
+       switch (Width) {
+       case 1:
+               return ((unsigned int) in8(MPC106_REG_DATA | (Reg & 0x3)));
+       case 2:
+               return ((unsigned int) in16r(MPC106_REG_DATA | (Reg & 0x3)));
+       case 4:
+               return (in32r(MPC106_REG_DATA | (Reg & 0x3)));
+       }
+
+       return 0; /* not reached: just to satisfy the compiler */
+}
+
+/*
+ * Subroutine:  PCI_Write_CFG_Reg
+ *
+ * Description: Write a PCI configuration register.
+ *
+ * Inputs:      BusDevFunc      PCI Bus+Device+Function number
+ *              Reg             Configuration register number
+ *              Value           Configuration register value
+ *              Width           Number of bytes to write (1, 2, or 4)
+ *
+ * Return:      0       Successful
+ *
+ */
+int PCI_Write_CFG_Reg(int BusDevFunc, int Reg, unsigned int Value, int Width)
+{
+       unsigned int    RegAddr;
+
+       /*
+        * bit 31 must be 1 and bits 1:0 must be 0 (note Little Endian bit notation)
+        * (DWORD alignment)
+        */
+       RegAddr = MPC106_REG | ((Reg|BusDevFunc) & 0xFFFFFFFC);
+
+       /*
+        * Write reg to PCI Config Address
+        */
+       out32r(MPC106_REG_ADDR, RegAddr);
+
+       /*
+        * Perform a read to update the data register.
+        */
+       in32r(MPC106_REG_DATA | (Reg & 0x3));
+
+       /*
+        * Write reg value to PCI Config Data
+        */
+       switch (Width) {
+       case 1: out8   (MPC106_REG_DATA | (Reg & 0x3),
+                       (unsigned char)(Value & 0xFF));
+               break;
+       case 2: out16r (MPC106_REG_DATA | (Reg & 0x3),
+                       (unsigned short)(Value & 0xFFFF));
+               break;
+       case 4: out32r (MPC106_REG_DATA | (Reg & 0x3), Value);
+               break;
+       }
+
+       return 0;
+}
+
+/*
+ * Subroutine:  PCI_Config_Device
+ *
+ * Description: Configure a PCI device by examining its I/O and memory
+ *              address space needs and allocating address space to it by
+ *              programming the address decoders in the Base Address Registers.
+ *
+ * Inputs:             BusDevFunc    Bus+Device+Function number
+ *              NumBaseAddr   Number of base address registers to
+ *                            configure
+ *
+ * Return:      None
+ *
+ */
+void PCI_Config_Device(int BusDevFunc, int NumBaseAddr)
+{
+       int     AddrSlot, i;
+       unsigned long  AddrDesc, AddrProg, Min_Gnt_Val;
+
+       unsigned long pcicmd;
+       pcicmd = PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_COMMAND, 2);
+       PCI_Write_CFG_Reg (BusDevFunc, PCI_CFG_COMMAND,
+                          pcicmd & ~(PCI_CMD_MEMEN|PCI_CMD_IOEN), 2);
+
+       for (AddrSlot = 0; AddrSlot < NumBaseAddr; AddrSlot++) {
+               /*
+                * Write virtual address into register to check LSB.
+                * LSB == 1 => IO space, else memory space.
+                */
+               PCI_Write_CFG_Reg (BusDevFunc,
+                                  PCI_CFG_BASE_ADDRESS_0 + (4*AddrSlot),
+                                  0xFFFFFFFF, 4);
+
+               AddrDesc = PCI_Read_CFG_Reg (BusDevFunc,
+                                            PCI_CFG_BASE_ADDRESS_0 + (4*AddrSlot),
+                                            4);
+
+               if (AddrDesc == 0)              /* unimplemented, stop looking */
+                       continue;               /* 01/04/99 MCG */
+
+#ifdef DEBUG
+               printf ("Read Base Addr Reg %d = 0x%08lx\n",
+                       AddrSlot, AddrDesc);
+#endif
+
+               if ((AddrDesc & 1) == 1) {        /* I/O space */
+                       AddrDesc &= 0xFFFFFFFC;
+
+                       for (i = 0; (AddrDesc & 1) != 1; i++)
+                               AddrDesc = AddrDesc >> 1;
+
+                       AddrDesc = 1 << i;
+#ifdef DEBUG
+                       printf("  PCI I/O space = 0x%lx bytes\n", AddrDesc);
+#endif
+                       for (AddrProg = CFG_PCI_PCI_IOADDR;
+                            AddrProg < LowestIOAddr;
+                            AddrProg += AddrDesc) {
+                               ;       /* empty */
+                       }
+                       PCI_Write_CFG_Reg (BusDevFunc,
+                                          PCI_CFG_BASE_ADDRESS_0 + (4*AddrSlot),
+                                          AddrProg, 4);
+#ifdef DEBUG
+                       printf("  PCI I/O addr = 0x%lx\n", AddrProg);
+#endif
+                       LowestIOAddr = AddrProg + AddrDesc;
+               } else {                          /* memory space */
+                       AddrDesc &= 0xFFFFFFF0;
+
+                       for (i = 0; (AddrDesc & 1) != 1; i++)
+                               AddrDesc = AddrDesc >> 1;
+
+                       AddrDesc = 1 << i;
+
+                       if ((unsigned long)AddrDesc < 4096)
+                               AddrDesc = 4096;
+#ifdef DEBUG
+                       printf("  PCI memory space = 0x%lx bytes \n",AddrDesc);
+#endif
+                       for (AddrProg = CFG_MIN_PCI_MEMADDR1;
+                            AddrProg < LowestMemAddr1;
+                            AddrProg += AddrDesc) {
+                               ;       /* empty */
+                       }
+
+                       PCI_Write_CFG_Reg (BusDevFunc,
+                                          PCI_CFG_BASE_ADDRESS_0 + (4*AddrSlot),
+                                          AddrProg, 4);
+#ifdef DEBUG
+                       printf("  PCI memory addr = 0x%lx\n", AddrProg);
+#endif
+                       LowestMemAddr1 = AddrProg + AddrDesc;
+               }
+       }
+
+       /*
+        * Assign expansion ROM address
+        */
+       PCI_Write_CFG_Reg(BusDevFunc, PCI_CFG_EXPANSION_ROM, 0xFFFFFFFE, 4);
+
+       AddrDesc = PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_EXPANSION_ROM, 4);
+
+       if (AddrDesc != 0) {
+#ifdef DEBUG
+               printf("Read Expansion ROM Addr Reg = 0x%08lx\n" , AddrDesc);
+#endif
+               for (i = 0; (AddrDesc & 1) != 1; i++)
+                       AddrDesc = AddrDesc >> 1;
+
+               AddrDesc = 1 << i;
+#ifdef DEBUG
+               printf("  PCI Expansion ROM space = 0x%lx bytes\n", AddrDesc);
+#endif
+               for (AddrProg = CFG_MIN_PCI_MEMADDR1;
+                    AddrProg < LowestMemAddr1;
+                    AddrProg += AddrDesc) {
+                       ;       /* empty */
+               }
+               PCI_Write_CFG_Reg(BusDevFunc, PCI_CFG_EXPANSION_ROM, AddrProg, 4);
+#ifdef DEBUG
+               printf("  PCI Expansion ROM addr = 0x%lx\n", AddrProg);
+#endif
+               LowestMemAddr1 = AddrProg + AddrDesc;
+       }
+
+       Min_Gnt_Val = 0x80;
+       PCI_Write_CFG_Reg(BusDevFunc, PCI_CFG_LATENCY_TIMER, Min_Gnt_Val, 1);
+
+       /*
+        * Disable interrupt line, if device says it wants to use interrupts
+        */
+       if (PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_DEV_INT_PIN, 1) != 0)
+               PCI_Write_CFG_Reg(BusDevFunc, PCI_CFG_DEV_INT_LINE, 0xFF, 1);
+       /*
+        * Enable i/o space and memory space on this device
+        */
+       PCI_Write_CFG_Reg (BusDevFunc, PCI_CFG_COMMAND,
+                          pcicmd | PCI_CMD_MEMEN | PCI_CMD_IOEN, 2);
+}
+
+/*
+ * Subroutine:  PCI_Config_VGA_Device
+ *
+ * Description: Configure a PCI VGA device by examining its I/O and memory
+ *              address space needs and allocating address space to it by
+ *              programming the address decoders in the Base Address Registers.
+ *
+ * Inputs:      BusDevFunc    Bus+Device+Function number
+ *              NumBaseAddr   Number of base address registers to
+ *                            configure
+ *
+ * Return:      None
+ *
+ */
+void PCI_Config_VGA_Device(int BusDevFunc, int NumBaseAddr)
+{
+       int     AddrSlot, i;
+       unsigned long  AddrDesc, AddrProg, Min_Gnt_Val;
+
+       unsigned long pcicmd;
+       pcicmd = PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_COMMAND, 2);
+       PCI_Write_CFG_Reg (BusDevFunc, PCI_CFG_COMMAND,
+                          pcicmd & ~(PCI_CMD_MEMEN|PCI_CMD_IOEN), 2);
+
+       for (AddrSlot = 0; AddrSlot < NumBaseAddr; AddrSlot++) {
+               /*
+                * Write virtual address into register to check LSB.
+                * LSB == 1 => IO space, else memory space.
+                */
+               PCI_Write_CFG_Reg (BusDevFunc,
+                                  PCI_CFG_BASE_ADDRESS_0 + (4*AddrSlot),
+                                  0xFFFFFFFF, 4);
+
+               AddrDesc = PCI_Read_CFG_Reg (BusDevFunc,
+                                            PCI_CFG_BASE_ADDRESS_0 + (4*AddrSlot),
+                                            4);
+
+               if (AddrDesc == 0)      /* unimplemented, stop looking */
+                       continue;       /* 01/04/99 MCG */
+
+#ifdef DEBUG
+               printf("Read Base Addr Reg %d = 0x%08lx\n",AddrSlot,AddrDesc);
+#endif
+
+               if ((AddrDesc & 1) == 1) {        /* I/O space */
+                       AddrDesc &= 0xFFFFFFFC;
+
+                       for (i = 0; (AddrDesc & 1) != 1; i++)
+                               AddrDesc = AddrDesc >> 1;
+
+                       AddrDesc = 1 << i;
+#ifdef DEBUG
+                       printf("  PCI I/O space = 0x%lx bytes \n",AddrDesc);
+#endif
+                       for (AddrProg = CFG_PCI_PCI_IOADDR;
+                            AddrProg < LowestIOAddr;
+                            AddrProg += AddrDesc) {
+                               ;       /* empty */
+                       }
+
+                       PCI_Write_CFG_Reg (BusDevFunc,
+                                          PCI_CFG_BASE_ADDRESS_0 + (4*AddrSlot),
+                                          AddrProg, 4);
+                       LowestIOAddr = AddrProg + AddrDesc;
+               }
+               else {                            /* memory space */
+                       AddrDesc &= 0xFFFFFFF0;
+
+                       for (i = 0; (AddrDesc & 1) != 1; i++)
+               AddrDesc = AddrDesc >> 1;
+
+                       AddrDesc = 1 << i;
+
+                       if ((unsigned long)AddrDesc < 4096)
+                               AddrDesc = 4096;
+#ifdef DEBUG
+                       printf("  PCI Memory space = 0x%lx bytes \n",AddrDesc);
+#endif
+                       for (AddrProg = CFG_MIN_PCI_MEMADDR2;
+                            AddrProg < LowestMemAddr2;
+                            AddrProg += AddrDesc) {
+                               ;       /* empty */
+                       }
+
+                       PCI_Write_CFG_Reg (BusDevFunc,
+                                          PCI_CFG_BASE_ADDRESS_0 + (4*AddrSlot),
+                                          AddrProg, 4);
+                       LowestMemAddr2 = AddrProg + AddrDesc;
+               }
+       }
+
+       /*
+        * Assign expansion ROM address
+        */
+       PCI_Write_CFG_Reg(BusDevFunc, PCI_CFG_EXPANSION_ROM, 0xFFFFFFFE, 4);
+
+       AddrDesc = PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_EXPANSION_ROM, 4);
+
+       if (AddrDesc != 0) {
+#ifdef DEBUG
+               printf("Read Expansion ROM Addr Reg = 0x%08lx\n" , AddrDesc);
+#endif
+               for (i = 0; (AddrDesc & 1) != 1; i++)
+                       AddrDesc = AddrDesc >> 1;
+
+               AddrDesc = 1 << i;
+#ifdef DEBUG
+               printf("  PCI Expansion ROM space = 0x%lx bytes\n", AddrDesc);
+#endif
+               for (AddrProg = CFG_MIN_PCI_MEMADDR2;
+                    AddrProg < LowestMemAddr2;
+                    AddrProg += AddrDesc) {
+                       ;       /* empty */
+               }
+               PCI_Write_CFG_Reg(BusDevFunc, PCI_CFG_EXPANSION_ROM, AddrProg, 4);
+#ifdef DEBUG
+               printf("  PCI Expansion ROM addr = 0x%lx\n", AddrProg);
+#endif
+               LowestMemAddr2 = AddrProg + AddrDesc;
+       }
+
+       Min_Gnt_Val = 0x80;
+       PCI_Write_CFG_Reg(BusDevFunc, PCI_CFG_LATENCY_TIMER, Min_Gnt_Val, 1);
+
+       /*
+        * Disable interrupt line, if device says it wants to use interrupts
+        */
+       if (PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_DEV_INT_PIN, 1) != 0)
+               PCI_Write_CFG_Reg(BusDevFunc, PCI_CFG_DEV_INT_LINE, 0xFF, 1);
+
+       /*
+        * Enable i/o space, memory space and master on this device
+        */
+       PCI_Write_CFG_Reg (BusDevFunc, PCI_CFG_COMMAND,
+                          pcicmd | PCI_CMD_MEMEN | PCI_CMD_IOEN, 2);
+}
+
+/*
+ * Subroutine:  PCI_Config_Bridge
+ *
+ * Description: Configure a PCI-PCI bridge
+ *
+ * Inputs:             BusDevFunc      Bus+Device+Function number
+ *
+ * Return:      None
+ *
+ */
+void PCI_Config_Bridge(int BusDevFunc)
+{
+       int     SecondaryBus;
+       int     PrimaryBus;
+       int     CommandReg_Val;
+       int     InitialLowestIOAddr, InitialLowestMemAddr;
+       int     IOBase, MemBase;
+       int     IOLimit, MemLimit;
+
+       InitialLowestIOAddr = LowestIOAddr;
+       InitialLowestMemAddr = LowestMemAddr1;
+
+       CommandReg_Val = PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_COMMAND, 2);
+
+       /* Configure bridge's base address registers */
+       PCI_Config_Device(BusDevFunc, 2);
+
+       /*
+        * PCI_config_device() for the bridge could have changed the values in
+        * LowestIOAddr and LowestMemAddr1, if the bridge itself uses
+        * I/O and/or memory space.
+        */
+       if ( LowestIOAddr > InitialLowestIOAddr )       /* bridge uses IO space? */
+               CommandReg_Val |= 0x01;                 /* enable I/O Space */
+
+       if ( LowestMemAddr1 > InitialLowestMemAddr ) /* bridge uses memory space? */
+       CommandReg_Val |= 0x02;                         /* enable Memory Space */
+
+       PrimaryBus = (BusDevFunc >> 16) & 0xFF;
+       PCI_Write_CFG_Reg(BusDevFunc, PCIPCI_PRIMARYBUS, PrimaryBus, 1);
+
+       SecondaryBus = ++MaxBusNum;
+       PCI_Write_CFG_Reg(BusDevFunc, PCIPCI_SECONDARYBUS, SecondaryBus, 1);
+
+       /*
+        * Start with max. possible value for subordinate bus number
+        * Later, after any additional child busses are found, we'll update this
+        */
+       PCI_Write_CFG_Reg(BusDevFunc, PCIPCI_SUBORDINATEBUS, 0xFF, 1);
+
+       /* IO Base must be on 4Kb boundary.  Adjust if needed */
+       if ((LowestIOAddr % 4096) != 0)
+       LowestIOAddr += 4096 - (LowestIOAddr % 4096);
+
+       PCI_Write_CFG_Reg (BusDevFunc, PCIPCI_IOBASE,
+                          (LowestIOAddr>>8) & 0xF0, 1);
+       PCI_Write_CFG_Reg (BusDevFunc, PCIPCI_IOBASEUPPER16,
+                          (LowestIOAddr>>16) & 0xFFFF, 2);
+
+       IOBase = LowestIOAddr;
+
+       /* Mem Base must be on 1 MB boundary.  adjust if needed */
+       if ((LowestMemAddr1 % 0x100000) != 0)
+       LowestMemAddr1 += 0x100000 - (LowestMemAddr1 % 0x100000);
+
+       PCI_Write_CFG_Reg (BusDevFunc, PCIPCI_MEMBASE,
+                          (LowestMemAddr1>>16) & 0xFFF0, 2);
+       MemBase = LowestMemAddr1;
+
+       /*
+        * secondary bus on this bridge
+        */
+       PCI_Scan(SecondaryBus);
+
+       PCI_Write_CFG_Reg(BusDevFunc, PCIPCI_SUBORDINATEBUS, MaxBusNum, 1);
+
+       IOLimit = LowestIOAddr;
+       if (LowestIOAddr > IOBase) {    /* IO space used on secondary bus?   */
+               CommandReg_Val |= 0x01; /*   enable IO Space                 */
+               IOLimit--;              /*   IOLimit is highest used address */
+       }
+
+       PCI_Write_CFG_Reg (BusDevFunc, PCIPCI_IOLIMIT,
+                          ((IOLimit)>>8) & 0xF0, 1);
+       PCI_Write_CFG_Reg (BusDevFunc, PCIPCI_IOLIMITUPPER16,
+                          ((IOLimit)>>16) & 0xFFFF, 2);
+
+       /*
+        * IOLIMIT is the starting address of a 4K block forwarded by the bridge.
+        * Round LowestIOAddr up to the next 4K boundary if IO space is enabled.
+        */
+       if ((CommandReg_Val & 0x01) == 0x01)
+       LowestIOAddr = (IOLimit | 0xFFF) + 1;
+
+       MemLimit = LowestMemAddr1;
+       if ( LowestMemAddr1 > MemBase ) { /* mem. space is used on secondary bus? */
+               CommandReg_Val |= 0x02; /*   enable Memory Space                */
+               MemLimit--;             /*   MemLimit is highest used address   */
+       }
+
+       PCI_Write_CFG_Reg (BusDevFunc, PCIPCI_MEMLIMIT,
+                          ((MemLimit)>>16) & 0xFFF0, 2);
+
+       /*
+        * MEMLIMIT is the starting address of a 1M block forwarded by the bridge.
+        * Round LowestMemAddr up to the next 1M boundary
+        * if Memory space is enabled.
+        */
+
+       if ( (CommandReg_Val & 0x02) == 0x02 )
+               LowestMemAddr1 = (MemLimit | 0xFFFFF) + 1;
+
+       /* Enable Bus Master on secondary bus */
+       CommandReg_Val |= 0x04;
+
+       PCI_Write_CFG_Reg(BusDevFunc, PCI_CFG_COMMAND, CommandReg_Val, 2);
+}
+
+/*
+ * Subroutine:  PCI_Find_Device
+ *
+ * Description: Locate a PCI device by vendor and device number on any bus.
+ *
+ * Inputs:             VendorID        Value of the device's Vendor ID field
+ *              DeviceID        Value of the device's Device ID field
+ *
+ * Return:      < 0     Device not found
+ *              (int)   PCI Bus+Device+Function number
+ *
+ */
+int PCI_Find_Device(unsigned short VendorID, unsigned short DeviceID)
+{
+       int     Device;
+       int     BusDevFunc;
+       int     BusNum;
+
+#if CFG_SCSI_SCAN_BUS_REVERSE
+       for (BusNum = MaxBusNum; BusNum >= 0; BusNum--) {
+#else
+       for (BusNum = 0; BusNum <= MaxBusNum; BusNum++) {
+#endif
+               for (Device = 0; Device < CFG_MAX_PCI_DEVICES; Device++) {
+               BusDevFunc = (BusNum << 16) | (Device << 11);
+
+                       if (PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_VENDOR_ID, 2) == VendorID
+                        && PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_DEVICE_ID, 2) == DeviceID) {
+                               return (BusDevFunc);
+                       }
+               }
+       }
+       return (-1);
+}
+
+
+#if (CONFIG_COMMANDS & CFG_CMD_PCI)
+/*
+ * Follows routines for the output of infos about devices on PCI bus.
+ */
+
+/*
+ * Subroutine:  do_pciinfo
+ *
+ * Description: Handler for 'pciinfo' command..
+ *
+ * Inputs:             argv[1] may contain the number of the bus to be scanned.
+ *                             Default is bus 0.
+ *
+ * Return:      None
+ *
+ */
+void do_pciinfo(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
+{
+       char *s;
+       int     bus_no = 0;
+
+       if (argc == 2)
+       {
+               bus_no = (int)simple_strtoul(argv[1], NULL, 10);
+       }
+
+       if ((s = getenv("pci_listing")) != NULL)
+               ShortPCIListing = (strcmp(s, "short") == 0) ? 1 : 0;
+       else
+               ShortPCIListing = 0;
+
+       pciinfo(bus_no);
+}
+
+
+/*
+ * Subroutine:  pciinfo
+ *
+ * Description: Show information about devices on PCI bus.
+ *                             Depending on the define CFG_SHORT_PCI_LISTING
+ *                             the output will be more or less exhaustive.
+ *
+ * Inputs:             bus_no          the number of the bus to be scanned.
+ *
+ * Return:      None
+ *
+ */
+void pciinfo(int BusNum)
+{
+       int Device;
+       int Function;
+       unsigned int HeaderType;
+       unsigned int VendorID;
+       int BusDevFunc;
+
+       printf("Scanning PCI devices on bus %d\n", BusNum);
+
+       if (ShortPCIListing) {
+               printf("No.   VendorId   DeviceId   Device Class       Sub-Class\n");
+               printf("________________________________________________________\n");
+       }
+
+       for (Device = 0; Device < CFG_MAX_PCI_DEVICES; Device++) {
+               HeaderType = 0;
+               VendorID = 0;
+               for (Function = 0; Function < CFG_MAX_PCI_FUNCTIONS; Function++) {
+                       /*
+                        * If this is not a multi-function device, we skip the rest.
+                        */
+                       if (Function && !(HeaderType & 0x80))
+                               break;
+
+                       BusDevFunc = (BusNum << 16) |
+                                    (Device << 11) |
+                                    (Function << 8);
+
+                       VendorID = PCI_Read_CFG_Reg (BusDevFunc, PCI_CFG_VENDOR_ID, 2);
+                       if ((VendorID == 0xFFFF) || (VendorID == 0x0000))
+                               continue;
+
+                       HeaderType = PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_HEADER_TYPE, 1);
+
+                       if (ShortPCIListing)
+                               printf("%02d.%d  ", Device, Function);
+                       else
+                       printf("\nFound PCI device %d, function %d:\n",
+                               Device, Function);
+
+                       PCI_Header_Show(BusDevFunc);
+           }
+    }
+}
+
+
+/*
+ * Subroutine:  PCI_Header_Show
+ *
+ * Description: Reads the header of the specified PCI device.
+ *
+ * Inputs:             BusDevFunc      Bus+Device+Function number
+ *
+ * Return:      None
+ *
+ */
+void PCI_Header_Show(int BusDevFunc)
+{
+    PCI_HEADER_DEVICE headerDevice;
+    PCI_HEADER_BRIDGE headerBridge;
+    PCI_HEADER_DEVICE * pD = &headerDevice;
+    PCI_HEADER_BRIDGE * pB = &headerBridge;
+
+    pD->headerType = PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_HEADER_TYPE, 1);
+
+    if (pD->headerType & 0x01) {               /* PCI-to-PCI bridge */
+       pB->vendorId      = PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_VENDOR_ID, 2);
+       pB->deviceId      = PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_DEVICE_ID, 2);
+       pB->command       = PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_COMMAND, 2);
+       pB->status        = PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_STATUS, 2);
+       pB->revisionId    = PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_REVISION, 1);
+       pB->progIf        = PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_PROGRAMMING_IF, 1);
+       pB->subClass      = PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_SUBCLASS, 1);
+       pB->classCode     = PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_CLASS, 1);
+       pB->cacheLine     = PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_CACHE_LINE_SIZE, 1);
+       pB->latency       = PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_LATENCY_TIMER, 1);
+       pB->headerType    = PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_HEADER_TYPE, 1);
+       pB->bist          = PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_BIST, 1);
+       pB->base0         = PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_BASE_ADDRESS_0, 4);
+       pB->base1         = PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_BASE_ADDRESS_1, 4);
+       pB->priBus        = PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_PRIMARY_BUS, 1);
+       pB->secBus        = PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_SECONDARY_BUS, 1);
+       pB->subBus        = PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_SUBORDINATE_BUS, 1);
+       pB->secLatency    = PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_SEC_LATENCY, 1);
+       pB->ioBase        = PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_IO_BASE, 1);
+       pB->ioLimit       = PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_IO_LIMIT, 1);
+       pB->secStatus     = PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_SEC_STATUS, 2);
+       pB->memBase       = PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_MEM_BASE, 2);
+       pB->memLimit      = PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_MEM_LIMIT, 2);
+       pB->preBase       = PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_PRE_MEM_BASE, 2);
+       pB->preLimit      = PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_PRE_MEM_LIMIT, 2);
+       pB->preBaseUpper  = PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_PRE_MEM_BASE_U, 4);
+       pB->preLimitUpper = PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_PRE_MEM_LIMIT_U, 4);
+       pB->ioBaseUpper   = PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_IO_BASE_U, 2);
+       pB->ioLimitUpper  = PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_IO_LIMIT_U, 2);
+       pB->romBase       = PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_ROM_BASE, 4);
+       pB->intLine       = PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_BRG_INT_LINE, 1);
+       pB->intPin        = PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_BRG_INT_PIN, 1);
+       pB->control       = PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_BRIDGE_CONTROL, 2);
+       PCI_Bheader_Print(pB);
+    } else {                                   /* PCI device */
+       pD->vendorId      = PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_VENDOR_ID, 2);
+       pD->deviceId      = PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_DEVICE_ID, 2);
+               pD->command       = PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_COMMAND, 2);
+       pD->status        = PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_STATUS, 1);
+       pD->revisionId    = PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_REVISION, 1);
+       pD->progIf        = PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_PROGRAMMING_IF, 1);
+       pD->subClass      = PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_SUBCLASS, 1);
+       pD->classCode     = PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_CLASS, 1);
+       pD->cacheLine     = PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_CACHE_LINE_SIZE, 1);
+       pD->latency       = PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_LATENCY_TIMER, 1);
+       pD->headerType    = PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_HEADER_TYPE, 1);
+       pD->bist          = PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_BIST, 1);
+       pD->base0         = PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_BASE_ADDRESS_0, 4);
+       pD->base1         = PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_BASE_ADDRESS_1, 4);
+       pD->base2         = PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_BASE_ADDRESS_2, 4);
+       pD->base3         = PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_BASE_ADDRESS_3, 4);
+       pD->base4         = PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_BASE_ADDRESS_4, 4);
+       pD->base5         = PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_BASE_ADDRESS_5, 4);
+       pD->cis           = PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_CIS, 4);
+       pD->subVendorId   = PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_SUB_VENDER_ID, 2);
+       pD->subSystemId   = PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_SUB_SYSTEM_ID, 2);
+       pD->romBase       = PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_EXPANSION_ROM, 4);
+       pD->intLine       = PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_DEV_INT_LINE, 1);
+       pD->intPin        = PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_DEV_INT_PIN, 1);
+       pD->minGrant      = PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_MIN_GRANT, 1);
+       pD->maxLatency    = PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_MAX_LATENCY, 1);
+       PCI_Dheader_Print(pD);
+    }
+}
+
+static char *PCI_classes[] = {
+       "Build before PCI Rev2.0",
+       "Mass storage controller",
+       "Network controller     ",
+       "Display controller     ",
+       "Multimedia device      ",
+       "Memory controller      ",
+       "Bridge device          ",
+       "Simple comm. controller",
+       "Base system peripheral ",
+       "Input device           ",
+       "Docking station        ",
+       "Processor              ",
+       "Serial bus controller  ",
+       "Reserved entry         ",
+       "Does not fit any class "
+};
+
+/*
+ * Subroutine:  PCI_Dheader_Print
+ *
+ * Description: Prints the header of the specified PCI device.
+ *
+ * Inputs:             pD      pointer to device header info
+ *
+ * Return:      None
+ *
+ */
+void PCI_Dheader_Print(PCI_HEADER_DEVICE * pD)
+{
+    if (ShortPCIListing) {
+       printf("0x%.4x     0x%.4x     %s 0x%.2x\n",
+               (ushort)pD->vendorId,
+               (ushort)pD->deviceId,
+               PCI_classes[(uchar)pD->classCode],
+               (uchar)pD->subClass);
+    } else {
+       printf("  vendor ID =                   0x%.4x\n", (ushort)pD->vendorId);
+       printf("  device ID =                   0x%.4x\n", (ushort)pD->deviceId);
+       printf("  command register =            0x%.4x\n", (ushort)pD->command);
+       printf("  status register =             0x%.4x\n", (ushort)pD->status);
+       printf("  revision ID =                 0x%.2x\n", (uchar)pD->revisionId);
+       printf("  class code =                  0x%.2x (%s)\n",
+               (uchar)pD->classCode,
+               PCI_classes[(int)pD->classCode]);
+       printf("  sub class code =              0x%.2x\n", (uchar)pD->subClass);
+       printf("  programming interface =       0x%.2x\n", (uchar)pD->progIf);
+       printf("  cache line =                  0x%.2x\n", (uchar)pD->cacheLine);
+       printf("  latency time =                0x%.2x\n", (uchar)pD->latency);
+       printf("  header type =                 0x%.2x\n", (uchar)pD->headerType);
+       printf("  BIST =                        0x%.2x\n", (uchar)pD->bist);
+       printf("  base address 0 =              0x%.8x\n", pD->base0);
+       printf("  base address 1 =              0x%.8x\n", pD->base1);
+       printf("  base address 2 =              0x%.8x\n", pD->base2);
+       printf("  base address 3 =              0x%.8x\n", pD->base3);
+       printf("  base address 4 =              0x%.8x\n", pD->base4);
+       printf("  base address 5 =              0x%.8x\n", pD->base5);
+       printf("  cardBus CIS pointer =         0x%.8x\n", pD->cis);
+       printf("  sub system vendor ID =        0x%.4x\n", (ushort)pD->subVendorId);
+       printf("  sub system ID =               0x%.4x\n", (ushort)pD->subSystemId);
+       printf("  expansion ROM base address =  0x%.8x\n", pD->romBase);
+       printf("  interrupt line =              0x%.2x\n", (uchar)pD->intLine);
+       printf("  interrupt pin =               0x%.2x\n", (uchar)pD->intPin);
+       printf("  min Grant =                   0x%.2x\n", (uchar)pD->minGrant);
+       printf("  max Latency =                 0x%.2x\n", (uchar)pD->maxLatency);
+    }
+}
+
+/*
+ * Subroutine:  PCI_Bheader_Print
+ *
+ * Description: Prints the header of the specified PCI-to-PCI bridge.
+ *
+ * Inputs:             pB      pointer to bridge header info
+ *
+ * Return:      None
+ *
+ */
+void PCI_Bheader_Print (PCI_HEADER_BRIDGE * pB)
+{
+     if (ShortPCIListing) {
+       printf("0x%.4x     0x%.4x     %s 0x%.2x\n",
+               (ushort)pB->vendorId,
+               (ushort)pB->deviceId,
+               PCI_classes[(uchar)pB->classCode],
+               (uchar)pB->subClass);
+     } else {
+       printf ("  vendor ID =                   0x%.4x\n", (ushort)pB->vendorId);
+       printf ("  device ID =                   0x%.4x\n", (ushort)pB->deviceId);
+       printf ("  command register =            0x%.4x\n", (ushort)pB->command);
+       printf ("  status register =             0x%.4x\n", (ushort)pB->status);
+       printf ("  revision ID =                 0x%.2x\n", (uchar)pB->revisionId);
+       printf ("  class code =                  0x%.2x (%s)\n",
+               (uchar)pB->classCode,
+               PCI_classes[(int)pB->classCode]);
+       printf ("  sub class code =              0x%.2x\n", (uchar)pB->subClass);
+       printf ("  programming interface =       0x%.2x\n", (uchar)pB->progIf);
+       printf ("  cache line =                  0x%.2x\n", (uchar)pB->cacheLine);
+       printf ("  latency time =                0x%.2x\n", (uchar)pB->latency);
+       printf ("  header type =                 0x%.2x\n", (uchar)pB->headerType);
+       printf ("  BIST =                        0x%.2x\n", (uchar)pB->bist);
+       printf ("  base address 0 =              0x%.8x\n", pB->base0);
+       printf ("  base address 1 =              0x%.8x\n", pB->base1);
+       printf ("  primary bus number =          0x%.2x\n", (uchar)pB->priBus);
+       printf ("  secondary bus number =        0x%.2x\n", (uchar)pB->secBus);
+       printf ("  subordinate bus number =      0x%.2x\n", (uchar)pB->subBus);
+       printf ("  secondary latency timer =     0x%.2x\n", (uchar)pB->secLatency);
+       printf ("  IO base =                     0x%.2x\n", (uchar)pB->ioBase);
+       printf ("  IO limit =                    0x%.2x\n", (uchar)pB->ioLimit);
+       printf ("  secondary status =            0x%.4x\n", (ushort)pB->secStatus);
+       printf ("  memory base =                 0x%.4x\n", (ushort)pB->memBase);
+       printf ("  memory limit =                0x%.4x\n", (ushort)pB->memLimit);
+       printf ("  prefetch memory base =        0x%.4x\n", (ushort)pB->preBase);
+       printf ("  prefetch memory limit =       0x%.4x\n", (ushort)pB->preLimit);
+       printf ("  prefetch memory base upper =  0x%.8x\n", pB->preBaseUpper);
+       printf ("  prefetch memory limit upper = 0x%.8x\n", pB->preLimitUpper);
+       printf ("  IO base upper 16 bits =       0x%.4x\n", (ushort)pB->ioBaseUpper);
+       printf ("  IO limit upper 16 bits =      0x%.4x\n", (ushort)pB->ioLimitUpper);
+       printf ("  expansion ROM base address =  0x%.8x\n", pB->romBase);
+       printf ("  interrupt line =              0x%.2x\n", (uchar)pB->intLine);
+       printf ("  interrupt pin =               0x%.2x\n", (uchar)pB->intPin);
+       printf ("  bridge control =              0x%.4x\n", (ushort)pB->control);
+     }
+}
+
+#endif /* CONFIG_COMMANDS & CFG_CMD_PCI */
+
+#endif /* CONFIG_PCI */
diff --git a/board/eltec/bab750/ns16550.c b/board/eltec/bab750/ns16550.c
new file mode 100644 (file)
index 0000000..f2181c5
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * COM1 NS16550 support
+ * originally from linux source (arch/ppc/boot/ns16550.c)
+ * modified to use CFG_ISA_MEM and new defines
+ */
+
+#include <config.h>
+#include "ns16550.h"
+
+
+void
+NS16550_init(volatile struct NS16550 *com_port, int baud_divisor)
+{
+ com_port->ier = 0x00;                 /* interrupt enable register */
+ com_port->lcr = LCR_BKSE;              /* Access baud rate */
+ com_port->dll = baud_divisor & 0xff;   /* 9600 baud */
+ com_port->dlm = (baud_divisor >> 8) & 0xff;
+ com_port->lcr = LCR_8N1;               /* 8 data, 1 stop, no parity */
+ com_port->mcr = MCR_DTR | MCR_RTS;     /* RTS/DTR */
+ com_port->fcr = FCR_FIFO_EN | FCR_RXSR | FCR_TXSR;                  /* Clear & enable FIFOs */
+}
+
+void
+NS16550_reinit(volatile struct NS16550 *com_port, int baud_divisor)
+{
+ com_port->ier = 0x00;
+ com_port->lcr = LCR_BKSE;              /* Access baud rate */
+ com_port->dll = baud_divisor & 0xff;   /* 9600 baud */
+ com_port->dlm = (baud_divisor >> 8) & 0xff;
+ com_port->lcr = LCR_8N1;               /* 8 data, 1 stop, no parity */
+ com_port->mcr = MCR_DTR | MCR_RTS;     /* RTS/DTR */
+ com_port->fcr = FCR_FIFO_EN | FCR_RXSR | FCR_TXSR;                  /* Clear & enable FIFOs */
+}
+
+void NS16550_putc(volatile struct NS16550 *com_port, unsigned char c)
+{
+ while ((com_port->lsr & LSR_THRE) == 0) ;
+ com_port->thr = c;
+}
+
+unsigned char
+NS16550_getc(volatile struct NS16550 *com_port)
+{
+ while ((com_port->lsr & LSR_DR) == 0) ;
+ return (com_port->rbr);
+}
+
+int NS16550_tstc(volatile struct NS16550 *com_port)
+{
+ return ((com_port->lsr & LSR_DR) != 0);
+}
+
+
+
diff --git a/board/eltec/bab750/ns16550.h b/board/eltec/bab750/ns16550.h
new file mode 100644 (file)
index 0000000..b694e86
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * NS16550 Serial Port
+ * originally from linux source (arch/ppc/boot/ns16550.h)
+ * modified slightly to
+ * have addresses as offsets from CFG_ISA_BASE
+ * added a few more definitions
+ * added prototypes for ns16550.c
+ * reduced no of com ports to 2
+ * modifications (c) Rob Taylor, Flying Pig Systems. 2000.
+ */
+
+
+struct NS16550
+ {
+  unsigned char rbr;  /* 0 Rx */
+  unsigned char ier;  /* 1 interrupt enable register, Divisor Latch High */
+  unsigned char fcr;  /* 2 fifo control rgister */
+  unsigned char lcr;  /* 3 line control register */
+  unsigned char mcr;  /* 4 modem control register */
+  unsigned char lsr;  /* 5 line status register */
+  unsigned char msr;  /* 6 modem status register */
+  unsigned char scr;  /* 7 scratch pad register  */
+ };
+
+typedef struct NS16550 *NS16550_t;
+
+#define thr rbr        /* Tx */
+#define iir fcr        /* interrupt identification register */
+#define dll rbr        /* divisor latch low */
+#define dlm ier        /* divisor latch high */
+
+#define FCR_FIFO_EN     0x01    /*fifo enable*/
+#define FCR_RXSR        0x02    /*reciever soft reset*/
+#define FCR_TXSR        0x04    /*transmitter soft reset*/
+
+
+#define MCR_DTR         0x01
+#define MCR_RTS         0x02
+#define MCR_DMA_EN      0x04
+#define MCR_TX_DFR      0x08
+
+
+#define LCR_WLS_MSK 0x03    /* character length slect mask*/
+#define LCR_WLS_5   0x00    /* 5 bit character length */
+#define LCR_WLS_6   0x01    /* 6 bit character length */
+#define LCR_WLS_7   0x02    /* 7 bit character length */
+#define LCR_WLS_8   0x03    /* 8 bit character length */
+#define LCR_STB     0x04    /* Number of stop Bits, off = 1, on = 1.5 or 2) */
+#define LCR_PEN     0x08    /* Parity eneble*/
+#define LCR_EPS     0x10    /* Even Parity Select*/
+#define LCR_STKP    0x20    /* Stick Parity*/
+#define LCR_SBRK    0x40    /* Set Break*/
+#define LCR_BKSE    0x80    /* Bank select enable*/
+
+#define LSR_DR      0x01    /* Data ready */
+#define LSR_OE      0x02    /* Overrun */
+#define LSR_PE      0x04    /* Parity error */
+#define LSR_FE      0x08    /* Framing error */
+#define LSR_BI      0x10    /* Break */
+#define LSR_THRE    0x20    /* Xmit holding register empty */
+#define LSR_TEMT    0x40    /* Xmitter empty */
+#define LSR_ERR     0x80    /* Error */
+
+/* useful defaults for LCR*/
+#define LCR_8N1     0x03
+
+
+#define COM1 0x03F8
+#define COM2 0x02F8
+
+void NS16550_init(volatile struct NS16550 *com_port, int baud_divisor);
+void NS16550_reinit(volatile struct NS16550 *com_port, int baud_divisor);
+void NS16550_putc(volatile struct NS16550 *com_port, unsigned char c);
+unsigned char NS16550_getc(volatile struct NS16550 *com_port);
+int NS16550_tstc(volatile struct NS16550 *com_port);
+
diff --git a/board/eltec/bab750/ns87308.c b/board/eltec/bab750/ns87308.c
new file mode 100644 (file)
index 0000000..821fac9
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * (C) Copyright 2000
+ * Rob Taylor, Flying Pig Systems. robt@flyingpig.com.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * 09-18-2001 Andreas Heppel, Sysgo RTS GmbH:
+ *             Added initialisation of additional logical devices on the chip.
+ */
+#include <config.h>
+
+#include "ns87308.h"
+#include "ns16550.h"                   /* to configure the 87308's internal 16550's */
+#include <asm/mc146818rtc.h>   /* to configure 87308's RTC */
+
+void initialise_ns87308 (void)
+{
+       unsigned char data;
+
+       /*
+        * Switch floppy drive to PS/2 mode.
+        */
+       read_pnp_config(SUPOERIO_CONF1, &data);
+       data &= 0xFB;
+       write_pnp_config(SUPOERIO_CONF1, data);
+       
+       PNP_SET_DEVICE_BASE(LDEV_UART1, COM1);
+       PNP_SET_DEVICE_BASE(LDEV_UART2, COM2);
+
+       PNP_SET_DEVICE_BASE(LDEV_KBC1, KBC1_BASE);
+       write_pnp_config(LUN_CONFIG_REG, 0);
+       write_pnp_config(CBASE_HIGH, 0x00);
+       write_pnp_config(CBASE_LOW, 0x64);
+       
+       PNP_ACTIVATE_DEVICE(LDEV_MOUSE);
+    
+       PNP_SET_DEVICE_BASE(LDEV_FDC, FDC_BASE);
+       write_pnp_config(LUN_CONFIG_REG, 0x40);
+
+       PNP_SET_DEVICE_BASE(LDEV_PARP, LPT_BASE);
+       PNP_SET_DEVICE_BASE(LDEV_GPIO, GPIO_BASE);
+
+       PNP_SET_DEVICE_BASE(LDEV_RTC_APC, RTC_PORT(0));
+       PNP_SET_DEVICE_BASE(LDEV_POWRMAN, PWMAN_BASE);
+    
+       /* Enable all units */
+       pci_writeb(0x00, CFG_ISA_IO + PWMAN_BASE);
+       eieio();
+       pci_writeb(0x7d, CFG_ISA_IO + PWMAN_BASE + 1);
+
+       pci_writeb(0x01, CFG_ISA_IO + PWMAN_BASE);
+       eieio();
+       pci_writeb(0x87, CFG_ISA_IO + PWMAN_BASE + 1);
+    
+       /* SuperI/O clock source is 24MHz via X1 */
+       pci_writeb(0x03, CFG_ISA_IO + PWMAN_BASE);
+       eieio();
+       pci_writeb(0x00, CFG_ISA_IO + PWMAN_BASE + 1);
+       
+       /*
+        * set up the NVRAM access registers
+        * NVRAM's controlled by the configurable CS line from the 87308
+        */
+       PNP_PGCS_CSLINE_BASE(0, 0x76);
+       PNP_PGCS_CSLINE_CONF(0, 0x40);
+       PNP_PGCS_CSLINE_BASE(1, 0x70);
+       PNP_PGCS_CSLINE_CONF(1, 0x1C);
+       PNP_PGCS_CSLINE_BASE(2, 0x71);
+       PNP_PGCS_CSLINE_CONF(2, 0x1C);
+}
diff --git a/board/eltec/bab750/ns87308.h b/board/eltec/bab750/ns87308.h
new file mode 100644 (file)
index 0000000..6e78b85
--- /dev/null
@@ -0,0 +1,218 @@
+/*
+ * (C) Copyright 2000
+ * Rob Taylor, Flying Pig Systems. robt@flyingpig.com.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _NS87308_H_
+#define _NS87308_H_
+
+#include <asm/pci_io.h>
+
+/* Note: I couldn't find a full data sheet for the ns87308, but the ns87307 seems to be pretty
+   functionally- (and pin-) equivalent to the 87308, but the 308 has better ir support. */
+
+void initialise_ns87308(void);
+
+/*
+ * The following struct represents the GPIO registers on the NS87308/NS97307
+ */
+struct GPIO
+{
+  unsigned char dta1;  /* 0 data port 1 */
+  unsigned char dir1;  /* 1 direction port 1 */
+  unsigned char out1;  /* 2 output type port 1 */
+  unsigned char puc1;  /* 3 pull-up control port 1 */
+  unsigned char dta2;  /* 4 data port 2 */
+  unsigned char dir2;  /* 5 direction port 2 */
+  unsigned char out2;  /* 6 output type port 2 */
+  unsigned char puc2;  /* 7 pull-up control port 2  */
+};
+
+#define GPIO_BASE      0x0220
+#define LPT_BASE       0x0278
+#define KBC1_BASE      0x0060
+#define FDC_BASE       0x03F0
+
+#define PWMAN_BASE     0x460
+/*
+ * The following represents the power management registers on the NS87308/NS97307
+ */
+#define PWM_FER1 0  /* 0 function enable reg. 1 */
+#define PWM_FER2 1  /* 1 function enable reg. 2 */
+#define PWM_PMC1 2  /* 2 power mgmt. control 1 */
+#define PWM_PMC2 3  /* 3 power mgmt. control 2 */
+#define PWM_PMC3 4  /* 4 power mgmt. control 3 */
+#define PWM_WDTO 5  /* 5 watchdog time-out */
+#define PWM_WDCF 6  /* 6 watchdog config. */
+#define PWM_WDST 7  /* 7 watchdog status  */
+
+/*PNP config registers:
+ * these depend on the stated of BADDR1 and BADDR0 on startup
+ * so there's three versions here with the last two digits indicating
+ * for which configuration their valid
+ * the 1st of the two digits indicates the state of BADDR1
+ * the 2st of the two digits indicates the state of BADDR0
+ */
+
+
+#define IO_INDEX_OFFSET_0x 0x0279  /* full PnP isa Mode */
+#define IO_INDEX_OFFSET_10 0x015C  /* PnP motherboard mode */
+#define IO_INDEX_OFFSET_11 0x002E  /* PnP motherboard mode */
+#define IO_DATA_OFFSET_0x  0x0A79  /* full PnP isa Mode */
+#define IO_DATA_OFFSET_10  0x015D  /* PnP motherboard mode */
+#define IO_DATA_OFFSET_11  0x002F  /* PnP motherboard mode */
+
+#if defined(CFG_NS87308_BADDR_0x)
+#define IO_INDEX (CFG_ISA_IO + IO_INDEX_OFFSET_0x)
+#define IO_DATA  (CFG_ISA_IO + IO_DATA_OFFSET_0x)
+#elif defined(CFG_NS87308_BADDR_10)
+#define IO_INDEX (CFG_ISA_IO + IO_INDEX_OFFSET_10)
+#define IO_DATA  (CFG_ISA_IO + IO_DATA_OFFSET_10)
+#elif defined(CFG_NS87308_BADDR_11)
+#define IO_INDEX (CFG_ISA_IO + IO_INDEX_OFFSET_11)
+#define IO_DATA  (CFG_ISA_IO + IO_DATA_OFFSET_11)
+#endif
+
+/* PnP register definitions */
+
+#define SET_RD_DATA_PORT    0x00
+#define SERIAL_ISOLATION    0x01
+#define CONFIG_CONTROL      0x02
+#define WAKE_CSN            0x03
+#define RES_DATA            0x04
+#define STATUS              0x05
+#define SET_CSN             0x06
+#define LOGICAL_DEVICE      0x07
+
+/*vendor defined values */
+#define SID_REG             0x20
+#define SUPOERIO_CONF1      0x21
+#define SUPOERIO_CONF2      0x22
+#define PGCS_INDEX          0x23
+#define PGCS_DATA           0x24
+
+/* values above 30 are different for each logical device
+   but I can't be arsed to enter them all. the ones here
+   are pretty consistent between all logical devices
+   feel free to correct the situation if you want.. ;)
+   */
+#define ACTIVATE            0x30
+#define ACTIVATE_OFF        0x00
+#define ACTIVATE_ON         0x01
+
+#define BASE_ADDR_HIGH      0x60
+#define BASE_ADDR_LOW       0x61
+#define LUN_CONFIG_REG         0xF0
+#define DBASE_HIGH                     0x60    /* SIO KBC data base address, 15:8 */
+#define DBASE_LOW                      0x61    /* SIO KBC data base address,  7:0 */
+#define CBASE_HIGH                     0x62    /* SIO KBC command base addr, 15:8 */
+#define CBASE_LOW                      0x63    /* SIO KBC command base addr,  7:0 */
+
+/* the logical devices*/
+#define LDEV_KBC1           0x00       /* 2 devices for keyboard and mouse controller*/
+#define LDEV_KBC2           0x01
+#define LDEV_MOUSE          0x01
+#define LDEV_RTC_APC        0x02       /*Real Time Clock and Advanced Power Control*/
+#define LDEV_FDC            0x03       /*floppy disk controller*/
+#define LDEV_PARP           0x04       /*Parallel port*/
+#define LDEV_UART1          0x06
+#define LDEV_UART2          0x05
+#define LDEV_GPIO           0x07    /*General Purpose IO and chip select output signals*/
+#define LDEV_POWRMAN        0x08    /*Power Managment*/
+
+/*some functions and macro's for doing configuration */
+
+static inline void read_pnp_config(unsigned char index, unsigned char *data)
+{
+    pci_writeb(index,IO_INDEX);
+    pci_readb(IO_DATA, *data);
+}
+
+static inline void write_pnp_config(unsigned char index, unsigned char data)
+{
+    pci_writeb(index,IO_INDEX);
+    pci_writeb(data, IO_DATA);
+}
+
+static inline void pnp_set_device(unsigned char dev)
+{
+    write_pnp_config(LOGICAL_DEVICE, dev);
+}
+
+
+/*void write_pnp_config(unsigned char index, unsigned char data);
+void pnp_set_device(unsigned char dev);
+*/
+
+#define PNP_SET_DEVICE_BASE(dev,base) \
+   pnp_set_device(dev); \
+   write_pnp_config(ACTIVATE, ACTIVATE_OFF); \
+   write_pnp_config(BASE_ADDR_HIGH, ((base) >> 8) & 0xff ); \
+   write_pnp_config(BASE_ADDR_LOW, (base) &0xff); \
+   write_pnp_config(ACTIVATE, ACTIVATE_ON);
+
+#define PNP_ACTIVATE_DEVICE(dev) \
+   pnp_set_device(dev); \
+   write_pnp_config(ACTIVATE, ACTIVATE_ON);
+
+#define PNP_DEACTIVATE_DEVICE(dev) \
+   pnp_set_device(dev); \
+   write_pnp_config(ACTIVATE, ACTIVATE_OFF);
+
+
+static inline void write_pgcs_config(unsigned char index, unsigned char data)
+{
+    write_pnp_config(PGCS_INDEX, index);
+    write_pnp_config(PGCS_DATA, data);
+}
+
+/* these macrose configure the 3 CS lines
+   on the sandpoint board these controll NVRAM
+   CS0 is connected to NVRAMCS
+   CS1 is connected to NVRAMAS0
+   CS2 is connected to NVRAMAS1
+   */
+#define PGCS_CS_ASSERT_ON_WRITE 0x10
+#define PGCS_CS_ASSERT_ON_READ  0x20
+
+#define PNP_PGCS_CSLINE_BASE(cs, base) \
+  write_pgcs_config((cs) << 2, ((base) >> 8) & 0xff ); \
+  write_pgcs_config(((cs) << 2) + 1, (base) & 0xff );
+
+#define PNP_PGCS_CSLINE_CONF(cs, conf) \
+  write_pgcs_config(((cs) << 2) + 2, (conf) );
+
+
+/* The following sections are for 87308 extensions to the standard compoents it emulates */
+
+/* extensions to 16550*/
+
+#define MCR_MDSL_MSK    0xe0 /*mode select mask*/
+#define MCR_MDSL_UART   0x00 /*uart, default*/
+#define MCR_MDSL_SHRPIR 0x02 /*Sharp IR*/
+#define MCR_MDSL_SIR    0x03 /*SIR*/
+#define MCR_MDSL_CIR    0x06 /*Consumer IR*/
+
+#define FCR_TXFTH0      0x10    /* these bits control threshod of data level in fifo */
+#define FCR_TXFTH1      0x20    /* for interrupt trigger */
+
+
+#endif /*_NS87308_H_*/
diff --git a/board/eltec/bab750/ppcboot.lds b/board/eltec/bab750/ppcboot.lds
new file mode 100644 (file)
index 0000000..1440140
--- /dev/null
@@ -0,0 +1,129 @@
+/*
+ * (C) Copyright 2001
+ * Josh Huber <huber@mclx.com>, Mission Critical Linux, Inc.
+ *
+ * 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
+ */
+
+/*
+ * ppcboot.lds - linker script for ppcboot on the Galileo Eval Board.
+ */
+
+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
+{
+  /* Read-only sections, merged into text segment: */
+  . = + SIZEOF_HEADERS;
+  .interp : { *(.interp) }
+  .hash          : { *(.hash)          }
+  .dynsym        : { *(.dynsym)                }
+  .dynstr        : { *(.dynstr)                }
+  .rel.text      : { *(.rel.text)              }
+  .rela.text     : { *(.rela.text)     }
+  .rel.data      : { *(.rel.data)              }
+  .rela.data     : { *(.rela.data)     }
+  .rel.rodata    : { *(.rel.rodata)    }
+  .rela.rodata   : { *(.rela.rodata)   }
+  .rel.got       : { *(.rel.got)               }
+  .rela.got      : { *(.rela.got)              }
+  .rel.ctors     : { *(.rel.ctors)     }
+  .rela.ctors    : { *(.rela.ctors)    }
+  .rel.dtors     : { *(.rel.dtors)     }
+  .rela.dtors    : { *(.rela.dtors)    }
+  .rel.bss       : { *(.rel.bss)               }
+  .rela.bss      : { *(.rela.bss)              }
+  .rel.plt       : { *(.rel.plt)               }
+  .rela.plt      : { *(.rela.plt)              }
+  .init          : { *(.init)  }
+  .plt : { *(.plt) }
+  .text      :
+  {
+    cpu/mpc75x/start.o (.text)
+
+/* store the environment in a seperate sector in the boot flash */
+/*    . = 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)
+   *(.bss)
+   *(COMMON)
+  }
+  _end = . ;
+  PROVIDE (end = .);
+}
diff --git a/board/eltec/bab750/ppcboot.lds.mw.debug b/board/eltec/bab750/ppcboot.lds.mw.debug
new file mode 100644 (file)
index 0000000..59fc9a2
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ * (C) Copyright 2000
+ * Rob Taylor, Flying Pig Systems Ltd. robt@flyingpig.com
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+OUTPUT_ARCH(powerpc)
+SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
+
+MEMORY {
+       ram  (!rx) : org = 0x00000000 , LENGTH = 8M
+       code (!rx) : org = 0x00002000 , LENGTH = (4M - 0x2000)
+       rom   (rx) : org = 0xfe000000 , LENGTH = (0x100000000 - 0xfe000000)
+}
+
+SECTIONS
+{
+  _f_init = .;
+  PROVIDE(_f_init = .);
+  _f_init_rom = .;
+  PROVIDE(_f_init_rom = .);
+
+  .init : {
+      cpu/mpc8240/start.o      (.text)
+      *(.init)
+  } > ram
+  _init_size = SIZEOF(.init);
+  PROVIDE(_init_size = SIZEOF(.init));
+
+  ENTRY(_start)
+
+/*  _ftext = .;
+  _ftext_rom = .;
+  _text_size = SIZEOF(.text);
+ */
+  .text : {
+      *(.text)
+      *(.got1)
+      } > ram
+  .rodata : { *(.rodata) } > ram
+  .dtors : { *(.dtors) } > ram
+  .data : { *(.data) } > ram
+  .sdata : { *(.sdata) } > ram
+  .sdata2 : { *(.sdata2)
+      *(.got)
+    _GOT2_TABLE_ = .;
+    *(.got2)
+    _FIXUP_TABLE_ = .;
+    *(.fixup)
+    } > ram
+  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+  __fixup_entries = (. - _FIXUP_TABLE_)>>2;
+
+  .sbss : { *(.sbss) } > ram
+  .sbss2 : { *(.sbss2) } > ram
+  .bss : { *(.bss) } > ram
+  .debug : { *(.debug) } > ram
+  .line : { *(.line) } > ram
+  .symtab : { *(.symtab) } > ram
+  .shrstrtab : { *(.shstrtab) } > ram
+  .strtab : { *(.strtab) } > ram
+ /* .reloc   :
+  {
+    *(.got)
+    _GOT2_TABLE_ = .;
+    *(.got2)
+    _FIXUP_TABLE_ = .;
+    *(.fixup)
+  } > ram
+  */
+   __start___ex_table = .;
+    __ex_table : { *(__ex_table) } > ram
+    __stop___ex_table = .;
+
+
+  .ppcenv      :
+  {
+    common/environment.o (.ppcenv)
+  } > ram
+
+  _end = . ;
+  PROVIDE (end = .);
+}
+
diff --git a/board/eltec/bab750/serial.c b/board/eltec/bab750/serial.c
new file mode 100644 (file)
index 0000000..98c01ab
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * (C) Copyright 2000
+ * Rob Taylor, Flying Pig Systems. robt@flyingpig.com.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#include "config.h"
+#include "ns16550.h"
+#include "ns87308.h"
+
+/*
+ * Minimal serial functions needed to use one87308's UARTs
+ * as serial console interface.
+ */
+
+#if (CONFIG_CONS_INDEX == 1)
+#define console (CFG_ISA_IO + COM1)
+#elif (CONFIG_CONS_INDEX == 2)
+#define console (CFG_ISA_IO + COM2)
+#else
+#error "Invalid COM port for console output (must be 1 or 2)."
+#endif
+
+void
+serial_init (unsigned long dummy, int baudrate)
+{
+    int clock_divisor = 115200/baudrate;
+
+    initialise_ns87308();
+    
+    NS16550_init((NS16550_t)console, clock_divisor);
+}
+
+void
+serial_putc(const char c)
+{
+       if (c == '\n')
+               NS16550_putc((NS16550_t)console, '\r');
+               
+    NS16550_putc((NS16550_t)console, c);
+}
+
+void
+serial_puts (const char *s)
+{
+    while (*s) {
+        serial_putc (*s++);
+    }
+}
+
+
+int
+serial_getc(void)
+{
+    return NS16550_getc((NS16550_t)console);
+}
+
+int
+serial_tstc(void)
+{
+    return NS16550_tstc((NS16550_t)console);
+}
+
+void
+serial_setbrg (unsigned long dummy, int baudrate)
+{
+   int clock_divisor = 115200/baudrate;
+   NS16550_reinit((NS16550_t)console, clock_divisor);
+}
diff --git a/board/eltec/bab750/serial.h b/board/eltec/bab750/serial.h
new file mode 100644 (file)
index 0000000..94ab81e
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * (C) Copyright 2000
+ * Rob Taylor, Flying Pig Systems. robt@flyingpig.com.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
diff --git a/board/eltec/bab750/speed.c b/board/eltec/bab750/speed.c
new file mode 100644 (file)
index 0000000..0582f53
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * (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
+ */
+
+/*
+ * 09-18-2001 Andreas Heppel, Sysgo RTS GmbH <aheppel@sysgo.de>
+ *             We use the GPIO device on the ns87308 chip to read the bus speed
+ */
+
+#include <ppcboot.h>
+#include <asm/processor.h>
+#include "ns87308.h"
+
+
+/* Access functions for the Machine State Register */
+static __inline__ unsigned long get_msr(void)
+{
+    unsigned long msr;
+
+    asm volatile("mfmsr %0" : "=r" (msr) :);
+    return msr;
+}
+
+static __inline__ void set_msr(unsigned long msr)
+{
+    asm volatile("mtmsr %0" : : "r" (msr));
+}
+
+/* ------------------------------------------------------------------------- */
+
+ulong get_bus_freq (ulong ignore)
+{
+       /*
+        * The GPIO Port 1 on BAB750 reflects the bus speed.
+        */
+    volatile struct GPIO *gpio = (struct GPIO *)(CFG_ISA_IO + GPIO_BASE);
+
+       unsigned char data = gpio->dta1;
+       
+       if (data & 0x02)
+               return 66000000;
+       
+       return 83000000;
+}
+
+/* ------------------------------------------------------------------------- */
+
+
diff --git a/board/eltec/bab750/sym53c8xx.c b/board/eltec/bab750/sym53c8xx.c
new file mode 100644 (file)
index 0000000..083113e
--- /dev/null
@@ -0,0 +1,785 @@
+/*
+ * (C) Copyright 2001
+ * Denis Peter, MPL AG Switzerland, d.peter@mpl.ch.
+ *
+ * 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
+ * partly derived from
+ * linux/drivers/scsi/sym53c8xx.c
+ *
+ */
+
+/* 
+ * SCSI support based on the chip sym53C810.
+ *
+ * 09-19-2001 Andreas Heppel, Sysgo RTS GmbH <aheppel@sysgo.de>
+ *             The local version of this driver for the BAB750 board does not
+ *             use interrupts but polls the chip instead (see the call of
+ *             'handle_scsi_int()' in 'scsi_issue()'.
+ */
+
+#include <ppcboot.h>
+#include <command.h> 
+#include <cmd_boot.h>
+#include <mpc106.h>
+#include <asm/processor.h>
+#include "sym53c8xx.h"
+#include <scsi.h>
+
+#undef SYM53C8XX_DEBUG
+
+#ifdef SYM53C8XX_DEBUG
+#define        PRINTF(fmt,args...)     printf (fmt ,##args)
+#else
+#define PRINTF(fmt,args...)
+#endif
+
+#if (CONFIG_COMMANDS & CFG_CMD_SCSI) && defined(CONFIG_SCSI_SYM53C8XX)
+
+
+#undef SCSI_SINGLE_STEP
+/*
+ * Single Step is only used for debug purposes
+ */
+#ifdef SCSI_SINGLE_STEP
+static unsigned long start_script_select;
+static unsigned long start_script_msgout;
+static unsigned long start_script_msgin;
+static unsigned long start_script_msg_ext;
+static unsigned long start_script_cmd;
+static unsigned long start_script_data_in;
+static unsigned long start_script_data_out;
+static unsigned long start_script_status;
+static unsigned long start_script_complete;
+static unsigned long start_script_error;
+static unsigned long start_script_reselection;
+static unsigned int len_script_select;
+static unsigned int len_script_msgout;
+static unsigned int len_script_msgin;
+static unsigned int len_script_msg_ext;
+static unsigned int len_script_cmd;
+static unsigned int len_script_data_in;
+static unsigned int len_script_data_out;
+static unsigned int len_script_status;
+static unsigned int len_script_complete;
+static unsigned int len_script_error;
+static unsigned int len_script_reselection;
+#endif
+
+
+static unsigned short scsi_int_mask;           /* shadow register for SCSI related interrupts */
+static unsigned char  script_int_mask; /* shadow register for SCRIPT related interrupts */
+static unsigned long script_select[8]; /* script for selection */
+static unsigned long script_msgout[8]; /* script for message out phase (NOT USED) */
+static unsigned long script_msgin[14]; /* script for message in phase */
+static unsigned long script_msg_ext[32]; /* script for message in phase when more than 1 byte message */
+static unsigned long script_cmd[18];    /* script for command phase */
+static unsigned long script_data_in[8]; /* script for data in phase */
+static unsigned long script_data_out[8]; /* script for data out phase */
+static unsigned long script_status[6]; /* script for status phase */
+static unsigned long script_complete[10]; /* script for complete */
+static unsigned long script_reselection[4]; /* script for reselection (NOT USED) */
+static unsigned long script_error[2]; /* script for error handling */
+
+static unsigned long int_stat[3]; /* interrupt status */
+static unsigned long scsi_mem_addr; /* base memory address =SCSI_MEM_ADDRESS; */
+
+
+#define SCSI_MAX_RETRY 3 /* number of retries in scsi_issue() */
+
+#define SCSI_MAX_RETRY_NOT_READY 10 /* number of retries when device is not ready */
+#define SCSI_NOT_READY_TIME_OUT 500 /* timeout per retry when not ready */
+
+/*********************************************************************************
+ * forward declerations
+ */
+
+void scsi_chip_init(void);
+void handle_scsi_int(void);
+
+
+/********************************************************************************
+ * reports SCSI errors to the user
+ */
+void scsi_print_error(ccb *pccb)
+{
+       int i;
+       printf("SCSI Error: Target %d LUN %d Command %02X\n",pccb->target, pccb->lun, pccb->cmd[0]);
+       printf("       CCB: ");
+       for(i=0;i<pccb->cmdlen;i++)
+               printf("%02X ",pccb->cmd[i]); 
+       printf("(len=%d)\n",pccb->cmdlen);
+       printf("     Cntrl: ");
+       switch(pccb->contr_stat) {
+               case SIR_COMPLETE:                                              printf("Complete (no Error)\n"); break;
+               case SIR_SEL_ATN_NO_MSG_OUT:    printf("Selected with ATN no MSG out phase\n"); break;
+               case SIR_CMD_OUT_ILL_PH:                        printf("Command out illegal phase\n"); break;
+               case SIR_MSG_RECEIVED:                          printf("MSG received Error\n"); break;
+               case SIR_DATA_IN_ERR:                           printf("Data in Error\n"); break;
+               case SIR_DATA_OUT_ERR:                          printf("Data out Error\n"); break;
+               case SIR_SCRIPT_ERROR:                          printf("Script Error\n"); break;
+               case SIR_MSG_OUT_NO_CMD:                        printf("MSG out no Command phase\n"); break;
+               case SIR_MSG_OVER7:                                     printf("MSG in over 7 bytes\n"); break;
+               case INT_ON_FY:                                                         printf("Interrupt on fly\n"); break;
+               case SCSI_SEL_TIME_OUT:                         printf("SCSI Selection Timeout\n"); break;
+               case SCSI_HNS_TIME_OUT:                         printf("SCSI Handshake Timeout\n"); break;
+               case SCSI_MA_TIME_OUT:                          printf("SCSI Phase Error\n"); break;
+               case SCSI_UNEXP_DIS:                                    printf("SCSI unexpected disconnect\n"); break;
+               default:                                                                                        printf("unknown status %lx\n",pccb->contr_stat); break;
+       }
+       printf("     Sense: SK %x (",pccb->sense_buf[2]&0x0f);
+       switch(pccb->sense_buf[2]&0xf) {
+               case SENSE_NO_SENSE: printf("No Sense)"); break;
+               case SENSE_RECOVERED_ERROR: printf("Recovered Error)"); break;
+               case SENSE_NOT_READY:   printf("Not Ready)"); break;
+               case SENSE_MEDIUM_ERROR: printf("Medium Error)"); break;
+               case SENSE_HARDWARE_ERROR: printf("Hardware Error)"); break;
+               case SENSE_ILLEGAL_REQUEST: printf("Illegal request)"); break;
+               case SENSE_UNIT_ATTENTION: printf("Unit Attention)"); break;
+               case SENSE_DATA_PROTECT: printf("Data Protect)"); break;
+               case SENSE_BLANK_CHECK: printf("Blank check)"); break;
+               case SENSE_VENDOR_SPECIFIC: printf("Vendor specific)"); break;
+               case SENSE_COPY_ABORTED: printf("Copy aborted)"); break;
+               case SENSE_ABORTED_COMMAND:     printf("Aborted Command)"); break;
+               case SENSE_VOLUME_OVERFLOW:     printf("Volume overflow)"); break;
+               case SENSE_MISCOMPARE: printf("Misscompare\n"); break;
+               default: printf("Illegal Sensecode\n"); break;
+       }                       
+       printf(" ASC %x ASCQ %x\n",pccb->sense_buf[12],pccb->sense_buf[13]);
+       printf("    Status: ");
+       switch(pccb->status) {
+               case S_GOOD :   printf("Good\n"); break;
+               case S_CHECK_COND: printf("Check condition\n"); break;
+               case S_COND_MET: printf("Condition Met\n"); break;
+               case S_BUSY: printf("Busy\n"); break;
+               case S_INT: printf("Intermediate\n"); break;
+               case S_INT_COND_MET: printf("Intermediate condition met\n"); break;
+               case S_CONFLICT: printf("Reservation conflict\n"); break;
+               case S_TERMINATED: printf("Command terminated\n"); break;
+               case S_QUEUE_FULL: printf("Task set full\n"); break;
+               default: printf("unknown: %02X\n",pccb->status); break;
+       }
+                       
+}
+
+
+
+/******************************************************************************
+ * sets-up the SCSI controller 
+ * the base memory address is retrived via the PCI_Read_CFG_Reg
+ */
+void scsi_low_level_init(int busdevfunc)
+{
+       unsigned long   cmd;
+       unsigned long addr;
+       unsigned char vec;
+       vec=PCI_Read_CFG_Reg(busdevfunc, PCI_CFG_DEV_INT_LINE, 1);
+       addr=PCI_Read_CFG_Reg(busdevfunc, PCI_CFG_BASE_ADDRESS_1, 4);
+
+       addr |= CFG_60X_PCI_MEM_OFFSET;
+       /*
+        * Enable bus mastering in case this has not been done, yet.
+        */
+       cmd=PCI_Read_CFG_Reg(busdevfunc, PCI_CFG_COMMAND, 4);
+       cmd |= PCI_CMD_MASTER;
+       PCI_Write_CFG_Reg(busdevfunc, PCI_CFG_COMMAND, cmd, 4);
+       
+       scsi_mem_addr=addr;
+       scsi_chip_init();
+       scsi_bus_reset();
+}
+
+
+/************************************************************************************
+ * Low level Part of SCSI Driver
+ */
+/*
+ * big-endian -> little endian conversion for the script
+ */ 
+unsigned long swap_script(unsigned long val)
+{
+       unsigned long tmp;
+       tmp = ((val>>24)&0xff) | ((val>>8)&0xff00) | ((val<<8)&0xff0000) | ((val<<24)&0xff000000);
+       return tmp;
+}
+
+
+void scsi_write_byte(ulong offset,unsigned char val)
+{
+       out8(scsi_mem_addr+offset,val);
+}
+
+
+unsigned char scsi_read_byte(ulong offset)
+{
+       return(in8(scsi_mem_addr+offset));
+}
+
+
+/********************************************************************************
+ * interrupt handler
+ */
+void handle_scsi_int(void)
+{
+       unsigned char stat,stat1,stat2;
+       unsigned short sstat;
+       int i;
+#ifdef SCSI_SINGLE_STEP
+       unsigned long tt;
+#endif
+       stat=scsi_read_byte(ISTAT);
+       if((stat & DIP)==DIP) { /* DMA Interrupt pending */
+               stat1=scsi_read_byte(DSTAT);
+#ifdef SCSI_SINGLE_STEP 
+               if((stat1 & SSI)==SSI)
+               {
+                       tt=in32r(scsi_mem_addr+DSP);
+                       if(((tt)>=start_script_select) && ((tt)<start_script_select+len_script_select)) {
+                               printf("select %d\n",(tt-start_script_select)>>2);
+                               goto end_single;
+                       }
+                       if(((tt)>=start_script_msgout) && ((tt)<start_script_msgout+len_script_msgout)) {
+                               printf("msgout %d\n",(tt-start_script_msgout)>>2);
+                               goto end_single;
+                       }
+                       if(((tt)>=start_script_msgin) && ((tt)<start_script_msgin+len_script_msgin)) {
+                               printf("msgin %d\n",(tt-start_script_msgin)>>2);
+                               goto end_single;
+                       }
+                       if(((tt)>=start_script_msg_ext) && ((tt)<start_script_msg_ext+len_script_msg_ext)) {
+                               printf("msgin_ext %d\n",(tt-start_script_msg_ext)>>2);
+                               goto end_single;
+                       }
+                       if(((tt)>=start_script_cmd) && ((tt)<start_script_cmd+len_script_cmd)) {
+                               printf("cmd %d\n",(tt-start_script_cmd)>>2);
+                               goto end_single;
+                       }
+                       if(((tt)>=start_script_data_in) && ((tt)<start_script_data_in+len_script_data_in)) {
+                               printf("data_in %d\n",(tt-start_script_data_in)>>2);
+                               goto end_single;
+                       }
+                       if(((tt)>=start_script_data_out) && ((tt)<start_script_data_out+len_script_data_out)) {
+                               printf("data_out %d\n",(tt-start_script_data_out)>>2);
+                               goto end_single;
+                       }
+                       if(((tt)>=start_script_status) && ((tt)<start_script_status+len_script_status)) {
+                               printf("status %d\n",(tt-start_script_status)>>2);
+                               goto end_single;
+                       }
+                       if(((tt)>=start_script_complete) && ((tt)<start_script_complete+len_script_complete)) {
+                               printf("complete %d\n",(tt-start_script_complete)>>2);
+                               goto end_single;
+                       }
+                       if(((tt)>=start_script_error) && ((tt)<start_script_error+len_script_error)) {
+                               printf("error %d\n",(tt-start_script_error)>>2);
+                               goto end_single;
+                       }
+                       if(((tt)>=start_script_reselection) && ((tt)<start_script_reselection+len_script_reselection)) {
+                               printf("reselection %d\n",(tt-start_script_reselection)>>2);
+                               goto end_single;
+                       }
+                       printf("sc: %lx\n",tt);
+end_single:
+                       stat2=scsi_read_byte(DCNTL);
+                       stat2|=STD;
+                       scsi_write_byte(DCNTL,stat2);
+               }
+#endif
+               if((stat1 & SIR)==SIR) /* script interrupt */
+               {
+                       int_stat[0]=in32(scsi_mem_addr+DSPS);
+               }
+               if((stat1 & DFE)==0) { /* fifo not epmty */
+                       scsi_write_byte(CTEST3,CLF); /* Clear DMA FIFO */
+                       stat2=scsi_read_byte(STEST3);
+                       scsi_write_byte(STEST3,(stat2 | CSF)); /* Clear SCSI FIFO */
+               }       
+       }
+       if((stat & SIP)==SIP) {  /* scsi interrupt */
+               sstat = (unsigned short)scsi_read_byte(SIST+1);
+               sstat <<=8;
+               sstat |= (unsigned short)scsi_read_byte(SIST);
+               for(i=0;i<3;i++) {
+                       if(int_stat[i]==0)
+                               break; /* found an empty int status */
+               }
+               int_stat[i]=SCSI_INT_STATE | sstat;
+               stat1=scsi_read_byte(DSTAT);
+               if((stat1 & DFE)==0) { /* fifo not epmty */
+                       scsi_write_byte(CTEST3,CLF); /* Clear DMA FIFO */
+                       stat2=scsi_read_byte(STEST3);
+                       scsi_write_byte(STEST3,(stat2 | CSF)); /* Clear SCSI FIFO */
+               }       
+       }
+       if((stat & INTF)==INTF) { /* interrupt on Fly */
+               scsi_write_byte(ISTAT,stat); /* clear it */
+               for(i=0;i<3;i++) {
+                       if(int_stat[i]==0)
+                               break; /* found an empty int status */
+               }
+               int_stat[i]=INT_ON_FY;
+       }
+}
+
+void scsi_bus_reset(void)
+{
+       unsigned char t;
+       int i;
+       int end = CFG_SCSI_SPIN_UP_TIME*1000;
+       
+       t=scsi_read_byte(SCNTL1);
+       scsi_write_byte(SCNTL1,(t | CRST));
+       udelay(50);
+       scsi_write_byte(SCNTL1,t);
+
+       puts("SCSI:  waiting for devices to spin up");
+       for(i=0;i<end;i++) {
+               udelay(1000); /* give the devices time to spin up */
+               if (i % 1000 == 0)
+                       putc('.');
+       }
+       putc('\n');     
+       scsi_chip_init(); /* reinit the chip ...*/
+
+}
+
+void scsi_int_enable(void)
+{
+       scsi_write_byte(SIEN,(unsigned char)scsi_int_mask);
+       scsi_write_byte(SIEN+1,(unsigned char)(scsi_int_mask>>8));
+       scsi_write_byte(DIEN,script_int_mask);
+}
+
+void scsi_write_dsp(unsigned long start)
+{
+       unsigned long val;
+#ifdef SCSI_SINGLE_STEP 
+       unsigned char t;
+#endif
+       val = start;
+       out32r(scsi_mem_addr + DSP,start);      
+#ifdef SCSI_SINGLE_STEP 
+       t=scsi_read_byte(DCNTL);
+  t|=STD;
+       scsi_write_byte(DCNTL,t);
+#endif
+}
+
+/* only used for debug purposes */
+void scsi_print_script(void)
+{
+       printf("script_select @         0x%08lX\n",(unsigned long)&script_select[0]);
+       printf("script_msgout @         0x%08lX\n",(unsigned long)&script_msgout[0]);
+       printf("script_msgin @          0x%08lX\n",(unsigned long)&script_msgin[0]);
+       printf("script_msgext @         0x%08lX\n",(unsigned long)&script_msg_ext[0]);
+       printf("script_cmd @            0x%08lX\n",(unsigned long)&script_cmd[0]);
+       printf("script_data_in @        0x%08lX\n",(unsigned long)&script_data_in[0]);
+       printf("script_data_out @       0x%08lX\n",(unsigned long)&script_data_out[0]);
+       printf("script_status @         0x%08lX\n",(unsigned long)&script_status[0]);
+       printf("script_complete @       0x%08lX\n",(unsigned long)&script_complete[0]);
+       printf("script_error @          0x%08lX\n",(unsigned long)&script_error[0]);
+}
+
+
+
+void scsi_set_script(ccb *pccb)
+{
+       int i;
+       i=0;
+       script_select[i++]=swap_script(SCR_REG_REG(GPREG, SCR_AND, 0xfe));
+       script_select[i++]=0; /* LED ON */
+       script_select[i++]=swap_script(SCR_CLR(SCR_TRG)); /* select initiator mode */
+       script_select[i++]=0;
+       /* script_select[i++]=swap_script(SCR_SEL_ABS_ATN | pccb->target << 16); */
+       script_select[i++]=swap_script(SCR_SEL_ABS | pccb->target << 16);
+       script_select[i++]=swap_script(phys_to_bus(&script_cmd[4])); /* error handling */
+       script_select[i++]=swap_script(SCR_JUMP); /* next section */
+       /*      script_select[i++]=swap_script((unsigned long)&script_msgout[0]); */ /* message out */
+       script_select[i++]=swap_script(phys_to_bus(&script_cmd[0])); /* command out */
+
+#ifdef SCSI_SINGLE_STEP
+       start_script_select=(unsigned long)&script_select[0];
+       len_script_select=i*4;
+#endif
+
+       i=0;
+       script_msgout[i++]=swap_script(SCR_INT ^ IFFALSE (WHEN (SCR_MSG_OUT)));
+       script_msgout[i++]=SIR_SEL_ATN_NO_MSG_OUT;
+       script_msgout[i++]=swap_script( SCR_MOVE_ABS(1) ^ SCR_MSG_OUT);
+       script_msgout[i++]=swap_script(phys_to_bus(&pccb->msgout[0]));
+       script_msgout[i++]=swap_script(SCR_JUMP ^ IFTRUE (WHEN (SCR_COMMAND))); /* if Command phase */
+       script_msgout[i++]=swap_script(phys_to_bus(&script_cmd[0])); /* switch to command */
+       script_msgout[i++]=swap_script(SCR_INT); /* interrupt if not */
+       script_msgout[i++]=SIR_MSG_OUT_NO_CMD;
+
+#ifdef SCSI_SINGLE_STEP
+       start_script_msgout=(unsigned long)&script_msgout[0];
+       len_script_msgout=i*4;
+#endif
+       i=0;
+       script_cmd[i++]=swap_script(SCR_MOVE_ABS(pccb->cmdlen) ^ SCR_COMMAND);
+       script_cmd[i++]=swap_script(phys_to_bus(&pccb->cmd[0]));
+       script_cmd[i++]=swap_script(SCR_JUMP ^ IFTRUE (WHEN (SCR_MSG_IN))); /* message in ? */
+       script_cmd[i++]=swap_script(phys_to_bus(&script_msgin[0]));
+       script_cmd[i++]=swap_script(SCR_JUMP ^ IFTRUE (IF (SCR_DATA_OUT))); /* data out ? */
+       script_cmd[i++]=swap_script(phys_to_bus(&script_data_out[0]));
+       script_cmd[i++]=swap_script(SCR_JUMP ^ IFTRUE (IF (SCR_DATA_IN))); /* data in ? */
+       script_cmd[i++]=swap_script(phys_to_bus(&script_data_in[0]));
+       script_cmd[i++]=swap_script(SCR_JUMP ^ IFTRUE (IF (SCR_STATUS)));  /* status ? */
+       script_cmd[i++]=swap_script(phys_to_bus(&script_status[0]));
+       script_cmd[i++]=swap_script(SCR_JUMP ^ IFTRUE (IF (SCR_COMMAND)));  /* command ? */
+       script_cmd[i++]=swap_script(phys_to_bus(&script_cmd[0]));
+       script_cmd[i++]=swap_script(SCR_JUMP ^ IFTRUE (IF (SCR_MSG_OUT)));  /* message out ? */
+       script_cmd[i++]=swap_script(phys_to_bus(&script_msgout[0]));
+       script_cmd[i++]=swap_script(SCR_JUMP ^ IFTRUE (IF (SCR_MSG_IN))); /* just for error handling message in ? */
+       script_cmd[i++]=swap_script(phys_to_bus(&script_msgin[0]));
+       script_cmd[i++]=swap_script(SCR_INT); /* interrupt if not */
+       script_cmd[i++]=SIR_CMD_OUT_ILL_PH;
+#ifdef SCSI_SINGLE_STEP
+       start_script_cmd=(unsigned long)&script_cmd[0];
+       len_script_cmd=i*4;
+#endif
+       i=0;
+       script_data_out[i++]=swap_script(SCR_MOVE_ABS(pccb->datalen)^ SCR_DATA_OUT); /* move */
+       script_data_out[i++]=swap_script(phys_to_bus(pccb->pdata)); /* pointer to buffer */
+       script_data_out[i++]=swap_script(SCR_JUMP ^ IFTRUE (WHEN (SCR_STATUS)));
+       script_data_out[i++]=swap_script(phys_to_bus(&script_status[0]));
+       script_data_out[i++]=swap_script(SCR_INT);
+       script_data_out[i++]=SIR_DATA_OUT_ERR;
+
+#ifdef SCSI_SINGLE_STEP
+       start_script_data_out=(unsigned long)&script_data_out[0];
+       len_script_data_out=i*4;
+#endif
+       i=0;
+       script_data_in[i++]=swap_script(SCR_MOVE_ABS(pccb->datalen)^ SCR_DATA_IN); /* move  */
+       script_data_in[i++]=swap_script(phys_to_bus(pccb->pdata)); /* pointer to buffer */
+       script_data_in[i++]=swap_script(SCR_JUMP ^ IFTRUE (WHEN (SCR_STATUS)));
+       script_data_in[i++]=swap_script(phys_to_bus(&script_status[0]));
+       script_data_in[i++]=swap_script(SCR_INT);
+       script_data_in[i++]=SIR_DATA_IN_ERR;
+#ifdef SCSI_SINGLE_STEP
+       start_script_data_in=(unsigned long)&script_data_in[0];
+       len_script_data_in=i*4;
+#endif
+       i=0;
+       script_msgin[i++]=swap_script(SCR_MOVE_ABS (1) ^ SCR_MSG_IN);
+       script_msgin[i++]=swap_script(phys_to_bus(&pccb->msgin[0]));
+       script_msgin[i++]=swap_script(SCR_JUMP ^ IFTRUE (DATA (M_COMPLETE)));
+       script_msgin[i++]=swap_script(phys_to_bus(&script_complete[0]));
+       script_msgin[i++]=swap_script(SCR_JUMP ^ IFTRUE (DATA (M_DISCONNECT)));
+       script_msgin[i++]=swap_script(phys_to_bus(&script_complete[0]));
+       script_msgin[i++]=swap_script(SCR_JUMP ^ IFTRUE (DATA (M_SAVE_DP)));
+       script_msgin[i++]=swap_script(phys_to_bus(&script_complete[0]));
+       script_msgin[i++]=swap_script(SCR_JUMP ^ IFTRUE (DATA (M_RESTORE_DP)));
+       script_msgin[i++]=swap_script(phys_to_bus(&script_complete[0]));
+       script_msgin[i++]=swap_script(SCR_JUMP ^ IFTRUE (DATA (M_EXTENDED)));
+       script_msgin[i++]=swap_script(phys_to_bus(&script_msg_ext[0]));
+       script_msgin[i++]=swap_script(SCR_INT);
+       script_msgin[i++]=SIR_MSG_RECEIVED;
+#ifdef SCSI_SINGLE_STEP
+       start_script_msgin=(unsigned long)&script_msgin[0];
+       len_script_msgin=i*4;
+#endif
+       i=0;
+       script_msg_ext[i++]=swap_script(SCR_CLR (SCR_ACK)); /* clear ACK */
+       script_msg_ext[i++]=0;
+       script_msg_ext[i++]=swap_script(SCR_MOVE_ABS (1) ^ SCR_MSG_IN); /* assuming this is the msg length */
+       script_msg_ext[i++]=swap_script(phys_to_bus(&pccb->msgin[1]));  
+       script_msg_ext[i++]=swap_script(SCR_JUMP ^ IFFALSE (IF (SCR_MSG_IN))); 
+       script_msg_ext[i++]=swap_script(phys_to_bus(&script_complete[0])); /* no more bytes */
+       script_msg_ext[i++]=swap_script(SCR_MOVE_ABS (1) ^ SCR_MSG_IN); /* next */
+       script_msg_ext[i++]=swap_script(phys_to_bus(&pccb->msgin[2]));  
+       script_msg_ext[i++]=swap_script(SCR_JUMP ^ IFFALSE (IF (SCR_MSG_IN))); 
+       script_msg_ext[i++]=swap_script(phys_to_bus(&script_complete[0])); /* no more bytes */
+       script_msg_ext[i++]=swap_script(SCR_MOVE_ABS (1) ^ SCR_MSG_IN); /* next */
+       script_msg_ext[i++]=swap_script(phys_to_bus(&pccb->msgin[3]));  
+       script_msg_ext[i++]=swap_script(SCR_JUMP ^ IFFALSE (IF (SCR_MSG_IN))); 
+       script_msg_ext[i++]=swap_script(phys_to_bus(&script_complete[0])); /* no more bytes */
+       script_msg_ext[i++]=swap_script(SCR_MOVE_ABS (1) ^ SCR_MSG_IN); /* next */
+       script_msg_ext[i++]=swap_script(phys_to_bus(&pccb->msgin[4]));  
+       script_msg_ext[i++]=swap_script(SCR_JUMP ^ IFFALSE (IF (SCR_MSG_IN))); 
+       script_msg_ext[i++]=swap_script(phys_to_bus(&script_complete[0])); /* no more bytes */
+       script_msg_ext[i++]=swap_script(SCR_MOVE_ABS (1) ^ SCR_MSG_IN); /* next */
+       script_msg_ext[i++]=swap_script(phys_to_bus(&pccb->msgin[5]));  
+       script_msg_ext[i++]=swap_script(SCR_JUMP ^ IFFALSE (IF (SCR_MSG_IN))); 
+       script_msg_ext[i++]=swap_script(phys_to_bus(&script_complete[0])); /* no more bytes */
+       script_msg_ext[i++]=swap_script(SCR_MOVE_ABS (1) ^ SCR_MSG_IN); /* next */
+       script_msg_ext[i++]=swap_script(phys_to_bus(&pccb->msgin[6]));  
+       script_msg_ext[i++]=swap_script(SCR_JUMP ^ IFFALSE (IF (SCR_MSG_IN))); 
+       script_msg_ext[i++]=swap_script(phys_to_bus(&script_complete[0])); /* no more bytes */
+       script_msg_ext[i++]=swap_script(SCR_MOVE_ABS (1) ^ SCR_MSG_IN); /* next */
+       script_msg_ext[i++]=swap_script(phys_to_bus(&pccb->msgin[7]));  
+       script_msg_ext[i++]=swap_script(SCR_JUMP ^ IFFALSE (IF (SCR_MSG_IN))); 
+       script_msg_ext[i++]=swap_script(phys_to_bus(&script_complete[0])); /* no more bytes */
+       script_msg_ext[i++]=swap_script(SCR_INT);
+       script_msg_ext[i++]=SIR_MSG_OVER7;
+#ifdef SCSI_SINGLE_STEP
+       start_script_msg_ext=(unsigned long)&script_msg_ext[0];
+       len_script_msg_ext=i*4;
+#endif
+       i=0;
+       script_status[i++]=swap_script(SCR_MOVE_ABS (1) ^ SCR_STATUS);
+       script_status[i++]=swap_script(phys_to_bus(&pccb->status));
+       script_status[i++]=swap_script(SCR_JUMP ^ IFTRUE (WHEN (SCR_MSG_IN)));
+       script_status[i++]=swap_script(phys_to_bus(&script_msgin[0]));
+       script_status[i++]=swap_script(SCR_INT);
+       script_status[i++]=SIR_STATUS_ILL_PH;
+#ifdef SCSI_SINGLE_STEP
+       start_script_status=(unsigned long)&script_status[0];
+       len_script_status=i*4;
+#endif
+       i=0;
+       script_complete[i++]=swap_script(SCR_REG_REG (SCNTL2, SCR_AND, 0x7f));
+       script_complete[i++]=0;
+       script_complete[i++]=swap_script(SCR_CLR (SCR_ACK|SCR_ATN));
+       script_complete[i++]=0;
+       script_complete[i++]=swap_script(SCR_WAIT_DISC);
+       script_complete[i++]=0;
+       script_complete[i++]=swap_script(SCR_REG_REG(GPREG, SCR_OR, 0x01));
+       script_complete[i++]=0; /* LED OFF */
+       script_complete[i++]=swap_script(SCR_INT);
+       script_complete[i++]=SIR_COMPLETE;
+#ifdef SCSI_SINGLE_STEP
+       start_script_complete=(unsigned long)&script_complete[0];
+       len_script_complete=i*4;
+#endif
+       i=0;
+       script_error[i++]=swap_script(SCR_INT); /* interrupt if error */
+       script_error[i++]=SIR_SCRIPT_ERROR;
+#ifdef SCSI_SINGLE_STEP
+       start_script_error=(unsigned long)&script_error[0];
+       len_script_error=i*4;
+#endif
+       i=0;
+       script_reselection[i++]=swap_script(SCR_CLR (SCR_TRG)); /* target status */
+       script_reselection[i++]=0;
+       script_reselection[i++]=swap_script(SCR_WAIT_RESEL); 
+       script_reselection[i++]=swap_script(phys_to_bus(&script_select[0])); /* len = 4 */
+#ifdef SCSI_SINGLE_STEP
+       start_script_reselection=(unsigned long)&script_reselection[0];
+       len_script_reselection=i*4;
+#endif
+}
+
+
+
+void scsi_issue(ccb *pccb)
+{
+       int i;
+       unsigned short sstat;
+       int retrycnt;  /* retry counter */
+       for(i=0;i<3;i++)
+               int_stat[i]=0; /* delete all int status */
+       /* struct pccb must be set-up correctly */
+       retrycnt=0;
+       PRINTF("ID %d issue cmd %02X\n",pccb->target,pccb->cmd[0]);
+       pccb->trans_bytes=0; /* no bytes transfered yet */
+       scsi_set_script(pccb); /* fill in SCRIPT                */
+       scsi_int_mask=STO | UDC | MA; /* | CMP; / * Interrupts which are enabled */
+       script_int_mask=0xff; /* enable all Ints */
+       scsi_int_enable();
+       scsi_write_dsp(phys_to_bus(&script_select[0])); /* start script */
+       /* now we have to wait for IRQs */
+retry:
+       /*
+        * This version of the driver is _not_ interrupt driven,
+        * but polls the chip's interrupt registers (ISTAT, DSTAT).
+        */
+       while(int_stat[0]==0)
+               handle_scsi_int();
+               
+       if(int_stat[0]==SIR_COMPLETE) {
+               if(pccb->msgin[0]==M_DISCONNECT) {
+                       PRINTF("Wait for reselection\n");
+                       for(i=0;i<3;i++)
+                               int_stat[i]=0; /* delete all int status */
+                       scsi_write_dsp(phys_to_bus(&script_reselection[0])); /* start reselection script */
+                       goto retry;
+               }
+               pccb->contr_stat=SIR_COMPLETE;
+               return;
+       }
+       if((int_stat[0] & SCSI_INT_STATE)==SCSI_INT_STATE) { /* scsi interrupt */
+               sstat=(unsigned short)int_stat[0];
+               if((sstat & STO)==STO) { /* selection timeout */
+                       pccb->contr_stat=SCSI_SEL_TIME_OUT;
+                       scsi_write_byte(GPREG,0x01);
+                       PRINTF("ID: %X Selection Timeout\n",pccb->target);
+                       return;
+               }
+               if((sstat & UDC)==UDC) { /* unexpected disconnect */
+                       pccb->contr_stat=SCSI_UNEXP_DIS;
+                       scsi_write_byte(GPREG,0x01);
+                       PRINTF("ID: %X Unexpected Disconnect\n",pccb->target);
+                       return;
+               }
+               if((sstat & RSL)==RSL) { /* reselection */
+                       pccb->contr_stat=SCSI_UNEXP_DIS;
+                       scsi_write_byte(GPREG,0x01);
+                       PRINTF("ID: %X Unexpected Disconnect\n",pccb->target);
+                       return;
+               }
+               if(((sstat & MA)==MA)||((sstat & HTH)==HTH)) { /* phase missmatch */
+                       if(retrycnt<SCSI_MAX_RETRY) {
+                               pccb->trans_bytes=pccb->datalen - 
+                                       ((unsigned long)scsi_read_byte(DBC) |
+                                       ((unsigned long)scsi_read_byte(DBC+1)<<8) | 
+                                       ((unsigned long)scsi_read_byte(DBC+2)<<16));
+                               for(i=0;i<3;i++)
+                                       int_stat[i]=0; /* delete all int status */
+                               retrycnt++;
+                               PRINTF("ID: %X Phase Missmatch Retry %d Phase %02X transfered %lx\n",
+                                               pccb->target,retrycnt,scsi_read_byte(SBCL),pccb->trans_bytes);
+                               scsi_write_dsp(phys_to_bus(&script_cmd[4])); /* start retry script */
+                               goto retry;
+                       }
+                       if((sstat & MA)==MA)
+                               pccb->contr_stat=SCSI_MA_TIME_OUT;
+                       else
+                               pccb->contr_stat=SCSI_HNS_TIME_OUT;
+                       PRINTF("Phase Missmatch stat %lx\n",pccb->contr_stat);
+                       return;
+               } /* no phase int */
+/*             if((sstat & CMP)==CMP) {
+                       pccb->contr_stat=SIR_COMPLETE;
+                       return;
+               }
+*/             
+               PRINTF("SCSI INT %lX\n",int_stat[0]);
+               pccb->contr_stat=int_stat[0];
+               return;
+       } /* end scsi int */
+       PRINTF("SCRIPT INT %lX phase %02X\n",int_stat[0],scsi_read_byte(SBCL));
+       pccb->contr_stat=int_stat[0];
+       return;
+}
+
+int scsi_exec(ccb *pccb)
+{
+       unsigned char tmpcmd[16],tmpstat;
+       int i,retrycnt,t;
+       unsigned long transbytes,datalen;
+       unsigned char *tmpptr;
+       retrycnt=0;
+retry:
+       scsi_issue(pccb);
+       if(pccb->contr_stat!=SIR_COMPLETE)
+               return FALSE;
+       if(pccb->status==S_GOOD)
+               return TRUE;
+       if(pccb->status==S_CHECK_COND) { /* check condition */
+               for(i=0;i<16;i++)
+                       tmpcmd[i]=pccb->cmd[i];
+               pccb->cmd[0]=SCSI_REQ_SENSE;
+               pccb->cmd[1]=pccb->lun<<5;
+               pccb->cmd[2]=0;
+               pccb->cmd[3]=0;
+               pccb->cmd[4]=14;
+               pccb->cmd[5]=0;
+               pccb->cmdlen=6;
+               pccb->msgout[0]=SCSI_IDENTIFY;
+               transbytes=pccb->trans_bytes;
+               tmpptr=pccb->pdata;
+               pccb->pdata=&pccb->sense_buf[0];
+               datalen=pccb->datalen;
+               pccb->datalen=14;
+               tmpstat=pccb->status;
+               scsi_issue(pccb);
+               for(i=0;i<16;i++)
+                       pccb->cmd[i]=tmpcmd[i];
+               pccb->trans_bytes=transbytes;
+               pccb->pdata=tmpptr;
+               pccb->datalen=datalen;
+               pccb->status=tmpstat;
+               PRINTF("Request_sense sense key %x ASC %x ASCQ %x\n",pccb->sense_buf[2]&0x0f,
+                       pccb->sense_buf[12],pccb->sense_buf[13]);
+               switch(pccb->sense_buf[2]&0xf) {
+                       case SENSE_NO_SENSE: 
+                       case SENSE_RECOVERED_ERROR: 
+                               /* seems to be ok */
+                               return TRUE;
+                               break;
+                       case SENSE_NOT_READY:
+                               if((pccb->sense_buf[12]!=0x04)||(pccb->sense_buf[13]!=0x01)) {
+                                       /* if device is not in process of becoming ready */
+                                       return FALSE;
+                                       break;
+                               } /* else fall through */
+                       case SENSE_UNIT_ATTENTION: 
+                               if(retrycnt<SCSI_MAX_RETRY_NOT_READY) {
+                                       PRINTF("Target %d not ready, retry %d\n",pccb->target,retrycnt);
+                                       for(t=0;t<SCSI_NOT_READY_TIME_OUT;t++)
+                                               udelay(1000); /* 1sec wait */
+                                       retrycnt++;
+                                       goto retry;
+                               }
+                               PRINTF("Target %d not ready, %d retried\n",pccb->target,retrycnt);
+                               return FALSE;
+                       default:
+                               return FALSE;
+               }
+       }
+       PRINTF("Status = %X\n",pccb->status);
+       return FALSE;
+}              
+               
+
+
+
+void scsi_chip_init(void)
+{
+       /* first we issue a soft reset */
+       scsi_write_byte(ISTAT,SRST);
+       udelay(1000);
+       scsi_write_byte(ISTAT,0);
+       /* setup chip */
+       scsi_write_byte(SCNTL0,0xC0); /* full arbitration no start, no message, parity disabled, master */
+       scsi_write_byte(SCNTL1,0x00); 
+       scsi_write_byte(SCNTL2,0x00);
+       scsi_write_byte(SCNTL3,0x13); /* synchronous clock 40/4=10MHz, asynchronous 40MHz */
+       scsi_write_byte(SCID,0x47); /* ID=7, enable reselection */
+       scsi_write_byte(SXFER,0x00); /* synchronous transfer period 10MHz, asynchronous */
+       scsi_write_byte(SDID,0x00);  /* targed SCSI ID = 0 */
+       scsi_int_mask=0x0000; /* no Interrupt is enabled */
+       script_int_mask=0x00;
+       scsi_int_enable();
+       scsi_write_byte(GPREG,0x01); /* GPIO0 is LED (off) */
+       scsi_write_byte(GPCNTL,0x0E); /* GPIO0 is Output */
+       scsi_write_byte(STIME0,0x08); /* handshake timer disabled, selection timeout 512msec */
+       scsi_write_byte(RESPID,0x80); /* repond only to the own ID (reselection) */
+       scsi_write_byte(STEST1,0x00); /* not isolated, SCLK is used */
+       scsi_write_byte(STEST2,0x00); /* no Lowlevel Mode? */
+       scsi_write_byte(STEST3,0x80); /* enable tolerANT */
+       scsi_write_byte(CTEST3,0x04); /* clear FIFO */
+       scsi_write_byte(CTEST4,0x00);
+       scsi_write_byte(CTEST5,0x00);   
+#ifdef SCSI_SINGLE_STEP 
+/*     scsi_write_byte(DCNTL,IRQM | SSM);      */
+       scsi_write_byte(DCNTL,IRQD | SSM);      
+       scsi_write_byte(DMODE,MAN);     
+#else
+/*     scsi_write_byte(DCNTL,IRQM);    */
+       scsi_write_byte(DCNTL,IRQD);    
+       scsi_write_byte(DMODE,0x00);    
+#endif
+}
+#endif /* (CONFIG_COMMANDS & CFG_CMD_SCSI) */
+
+
diff --git a/board/eltec/bab750/sym53c8xx.h b/board/eltec/bab750/sym53c8xx.h
new file mode 100644 (file)
index 0000000..32a78f0
--- /dev/null
@@ -0,0 +1,583 @@
+/*
+ * (C) Copyright 2001
+ * Denis Peter, MPL AG Switzerland
+ *
+ * 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
+ *
+ *
+ * Most of these definitions are derived from
+ * linux/drivers/scsi/sym53c8xx_defs.h
+ *
+ */
+
+#ifndef _SYM53C8XX_DEFS_H
+#define _SYM53C8XX_DEFS_H
+
+
+#define SCNTL0         0x00    /* full arb., ena parity, par->ATN  */
+
+#define SCNTL1         0x01    /* no reset                         */
+  #define   ISCON   0x10  /* connected to scsi                                         */
+  #define   CRST    0x08  /* force reset                      */
+  #define   IARB    0x02  /* immediate arbitration            */
+
+#define SCNTL2         0x02    /* no disconnect expected           */
+       #define   SDU     0x80  /* cmd: disconnect will raise error */
+       #define   CHM     0x40  /* sta: chained mode                */
+       #define   WSS     0x08  /* sta: wide scsi send           [W]*/
+       #define   WSR     0x01  /* sta: wide scsi received       [W]*/
+
+#define SCNTL3         0x03    /* cnf system clock dependent       */
+       #define   EWS     0x08  /* cmd: enable wide scsi         [W]*/
+       #define   ULTRA   0x80  /* cmd: ULTRA enable                */
+                               /* bits 0-2, 7 rsvd for C1010       */
+
+#define SCID                   0x04            /* cnf host adapter scsi address    */
+       #define   RRE     0x40  /* r/w:e enable response to resel.  */
+       #define   SRE     0x20  /* r/w:e enable response to select  */
+
+#define SXFER                  0x05            /* ### Sync speed and count         */
+                               /* bits 6-7 rsvd for C1010          */
+
+#define SDID                   0x06    /* ### Destination-ID               */
+
+#define GPREG                  0x07    /* ??? IO-Pins                      */
+
+#define SFBR                   0x08    /* ### First byte in phase          */
+
+#define SOCL                   0x09
+       #define   CREQ    0x80  /* r/w: SCSI-REQ                    */
+       #define   CACK    0x40  /* r/w: SCSI-ACK                    */
+       #define   CBSY    0x20  /* r/w: SCSI-BSY                    */
+       #define   CSEL    0x10  /* r/w: SCSI-SEL                    */
+       #define   CATN    0x08  /* r/w: SCSI-ATN                    */
+       #define   CMSG    0x04  /* r/w: SCSI-MSG                    */
+       #define   CC_D    0x02  /* r/w: SCSI-C_D                    */
+       #define   CI_O    0x01  /* r/w: SCSI-I_O                    */
+
+#define SSID                   0x0a
+
+#define SBCL                   0x0b
+
+#define DSTAT                  0x0c
+  #define   DFE     0x80  /* sta: dma fifo empty              */
+  #define   MDPE    0x40  /* int: master data parity error    */
+  #define   BF      0x20  /* int: script: bus fault           */
+  #define   ABRT    0x10  /* int: script: command aborted     */
+  #define   SSI     0x08  /* int: script: single step         */
+  #define   SIR     0x04  /* int: script: interrupt instruct. */
+  #define   IID     0x01  /* int: script: illegal instruct.   */
+
+#define SSTAT0         0x0d
+  #define   ILF     0x80  /* sta: data in SIDL register lsb   */
+  #define   ORF     0x40  /* sta: data in SODR register lsb   */
+  #define   OLF     0x20  /* sta: data in SODL register lsb   */
+  #define   AIP     0x10  /* sta: arbitration in progress     */
+  #define   LOA     0x08  /* sta: arbitration lost            */
+  #define   WOA     0x04  /* sta: arbitration won             */
+  #define   IRST    0x02  /* sta: scsi reset signal           */
+  #define   SDP     0x01  /* sta: scsi parity signal          */
+
+#define SSTAT1         0x0e
+       #define   FF3210  0xf0  /* sta: bytes in the scsi fifo      */
+
+#define SSTAT2         0x0f
+  #define   ILF1    0x80  /* sta: data in SIDL register msb[W]*/
+  #define   ORF1    0x40  /* sta: data in SODR register msb[W]*/
+  #define   OLF1    0x20  /* sta: data in SODL register msb[W]*/
+  #define   DM      0x04  /* sta: DIFFSENS mismatch (895/6 only) */
+  #define   LDSC    0x02  /* sta: disconnect & reconnect      */
+
+#define DSA                            0x10            /* --> Base page                    */
+#define DSA1                   0x11
+#define DSA2                   0x12
+#define DSA3                   0x13
+
+#define ISTAT                  0x14    /* --> Main Command and status      */
+  #define   CABRT   0x80  /* cmd: abort current operation     */
+  #define   SRST    0x40  /* mod: reset chip                  */
+  #define   SIGP    0x20  /* r/w: message from host to ncr    */
+  #define   SEM     0x10  /* r/w: message between host + ncr  */
+  #define   CON     0x08  /* sta: connected to scsi           */
+  #define   INTF    0x04  /* sta: int on the fly (reset by wr)*/
+  #define   SIP     0x02  /* sta: scsi-interrupt              */
+  #define   DIP     0x01  /* sta: host/script interrupt       */
+
+
+#define CTEST0         0x18
+#define CTEST1         0x19
+#define CTEST2         0x1a
+       #define   CSIGP   0x40
+                               /* bits 0-2,7 rsvd for C1010        */
+
+#define CTEST3         0x1b
+       #define   FLF     0x08  /* cmd: flush dma fifo              */
+       #define   CLF           0x04    /* cmd: clear dma fifo              */
+       #define   FM      0x02  /* mod: fetch pin mode              */
+       #define   WRIE    0x01  /* mod: write and invalidate enable */
+                               /* bits 4-7 rsvd for C1010          */
+
+#define DFIFO                  0x20
+#define CTEST4         0x21
+       #define   BDIS    0x80  /* mod: burst disable               */
+       #define   MPEE    0x08  /* mod: master parity error enable  */
+
+#define CTEST5         0x22
+       #define   DFS     0x20  /* mod: dma fifo size               */
+                               /* bits 0-1, 3-7 rsvd for C1010          */
+#define CTEST6         0x23
+
+#define DBC                            0x24    /* ### Byte count and command       */
+#define DNAD                   0x28    /* ### Next command register        */
+#define DSP                            0x2c    /* --> Script Pointer               */
+#define DSPS                   0x30    /* --> Script pointer save/opcode#2 */
+
+#define SCRATCHA       0x34  /* Temporary register a            */
+#define SCRATCHA1      0x35
+#define SCRATCHA2      0x36
+#define SCRATCHA3      0x37
+
+#define DMODE                  0x38
+       #define   BL_2    0x80  /* mod: burst length shift value +2 */
+       #define   BL_1    0x40  /* mod: burst length shift value +1 */
+       #define   ERL     0x08  /* mod: enable read line            */
+       #define   ERMP    0x04  /* mod: enable read multiple        */
+       #define   BOF     0x02  /* mod: burst op code fetch         */
+       #define   MAN     0x01  /* mod: manual start                                     */
+
+#define DIEN           0x39
+#define SBR                    0x3a
+
+#define DCNTL          0x3b                    /* --> Script execution control     */
+       #define   CLSE    0x80  /* mod: cache line size enable      */
+       #define   PFF     0x40  /* cmd: pre-fetch flush             */
+       #define   PFEN    0x20  /* mod: pre-fetch enable            */
+       #define   SSM     0x10  /* mod: single step mode            */
+       #define   IRQM    0x08  /* mod: irq mode (1 = totem pole !) */
+       #define   STD     0x04  /* cmd: start dma mode              */
+       #define   IRQD    0x02  /* mod: irq disable                 */
+       #define   NOCOM   0x01  /* cmd: protect sfbr while reselect */
+                               /* bits 0-1 rsvd for C1010          */
+
+#define ADDER                  0x3c
+
+#define SIEN                   0x40    /* -->: interrupt enable            */
+#define SIST                   0x42    /* <--: interrupt status            */
+  #define   SBMC    0x1000/* sta: SCSI Bus Mode Change (895/6 only) */
+  #define   STO     0x0400/* sta: timeout (select)            */
+  #define   GEN     0x0200/* sta: timeout (general)           */
+  #define   HTH     0x0100/* sta: timeout (handshake)         */
+  #define   MA      0x80  /* sta: phase mismatch              */
+  #define   CMP     0x40  /* sta: arbitration complete        */
+  #define   SEL     0x20  /* sta: selected by another device  */
+  #define   RSL     0x10  /* sta: reselected by another device*/
+  #define   SGE     0x08  /* sta: gross error (over/underflow)*/
+  #define   UDC     0x04  /* sta: unexpected disconnect       */
+  #define   RST     0x02  /* sta: scsi bus reset detected     */
+  #define   PAR     0x01  /* sta: scsi parity error           */
+
+#define SLPAR                          0x44
+#define SWIDE                          0x45
+#define MACNTL                 0x46
+#define GPCNTL                 0x47
+#define STIME0                 0x48    /* cmd: timeout for select&handshake*/
+#define STIME1                 0x49    /* cmd: timeout user defined        */
+#define RESPID                 0x4a    /* sta: Reselect-IDs                */
+
+#define STEST0                 0x4c
+
+#define STEST1                 0x4d
+       #define   SCLK    0x80  /* Use the PCI clock as SCSI clock      */
+       #define   DBLEN   0x08  /* clock doubler running                */
+       #define   DBLSEL  0x04  /* clock doubler selected               */
+  
+
+#define STEST2                 0x4e
+       #define   ROF     0x40  /* reset scsi offset (after gross error!) */
+       #define   EXT     0x02  /* extended filtering                     */
+
+#define STEST3                 0x4f
+       #define   TE     0x80   /* c: tolerAnt enable */
+       #define   HSC    0x20   /* c: Halt SCSI Clock */
+       #define   CSF    0x02   /* c: clear scsi fifo */
+
+#define SIDL                   0x50    /* Lowlevel: latched from scsi data */
+#define STEST4         0x52
+       #define SMODE   0xc0    /* SCSI bus mode      (895/6 only) */
+       #define SMODE_HVD 0x40  /* High Voltage Differential       */
+       #define SMODE_SE  0x80  /* Single Ended                    */
+       #define SMODE_LVD 0xc0  /* Low Voltage Differential        */
+       #define LCKFRQ 0x20     /* Frequency Lock (895/6 only)     */
+                               /* bits 0-5 rsvd for C1010          */
+
+#define SODL                   0x54    /* Lowlevel: data out to scsi data  */
+
+#define SBDL                   0x58    /* Lowlevel: data from scsi data    */
+
+
+
+
+/*-----------------------------------------------------------
+**
+**     Utility macros for the script.
+**
+**-----------------------------------------------------------
+*/
+
+#define REG(r) (r)
+
+/*-----------------------------------------------------------
+**
+**     SCSI phases
+**
+**     DT phases illegal for ncr driver.
+**
+**-----------------------------------------------------------
+*/
+
+#define        SCR_DATA_OUT    0x00000000
+#define        SCR_DATA_IN     0x01000000
+#define        SCR_COMMAND     0x02000000
+#define        SCR_STATUS      0x03000000
+#define SCR_DT_DATA_OUT        0x04000000
+#define SCR_DT_DATA_IN 0x05000000
+#define SCR_MSG_OUT    0x06000000
+#define SCR_MSG_IN      0x07000000
+
+#define SCR_ILG_OUT    0x04000000
+#define SCR_ILG_IN     0x05000000
+
+/*-----------------------------------------------------------
+**
+**     Data transfer via SCSI.
+**
+**-----------------------------------------------------------
+**
+**     MOVE_ABS (LEN)
+**     <<start address>>
+**
+**     MOVE_IND (LEN)
+**     <<dnad_offset>>
+**
+**     MOVE_TBL
+**     <<dnad_offset>>
+**
+**-----------------------------------------------------------
+*/
+
+#define OPC_MOVE          0x08000000
+
+#define SCR_MOVE_ABS(l) ((0x00000000 | OPC_MOVE) | (l))
+#define SCR_MOVE_IND(l) ((0x20000000 | OPC_MOVE) | (l))
+#define SCR_MOVE_TBL     (0x10000000 | OPC_MOVE)
+
+#define SCR_CHMOV_ABS(l) ((0x00000000) | (l))
+#define SCR_CHMOV_IND(l) ((0x20000000) | (l))
+#define SCR_CHMOV_TBL     (0x10000000)
+
+
+/*-----------------------------------------------------------
+**
+**     Selection
+**
+**-----------------------------------------------------------
+**
+**     SEL_ABS | SCR_ID (0..15)    [ | REL_JMP]
+**     <<alternate_address>>
+**
+**     SEL_TBL | << dnad_offset>>  [ | REL_JMP]
+**     <<alternate_address>>
+**
+**-----------------------------------------------------------
+*/
+
+#define        SCR_SEL_ABS     0x40000000
+#define        SCR_SEL_ABS_ATN 0x41000000
+#define        SCR_SEL_TBL     0x42000000
+#define        SCR_SEL_TBL_ATN 0x43000000
+
+
+#define SCR_JMP_REL     0x04000000
+#define SCR_ID(id)     (((unsigned long)(id)) << 16)
+
+/*-----------------------------------------------------------
+**
+**     Waiting for Disconnect or Reselect
+**
+**-----------------------------------------------------------
+**
+**     WAIT_DISC
+**     dummy: <<alternate_address>>
+**
+**     WAIT_RESEL
+**     <<alternate_address>>
+**
+**-----------------------------------------------------------
+*/
+
+#define        SCR_WAIT_DISC   0x48000000
+#define SCR_WAIT_RESEL  0x50000000
+
+/*-----------------------------------------------------------
+**
+**     Bit Set / Reset
+**
+**-----------------------------------------------------------
+**
+**     SET (flags {|.. })
+**
+**     CLR (flags {|.. })
+**
+**-----------------------------------------------------------
+*/
+
+#define SCR_SET(f)     (0x58000000 | (f))
+#define SCR_CLR(f)     (0x60000000 | (f))
+
+#define        SCR_CARRY       0x00000400
+#define        SCR_TRG         0x00000200
+#define        SCR_ACK         0x00000040
+#define        SCR_ATN         0x00000008
+
+
+
+
+/*-----------------------------------------------------------
+**
+**     Memory to memory move
+**
+**-----------------------------------------------------------
+**
+**     COPY (bytecount)
+**     << source_address >>
+**     << destination_address >>
+**
+**     SCR_COPY   sets the NO FLUSH option by default.
+**     SCR_COPY_F does not set this option.
+**
+**     For chips which do not support this option,
+**     ncr_copy_and_bind() will remove this bit.
+**-----------------------------------------------------------
+*/
+
+#define SCR_NO_FLUSH 0x01000000
+
+#define SCR_COPY(n) (0xc0000000 | SCR_NO_FLUSH | (n))
+#define SCR_COPY_F(n) (0xc0000000 | (n))
+
+/*-----------------------------------------------------------
+**
+**     Register move and binary operations
+**
+**-----------------------------------------------------------
+**
+**     SFBR_REG (reg, op, data)        reg  = SFBR op data
+**     << 0 >>
+**
+**     REG_SFBR (reg, op, data)        SFBR = reg op data
+**     << 0 >>
+**
+**     REG_REG  (reg, op, data)        reg  = reg op data
+**     << 0 >>
+**
+**-----------------------------------------------------------
+**     On 810A, 860, 825A, 875, 895 and 896 chips the content 
+**     of SFBR register can be used as data (SCR_SFBR_DATA).
+**     The 896 has additionnal IO registers starting at 
+**     offset 0x80. Bit 7 of register offset is stored in 
+**     bit 7 of the SCRIPTS instruction first DWORD.
+**-----------------------------------------------------------
+*/
+
+#define SCR_REG_OFS(ofs) ((((ofs) & 0x7f) << 16ul)) /* + ((ofs) & 0x80)) */
+
+#define SCR_SFBR_REG(reg,op,data) \
+        (0x68000000 | (SCR_REG_OFS(REG(reg))) | (op) | (((data)&0xff)<<8ul))
+
+#define SCR_REG_SFBR(reg,op,data) \
+        (0x70000000 | (SCR_REG_OFS(REG(reg))) | (op) | (((data)&0xff)<<8ul))
+
+#define SCR_REG_REG(reg,op,data) \
+        (0x78000000 | (SCR_REG_OFS(REG(reg))) | (op) | (((data)&0xff)<<8ul))
+
+
+#define      SCR_LOAD   0x00000000
+#define      SCR_SHL    0x01000000
+#define      SCR_OR     0x02000000
+#define      SCR_XOR    0x03000000
+#define      SCR_AND    0x04000000
+#define      SCR_SHR    0x05000000
+#define      SCR_ADD    0x06000000
+#define      SCR_ADDC   0x07000000
+
+#define      SCR_SFBR_DATA   (0x00800000>>8ul) /* Use SFBR as data */
+
+/*-----------------------------------------------------------
+**
+**     FROM_REG (reg)            SFBR = reg
+**     << 0 >>
+**
+**     TO_REG   (reg)            reg  = SFBR
+**     << 0 >>
+**
+**     LOAD_REG (reg, data)      reg  = <data>
+**     << 0 >>
+**
+**     LOAD_SFBR(data)           SFBR = <data>
+**     << 0 >>
+**
+**-----------------------------------------------------------
+*/
+
+#define        SCR_FROM_REG(reg) \
+       SCR_REG_SFBR(reg,SCR_OR,0)
+
+#define        SCR_TO_REG(reg) \
+       SCR_SFBR_REG(reg,SCR_OR,0)
+
+#define        SCR_LOAD_REG(reg,data) \
+       SCR_REG_REG(reg,SCR_LOAD,data)
+
+#define SCR_LOAD_SFBR(data) \
+        (SCR_REG_SFBR (gpreg, SCR_LOAD, data))
+
+/*-----------------------------------------------------------
+**
+**     LOAD  from memory   to register.
+**     STORE from register to memory.
+**
+**     Only supported by 810A, 860, 825A, 875, 895 and 896.
+**
+**-----------------------------------------------------------
+**
+**     LOAD_ABS (LEN)
+**     <<start address>>
+**
+**     LOAD_REL (LEN)        (DSA relative)
+**     <<dsa_offset>>
+**
+**-----------------------------------------------------------
+*/
+
+#define SCR_REG_OFS2(ofs) (((ofs) & 0xff) << 16ul)
+#define SCR_NO_FLUSH2  0x02000000
+#define SCR_DSA_REL2   0x10000000
+
+#define SCR_LOAD_R(reg, how, n) \
+        (0xe1000000 | how | (SCR_REG_OFS2(REG(reg))) | (n))
+
+#define SCR_STORE_R(reg, how, n) \
+        (0xe0000000 | how | (SCR_REG_OFS2(REG(reg))) | (n))
+
+#define SCR_LOAD_ABS(reg, n)   SCR_LOAD_R(reg, SCR_NO_FLUSH2, n)
+#define SCR_LOAD_REL(reg, n)   SCR_LOAD_R(reg, SCR_NO_FLUSH2|SCR_DSA_REL2, n)
+#define SCR_LOAD_ABS_F(reg, n) SCR_LOAD_R(reg, 0, n)
+#define SCR_LOAD_REL_F(reg, n) SCR_LOAD_R(reg, SCR_DSA_REL2, n)
+
+#define SCR_STORE_ABS(reg, n)  SCR_STORE_R(reg, SCR_NO_FLUSH2, n)
+#define SCR_STORE_REL(reg, n)  SCR_STORE_R(reg, SCR_NO_FLUSH2|SCR_DSA_REL2,n)
+#define SCR_STORE_ABS_F(reg, n)        SCR_STORE_R(reg, 0, n)
+#define SCR_STORE_REL_F(reg, n)        SCR_STORE_R(reg, SCR_DSA_REL2, n)
+
+
+/*-----------------------------------------------------------
+**
+**     Waiting for Disconnect or Reselect
+**
+**-----------------------------------------------------------
+**
+**     JUMP            [ | IFTRUE/IFFALSE ( ... ) ]
+**     <<address>>
+**
+**     JUMPR           [ | IFTRUE/IFFALSE ( ... ) ]
+**     <<distance>>
+**
+**     CALL            [ | IFTRUE/IFFALSE ( ... ) ]
+**     <<address>>
+**
+**     CALLR           [ | IFTRUE/IFFALSE ( ... ) ]
+**     <<distance>>
+**
+**     RETURN          [ | IFTRUE/IFFALSE ( ... ) ]
+**     <<dummy>>
+**
+**     INT             [ | IFTRUE/IFFALSE ( ... ) ]
+**     <<ident>>
+**
+**     INT_FLY         [ | IFTRUE/IFFALSE ( ... ) ]
+**     <<ident>>
+**
+**     Conditions:
+**          WHEN (phase)
+**          IF   (phase)
+**          CARRYSET
+**          DATA (data, mask)
+**
+**-----------------------------------------------------------
+*/
+
+#define SCR_NO_OP       0x80000000
+#define SCR_JUMP        0x80080000
+#define SCR_JUMP64      0x80480000
+#define SCR_JUMPR       0x80880000
+#define SCR_CALL        0x88080000
+#define SCR_CALLR       0x88880000
+#define SCR_RETURN      0x90080000
+#define SCR_INT         0x98080000
+#define SCR_INT_FLY     0x98180000
+
+#define IFFALSE(arg)   (0x00080000 | (arg))
+#define IFTRUE(arg)    (0x00000000 | (arg))
+
+#define WHEN(phase)    (0x00030000 | (phase))
+#define IF(phase)      (0x00020000 | (phase))
+
+#define DATA(D)        (0x00040000 | ((D) & 0xff))
+#define MASK(D,M)      (0x00040000 | (((M ^ 0xff) & 0xff) << 8ul)|((D) & 0xff))
+
+#define CARRYSET       (0x00200000)
+
+
+
+#define SIR_COMPLETE                                    0x10000000
+/* script errors */
+#define SIR_SEL_ATN_NO_MSG_OUT 0x00000001
+#define SIR_CMD_OUT_ILL_PH     0x00000002
+#define SIR_STATUS_ILL_PH                       0x00000003
+#define SIR_MSG_RECEIVED                        0x00000004
+#define SIR_DATA_IN_ERR        0x00000005
+#define SIR_DATA_OUT_ERR                        0x00000006
+#define SIR_SCRIPT_ERROR                        0x00000007
+#define SIR_MSG_OUT_NO_CMD              0x00000008
+#define SIR_MSG_OVER7                                   0x00000009
+/* Fly interrupt */
+#define INT_ON_FY                                                       0x00000080
+
+/* Hardware errors  are defined in scsi.h */
+
+#define SCSI_IDENTIFY                                  0xC0 
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#endif
diff --git a/board/eltec/bab750/w83c553f.c b/board/eltec/bab750/w83c553f.c
new file mode 100644 (file)
index 0000000..d16ba50
--- /dev/null
@@ -0,0 +1,212 @@
+/*
+ * (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Andreas Heppel <aheppel@sysgo.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
+ */
+
+/*
+ * Initialisation of the PCI-to-ISA bridge and disabling the BIOS
+ * write protection (for flash) in function 0 of the chip.
+ * Enabling function 1 (IDE controller of the chip.
+ */
+#include <ppcboot.h>
+#include <config.h>
+#include <mpc106.h>
+
+#include <w83c553f.h>
+
+#define EIEIO_SYNC  __asm__ volatile ("eieio;sync")
+
+ulong bus_offset[CFG_IDE_MAXBUS];
+
+void initialise_pic(void);
+void initialise_dma(void);
+
+void initialise_w83c553f(void)
+{
+       int regval = 0;
+       int devbusfn = 0;
+       
+       devbusfn = PCI_Find_Device(W83C553F_VID, W83C553F_DID);
+       if (devbusfn == -1)
+       {
+               printf("Error: Cannot find W83C553F controller on any PCI bus.");
+       return;
+       }
+
+       regval = PCI_Read_CFG_Reg(devbusfn, PCI_CFG_COMMAND, 2);
+       regval |= PCI_CMD_MASTER | PCI_CMD_IOEN | PCI_CMD_MEMEN;
+       PCI_Write_CFG_Reg(devbusfn, PCI_CFG_COMMAND, regval, 2);
+
+       regval = PCI_Read_CFG_Reg(devbusfn, WINBOND_IPADCR, 1);
+       /* 16 MB ISA memory space */
+       regval |= (IPADCR_IPATOM4 | IPADCR_IPATOM5 | IPADCR_IPATOM6 | IPADCR_IPATOM7);
+       regval &= ~IPADCR_MBE512;
+       PCI_Write_CFG_Reg(devbusfn, WINBOND_IPADCR, regval, 1);
+
+       regval = PCI_Read_CFG_Reg(devbusfn, WINBOND_CSCR, 1);
+       /* switch off BIOS write protection */
+       regval |= CSCR_UBIOSCSE;
+       regval &= ~CSCR_BIOSWP;
+       PCI_Write_CFG_Reg(devbusfn, WINBOND_CSCR, regval, 1);
+
+       /*
+        * Interrupt routing:
+        *  - IDE  -> IRQ 9/0
+        *  - INTA -> IRQ 10
+        *  - INTB -> IRQ 11
+        *  - INTC -> IRQ 14
+        *  - INTD -> IRQ 15
+        */
+       PCI_Write_CFG_Reg(devbusfn, WINBOND_IDEIRCR, 0x90, 1);
+       PCI_Write_CFG_Reg(devbusfn, WINBOND_PCIIRCR, 0xABEF, 2);
+       
+       /*
+        * Read IDE bus offsets from function 1 device.
+        * We must unmask the LSB indicating that ist is an IO address.
+        */
+       devbusfn |= (1<<8);
+       
+       /*
+        * Switch off legacy IRQ for IDE and IDE port 1.
+        */
+       PCI_Write_CFG_Reg(devbusfn, 0x09, 0x8F, 1);
+
+       regval = PCI_Read_CFG_Reg(devbusfn, WINDOND_IDECSR, 4);
+       regval &= ~(IDECSR_LEGIRQ | IDECSR_P1EN | IDECSR_P1F16);
+       PCI_Write_CFG_Reg(devbusfn, WINDOND_IDECSR, regval, 4);
+       
+       bus_offset[0] = PCI_Read_CFG_Reg(devbusfn, PCI_CFG_BASE_ADDRESS_0, 4) & ~1;
+#if CFG_IDE_MAXBUS > 1
+       bus_offset[1] = PCI_Read_CFG_Reg(devbusfn, PCI_CFG_BASE_ADDRESS_2, 4) & ~1;
+#endif
+
+       /*
+        * Enable function 1, IDE -> busmastering and IO space access
+        */
+       regval = PCI_Read_CFG_Reg(devbusfn, PCI_CFG_COMMAND, 2);
+       regval |= PCI_CMD_MASTER | PCI_CMD_IOEN;
+       PCI_Write_CFG_Reg(devbusfn, PCI_CFG_COMMAND, regval, 2);
+               
+       /*
+        * Initialise ISA interrupt controller
+        */
+       initialise_pic();
+               
+       /*
+        * Initialise DMA controller
+        */
+       initialise_dma();
+}
+
+void initialise_pic(void)
+{
+       out8(W83C553F_PIC1_ICW1, 0x11);
+       out8(W83C553F_PIC1_ICW2, 0x08);
+       out8(W83C553F_PIC1_ICW3, 0x04);
+       out8(W83C553F_PIC1_ICW4, 0x01);
+       out8(W83C553F_PIC1_OCW1, 0xfb);
+       out8(W83C553F_PIC1_ELC, 0x20);
+
+       out8(W83C553F_PIC2_ICW1, 0x11);
+       out8(W83C553F_PIC2_ICW2, 0x08);
+       out8(W83C553F_PIC2_ICW3, 0x02);
+       out8(W83C553F_PIC2_ICW4, 0x01);
+       out8(W83C553F_PIC2_OCW1, 0xff);
+       out8(W83C553F_PIC2_ELC, 0xce);
+
+       out8(W83C553F_TMR1_CMOD, 0x74);
+
+       out8(W83C553F_PIC2_OCW1, 0x20);
+       out8(W83C553F_PIC1_OCW1, 0x20);
+
+       out8(W83C553F_PIC2_OCW1, 0x2b);
+       out8(W83C553F_PIC1_OCW1, 0x2b);
+}
+
+void initialise_dma(void)
+{
+    unsigned int channel;
+    unsigned int rvalue1, rvalue2;
+
+    /* perform a H/W reset of the devices */
+
+       out8(W83C553F_DMA1 + W83C553F_DMA1_MC, 0x00);
+       out16(W83C553F_DMA2 + W83C553F_DMA2_MC, 0x0000);
+       
+    /* initialise all channels to a sane state */
+
+    for (channel = 0; channel < 4; channel++) {
+        /*
+         * dependent upon the channel, setup the specifics:
+         *
+         * demand
+         * address-increment
+         * autoinitialize-disable
+         * verify-transfer
+         */
+
+               switch (channel) {
+                       case 0:
+                               rvalue1 = (W83C553F_MODE_TM_DEMAND|W83C553F_MODE_CH0SEL|W83C553F_MODE_TT_VERIFY);
+                               rvalue2 = (W83C553F_MODE_TM_CASCADE|W83C553F_MODE_CH0SEL);
+                               break;
+               case 1:
+                               rvalue1 = (W83C553F_MODE_TM_DEMAND|W83C553F_MODE_CH1SEL|W83C553F_MODE_TT_VERIFY);
+                               rvalue2 = (W83C553F_MODE_TM_DEMAND|W83C553F_MODE_CH1SEL|W83C553F_MODE_TT_VERIFY);
+                               break;
+                       case 2:
+                               rvalue1 = (W83C553F_MODE_TM_DEMAND|W83C553F_MODE_CH2SEL|W83C553F_MODE_TT_VERIFY);
+                               rvalue2 = (W83C553F_MODE_TM_DEMAND|W83C553F_MODE_CH2SEL|W83C553F_MODE_TT_VERIFY);
+                               break;
+                       case 3:
+                               rvalue1 = (W83C553F_MODE_TM_DEMAND|W83C553F_MODE_CH3SEL|W83C553F_MODE_TT_VERIFY);
+                               rvalue2 = (W83C553F_MODE_TM_DEMAND|W83C553F_MODE_CH3SEL|W83C553F_MODE_TT_VERIFY);
+                               break;
+                       default:
+                               rvalue1 = 0x00;
+                               rvalue2 = 0x00;
+                               break;
+               }
+
+               /* write to write mode registers */
+
+               out8(W83C553F_DMA1 + W83C553F_DMA1_WM, rvalue1 & 0xFF);
+               out16(W83C553F_DMA2 + W83C553F_DMA2_WM, rvalue2 & 0x00FF);
+       }
+
+    /* enable all channels */
+
+       out8(W83C553F_DMA1 + W83C553F_DMA1_CM, 0x00);
+       out16(W83C553F_DMA2 + W83C553F_DMA2_CM, 0x0000);
+       /*
+        * initialize the global DMA configuration
+     *
+     * DACK# active low
+     * DREQ active high
+     * fixed priority
+     * channel group enable
+        */
+
+       out8(W83C553F_DMA1 + W83C553F_DMA1_CS, 0x00);
+       out16(W83C553F_DMA2 + W83C553F_DMA2_CS, 0x0000);
+}
+
index cf155a77d8bbd5afa3ed15bb208f6bab21576ee5..44ce94b52275578a5d1ad9f54b11ff3331559663 100644 (file)
@@ -48,6 +48,9 @@
 #include <commproc.h>
 #endif
 #include <version.h>
+#if defined(CONFIG_BAB750)
+#include <w83c553f.h>
+#endif
 
 #undef DEBUG
 
@@ -590,6 +593,18 @@ void    board_init_r  (bd_t *bd, ulong dest_addr)
     icache_enable();   /* it's time to enable the instruction cache */
 #endif
 
+#if defined(CONFIG_BAB750)
+    /*
+     * Do pci configuration on BAB 750 _before_ the flash
+     * is initialised, because we need the ISA bridge there.
+     */
+    pci_init(bd);
+    /*
+     * Initialise the ISA bridge
+     */
+    initialise_w83c553f();
+#endif
+
     asm ("sync ; isync");
 
     /*
@@ -654,7 +669,7 @@ void    board_init_r  (bd_t *bd, ulong dest_addr)
     watchdog_reset ();
 #endif /* CONFIG_WATCHDOG */
 
-#ifdef CONFIG_PCI
+#if defined(CONFIG_PCI) && !defined(CONFIG_BAB750)
     /*
      * Do pci configuration
      */
index 2bd30c263bceaf636b874ded04b9264151170d25..0c4c0149366cb44de454d41a7f2cd762c7e92f3f 100644 (file)
@@ -98,8 +98,10 @@ static int curr_device = -1;
 
 /* Current offset for IDE0 / IDE1 bus access   */
 static ulong bus_offset[CFG_IDE_MAXBUS] = {
+#if defined(CFG_ATA_IDE0_OFFSET)
        CFG_ATA_IDE0_OFFSET,
-#if CFG_IDE_MAXBUS > 1
+#endif
+#if defined(CFG_ATA_IDE1_OFFSET) && (CFG_IDE_MAXBUS > 1)
        CFG_ATA_IDE1_OFFSET,
 #endif
 };
index 7279ead7ed860c6439bcca134004c93b4c95a9e4..de2aabd551eeb7603e490394efa5867b1803fcd3 100644 (file)
@@ -2,6 +2,9 @@
  * (C) Copyright 2000
  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  *
+ * (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Andreas Heppel <aheppel@sysgo.de>
+
  * See file CREDITS for list of people who contributed to this
  * project.
  *
 /*
  * Support for persistent environment data
  */
+
+/*
+ * 09-18-2001 Andreas Heppel, Sysgo RTS GmbH <aheppel@sysgo.de>
+ *
+ * It might not be possible in all cases to use 'memcpy()' to copy
+ * the environment to NVRAM, as the NVRAM might not be mapped into
+ * the memory space. (I.e. this is the case for the BAB750). In those
+ * cases it might be possible to access the NVRAM using a different
+ * method. For example, the RTC on the BAB750 is accessible in IO
+ * space using its address and data registers. To enable usage of
+ * NVRAM in those cases I invented the functions 'nvram_read()' and
+ * 'nvram_write()', which will be activated upon the configuration
+ * #define CFG_NVRAM_ACCESS_ROUTINE. Note, that those functions are
+ * strongly dependent on the used HW, and must be redefined for each
+ * board that wants to use them.
+ */
+
 #include <ppcboot.h>
 #include <command.h>
 #include <cmd_nvedit.h>
@@ -90,8 +110,18 @@ typedef     struct environment_s {
 /*---  NVRAM  ----------------------------------------------------------*/
 #ifdef CFG_ENV_IS_IN_NVRAM                     /* Environment is in NVRAM      */
 
+#ifdef CFG_NVRAM_ACCESS_ROUTINE
+
+static env_t *env_ptr = NULL;
+void *nvram_read(void *dest, const short src, size_t count);
+void nvram_write(short dest, const void *src, size_t count);
+
+#else
+
 static env_t *env_ptr = (env_t *)CFG_ENV_ADDR;
 
+#endif
+
 /*---  EEPROM ----------------------------------------------------------*/
 #elif defined(CFG_ENV_IS_IN_EEPROM)            /* Environment is in EEPROM     */
 static env_t *env_ptr = NULL;
@@ -204,6 +234,9 @@ static int envmatch (uchar *, int);
 #ifdef CFG_ENV_IS_IN_EEPROM
 static uchar  get_env_char_eeprom(int);
 #endif
+#if defined(CFG_ENV_IS_IN_NVRAM) && defined(CFG_NVRAM_ACCESS_ROUTINE)
+static uchar  get_env_char_nvram(int);
+#endif
 static uchar  get_env_char_memory(int);
 static uchar *get_env_addr_memory(int);
 
@@ -211,6 +244,8 @@ static uchar *get_env_addr_memory(int);
 static uchar (*get_env_char)(int) =
 #ifdef CFG_ENV_IS_IN_EEPROM
        get_env_char_eeprom;
+#elif defined(CFG_ENV_IS_IN_NVRAM) && defined(CFG_NVRAM_ACCESS_ROUTINE)
+       get_env_char_nvram;
 #else
        get_env_char_memory;
 #endif
@@ -275,6 +310,11 @@ void env_relocate (ulong offset)
                eeprom_read (CFG_ENV_OFFSET+offsetof(env_t,data),
                             env_ptr->data,
                             ENV_SIZE);
+#elif defined(CFG_ENV_IS_IN_NVRAM) && defined(CFG_NVRAM_ACCESS_ROUTINE)
+               DEBUGF ("%s[%d] read ENV from NVRAM\n", __FUNCTION__,__LINE__);
+               nvram_read(env_ptr->data,
+                            CFG_ENV_ADDR + sizeof(long),
+                            ENV_SIZE);
 # else
                DEBUGF ("%s[%d] read ENV from NVRAM/FLASH\n",__FUNCTION__,__LINE__);
                memcpy (env_ptr->data,
@@ -314,6 +354,22 @@ static uchar *get_env_addr_memory(int index)
        }
 }
 
+#if defined(CFG_ENV_IS_IN_NVRAM) && defined(CFG_NVRAM_ACCESS_ROUTINE)
+static uchar  get_env_char_nvram(int index)
+{
+       uchar c;
+       init_data_t *idata = (init_data_t*)(CFG_INIT_RAM_ADDR+CFG_INIT_DATA_OFFSET);
+
+       /* if the NVRAM crc was bad, use the default environment */
+       if (idata->env_valid)
+               nvram_read(&c, CFG_ENV_ADDR+index, 1);
+       else
+               c = default_environment[index];
+               
+       return c;
+}
+#endif
+
 #ifdef CFG_ENV_IS_IN_EEPROM
 /*
  * Utility function when we have to read from serial device
@@ -763,8 +819,14 @@ int do_saveenv  (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
 {
        int rcode = 0;
        printf ("Saving Environment to NVRAM...\n");
+
+#ifdef CFG_NVRAM_ACCESS_ROUTINE
+       nvram_write((short)CFG_ENV_ADDR, env_ptr, CFG_ENV_SIZE);
+       rcode = 0;
+#else
        if (memcpy ((char *)CFG_ENV_ADDR, env_ptr, CFG_ENV_SIZE) == NULL)
                    rcode = 1 ;
+#endif
        return rcode;       
 }
 
@@ -856,6 +918,25 @@ int do_saveenv  (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
  * We are still running from ROM, so data use is limited
  */
 #ifndef        CFG_ENV_IS_IN_EEPROM
+
+#if defined(CFG_ENV_IS_IN_NVRAM) && defined(CFG_NVRAM_ACCESS_ROUTINE)
+
+void env_init(init_data_t *idata)
+{
+       ulong crc;
+       uchar data[ENV_SIZE];
+       nvram_read (&crc, CFG_ENV_ADDR, sizeof(ulong));
+       nvram_read (data, CFG_ENV_ADDR+sizeof(ulong), ENV_SIZE);
+               
+       if (crc32(0, data, ENV_SIZE) == crc) {
+               idata->env_addr  = (ulong)CFG_ENV_ADDR + sizeof(long);
+               idata->env_valid = 1;
+       } else {
+               idata->env_addr  = (ulong)&default_environment[0];
+               idata->env_valid = 0;
+       }
+}
+#else
 void env_init(init_data_t *idata)
 {
        if (crc32(0, env_ptr->data, ENV_SIZE) == env_ptr->crc) {
@@ -866,6 +947,8 @@ void env_init(init_data_t *idata)
                idata->env_valid = 0;
        }
 }
+#endif /* defined(CFG_ENV_IS_IN_NVRAM) && defined(CFG_NVRAM_ACCESS_ROUTINE) */
+
 #else  /* CFG_ENV_IS_IN_EEPROM */
 /*
  * Use a (moderately small) buffer on the stack
diff --git a/cpu/mpc75x/Makefile b/cpu/mpc75x/Makefile
new file mode 100644 (file)
index 0000000..3a174d1
--- /dev/null
@@ -0,0 +1,43 @@
+#
+# (C) Copyright 2001
+# Josh Huber <huber@mclx.com>, Mission Critical Linux, Inc.
+#
+# 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$(CPU).a
+
+START  = start.o kgdb.o
+OBJS   = traps.o cpu.o cpu_init.o speed.o interrupts.o
+
+all:   .depend $(START) $(LIB)
+
+$(LIB):        $(OBJS)
+       $(AR) crv $@ $(OBJS) kgdb.o start.o
+
+#########################################################################
+
+.depend:       Makefile $(START:.o=.S) $(OBJS:.o=.c)
+               $(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) > $@
+
+sinclude .depend
+
+#########################################################################
diff --git a/cpu/mpc75x/config.mk b/cpu/mpc75x/config.mk
new file mode 100644 (file)
index 0000000..4a669d4
--- /dev/null
@@ -0,0 +1,26 @@
+#
+# (C) Copyright 2001
+# Josh Huber <huber@mclx.com>, Mission Critical Linux, Inc.
+#
+# 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
+#
+
+PLATFORM_RELFLAGS += -mrelocatable -ffixed-r14
+
+PLATFORM_CPPFLAGS += -DCONFIG_75x -ffixed-r2 -mstring
diff --git a/cpu/mpc75x/cpu.c b/cpu/mpc75x/cpu.c
new file mode 100644 (file)
index 0000000..731c9c4
--- /dev/null
@@ -0,0 +1,129 @@
+/*
+ * (C) Copyright 2001  Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Andreas Heppel <aheppel@sysgo.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
+ */
+
+/*
+ * cpu.c
+ *
+ * CPU specific code
+ *
+ * written or collected and sometimes rewritten by
+ * Magnus Damm <damm@bitsmart.com>
+ *
+ * minor modifications by
+ * Wolfgang Denk <wd@denx.de>
+ *
+ * more minor modifications by
+ * Andreas Heppel <aheppel@sysgo.de>
+ */
+
+#include <ppcboot.h>
+#include <mpc75x.h>
+#include <asm/cache.h>
+#include <config.h>
+
+#if !defined(CONFIG_74x) && !defined(CONFIG_75x) && !defined(CONFIG_74xx)
+#error CPU undefined
+#endif
+
+int
+checkcpu(long clock)
+{
+       uint pvr = get_pvr(); /* processor version register */
+
+       switch (PVR_VER(pvr)) {
+       case 0x0008:
+               puts("PPC74x/75x ");
+               break;
+
+       case 0x000c:
+               puts("PPC7400 ");
+               break;
+
+       default:
+               puts("Unknown CPU -- configuration error!\n");
+               return -1;
+               break;
+       }
+       
+       printf("v%d.%d at %ld / %ld MHz\n", (pvr >> 8) & 0xFF, pvr & 0xFF, clock/1000000, get_bus_freq(0)/1000000);
+       
+       return 0;
+}
+
+/* these two functions are unimplemented currently [josh] */
+
+/* ------------------------------------------------------------------------- */
+/* L1 i-cache                                                                */
+
+int
+checkicache(void)
+{
+       return 0; /* XXX */
+}
+
+/* ------------------------------------------------------------------------- */
+/* L1 d-cache                                                                */
+
+int
+checkdcache(void)
+{
+       return 0; /* XXX */
+}
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * For the 603 the TB clock runs at 1/4 the cpu bus speed.
+ */
+unsigned long
+get_tbclk (void)
+{
+       return get_bus_freq(0) / 4;
+}
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * The MPC7xx/74xx CPUs do not have an internal watchdog and also do not have
+ * any possibility to reset on check stop. If any of those features is to be
+ * used, there must be a board specific solution. Thus, the functions do_reset()
+ * and watchdog_reset() are not implemented here, but in the board's main file.
+ */
+/*void
+do_reset (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
+{
+}
+*/
+
+/* ------------------------------------------------------------------------- */
+
+/*#if defined(CONFIG_WATCHDOG)
+void
+watchdog_reset(void)
+{
+}
+#endif
+*/
+
+/* ------------------------------------------------------------------------- */
diff --git a/cpu/mpc75x/cpu_init.c b/cpu/mpc75x/cpu_init.c
new file mode 100644 (file)
index 0000000..34193cc
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * (C) Copyright 2001  Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Andreas Heppel <aheppel@sysgo.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
+ */
+
+/*
+ * cpu_init.c - low level cpu init
+ */
+
+#include <ppcboot.h>
+#include <mpc75x.h>
+
+/*
+ * Breath some life into the CPU...
+ *
+ * there's basically nothing to do here since the memory controller
+ * isn't on the CPU in this case.
+ */
+
+void l2_enable(void);
+
+void
+cpu_init_f (void)
+{
+}
+
+/*
+ * initialize higher level parts of CPU like timers and L2 cache
+ */
+void
+cpu_init_r  (bd_t *bd)
+{
+#if defined(CFG_L2) && (defined(CONFIG_75x) || defined(CONFIG_74xx))
+       l2_enable();
+#endif
+}
diff --git a/cpu/mpc75x/interrupts.c b/cpu/mpc75x/interrupts.c
new file mode 100644 (file)
index 0000000..33ea7a3
--- /dev/null
@@ -0,0 +1,169 @@
+/*
+ * (C) Copyright 2001
+ * Josh Huber <huber@mclx.com>, Mission Critical Linux, Inc.
+ *
+ * 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
+ */
+
+/*
+ * interrupts.c - just enough support for the decrementer/timer
+ */
+
+#include <ppcboot.h>
+#include <asm/processor.h>
+#include <commproc.h>
+#include <command.h>
+
+/*#define DEBUG */
+
+/****************************************************************************/
+
+unsigned decrementer_count;         /* count value for 1e6/HZ microseconds */
+
+/****************************************************************************/
+
+static __inline__ unsigned long
+get_msr(void)
+{
+       unsigned long msr;
+
+       asm volatile("mfmsr %0" : "=r" (msr) :);
+       return msr;
+}
+
+static __inline__ void
+set_msr(unsigned long msr)
+{
+       asm volatile("mtmsr %0" : : "r" (msr)); 
+}
+
+static __inline__ unsigned long
+get_dec(void)
+{
+       unsigned long val;
+
+       asm volatile("mfdec %0" : "=r" (val) :);
+       return val;
+}
+
+
+static __inline__ void
+set_dec(unsigned long val)
+{
+       asm volatile("mtdec %0" : : "r" (val)); 
+}
+
+
+void
+enable_interrupts(void)
+{
+/*     set_msr (get_msr() | MSR_EE);*/
+}
+
+/* returns flag if MSR_EE was set before */
+int
+disable_interrupts(void)
+{
+       ulong msr = get_msr();
+       set_msr (msr & ~MSR_EE);
+       return ((msr & MSR_EE) != 0);
+}
+
+/****************************************************************************/
+
+void
+interrupt_init(bd_t *bd)
+{
+       decrementer_count = get_tbclk() / CFG_HZ;
+
+       set_dec (decrementer_count);
+
+       enable_interrupts();
+}
+
+/****************************************************************************/
+
+/*
+ * Handle external interrupts
+ */
+void
+external_interrupt(struct pt_regs *regs)
+{
+       puts("external_interrupt (oops!)\n");
+}
+
+volatile ulong timestamp = 0;
+
+/*
+ * timer_interrupt - gets called when the decrementer overflows,
+ * with interrupts disabled.
+ * Trivial implementation - no need to be really accurate.
+ */
+void
+timer_interrupt(struct pt_regs *regs)
+{
+       set_dec(decrementer_count);
+       timestamp++;
+}
+
+/****************************************************************************/
+
+void
+reset_timer(void)
+{
+       timestamp = 0;
+}
+
+ulong
+get_timer(ulong base)
+{
+       return (timestamp - base);
+}
+
+void
+set_timer(ulong t)
+{
+       timestamp = t;
+}
+
+/****************************************************************************/
+
+/*
+ * Install and free a interrupt handler.
+ */
+
+void
+irq_install_handler(int vec, interrupt_handler_t *handler, void *arg)
+{
+
+}
+
+void
+irq_free_handler(int vec)
+{
+
+}
+
+/****************************************************************************/
+
+void
+do_irqinfo(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
+{
+       puts("IRQ related functions are unimplemented currently.\n");
+}
diff --git a/cpu/mpc75x/kgdb.S b/cpu/mpc75x/kgdb.S
new file mode 100644 (file)
index 0000000..f3a6c03
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ *  Copyright (C) 2000 Murray Jensen <Murray.Jensen@cmst.csiro.au>
+ *
+ * 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-1307USA
+ */
+
+/* note - this won't work with the 74xx cpus.  needs more work [josh] */
+       
+#include <config.h>
+#include <command.h>
+#include <mpc75x.h>
+#include "version.h"
+
+#include <ppc_asm.tmpl>
+#include <ppc_defs.h>
+
+#include <asm/cache.h>
+#include <asm/mmu.h>
+
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+
+ /*
+ * cache flushing routines for kgdb
+ */
+
+       .globl  kgdb_flush_cache_all
+kgdb_flush_cache_all:
+       lis     r3, IDC_INVALL@h
+       mtspr   DC_CST, r3
+       sync
+       lis     r3, IDC_INVALL@h
+       mtspr   IC_CST, r3
+       SYNC
+       blr
+
+       .globl  kgdb_flush_cache_range
+kgdb_flush_cache_range:
+       li      r5,CFG_CACHELINE_SIZE-1
+       andc    r3,r3,r5
+       subf    r4,r3,r4
+       add     r4,r4,r5
+       srwi.   r4,r4,CFG_CACHELINE_SHIFT
+       beqlr
+       mtctr   r4
+       mr      r6,r3
+1:     dcbst   0,r3
+       addi    r3,r3,CFG_CACHELINE_SIZE
+       bdnz    1b
+       sync                            /* wait for dcbst's to get to ram */
+       mtctr   r4
+2:     icbi    0,r6
+       addi    r6,r6,CFG_CACHELINE_SIZE
+       bdnz    2b
+       SYNC
+       blr
+
+#endif /* CFG_CMD_KGDB */
diff --git a/cpu/mpc75x/speed.c b/cpu/mpc75x/speed.c
new file mode 100644 (file)
index 0000000..74f5131
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * (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 <ppcboot.h>
+#include <mpc75x.h>
+#include <asm/processor.h>
+
+/*
+ * 7xx CPU specific modifications by
+ * Andreas Heppel <aheppel@sysgo.de>
+ */
+/* Access functions for the Machine State Register */
+static __inline__ unsigned long
+get_msr(void)
+{
+       unsigned long msr;
+
+       asm volatile("mfmsr %0" : "=r" (msr) :);
+       return msr;
+}
+
+static __inline__ void
+set_msr(unsigned long msr)
+{
+       asm volatile("mtmsr %0" : : "r" (msr)); 
+}
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * Measure CPU clock speed (core clock GCLK1)
+ *
+ * (Approx. GCLK frequency in Hz)
+ */
+short pllratio_to_factor[] = {
+    00, 75, 70, 00, 20, 65, 100, 45, 30, 55, 40, 50, 80, 60, 35, 00,
+};
+
+ulong
+get_gclk_freq (void)
+{
+       uint hid1 = mfspr(HID1);
+
+       hid1 = (hid1 >> (32-4)) & 0xf;
+
+       return (pllratio_to_factor[hid1] * get_bus_freq(0)) / 10;
+}
+
+/* ------------------------------------------------------------------------- */
+
diff --git a/cpu/mpc75x/start.S b/cpu/mpc75x/start.S
new file mode 100644 (file)
index 0000000..e8ef5cc
--- /dev/null
@@ -0,0 +1,929 @@
+/*
+ *  Copyright (C) 1998 Dan Malek <dmalek@jlc.net>
+ *  Copyright (C) 1999 Magnus Damm <kieraypc01.p.y.kie.era.ericsson.se>
+ *  Copyright (C) 2000 Wolfgang Denk <wd@denx.de>
+ *  Copyright (C) 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ *                     Andreas Heppel <aheppel@sysgo.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
+ */
+
+/*  ppcboot - Startup Code for PowerPC based Embedded Boards
+ *
+ *
+ *  The processor starts at 0xfff00100 and the code is executed
+ *  from flash. The code is organized to be at an other address
+ *  in memory, but as long we don't jump around before relocating.
+ *  board_init lies at a quite high address and when the cpu has
+ *  jumped there, everything is ok.
+ */
+/* Although this file was originally dvelopped for the MPC750 CPU,
+ * it should be possible to use it for MPC740/MPC7400 CPUs as well
+ * since there are anly small differences in the basic operation.
+ * However, the code has been tested with an MPC750 CPU only.
+ */
+
+#include <config.h>
+#include <mpc75x.h>
+#include "version.h"
+
+#include <ppc_asm.tmpl>
+#include <ppc_defs.h>
+
+#include <asm/cache.h>
+#include <asm/mmu.h>
+
+#ifndef  CONFIG_IDENT_STRING
+#define  CONFIG_IDENT_STRING ""
+#endif
+
+/* We don't want the  MMU yet.
+*/
+#undef MSR_KERNEL
+/* Machine Check and Recoverable Interr. */
+#define MSR_KERNEL ( MSR_ME | MSR_RI )
+
+       
+/*
+ * Set up GOT: Global Offset Table
+ *
+ * Use r14 to access the GOT
+ */
+       START_GOT
+       GOT_ENTRY(_GOT2_TABLE_)
+       GOT_ENTRY(_FIXUP_TABLE_)
+
+       GOT_ENTRY(_start)
+       GOT_ENTRY(_start_of_vectors)
+       GOT_ENTRY(_end_of_vectors)
+       GOT_ENTRY(transfer_to_handler)
+
+       GOT_ENTRY(MessageBlock)
+/*     GOT_ENTRY(spdRead)*/
+       GOT_ENTRY(_end)
+       GOT_ENTRY(.bss)
+       END_GOT
+
+/*
+ * r3 - 1st arg to board_init(): IMMP pointer
+ * r4 - 2nd arg to board_init(): boot flag
+ */
+       .text
+       .long   0x27051956              /* PPCBOOT Magic Number         */
+
+       .globl  version_string
+version_string:
+       .ascii PPCBOOT_VERSION
+       .ascii " (", __DATE__, " - ", __TIME__, ")"
+       .ascii CONFIG_IDENT_STRING, "\0"
+
+       . = EXC_OFF_SYS_RESET
+       .globl  _start
+_start:
+       li      r21, BOOTFLAG_COLD      /* Normal Power-On: Boot from FLASH */
+       b       boot_cold
+
+       . = EXC_OFF_SYS_RESET + 0x10
+
+       .globl  _start_warm
+_start_warm:
+       li      r21, BOOTFLAG_WARM      /* Software reboot              */
+       b       boot_warm
+
+       /* the boot code is located below the exception table */
+       
+       .globl  _start_of_vectors
+_start_of_vectors:
+
+/* Machine check */
+       STD_EXCEPTION(0x200, MachineCheck, MachineCheckException)
+
+/* Data Storage exception.  "Never" generated on the 860. */
+       STD_EXCEPTION(0x300, DataStorage, UnknownException)
+
+/* Instruction Storage exception.  "Never" generated on the 860. */
+       STD_EXCEPTION(0x400, InstStorage, UnknownException)
+
+/* External Interrupt exception. */
+       STD_EXCEPTION(0x500, ExtInterrupt, external_interrupt)
+
+/* Alignment exception. */
+       . = 0x600
+Alignment:
+       EXCEPTION_PROLOG
+       mfspr   r4,DAR
+       stw     r4,_DAR(r21)
+       mfspr   r5,DSISR
+       stw     r5,_DSISR(r21)
+       addi    r3,r1,STACK_FRAME_OVERHEAD
+       li      r20,MSR_KERNEL
+       rlwimi  r20,r23,0,16,16         /* copy EE bit from saved MSR */
+       lwz     r6,GOT(transfer_to_handler)
+       mtlr    r6
+       blrl
+.L_Alignment:
+       .long   AlignmentException - _start + EXC_OFF_SYS_RESET
+       .long   int_return - _start + EXC_OFF_SYS_RESET
+
+/* Program check exception */
+       . = 0x700
+ProgramCheck:
+       EXCEPTION_PROLOG
+       addi    r3,r1,STACK_FRAME_OVERHEAD
+       li      r20,MSR_KERNEL
+       rlwimi  r20,r23,0,16,16         /* copy EE bit from saved MSR */
+       lwz     r6,GOT(transfer_to_handler)
+       mtlr    r6
+       blrl
+.L_ProgramCheck:
+       .long   ProgramCheckException - _start + EXC_OFF_SYS_RESET
+       .long   int_return - _start + EXC_OFF_SYS_RESET
+
+       /* No FPU on MPC8xx.  This exception is not supposed to happen.
+       */
+       STD_EXCEPTION(0x800, FPUnavailable, UnknownException)
+
+       /* I guess we could implement decrementer, and may have
+        * to someday for timekeeping.
+        */
+       STD_EXCEPTION(0x900, Decrementer, timer_interrupt)
+       STD_EXCEPTION(0xa00, Trap_0a, UnknownException)
+       STD_EXCEPTION(0xb00, Trap_0b, UnknownException)
+
+       STD_EXCEPTION(0xc00, SystemCall, UnknownException)
+       STD_EXCEPTION(0xd00, SingleStep, UnknownException)
+
+       STD_EXCEPTION(0xe00, Trap_0e, UnknownException)
+       STD_EXCEPTION(0xf00, Trap_0f, UnknownException)
+
+       /* On the MPC8xx, this is a software emulation interrupt.  It occurs
+        * for all unimplemented and illegal instructions.
+        */
+       STD_EXCEPTION(0x1000, SoftEmu, SoftEmuException)
+
+       STD_EXCEPTION(0x1100, InstructionTLBMiss, UnknownException)
+       STD_EXCEPTION(0x1200, DataTLBMiss, UnknownException)
+       STD_EXCEPTION(0x1300, InstructionTLBError, UnknownException)
+       STD_EXCEPTION(0x1400, DataTLBError, UnknownException)
+
+       STD_EXCEPTION(0x1500, Reserved5, UnknownException)
+       STD_EXCEPTION(0x1600, Reserved6, UnknownException)
+       STD_EXCEPTION(0x1700, Reserved7, UnknownException)
+       STD_EXCEPTION(0x1800, Reserved8, UnknownException)
+       STD_EXCEPTION(0x1900, Reserved9, UnknownException)
+       STD_EXCEPTION(0x1a00, ReservedA, UnknownException)
+       STD_EXCEPTION(0x1b00, ReservedB, UnknownException)
+
+       STD_EXCEPTION(0x1c00, DataBreakpoint, UnknownException)
+       STD_EXCEPTION(0x1d00, InstructionBreakpoint, UnknownException)
+       STD_EXCEPTION(0x1e00, PeripheralBreakpoint, UnknownException)
+       STD_EXCEPTION(0x1f00, DevPortBreakpoint, UnknownException)
+
+       /* PPC documentation says that the vector table ends at 0x3000 */
+       .globl  _end_of_vectors
+_end_of_vectors:
+
+       . = 0x3000
+
+boot_cold:
+boot_warm:
+       /* disable everything */
+       li      r0, 0
+       
+       /* hardware imlementation register */
+       mtspr   HID0, r0
+       sync
+       mtmsr   0
+
+       /* invalidate BATs */
+       mtspr   IBAT0U, r0
+       mtspr   IBAT1U, r0
+       mtspr   IBAT2U, r0
+       mtspr   IBAT3U, r0
+       isync
+       mtspr   DBAT0U, r0
+       mtspr   DBAT1U, r0
+       mtspr   DBAT2U, r0
+       mtspr   DBAT3U, r0
+       isync
+
+       /* Turn off data and instruction cache control bits */
+       mfspr   r3, HID0
+       isync
+       rlwinm  r4, r3, 0, 18, 15
+       sync
+       isync
+       mtspr   HID0, r4
+       isync
+
+       /* invalidate the MPU's data/instruction caches */
+       ori     r3, r3, 0xCC00
+       or      r4, r4, r3
+       isync
+       mtspr   HID0, r4
+       andc    r4, r4, r3
+       isync
+       mtspr   HID0, r4
+       isync
+       
+       ori     r4, r4, 0x8800
+
+    /*
+     * The setting of the instruction cache enable (ICE) bit must be
+     * preceded by an isync instruction to prevent the cache from being
+     * enabled or disabled while an instruction access is in progress.
+     */
+       isync
+
+    mtspr   HID0, r4
+       isync
+
+#if defined(CFG_L2) && (defined(CONFIG_75x) || defined(CONFIG_74xx))
+       /* init the L2 cache */
+       addis   r3, r0, L2_INIT@h
+       ori     r3, r3, L2_INIT@l
+       mtspr   l2cr, r3
+
+       /* invalidate the L2 cache */
+       sync
+       oris    r3, r3, L2CR_L2I@h
+       mtspr   l2cr, r3
+       sync
+
+invl2:
+       mfspr   r3, l2cr
+       andi.   r3, r3, L2CR_L2IP
+       bne     invl2
+
+       /* turn off the global invalidate bit */
+       mfspr   r3, l2cr
+       rlwinm  r3, r3, 0, 11, 9
+       mtspr   l2cr, r3
+#endif
+
+       /* setup the bats */
+       bl      setup_bats
+       sync
+
+#if CFG_MMU
+       /*enable address translation */
+       bl      enable_addr_trans
+       sync
+#endif
+
+       /*
+        * Calculate absolute address in FLASH and jump there
+        *------------------------------------------------------*/
+       lis     r3, CFG_MONITOR_BASE@h
+       ori     r3, r3, CFG_MONITOR_BASE@l
+       addi    r3, r3, in_flash - _start + EXC_OFF_SYS_RESET
+       mtlr    r3
+       blr
+
+in_flash:
+       /* let the C-code set up the rest                       */
+       /*                                                      */
+       /* Be careful to keep code relocatable !                */
+       /*------------------------------------------------------*/
+
+       GET_GOT                 /* initialize GOT access        */
+
+       /*
+        * Change the address map if this is configured
+        */
+       bl set_address_map
+
+       /*
+        * Since the 7xx/7xxx CPUs do not have any RAM on chip
+        * we cannot wait to initialise the RAM during board_init_f.
+        * We need some RAM before we can run C code.
+        */
+       bl ram_init
+       
+       /* set up r1 (SP) */
+       lis             r1,CFG_INIT_RAM_ADDR@h
+       ori             r1,r1,CFG_INIT_SP_OFFSET        /* set up the stack in SDRAM */
+       stwu    r1, -8(r1)                                      /* make room for stack frame header */
+
+       /* run low-level CPU init code     (from Flash) */
+       bl      cpu_init_f
+
+       /* r3: BOOTFLAG */
+       mr      r3, r21
+       /* run 1st part of board init code (from Flash)   */
+       bl      board_init_f
+
+       /* NOTREACHED */
+       
+       /* setup_bats - set them up to some initial state */
+       .globl  setup_bats
+setup_bats:
+
+       /*
+        * We need the bats only, if we use the MMU, otherwise they may remain
+        * invalidated
+        */
+#ifdef CFG_MMU
+       addis   r0, r0, 0x0000
+
+       /* IBAT 0 */
+       addis   r4, r0, CFG_IBAT0L@h
+       ori     r4, r4, CFG_IBAT0L@l
+       addis   r3, r0, CFG_IBAT0U@h
+       ori     r3, r3, CFG_IBAT0U@l
+       mtspr   IBAT0L, r4
+       mtspr   IBAT0U, r3
+       isync
+
+       /* DBAT 0 */
+       addis   r4, r0, CFG_DBAT0L@h
+       ori     r4, r4, CFG_DBAT0L@l
+       addis   r3, r0, CFG_DBAT0U@h
+       ori     r3, r3, CFG_DBAT0U@l
+       mtspr   DBAT0L, r4
+       mtspr   DBAT0U, r3
+       isync
+
+       /* IBAT 1 */
+       addis   r4, r0, CFG_IBAT1L@h
+       ori     r4, r4, CFG_IBAT1L@l
+       addis   r3, r0, CFG_IBAT1U@h
+       ori     r3, r3, CFG_IBAT1U@l
+       mtspr   IBAT1L, r4
+       mtspr   IBAT1U, r3
+       isync
+
+       /* DBAT 1 */
+       addis   r4, r0, CFG_DBAT1L@h
+       ori     r4, r4, CFG_DBAT1L@l
+       addis   r3, r0, CFG_DBAT1U@h
+       ori     r3, r3, CFG_DBAT1U@l
+       mtspr   DBAT1L, r4
+       mtspr   DBAT1U, r3
+       isync
+
+       /* IBAT 2 */
+       addis   r4, r0, CFG_IBAT2L@h
+       ori     r4, r4, CFG_IBAT2L@l
+       addis   r3, r0, CFG_IBAT2U@h
+       ori     r3, r3, CFG_IBAT2U@l
+       mtspr   IBAT2L, r4
+       mtspr   IBAT2U, r3
+       isync
+
+       /* DBAT 2 */
+       addis   r4, r0, CFG_DBAT2L@h
+       ori     r4, r4, CFG_DBAT2L@l
+       addis   r3, r0, CFG_DBAT2U@h
+       ori     r3, r3, CFG_DBAT2U@l
+       mtspr   DBAT2L, r4
+       mtspr   DBAT2U, r3
+       isync
+
+       /* IBAT 3 */
+       addis   r4, r0, CFG_IBAT3L@h
+       ori     r4, r4, CFG_IBAT3L@l
+       addis   r3, r0, CFG_IBAT3U@h
+       ori     r3, r3, CFG_IBAT3U@l
+       mtspr   IBAT3L, r4
+       mtspr   IBAT3U, r3
+       isync
+
+       /* DBAT 3 */
+       addis   r4, r0, CFG_DBAT3L@h
+       ori     r4, r4, CFG_DBAT3L@l
+       addis   r3, r0, CFG_DBAT3U@h
+       ori     r3, r3, CFG_DBAT3U@l
+       mtspr   DBAT3L, r4
+       mtspr   DBAT3U, r3
+       isync
+#endif
+
+       /* now invalidate the TLBs */
+       addis   r3, 0, 0x0000
+#ifdef CONFIG_74x
+       addis   r5, 0, 0x2    /* upper bound of 0x00020000 for 740 (603e) */
+#endif
+#if defined(CONFIG_75x) || defined(CONFIG_74xx)
+       addis   r5, 0, 0x4    /* upper bound of 0x00040000 for 750/7400 */
+#endif
+       isync
+
+tlblp:
+       tlbie   r3
+       sync
+       addi    r3, r3, 0x1000
+       cmp     0, 0, r3, r5
+       blt tlblp
+
+       blr
+
+       .globl enable_addr_trans
+enable_addr_trans:
+       /* enable address translation */
+       mfmsr   r5
+       ori     r5, r5, (MSR_IR | MSR_DR)
+       mtmsr   r5
+       isync
+       blr
+
+       .globl disable_addr_trans
+disable_addr_trans:
+       /* disable address translation */
+       mfmsr   r5
+       andi.   r5, r5, (~(MSR_IR | MSR_DR) & 0xFFFF)
+       mtmsr   r5
+       isync
+       blr
+       
+
+/*
+ * This code finishes saving the registers to the exception frame
+ * and jumps to the appropriate handler for the exception.
+ * Register r21 is pointer into trap frame, r1 has new stack pointer.
+ */
+       .globl  transfer_to_handler
+transfer_to_handler:
+       stw     r22,_NIP(r21)
+       lis     r22,MSR_POW@h
+       andc    r23,r23,r22
+       stw     r23,_MSR(r21)
+       SAVE_GPR(7, r21)
+       SAVE_4GPRS(8, r21)
+       SAVE_8GPRS(12, r21)
+       SAVE_8GPRS(24, r21)
+       mflr    r23
+       andi.   r24,r23,0x3f00          /* get vector offset */
+       stw     r24,TRAP(r21)
+       li      r22,0
+       stw     r22,RESULT(r21)
+       mtspr   SPRG2,r22               /* r1 is now kernel sp */
+       lwz     r24,0(r23)              /* virtual address of handler */
+       lwz     r23,4(r23)              /* where to go when done */
+       mtspr   SRR0,r24
+       mtspr   SRR1,r20
+       mtlr    r23
+       SYNC
+       rfi                             /* jump to handler, enable MMU */
+
+int_return:
+       mfmsr   r29             /* Disable interrupts */
+       li      r4,0
+       ori     r4,r4,MSR_EE
+       andc    r29,r29,r4
+       SYNC                    /* Some chip revs need this... */
+       mtmsr   r29
+       SYNC
+       lwz     r2,_CTR(r1)
+       lwz     r0,_LINK(r1)
+       mtctr   r2
+       mtlr    r0
+       lwz     r2,_XER(r1)
+       lwz     r0,_CCR(r1)
+       mtspr   XER,r2
+       mtcrf   0xFF,r0
+       REST_10GPRS(3, r1)
+       REST_10GPRS(13, r1)
+       REST_8GPRS(23, r1)
+       REST_GPR(31, r1)
+       lwz     r2,_NIP(r1)     /* Restore environment */
+       lwz     r0,_MSR(r1)
+       mtspr   SRR0,r2
+       mtspr   SRR1,r0
+       lwz     r0,GPR0(r1)
+       lwz     r2,GPR2(r1)
+       lwz     r1,GPR1(r1)
+       SYNC
+       rfi
+
+/* Cache functions.  XXX fix these, I think they're broken [josh].
+*/
+       .globl  icache_enable
+icache_enable:
+       mfspr   r3, HID0
+       ori     r3, r3, (HID0_ICE | HID0_ICFI)
+       isync
+       mtspr   HID0, r3
+       blr
+
+       .globl  icache_disable
+icache_disable:
+       mfspr   r3, HID0
+       li      r4, 0
+       ori     r4, r4, HID0_ICE
+       andc    r3, r3, r4
+       isync
+       mtspr   HID0, r3
+       blr
+
+       .globl  icache_status
+icache_status:
+       mfspr   r3, HID0
+       andi.   r3, r3, HID0_ICE
+       blr
+
+       .globl  dcache_enable
+dcache_enable:
+       mfspr   r3, HID0
+       ori     r3, r3, (HID0_DCI | HID0_DCE)
+       sync
+       mtspr   HID0, r3
+       blr
+
+       .globl  dcache_disable
+dcache_disable:
+       mfspr   r3, HID0
+       li      r4, HID0_DCE
+       andc    r3, r3, r4
+       sync
+       mtspr   HID0, r3
+       blr
+
+       .globl  dcache_status
+dcache_status:
+       mfspr   r3, HID0
+       andi.   r3, r3, HID0_DCE
+       blr
+
+       .globl  l2_enable
+l2_enable:
+       addis   r3, r0, L2_ENABLE@h
+       ori     r3, r3, L2_ENABLE@l
+       mtspr   l2cr, r3
+       blr     
+       
+       .globl  dc_read
+dc_read:
+       blr
+
+       .globl get_pvr
+get_pvr:
+       mfspr   r3, PVR
+       blr
+
+/*-----------------------------------------------------------------------*/
+
+/*
+ * void relocate_code (addr_sp, bd, addr_moni)
+ *
+ * This "function" does not return, instead it continues in RAM
+ * after relocating the monitor code.
+ *
+ * r3 = dest
+ * r4 = src
+ * r5 = length in bytes
+ * r6 = cachelinesize
+ */
+       .globl  relocate_code
+relocate_code:
+       mr      r1,  r3         /* Set new stack pointer                */
+       mr      r9,  r4         /* Save copy of Board Info pointer      */
+       mr      r10, r5         /* Save copy of Destination Address     */
+
+       mr      r3,  r5                         /* Destination Address  */
+       lis     r4, CFG_MONITOR_BASE@h          /* Source      Address  */
+       ori     r4, r4, CFG_MONITOR_BASE@l
+       lis     r5, CFG_MONITOR_LEN@h           /* Length in Bytes      */
+       ori     r5, r5, CFG_MONITOR_LEN@l
+       li      r6, CFG_CACHELINE_SIZE          /* Cache Line Size      */
+
+       /*
+        * Fix GOT pointer:
+        *
+        * New GOT-PTR = (old GOT-PTR - CFG_MONITOR_BASE) + Destination Address
+        *
+        * Offset:
+        */
+       sub     r15, r10, r4    /* dest addr - moni base */
+
+       /* First our own GOT */
+       add     r14, r14, r15
+       /* then the one used by the C code */
+       add     r30, r30, r15
+
+       /*
+        * Now relocate code
+        */
+       
+       cmplw   cr1,r3,r4       /* cmp dest addr /w src addr */
+       addi    r0,r5,3
+       srwi.   r0,r0,2
+       beq     cr1,4f          /* In place copy is not necessary       */
+       beq     7f              /* Protect against 0 count              */
+       mtctr   r0              /* ctr contains now moni len in DWORDS  */
+       bge     cr1,2f
+
+       la      r8,-4(r4)
+       la      r7,-4(r3)
+1:     lwzu    r0,4(r8)
+       stwu    r0,4(r7)
+       bdnz    1b
+       b       4f
+
+2:     slwi    r0,r0,2
+       add     r8,r4,r0
+       add     r7,r3,r0
+3:     lwzu    r0,-4(r8)
+       stwu    r0,-4(r7)
+       bdnz    3b
+
+/*
+ * Now flush the cache: note that we must start from a cache aligned
+ * address. Otherwise we might miss one cache line.
+ */
+4:
+       cmpwi   r6,0
+       add     r5,r3,r5
+       beq     7f              /* Always flush prefetch queue in any case */
+       subi    r0,r6,1
+       andc    r3,r3,r0
+       mr      r4,r3
+5:     cmplw   r4,r5
+       dcbst   0,r4
+       add     r4,r4,r6
+       blt     5b
+       sync                    /* Wait for all dcbst to complete on bus */
+       mr      r4,r3
+6:     cmplw   r4,r5
+       icbi    0,r4
+       add     r4,r4,r6
+       blt     6b
+
+7:
+       sync                    /* Wait for all icbi to complete on bus */
+       isync
+
+/*
+ * We are done. Do not return, instead branch to second part of board
+ * initialization, now running from RAM.
+ */
+       addi    r0, r10, in_ram - _start + EXC_OFF_SYS_RESET
+       mtlr    r0
+       blr
+
+in_ram:
+       /*
+        * Relocation Function, r14 point to got2+0x8000
+        *
+         * Adjust got2 pointers, no need to check for 0, this code
+         * already puts a few entries in the table.
+        */
+       li      r0,__got2_entries@sectoff@l
+       la      r3,GOT(_GOT2_TABLE_)
+       lwz     r11,GOT(_GOT2_TABLE_)
+       mtctr   r0
+       sub     r11,r3,r11
+       addi    r3,r3,-4
+1:     lwzu    r0,4(r3)
+       add     r0,r0,r11
+       stw     r0,0(r3)
+       bdnz    1b
+       
+       /*
+     * Now adjust the fixups and the pointers to the fixups
+        * in case we need to move ourselves again.
+        */     
+2:     li      r0,__fixup_entries@sectoff@l
+       lwz     r3,GOT(_FIXUP_TABLE_)
+       cmpwi   r0,0
+       mtctr   r0
+       addi    r3,r3,-4
+       beq     4f
+3:     lwzu    r4,4(r3)
+       lwzux   r0,r4,r11
+       add     r0,r0,r11
+       stw     r10,0(r3)
+       stw     r0,0(r4)
+       bdnz    3b
+4:
+clear_bss:
+       /*
+        * Now clear BSS segment
+        */
+       lwz     r3,GOT(.bss)
+       lwz     r4,GOT(_end)
+
+       cmplw   0, r3, r4
+       beq     6f
+
+       li      r0, 0
+5:
+       stw     r0, 0(r3)
+       addi    r3, r3, 4
+       cmplw   0, r3, r4
+       bne     5b
+6:
+       mr      r3, r9          /* Board Info pointer           */
+       mr      r4, r10         /* Destination Address          */
+
+       bl      board_init_r
+
+       /* Problems accessing "end" in C, so do it here */
+       .globl  get_endaddr
+get_endaddr:
+       lwz     r3,GOT(_end)
+       blr
+
+       .globl  get_startaddr
+get_startaddr:
+       lwz     r3,GOT(_start)
+       blr
+
+       .globl  get_msgblk
+get_msgblk:
+       lwz     r3,GOT(MessageBlock)
+       blr
+
+/*     .globl  get_spdread
+get_spdread:
+       lwz     r3,GOT(spdRead)
+       blr
+
+*/
+       /*
+        * Copy exception vector code to low memory
+        *
+        * r3: dest_addr
+        * r7: source address, r8: end address, r9: target address
+        */
+       .globl  trap_init
+trap_init:
+       lwz     r7, GOT(_start)
+       lwz     r8, GOT(_end_of_vectors)
+
+       rlwinm  r9, r7, 0, 18, 31       /* _start & 0x3FFF      */
+
+       cmplw   0, r7, r8
+       bgelr                           /* return if r7>=r8 - just in case */
+
+       mflr    r4                      /* save link register           */
+1:
+       lwz     r0, 0(r7)
+       stw     r0, 0(r9)
+       addi    r7, r7, 4
+       addi    r9, r9, 4
+       cmplw   0, r7, r8
+       bne     1b
+
+       /*
+        * relocate `hdlr' and `int_return' entries
+        */
+       li      r7, .L_MachineCheck - _start + EXC_OFF_SYS_RESET
+       li      r8, Alignment - _start + EXC_OFF_SYS_RESET
+2:
+       bl      trap_reloc
+       addi    r7, r7, 0x100           /* next exception vector        */
+       cmplw   0, r7, r8
+       blt     2b
+
+       li      r7, .L_Alignment - _start + EXC_OFF_SYS_RESET
+       bl      trap_reloc
+
+       li      r7, .L_ProgramCheck - _start + EXC_OFF_SYS_RESET
+       bl      trap_reloc
+
+       li      r7, .L_FPUnavailable - _start + EXC_OFF_SYS_RESET
+       li      r8, _end_of_vectors - _start + EXC_OFF_SYS_RESET
+3:
+       bl      trap_reloc
+       addi    r7, r7, 0x100           /* next exception vector        */
+       cmplw   0, r7, r8
+       blt     3b
+
+       mtlr    r4                      /* restore link register        */
+       blr
+
+       /*
+        * Function: relocate entries for one exception vector
+        */
+trap_reloc:
+       lwz     r0, 0(r7)               /* hdlr ...                     */
+       add     r0, r0, r3              /*  ... += dest_addr            */
+       stw     r0, 0(r7)
+
+       lwz     r0, 4(r7)               /* int_return ...               */
+       add     r0, r0, r3              /*  ... += dest_addr            */
+       stw     r0, 4(r7)
+
+       sync
+       isync
+
+       blr
+
+/* ------------------------------------------------------------------------------- */
+/*  Function:     in8 */
+/*  Description:  Input 8 bits */
+/* ------------------------------------------------------------------------------- */
+       .globl  in8
+in8:
+       lbz     r3,0(r3)
+       sync
+       blr
+
+/* ------------------------------------------------------------------------------- */
+/*  Function:     in16 */
+/*  Description:  Input 16 bits */
+/* ------------------------------------------------------------------------------- */
+       .globl  in16
+in16:
+       lhz     r3,0(r3)
+       sync
+       blr
+
+/* ------------------------------------------------------------------------------- */
+/*  Function:     in16r */
+/*  Description:  Input 16 bits and byte reverse */
+/* ------------------------------------------------------------------------------- */
+       .globl  in16r
+in16r:
+       lhbrx   r3,0,r3
+       sync
+       blr
+
+/* ------------------------------------------------------------------------------- */
+/*  Function:     in32 */
+/*  Description:  Input 32 bits */
+/* ------------------------------------------------------------------------------- */
+       .globl  in32
+in32:
+       lwz     3,0(3)
+       sync
+       blr
+
+/* ------------------------------------------------------------------------------- */
+/*  Function:     in32r */
+/*  Description:  Input 32 bits and byte reverse */
+/* ------------------------------------------------------------------------------- */
+    .globl  in32r
+in32r:
+       lwbrx   r3,0,r3
+       sync
+       blr
+
+/* ------------------------------------------------------------------------------- */
+/*  Function:     out8 */
+/*  Description:  Output 8 bits */
+/* ------------------------------------------------------------------------------- */
+       .globl  out8
+out8:
+       stb     r4,0(r3)
+       sync
+       blr
+
+/* ------------------------------------------------------------------------------- */
+/*  Function:     out16 */
+/*  Description:  Output 16 bits */
+/* ------------------------------------------------------------------------------- */
+       .globl  out16
+out16:
+       sth     r4,0(r3)
+       sync
+       blr
+
+/* ------------------------------------------------------------------------------- */
+/*  Function:     out16r */
+/*  Description:  Byte reverse and output 16 bits */
+/* ------------------------------------------------------------------------------- */
+       .globl  out16r
+out16r:
+       sthbrx  r4,0,r3
+       sync
+       blr
+
+/* ------------------------------------------------------------------------------- */
+/*  Function:     out32 */
+/*  Description:  Output 32 bits */
+/* ------------------------------------------------------------------------------- */
+       .globl  out32
+out32:
+       stw     r4,0(r3)
+       sync
+       blr
+
+/* ------------------------------------------------------------------------------- */
+/*  Function:     out32r */
+/*  Description:  Byte reverse and output 32 bits */
+/* ------------------------------------------------------------------------------- */
+       .globl  out32r
+out32r:
+       stwbrx  r4,0,r3
+       sync
+       blr
+
diff --git a/cpu/mpc75x/traps.c b/cpu/mpc75x/traps.c
new file mode 100644 (file)
index 0000000..1890d61
--- /dev/null
@@ -0,0 +1,234 @@
+/*
+ * linux/arch/ppc/kernel/traps.c
+ *
+ * Copyright (C) 1995-1996  Gary Thomas (gdt@linuxppc.org)
+ *
+ * Modified by Cort Dougan (cort@cs.nmt.edu)
+ * and Paul Mackerras (paulus@cs.anu.edu.au)
+ *
+ * (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
+ */
+
+/*
+ * This file handles the architecture-dependent parts of hardware exceptions
+ */
+
+#include <ppcboot.h>
+#include <command.h>
+#include <asm/processor.h>
+
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+int (*debugger_exception_handler)(struct pt_regs *) = 0;
+#endif
+
+/* Returns 0 if exception not found and fixup otherwise.  */
+extern unsigned long search_exception_table(unsigned long);
+
+/* THIS NEEDS CHANGING to use the board info structure.
+*/
+#define END_OF_MEM     0x02000000
+
+/*
+ * Trap & Exception support
+ */
+
+void
+print_backtrace(unsigned long *sp)
+{
+       int cnt = 0;
+       unsigned long i;
+
+       printf("Call backtrace: ");
+       while (sp) {
+               if ((uint)sp > END_OF_MEM)
+                       break;
+
+               i = sp[1];
+               if (cnt++ % 7 == 0)
+                       printf("\n");
+               printf("%08lX ", i);
+               if (cnt > 32) break;
+               sp = (unsigned long *)*sp;
+       }
+       printf("\n");
+}
+
+void
+show_regs(struct pt_regs * regs)
+{
+       int i;
+
+       printf("NIP: %08lX XER: %08lX LR: %08lX REGS:"
+              " %p TRAP: %04lx DAR: %08lX\n",
+              regs->nip, regs->xer, regs->link, regs, regs->trap, regs->dar);
+       printf("MSR: %08lx EE: %01x PR: %01x FP:"
+              " %01x ME: %01x IR/DR: %01x%01x\n",
+              regs->msr, regs->msr&MSR_EE ? 1 : 0, regs->msr&MSR_PR ? 1 : 0,
+              regs->msr & MSR_FP ? 1 : 0,regs->msr&MSR_ME ? 1 : 0,
+              regs->msr&MSR_IR ? 1 : 0,
+              regs->msr&MSR_DR ? 1 : 0);
+
+       printf("\n");
+       for (i = 0;  i < 32;  i++) {
+               if ((i % 8) == 0)
+               {
+                       printf("GPR%02d: ", i);
+               }
+
+               printf("%08lX ", regs->gpr[i]);
+               if ((i % 8) == 7)
+               {
+                       printf("\n");
+               }
+       }
+}
+
+
+void
+_exception(int signr, struct pt_regs *regs)
+{
+       show_regs(regs);
+       print_backtrace((unsigned long *)regs->gpr[1]);
+       panic("Exception in kernel pc %lx signal %d",regs->nip,signr);
+}
+
+void
+MachineCheckException(struct pt_regs *regs)
+{
+       unsigned long fixup;
+
+       /* Probing PCI using config cycles cause this exception
+        * when a device is not present.  Catch it and return to
+        * the PCI exception handler.
+        */
+       if ((fixup = search_exception_table(regs->nip)) != 0) {
+               regs->nip = fixup;
+               return;
+       }
+
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+       if (debugger_exception_handler && (*debugger_exception_handler)(regs))
+               return;
+#endif
+
+       printf("Machine check in kernel mode.\n");
+       printf("Caused by (from msr): ");
+       printf("regs %p ",regs);
+       switch( regs->msr & 0x0000F000)
+       {
+       case (1<<12) :
+               printf("Machine check signal - probably due to mm fault\n"
+                       "with mmu off\n");
+               break;
+       case (1<<13) :
+               printf("Transfer error ack signal\n");
+               break;
+       case (1<<14) :
+               printf("Data parity signal\n");
+               break;
+       case (1<<15) :
+               printf("Address parity signal\n");
+               break;
+       default:
+               printf("Unknown values in msr\n");
+       }
+       show_regs(regs);
+       print_backtrace((unsigned long *)regs->gpr[1]);
+       panic("machine check");
+}
+
+void
+AlignmentException(struct pt_regs *regs)
+{
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+       if (debugger_exception_handler && (*debugger_exception_handler)(regs))
+               return;
+#endif
+       show_regs(regs);
+       print_backtrace((unsigned long *)regs->gpr[1]);
+       panic("Alignment Exception");
+}
+
+void
+ProgramCheckException(struct pt_regs *regs)
+{
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+       if (debugger_exception_handler && (*debugger_exception_handler)(regs))
+               return;
+#endif
+       show_regs(regs);
+       print_backtrace((unsigned long *)regs->gpr[1]);
+       panic("Program Check Exception");
+}
+
+void
+SoftEmuException(struct pt_regs *regs)
+{
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+       if (debugger_exception_handler && (*debugger_exception_handler)(regs))
+               return;
+#endif
+       show_regs(regs);
+       print_backtrace((unsigned long *)regs->gpr[1]);
+       panic("Software Emulation Exception");
+}
+
+
+void
+UnknownException(struct pt_regs *regs)
+{
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+       if (debugger_exception_handler && (*debugger_exception_handler)(regs))
+               return;
+#endif
+       printf("Bad trap at PC: %lx, SR: %lx, vector=%lx\n",
+              regs->nip, regs->msr, regs->trap);
+       _exception(0, regs);
+}
+
+/* Probe an address by reading.  If not present, return -1, otherwise
+ * return 0.
+ */
+int
+addr_probe(uint *addr)
+{
+#if 0
+       int     retval;
+
+       __asm__ __volatile__(                   \
+               "1:     lwz %0,0(%1)\n"         \
+               "       eieio\n"                \
+               "       li %0,0\n"              \
+               "2:\n"                          \
+               ".section .fixup,\"ax\"\n"      \
+               "3:     li %0,-1\n"             \
+               "       b 2b\n"                 \
+               ".section __ex_table,\"a\"\n"   \
+               "       .align 2\n"             \
+               "       .long 1b,3b\n"          \
+               ".text"                         \
+               : "=r" (retval) : "r"(addr));
+
+       return (retval);
+#endif
+       return 0;
+}
diff --git a/include/config_BAB750.h b/include/config_BAB750.h
new file mode 100644 (file)
index 0000000..0699d28
--- /dev/null
@@ -0,0 +1,378 @@
+/*
+ * (C) Copyright 2001
+ * Josh Huber <huber@mclx.com>, Mission Critical Linux, Inc.
+ *
+ * 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
+
+#include <asm/processor.h>
+
+/*#define DEBUG 1*/
+/*
+ * High Level Configuration Options
+ * (easy to change)
+ */
+
+/* these hardware addresses are pretty bogus, please change them to
+   suit your needs */
+
+/* first ethernet */
+#define CONFIG_ETHADDR          00:00:5B:00:6E:8A
+
+#define CONFIG_IPADDR  172.22.2.112
+#define CONFIG_SERVERIP        172.22.2.111
+
+#define CONFIG_ENV_OVERWRITE
+
+#if 0
+
+#define CFG_ENV_IS_IN_FLASH    1               /* use Flash for environment vars       */
+#define CFG_ENV_OFFSET         0x70000         /* Last sector of AMD29F040 flash */
+#define CFG_ENV_SECT_SIZE      0x10000         /* Total Size of Environment Sector (64kB) */
+
+#else
+
+#define CFG_ENV_IS_IN_NVRAM    1               /* use NVRAM for environment vars       */
+#define CFG_NVRAM_SIZE         (8*1024-16)     /* NVRAM size (8kB), we must protect the clock data (16 bytes) */
+#define CFG_ENV_SIZE           0x400           /* Size of Environment vars     (1kB)*/
+/*
+ * We store the environment in the upper part of the NVRAM. Thus,
+ * user applications can use the remaining space for other purposes.
+ */
+#define CFG_ENV_ADDR           (CFG_NVRAM_SIZE-CFG_ENV_SIZE)
+#define CFG_NVRAM_ACCESS_ROUTINE 1             /* This board needs a special routine to access the NVRAM */
+
+#endif
+
+#define CONFIG_75x             1       /* This is a MPC75x             */
+#define CONFIG_BAB750          1       /* ...on an BAB750 board        */
+
+#define CONFIG_BAUDRATE                115200  /* console baudrate = 115kbps   */
+
+#undef CONFIG_WATCHDOG
+
+/* to change the default ethernet port, use this define (options: 0, 1, 2) */
+#define CONFIG_ETHER_PORT      0
+
+#if 1
+#define CONFIG_BOOTDELAY       -1      /* autoboot disabled            */
+#else
+#define CONFIG_BOOTDELAY       5       /* autoboot after 5 seconds     */
+#endif
+#define CONFIG_ZERO_BOOTDELAY_CHECK
+
+#undef CONFIG_BOOTARGS
+
+#define CONFIG_BOOTCOMMAND                                                  \
+       "bootp 1000000; "                                                    \
+       "setenv bootargs root=/dev/nfs rw nfsroot=$(serverip):$(rootpath) "  \
+       "ip=$(ipaddr):$(serverip):$(gatewayip):" \
+       "$(netmask):$(hostname):eth0:none; "\
+       "bootm" 
+
+#define CONFIG_LOADS_ECHO      0       /* echo off for serial download */
+#define        CFG_LOADS_BAUD_CHANGE           /* allow baudrate changes       */
+
+#define CONFIG_BOOTP_MASK      (CONFIG_BOOTP_DEFAULT | \
+                                CONFIG_BOOTP_BOOTFILESIZE)
+
+#define CONFIG_COMMANDS  (CONFIG_CMD_DFL | CFG_CMD_PCI | CFG_CMD_SCSI | CFG_CMD_IDE | CFG_CMD_DATE | CFG_CMD_FDC)
+
+/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
+#include <cmd_confdefs.h>
+
+/*
+ * Miscellaneous configurable options
+ */
+#define        CFG_LONGHELP                    /* undef to save memory         */
+#define        CFG_PROMPT      "=> "           /* Monitor Command Prompt       */
+
+/*
+ * choose between COM1 and COM2 as serial console
+ */
+#define CONFIG_CONS_INDEX      1
+
+#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      0x00000000      /* memtest works on     */
+#define CFG_MEMTEST_END                0x04000000      /* 0 ... 64 MB in DRAM  */
+
+#define CFG_LOAD_ADDR          0x100000        /* default load address */
+
+#define CFG_HZ         1000            /* decrementer freq: 1 ms ticks */
+
+#define CFG_BAUDRATE_TABLE    { 9600, 19200, 38400, 57600, 115200, 230400 }
+
+/*
+ * Choose the address mapping scheme for the MPC106 mem controller.
+ * Default is mapping B (CHRP), set this define to choose mapping A (PReP).
+ */
+#define CFG_ADDRESS_MAP_A 1
+
+/*
+ * Low Level Configuration Settings
+ * (address mappings, register initial values, etc.)
+ * You should know what you are doing if you make changes here.
+ */
+
+/*
+ * Definitions for initial stack pointer and data area
+ */
+#define CFG_INIT_RAM_ADDR      0x00fd0000     /* above the memtest region */
+#define CFG_INIT_RAM_END       0x4000
+#define CFG_INIT_DATA_SIZE     64  /* size in bytes reserved for init data */
+#define CFG_INIT_DATA_OFFSET   (CFG_INIT_RAM_END - CFG_INIT_DATA_SIZE)
+#define CFG_INIT_SP_OFFSET     CFG_INIT_DATA_OFFSET
+
+/*
+ * 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
+
+/*
+ * The mapped position of the flashes is independent from
+ * the chosen address map for the MPC106.
+ */
+#define CFG_FLASH_BASE         0xFFC00000
+#define FLASH_BASE0_PRELIM     0xFFC00000
+#define FLASH_BASE1_PRELIM     0xFF800000
+
+#define CFG_MONITOR_BASE       TEXT_BASE
+
+#ifdef IN_RAM
+  #define CFG_MONITOR_LEN      (4 <<20)        /* if we're running in ram, give us plenty of space for debug info*/
+  #undef CFG_MEMTEST
+#else
+  #define CFG_MONITOR_LEN      (256 << 10)     /* Reserve 256 kB for Monitor */
+  #undef CFG_MEMTEST
+#endif
+
+#define        CFG_MALLOC_LEN          (128 << 10)  /* Reserve 128 kB for malloc() */
+
+#define CFG_CPU_CLK            266000000
+#define CFG_BUS_CLK            6600000
+
+/*
+ * Do NOT change the following table!!! Important mapping information!!
+ */
+#ifdef CFG_ADDRESS_MAP_A
+#define CFG_ISA_MEM         0xC0000000
+#define CFG_ISA_IO_BASE_ADDRESS        0x80000000
+#define CFG_ISA_IO          CFG_ISA_IO_BASE_ADDRESS
+#define CFG_PCI_IO_BASE_ADDRESS        0x81000000
+#define CFG_PCI_IO                     CFG_PCI_IO_BASE_ADDRESS
+#else
+#define CFG_ISA_MEM         0xFD000000
+#define CFG_ISA_IO_BASE_ADDRESS        0xFE000000
+#define CFG_ISA_IO          CFG_ISA_IO_BASE_ADDRESS
+#define CFG_PCI_IO_BASE_ADDRESS        0xFE800000
+#define CFG_PCI_IO                     CFG_PCI_IO_BASE_ADDRESS
+#endif
+
+/*
+ * PCI stuff
+ */
+#define CONFIG_PCI             /* include pci support          */
+#define CONFIG_PCI_HOST PCI_HOST_AUTO
+#define CONFIG_PCI_PNP /* pci plug-and-play                    */
+
+/*
+ * Do NOT change the following table!!! Important mapping information!!
+ */
+#ifdef CFG_ADDRESS_MAP_A
+#define CFG_PCI_DRAM_OFFSET            0x80000000
+#define CFG_60X_PCI_MEM_OFFSET 0xC0000000
+#define CFG_60X_PCI_IO_OFFSET  0x80000000
+#define CFG_MIN_PCI_MEMADDR1   0x01010000
+#define CFG_MIN_PCI_MEMADDR2   0x01010000
+#define CFG_PCI_PCI_IOADDR             0x01000000
+#else
+#define CFG_PCI_DRAM_OFFSET            0x00000000
+#define CFG_60X_PCI_MEM_OFFSET 0x00000000
+#define CFG_60X_PCI_IO_OFFSET  0xFE000000
+#define CFG_MIN_PCI_MEMADDR1   0xF9000000
+#define CFG_MIN_PCI_MEMADDR2   0xFA000000
+#define CFG_PCI_PCI_IOADDR             0x00800000
+#endif
+
+#define CFG_MAX_PCI_DEVICES     32
+#define CFG_MAX_PCI_FUNCTIONS  8
+
+/*
+ * IDE/ATA stuff
+ */
+#define CFG_IDE_MAXBUS         1   /* max. 2 IDE busses        */
+#define CFG_IDE_MAXDEVICE      (CFG_IDE_MAXBUS*2) /* max. 2 drives per IDE bus */
+
+#define CFG_ATA_BASE_ADDR      CFG_60X_PCI_IO_OFFSET /* base address */
+#define CFG_ATA_IDE0_OFFSET 0x1F0      /* default ide0 offste */
+#define CFG_ATA_IDE1_OFFSET 0x170      /* default ide1 offset */
+#define CFG_ATA_DATA_OFFSET 0                          /* data reg offset      */
+#define CFG_ATA_REG_OFFSET  0                          /* reg offset */
+#define CFG_ATA_ALT_OFFSET     0x200           /* alternate register offset */
+
+#undef  CONFIG_IDE_PCMCIA      /* no pcmcia interface required */
+#undef  CONFIG_IDE_LED         /* no led for ide supported     */
+
+/*
+ * ATAPI support (experimental)
+ */
+#define CONFIG_ATAPI                   /* enable ATAPI Support */
+
+
+/*
+ * SCSI support (experimental) only SYM53C8xx supported
+ */
+#define CONFIG_SCSI_SYM53C8XX
+#define CONFIG_SCSI_DEV_ID             0x000F          /* 53c875 */
+#define CFG_SCSI_MAX_LUN               8 /* number of supported LUNs */
+#define CFG_SCSI_MAX_SCSI_ID   15 /* maximum SCSI ID (0..6) */
+#define CFG_SCSI_MAX_DEVICE            CFG_SCSI_MAX_SCSI_ID * CFG_SCSI_MAX_LUN /* maximum Target devices */
+#define CFG_SCSI_SPIN_UP_TIME  2
+#define CFG_SCSI_SCAN_BUS_REVERSE 0
+#define CONFIG_DOS_PARTITION
+#define CONFIG_MAC_PARTITION
+#define CONFIG_ISO_PARTITION
+
+#define CFG_WINBOND_83C553      1           /*has a winbond bridge  */
+#define CFG_USE_WINBOND_IDE     0           /*use winbond 83c553 internal ide controller */
+#define CFG_WINBOND_ISA_CFG_ADDR    0x80005800  /*pci-isa bridge config addr */
+#define CFG_WINBOND_IDE_CFG_ADDR    0x80005900  /*ide config addr */
+#define CFG_NS87308_BADDR_10    1
+
+#define CFG_NS_PC87308UL        1           /* Nat Semi super-io controller on ISA bus */
+
+#define CONFIG_RTC_MK48T59
+
+/*
+ * Initial BAT mappings
+ */
+
+/* do we need the MMU? probably not, but if we do, we must use the BATs */
+#undef  CFG_MMU
+
+#ifdef CFG_MMU
+/* SDRAM */
+#define CFG_IBAT0L (CFG_SDRAM_BASE | BATL_RW)
+#define CFG_IBAT0U (CFG_SDRAM_BASE | BATU_BL_256M | BATU_VS | BATU_VP)
+#define CFG_DBAT0L CFG_IBAT1L
+#define CFG_DBAT0U CFG_IBAT1U
+
+/* address range for flashes */
+#define CFG_IBAT1L (CFG_FLASH_BASE | BATL_RW | BATL_CACHEINHIBIT)
+#define CFG_IBAT1U (CFG_FLASH_BASE | BATU_BL_16M | BATU_VS | BATU_VP)
+#define CFG_DBAT1L CFG_IBAT1L
+#define CFG_DBAT1U CFG_IBAT1U
+
+/* ISA IO space */
+#define CFG_IBAT2L (CFG_ISA_IO | BATL_RW | BATL_CACHEINHIBIT)
+#define CFG_IBAT2U (CFG_ISA_IO | BATU_BL_16M | BATU_VS | BATU_VP)
+#define CFG_DBAT2L CFG_IBAT2L
+#define CFG_DBAT2U CFG_IBAT2U
+
+/* ISA memory space */
+#define CFG_IBAT3L (CFG_ISA_MEM | BATL_RW | BATL_CACHEINHIBIT)
+#define CFG_IBAT3U (CFG_ISA_MEM | BATU_BL_16M | BATU_VS | BATU_VP)
+#define CFG_DBAT3L CFG_IBAT3L
+#define CFG_DBAT3U CFG_IBAT3U
+
+#else
+
+#define CFG_IBAT0L 0
+#define CFG_IBAT0U 0
+#define CFG_DBAT0L CFG_IBAT1L
+#define CFG_DBAT0U CFG_IBAT1U
+
+#define CFG_IBAT1L 0
+#define CFG_IBAT1U 0
+#define CFG_DBAT1L CFG_IBAT1L
+#define CFG_DBAT1U CFG_IBAT1U
+
+/* ISA IO space */
+#define CFG_IBAT2L 0
+#define CFG_IBAT2U 0
+#define CFG_DBAT2L CFG_IBAT2L
+#define CFG_DBAT2U CFG_IBAT2U
+
+/* ISA memory space */
+#define CFG_IBAT3L 0
+#define CFG_IBAT3U 0
+#define CFG_DBAT3L CFG_IBAT3L
+#define CFG_DBAT3U CFG_IBAT3U
+
+#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    2       /* max number of memory banks   */
+#define CFG_MAX_FLASH_SECT     67      /* 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) */
+
+/*
+ * Cache Configuration
+ */
+#define CFG_CACHELINE_SIZE     32      /* For all MPC74xx CPUs          */
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#define CFG_CACHELINE_SHIFT    5       /* log base 2 of the above value */
+#endif
+
+/*
+ * L2CR setup -- make sure this is right for your board!
+ * look in include/mpc74xx.h for the defines used here
+ */
+/*#define CFG_L2*/
+#define L2_INIT   (L2CR_L2SIZ_HM | L2CR_L2CLK_3 | L2CR_L2RAM_BURST | \
+                   L2CR_L2OH_5 | L2CR_L2CTL | L2CR_L2WT)
+#define L2_ENABLE (L2_INIT | L2CR_L2E)
+
+/*
+ * Internal Definitions
+ *
+ * Boot Flags
+ */
+#define        BOOTFLAG_COLD   0x01            /* Normal Power-On: Boot from FLASH     */
+#define BOOTFLAG_WARM  0x02            /* Software reboot                      */
+
+#endif /* __CONFIG_H */
diff --git a/include/mk48t59.h b/include/mk48t59.h
new file mode 100644 (file)
index 0000000..e3483d2
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Andreas Heppel <aheppel@sysgo.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
+ */
+
+/*
+ * Date & Time support for the MK48T59 RTC
+ */
+
+
+#if defined(CONFIG_RTC_MK48T59) && (CONFIG_COMMANDS & CFG_CMD_DATE)
+
+#define RTC_PORT_ADDR0         CFG_ISA_IO +  0x70
+#define RTC_PORT_ADDR1         RTC_PORT_ADDR0 +  0x1
+#define RTC_PORT_DATA          CFG_ISA_IO +  0x76
+
+/* RTC Offsets */
+#define RTC_SECONDS             0x1FF9
+#define RTC_MINUTES             0x1FFA
+#define RTC_HOURS               0x1FFB
+#define RTC_DAY_OF_WEEK         0x1FFC
+#define RTC_DAY_OF_MONTH        0x1FFD
+#define RTC_MONTH               0x1FFE
+#define RTC_YEAR                0x1FFF
+#define RTC_CONTROLA            0x1FF8
+#define RTC_CA_WRITE            0x80
+#define RTC_CA_READ             0x40
+#define RTC_CA_CALIB_SIGN       0x20
+#define RTC_CA_CALIB_MASK       0x1f
+#define RTC_CONTROLB            0x1FF9
+#define RTC_CB_STOP             0x80
+#define RTC_WATCHDOG                   0x1FF7
+#define RTC_WDS                                        0x80
+#define RTC_WD_RB_16TH                 0x0
+#define RTC_WD_RB_4TH                  0x1
+#define RTC_WD_RB_1                            0x2
+#define RTC_WD_RB_4                            0x3
+
+void rtc_set_watchdog(short multi, short res);
+void *nvram_read(void *dest, const short src, size_t count);
+void nvram_write(short dest, const void *src, size_t count);
+
+#endif
diff --git a/include/mpc106.h b/include/mpc106.h
new file mode 100644 (file)
index 0000000..9388b34
--- /dev/null
@@ -0,0 +1,292 @@
+/*
+ * (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Andreas Heppel <aheppel@sysgo.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
+ */
+
+#ifndef _MPC106_PCI_H
+#define _MPC106_PCI_H
+
+#ifndef DEFS_ONLY
+typedef struct pciHeaderDevice {
+    short      vendorId;       /* vendor ID */
+    short      deviceId;       /* device ID */
+    short      command;        /* command register */
+    short      status;         /* status register */
+    char       revisionId;     /* revision ID */
+    char       classCode;      /* class code */
+    char       subClass;       /* sub class code */
+    char       progIf;         /* programming interface */
+    char       cacheLine;      /* cache line */
+    char       latency;        /* latency time */
+    char       headerType;     /* header type */
+    char       bist;           /* BIST */
+    int                base0;          /* base address 0 */
+    int                base1;          /* base address 1 */
+    int                base2;          /* base address 2 */
+    int                base3;          /* base address 3 */
+    int                base4;          /* base address 4 */
+    int                base5;          /* base address 5 */
+    int                cis;            /* cardBus CIS pointer */
+    short      subVendorId;    /* sub system vendor ID */
+    short      subSystemId;    /* sub system ID */
+    int                romBase;        /* expansion ROM base address */
+    int                reserved0;      /* reserved */
+    int                reserved1;      /* reserved */
+    char       intLine;        /* interrupt line */
+    char       intPin;         /* interrupt pin */
+    char       minGrant;       /* min Grant */
+    char       maxLatency;     /* max Latency */
+} PCI_HEADER_DEVICE;
+
+typedef struct pciHeaderBridge {
+    short      vendorId;       /* vendor ID */
+    short      deviceId;       /* device ID */
+    short      command;        /* command register */
+    short      status;         /* status register */
+    char       revisionId;     /* revision ID */
+    char       classCode;      /* class code */
+    char       subClass;       /* sub class code */
+    char       progIf;         /* programming interface */
+    char       cacheLine;      /* cache line */
+    char       latency;        /* latency time */
+    char       headerType;     /* header type */
+    char       bist;           /* BIST */
+    int                base0;          /* base address 0 */
+    int                base1;          /* base address 1 */
+    char       priBus;         /* primary bus number */
+    char       secBus;         /* secondary bus number */
+    char       subBus;         /* subordinate bus number */
+    char       secLatency;     /* secondary latency timer */
+    char       ioBase;         /* IO base */
+    char       ioLimit;        /* IO limit */
+    short      secStatus;      /* secondary status */
+    short      memBase;        /* memory base */
+    short      memLimit;       /* memory limit */
+    short      preBase;        /* prefetchable memory base */
+    short      preLimit;       /* prefetchable memory limit */
+    int                preBaseUpper;   /* prefetchable memory base upper 32 bits */
+    int                preLimitUpper;  /* prefetchable memory base upper 32 bits */
+    short      ioBaseUpper;    /* IO base upper 16 bits */
+    short      ioLimitUpper;   /* IO limit upper 16 bits */
+    int                reserved;       /* reserved */
+    int                romBase;        /* expansion ROM base address */
+    char       intLine;        /* interrupt line */
+    char       intPin;         /* interrupt pin */
+    short      control;        /* bridge control */
+} PCI_HEADER_BRIDGE;
+
+#endif /*  DEFS_ONLY */
+
+
+/*
+ * Defines for the MPC106 PCI Config address and data registers followed by
+ * defines for the standard PCI device configuration header.
+ */
+#define PCIDEVID_MPC106        0x0
+
+/*
+ * MPC106 Registers
+ */
+#define        MPC106_REG                      0x80000000
+
+#ifdef CFG_ADDRESS_MAP_A
+#define MPC106_REG_ADDR        0x80000cf8
+#define        MPC106_REG_DATA         0x80000cfc
+#else
+#define MPC106_REG_ADDR        0xfec00cf8
+#define        MPC106_REG_DATA         0xfee00cfc
+#endif
+
+#define CMD_SERR               0x0100
+#define PCI_CMD_MASTER 0x0004
+#define PCI_CMD_MEMEN  0x0002
+#define PCI_CMD_IOEN   0x0001
+
+#define PCI_STAT_NO_RSV_BITS   0xffff
+
+#define PCI_BUSNUM       0x40
+#define PCI_SUBBUSNUM    0x41
+#define PCI_DISCOUNT     0x42
+
+#define PCI_PICR1                      0xA8
+#define PICR1_CF_CBA(value)             ((value & 0xff) << 24)
+#define PICR1_CF_BREAD_WS(value) ((value & 0x3) << 22)
+#define PICR1_PROC_TYPE_603    0x40000
+#define PICR1_PROC_TYPE_604    0x60000
+#define PICR1_MCP_EN           0x800
+#define PICR1_CF_DPARK         0x200
+#define PICR1_CF_LOOP_SNOOP    0x10
+#define PICR1_CF_APARK         0x8
+#define PICR1_ADDRESS_MAP      0x10000
+#define PICR1_XIO_MODE         0x80000
+
+#define PCI_PICR2                      0xAC
+#define PICR2_CF_SNOOP_WS(value)        ((value & 0x3) << 18)
+#define PICR2_CF_FLUSH_L2      0x10000000
+#define PICR2_CF_L2_HIT_DELAY(value) ((value & 0x3) << 9)
+#define PICR2_CF_APHASE_WS(value)       ((value & 0x3) << 2)
+#define PICR2_L2_EN                    0x40000000
+#define PICR2_L2_UPDATE_EN     0x80000000
+
+/*
+ * PCI-PCI bridge header
+ */
+#define PCIPCI_PRIMARYBUS       0x18
+#define PCIPCI_SECONDARYBUS     0x19
+#define PCIPCI_SUBORDINATEBUS   0x1A
+#define PCIPCI_SECONDARYLATENCY 0x1B
+#define PCIPCI_IOBASE           0x1C
+#define PCIPCI_IOLIMIT          0x1D
+#define PCIPCI_SECONDARYSTATUS  0x1E
+#define PCIPCI_MEMBASE          0x20
+#define PCIPCI_MEMLIMIT         0x22
+#define PCIPCI_PREFETCHMEMBASE  0x24
+#define PCIPCI_PREFETCHMEMLIMIT 0x26
+#define PCIPCI_IOBASEUPPER16    0x30
+#define PCIPCI_IOLIMITUPPER16   0x32
+
+/*
+ * Standard device configuration register offsets
+ * Note that only modulo-4 addresses are written to the address register
+ */
+#define        PCI_CFG_VENDOR_ID       0x00
+#define        PCI_CFG_DEVICE_ID       0x02
+#define        PCI_CFG_COMMAND         0x04
+#define        PCI_CFG_STATUS          0x06
+#define        PCI_CFG_REVISION        0x08
+#define        PCI_CFG_PROGRAMMING_IF  0x09
+#define        PCI_CFG_SUBCLASS        0x0a
+#define        PCI_CFG_CLASS           0x0b
+#define        PCI_CFG_CACHE_LINE_SIZE 0x0c
+#define        PCI_CFG_LATENCY_TIMER   0x0d
+#define        PCI_CFG_HEADER_TYPE     0x0e
+#define        PCI_CFG_BIST            0x0f
+#define        PCI_CFG_BASE_ADDRESS_0  0x10
+#define        PCI_CFG_BASE_ADDRESS_1  0x14
+#define        PCI_CFG_BASE_ADDRESS_2  0x18
+#define        PCI_CFG_BASE_ADDRESS_3  0x1c
+#define        PCI_CFG_BASE_ADDRESS_4  0x20
+#define        PCI_CFG_BASE_ADDRESS_5  0x24
+#define        PCI_CFG_CIS             0x28
+#define        PCI_CFG_SUB_VENDER_ID   0x2c
+#define        PCI_CFG_SUB_SYSTEM_ID   0x2e
+#define        PCI_CFG_EXPANSION_ROM   0x30
+#define        PCI_CFG_RESERVED_0      0x34
+#define        PCI_CFG_RESERVED_1      0x38
+#define        PCI_CFG_DEV_INT_LINE    0x3c
+#define        PCI_CFG_DEV_INT_PIN     0x3d
+#define        PCI_CFG_MIN_GRANT       0x3e
+#define        PCI_CFG_MAX_LATENCY     0x3f
+#define PCI_CFG_SPECIAL_USE     0x41
+#define PCI_CFG_MODE            0x43
+
+
+/*
+ * PCI-to-PCI bridge configuration register offsets
+ * Note that only modulo-4 addresses are written to the address register
+ */
+#define        PCI_CFG_PRIMARY_BUS     0x18
+#define        PCI_CFG_SECONDARY_BUS   0x19
+#define        PCI_CFG_SUBORDINATE_BUS 0x1a
+#define        PCI_CFG_SEC_LATENCY     0x1b
+#define        PCI_CFG_IO_BASE         0x1c
+#define        PCI_CFG_IO_LIMIT        0x1d
+#define        PCI_CFG_SEC_STATUS      0x1e
+#define        PCI_CFG_MEM_BASE        0x20
+#define        PCI_CFG_MEM_LIMIT       0x22
+#define        PCI_CFG_PRE_MEM_BASE    0x24
+#define        PCI_CFG_PRE_MEM_LIMIT   0x26
+#define        PCI_CFG_PRE_MEM_BASE_U  0x28
+#define        PCI_CFG_PRE_MEM_LIMIT_U 0x2c
+#define        PCI_CFG_IO_BASE_U       0x30
+#define        PCI_CFG_IO_LIMIT_U      0x32
+#define        PCI_CFG_ROM_BASE        0x38
+#define        PCI_CFG_BRG_INT_LINE    0x3c
+#define        PCI_CFG_BRG_INT_PIN     0x3d
+#define        PCI_CFG_BRIDGE_CONTROL  0x3e
+
+
+/*
+ * Memory controller
+ */
+#define MPC106_MCCR1           0xF0
+#define MCCR1_TYPE_EDO         0x00020000
+#define MCCR1_BK0_9BITS                0x0
+#define MCCR1_BK0_10BITS       0x1
+#define MCCR1_BK0_11BITS       0x2
+#define MCCR1_BK0_12BITS       0x3
+#define MCCR1_BK1_9BITS                0x0
+#define MCCR1_BK1_10BITS       0x4
+#define MCCR1_BK1_11BITS       0x8
+#define MCCR1_BK1_12BITS       0xC
+#define MCCR1_BK2_9BITS                0x00
+#define MCCR1_BK2_10BITS       0x10
+#define MCCR1_BK2_11BITS       0x20
+#define MCCR1_BK2_12BITS       0x30
+#define MCCR1_BK3_9BITS                0x00
+#define MCCR1_BK3_10BITS       0x40
+#define MCCR1_BK3_11BITS       0x80
+#define MCCR1_BK3_12BITS       0xC0
+#define MCCR1_MEMGO                    0x00080000
+
+#define MPC106_MCCR2           0xF4
+#define MPC106_MCCR3           0xF8
+#define MPC106_MCCR4           0xFC
+
+#define MPC106_MSAR1           0x80
+#define MPC106_EMSAR1          0x88
+#define MPC106_EMSAR2          0x8C
+#define MPC106_MEAR1           0x90
+#define MPC106_EMEAR1          0x98
+#define MPC106_EMEAR2          0x9C
+
+#define MPC106_MBER                    0xA0
+#define MBER_BANK0                     0x1
+#define MBER_BANK1                     0x2
+#define MBER_BANK2                     0x4
+#define MBER_BANK3                     0x8
+
+
+#ifndef DEFS_ONLY
+
+unsigned int    PCI_Read_CFG_Reg(int BusDevFunc, int Reg, int Width);
+int                            PCI_Write_CFG_Reg(int BusDevFunc, int Reg, unsigned int Value, int Width);
+int             PCI_Scan(int BusNum);
+void            PCI_Config_Device(int BusDevFunc, int NumBaseAddr);
+void            PCI_Config_VGA_Device(int BusDevFunc, int NumBaseAddr);
+void            PCI_Config_Bridge(int BusDevFunc);
+int             PCI_Find_Device(unsigned short VendorID, unsigned short DeviceID);
+void            PCI_Header_Show(int BusDevFunc);
+void            PCI_Dheader_Print(PCI_HEADER_DEVICE * pD);
+void            PCI_Bheader_Print(PCI_HEADER_BRIDGE * pB);
+
+/*
+ * memory mapping functions
+ */
+unsigned long  phys_to_bus(void*);
+void *bus_to_phys(unsigned long);
+
+#endif /*  DEFS_ONLY */
+
+
+#endif
+
diff --git a/include/mpc75x.h b/include/mpc75x.h
new file mode 100644 (file)
index 0000000..ddac6e4
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Andreas Heppel <aheppel@sysgo.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
+ */
+
+/*
+ * mpc75x.h
+ *
+ * MPC75x/MPC74xx specific definitions
+ */
+
+#ifndef __MPC75X_H__
+#define __MPC75X_H__
+
+/*----------------------------------------------------------------
+ * Exception offsets (PowerPC standard)
+ */
+#define EXC_OFF_SYS_RESET        0x0100      /* default system reset offset */
+
+/*----------------------------------------------------------------
+ * l2cr values
+ */
+#define l2cr 1017
+
+#define L2CR_L2E         0x80000000 /* bit 0 - enable */
+#define L2CR_L2PE        0x40000000 /* bit 1 - data parity */
+#define L2CR_L2SIZ_2M    0x00000000 /* bits 2-3 - 2MB, MPC7400 only! */
+#define L2CR_L2SIZ_1M    0x30000000 /* ... 1MB */
+#define L2CR_L2SIZ_HM    0x20000000 /* ... 512K */
+#define L2CR_L2SIZ_QM    0x10000000 /* ... 256k */
+#define L2CR_L2CLK_1     0x02000000 /* bits 4-6 clock ratio div 1 */
+#define L2CR_L2CLK_1_5   0x04000000 /* bits 4-6 clock ratio div 1.5 */
+#define L2CR_L2CLK_2     0x08000000 /* bits 4-6 clock ratio div 2 */
+#define L2CR_L2CLK_2_5   0x0a000000 /* bits 4-6 clock ratio div 2.5 */
+#define L2CR_L2CLK_3     0x0c000000 /* bits 4-6 clock ratio div 3 */
+#define L2CR_L2CLK_3_5   0x06000000 /* bits 4-6 clock ratio div 3.5 */
+#define L2CR_L2CLK_4     0x0e000000 /* bits 4-6 clock ratio div 4 */
+#define L2CR_L2RAM_BURST 0x01000000 /* bits 7-8 - burst SRAM */
+#define L2CR_DO          0x00400000 /* bit 9 - enable caching of instr. in L2 */
+#define L2CR_L2I         0x00200000 /* bit 10 - global invalidate bit */
+#define L2CR_L2CTL       0x00100000 /* bit 11 - l2 ram control */
+#define L2CR_L2WT        0x00080000 /* bit 12 - l2 write-through */
+#define L2CR_TS          0x00040000 /* bit 13 - test support on */
+#define L2CR_TS_OFF      -L2CR_TS   /* bit 13 - test support off */
+#define L2CR_L2OH_5      0x00000000 /* bits 14-15 - output hold time = short */
+#define L2CR_L2OH_1      0x00010000 /* bits 14-15 - output hold time = medium */
+#define L2CR_L2OH_INV    0x00020000 /* bits 14-15 - output hold time = long */
+#define L2CR_L2IP        0x00000001 /* global invalidate in progress */
+
+/*----------------------------------------------------------------
+ * BAT settings.  Look in config_<BOARD>.h for the actual setup
+ */
+
+#define BATU_BL_128K             0x00000000
+#define BATU_BL_256K             0x00000004
+#define BATU_BL_512K             0x0000000c
+#define BATU_BL_1M               0x0000001c
+#define BATU_BL_2M               0x0000003c
+#define BATU_BL_4M               0x0000007c
+#define BATU_BL_8M               0x000000fc
+#define BATU_BL_16M              0x000001fc
+#define BATU_BL_32M              0x000003fc
+#define BATU_BL_64M              0x000007fc
+#define BATU_BL_128M             0x00000ffc
+#define BATU_BL_256M             0x00001ffc
+
+#define BATU_VS                  0x00000002
+#define BATU_VP                  0x00000001
+#define BATU_INVALID             0x00000000
+
+#define BATL_WRITETHROUGH        0x00000080
+#define BATL_CACHEINHIBIT        0x00000040
+#define BATL_COHERENT            0x00000020
+#define BATL_GUARDED             0x00000010
+
+#define BATL_NO_ACCESS           0x00000000
+#define BATL_RO                  0x00000001
+#define BATL_RW                  0x00000002
+
+#endif  /* __MPC75X_H__ */
index 936ae452bdee90a85b5a0390ac548c293246a3f4..aff0deec5c07352df2e1d4266c605b83609f336a 100644 (file)
@@ -204,6 +204,7 @@ void inline         setenv (char *, char *);
     defined (CONFIG_DASA_SIM)  || \
     defined (CONFIG_ERIC)      || \
     defined (CONFIG_MOUSSE)    || \
+    defined (CONFIG_BAB750)    || \
     defined (CONFIG_W7O)
 /* $(CPU)/405gp_pci.c */
 void    pci_init      (bd_t *);
@@ -356,7 +357,10 @@ void       dcache_disable(void);
 void   relocate_code (ulong, bd_t *, ulong);
 ulong  get_endaddr   (void);
 void   trap_init     (ulong);
-#ifdef  CONFIG_4xx
+#if defined (CONFIG_4xx)       || \
+    defined (CONFIG_74x)       || \
+    defined (CONFIG_75x)       || \
+    defined (CONFIG_74xx)
 unsigned char   in8(unsigned int);
 void            out8(unsigned int, unsigned char);
 unsigned short  in16(unsigned int);
@@ -392,6 +396,7 @@ void        prt_8260_clks (void);
       defined(CONFIG_EVB64260) || \
       defined(CONFIG_IOP480)   || \
       defined(CONFIG_MOUSSE)   || \
+      defined(CONFIG_BAB750)   || \
       defined(CONFIG_SANDPOINT)
 ulong  get_gclk_freq (void);
 ulong  get_OPB_freq (void);
diff --git a/include/w83c553f.h b/include/w83c553f.h
new file mode 100644 (file)
index 0000000..1f8d2bd
--- /dev/null
@@ -0,0 +1,178 @@
+/*
+ * (C) Copyright 2000
+ * Rob Taylor, Flying Pig Systems. robt@flyingpig.com.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+ /* winbond access routines and defines*/
+
+/* from the winbond data sheet -
+ The W83C553F SIO controller with PCI arbiter is a multi-function PCI device.
+ Function 0 is the ISA bridge, and Function 1 is the bus master IDE controller.
+*/
+
+/*ISA bridge configuration space*/
+
+#define W83C553F_VID           0x10AD
+#define W83C553F_DID           0x0565
+
+#define WINBOND_PCICONTR       0x40  /*pci control reg*/
+#define WINBOND_SGBAR          0x41  /*scatter/gather base address reg*/
+#define WINBOND_LBCR           0x42  /*Line Buffer Control reg*/
+#define WINBOND_IDEIRCR                0x43  /*IDE Interrupt Routing Control  Reg*/
+#define WINBOND_PCIIRCR                0x44  /*PCI Interrupt Routing Control Reg*/
+#define WINBOND_BTBAR          0x46  /*BIOS Timer Base Address Register*/
+#define WINBOND_IPADCR         0x48  /*ISA to PCI Address Decoder Control Register*/
+#define WINBOND_IRADCR         0x49  /*ISA ROM Address Decoder Control Register*/
+#define WINBOND_IPMHSAR                0x4a  /*ISA to PCI Memory Hole STart Address Register*/
+#define WINBOND_IPMHSR         0x4b  /*ISA to PCI Memory Hols Size Register*/
+#define WINBOND_CDR                    0x4c  /*Clock Divisor Register*/
+#define WINBOND_CSCR           0x4d  /*Chip Select Control Register*/
+#define WINBOND_ATSCR          0x4e  /*AT System Control register*/
+#define WINBOND_ATBCR          0x4f  /*AT Bus ControL Register*/
+#define WINBOND_IRQBEE0R       0x60  /*IRQ Break Event Enable 0 Register*/
+#define WINBOND_IRQBEE1R       0x61  /*IRQ Break Event Enable 1 Register*/
+#define WINBOND_ABEER          0x62  /*Additional Break Event Enable Register*/
+#define WINBOND_DMABEER                0x63  /*DMA Break Event Enable Register*/
+
+#define WINDOND_IDECSR         0x40  /*IDE Control/Status Register, Function 1*/
+
+#define IPADCR_MBE512          0x1
+#define IPADCR_MBE640          0x2
+#define IPADCR_IPATOM4         0x10
+#define IPADCR_IPATOM5         0x20
+#define IPADCR_IPATOM6         0x40
+#define IPADCR_IPATOM7         0x80
+
+#define CSCR_UBIOSCSE          0x10
+#define CSCR_BIOSWP                    0x20
+
+#define IDECSR_P0EN                    0x01
+#define IDECSR_P0F16           0x02
+#define IDECSR_P1EN                    0x10
+#define IDECSR_P1F16           0x20
+#define IDECSR_LEGIRQ          0x800
+
+/*
+ * Interrupt controller
+ */
+#define W83C553F_PIC1_ICW1     CFG_ISA_IO + 0x20
+#define W83C553F_PIC1_ICW2     CFG_ISA_IO + 0x21
+#define W83C553F_PIC1_ICW3     CFG_ISA_IO + 0x21
+#define W83C553F_PIC1_ICW4     CFG_ISA_IO + 0x21
+#define W83C553F_PIC1_OCW1     CFG_ISA_IO + 0x21
+#define W83C553F_PIC1_OCW2     CFG_ISA_IO + 0x20
+#define W83C553F_PIC1_OCW3     CFG_ISA_IO + 0x20
+#define W83C553F_PIC1_ELC      CFG_ISA_IO + 0x4D0
+#define W83C553F_PIC2_ICW1     CFG_ISA_IO + 0xA0
+#define W83C553F_PIC2_ICW2     CFG_ISA_IO + 0xA1
+#define W83C553F_PIC2_ICW3     CFG_ISA_IO + 0xA1
+#define W83C553F_PIC2_ICW4     CFG_ISA_IO + 0xA1
+#define W83C553F_PIC2_OCW1     CFG_ISA_IO + 0xA1
+#define W83C553F_PIC2_OCW2     CFG_ISA_IO + 0xA0
+#define W83C553F_PIC2_OCW3     CFG_ISA_IO + 0xA0
+#define W83C553F_PIC2_ELC      CFG_ISA_IO + 0x4D1
+
+#define W83C553F_TMR1_CMOD     CFG_ISA_IO + 0x43
+/*
+ * DMA controller
+ */
+#define W83C553F_DMA1  CFG_ISA_IO + 0x000      /* channel 0 - 3 */
+#define W83C553F_DMA2  CFG_ISA_IO + 0x0C0      /* channel 4 - 7 */
+
+/* command/status register bit definitions */
+
+#define W83C553F_CS_COM_DACKAL (1<<7)  /* DACK# assert level */
+#define W83C553F_CS_COM_DREQSAL        (1<<6)  /* DREQ sense assert level */
+#define W83C553F_CS_COM_GAP    (1<<4)  /* group arbitration priority */
+#define W83C553F_CS_COM_CGE    (1<<2)  /* channel group enable */
+
+#define W83C553F_CS_STAT_CH0REQ        (1<<4)  /* channel 0 (4) DREQ status */
+#define W83C553F_CS_STAT_CH1REQ        (1<<5)  /* channel 1 (5) DREQ status */
+#define W83C553F_CS_STAT_CH2REQ        (1<<6)  /* channel 2 (6) DREQ status */
+#define W83C553F_CS_STAT_CH3REQ        (1<<7)  /* channel 3 (7) DREQ status */
+
+#define W83C553F_CS_STAT_CH0TC (1<<0)  /* channel 0 (4) TC status */
+#define W83C553F_CS_STAT_CH1TC (1<<1)  /* channel 1 (5) TC status */
+#define W83C553F_CS_STAT_CH2TC (1<<2)  /* channel 2 (6) TC status */
+#define W83C553F_CS_STAT_CH3TC (1<<3)  /* channel 3 (7) TC status */
+
+/* mode register bit definitions */
+
+#define W83C553F_MODE_TM_DEMAND        (0<<6)  /* transfer mode - demand */
+#define W83C553F_MODE_TM_SINGLE        (1<<6)  /* transfer mode - single */
+#define W83C553F_MODE_TM_BLOCK (2<<6)  /* transfer mode - block */
+#define W83C553F_MODE_TM_CASCADE       (3<<6)  /* transfer mode - cascade */
+#define W83C553F_MODE_ADDRDEC  (1<<5)  /* address increment/decrement select */
+#define W83C553F_MODE_AUTOINIT (1<<4)  /* autoinitialize enable */
+#define W83C553F_MODE_TT_VERIFY        (0<<2)  /* transfer type - verify */
+#define W83C553F_MODE_TT_WRITE (1<<2)  /* transfer type - write */
+#define W83C553F_MODE_TT_READ  (2<<2)  /* transfer type - read */
+#define W83C553F_MODE_TT_ILLEGAL       (3<<2)  /* transfer type - illegal */
+#define W83C553F_MODE_CH0SEL   (0<<0)  /* channel 0 (4) select */
+#define W83C553F_MODE_CH1SEL   (1<<0)  /* channel 1 (5) select */
+#define W83C553F_MODE_CH2SEL   (2<<0)  /* channel 2 (6) select */
+#define W83C553F_MODE_CH3SEL   (3<<0)  /* channel 3 (7) select */
+
+/* request register bit definitions */
+
+#define W83C553F_REQ_CHSERREQ  (1<<2)  /* channel service request */
+#define W83C553F_REQ_CH0SEL    (0<<0)  /* channel 0 (4) select */
+#define W83C553F_REQ_CH1SEL    (1<<0)  /* channel 1 (5) select */
+#define W83C553F_REQ_CH2SEL    (2<<0)  /* channel 2 (6) select */
+#define W83C553F_REQ_CH3SEL    (3<<0)  /* channel 3 (7) select */
+
+/* write single mask bit register bit definitions */
+
+#define W83C553F_WSMB_CHMASKSEL        (1<<2)  /* channel mask select */
+#define W83C553F_WSMB_CH0SEL   (0<<0)  /* channel 0 (4) select */
+#define W83C553F_WSMB_CH1SEL   (1<<0)  /* channel 1 (5) select */
+#define W83C553F_WSMB_CH2SEL   (2<<0)  /* channel 2 (6) select */
+#define W83C553F_WSMB_CH3SEL   (3<<0)  /* channel 3 (7) select */
+
+/* read/write all mask bits register bit definitions */
+
+#define W83C553F_RWAMB_CH0MASK (1<<0)  /* channel 0 (4) mask */
+#define W83C553F_RWAMB_CH1MASK (1<<1)  /* channel 1 (5) mask */
+#define W83C553F_RWAMB_CH2MASK (1<<2)  /* channel 2 (6) mask */
+#define W83C553F_RWAMB_CH3MASK (1<<3)  /* channel 3 (7) mask */
+
+/* typedefs */
+
+#define W83C553F_DMA1_CS               0x8
+#define W83C553F_DMA1_WR               0x9
+#define W83C553F_DMA1_WSMB             0xA
+#define W83C553F_DMA1_WM               0xB
+#define W83C553F_DMA1_CBP              0xC
+#define W83C553F_DMA1_MC               0xD
+#define W83C553F_DMA1_CM               0xE
+#define W83C553F_DMA1_RWAMB            0xF
+
+#define W83C553F_DMA2_CS               0x10
+#define W83C553F_DMA2_WR               0x12
+#define W83C553F_DMA2_WSMB             0x14
+#define W83C553F_DMA2_WM               0x16
+#define W83C553F_DMA2_CBP              0x18
+#define W83C553F_DMA2_MC               0x1A
+#define W83C553F_DMA2_CM               0x1C
+#define W83C553F_DMA2_RWAMB            0x1E
+
+void initialise_w83c553f(void);
index 45b25aa5662d6e83ffb82e12a446338907427e5d..5df2439ef60634e68cddc7e9560f0cb64033babc 100644 (file)
@@ -27,7 +27,7 @@ include $(TOPDIR)/config.mk
 
 LIB    = librtc.a
 
-OBJS   = date.o pcf8563.o mpc8xx.o mc146818.o ds174x.o m48t35ax.o
+OBJS   = date.o pcf8563.o mpc8xx.o mc146818.o ds174x.o m48t35ax.o mk48t59.o
 
 all:   $(LIB)
 
diff --git a/rtc/mk48t59.c b/rtc/mk48t59.c
new file mode 100644 (file)
index 0000000..dd29658
--- /dev/null
@@ -0,0 +1,187 @@
+/*
+ * (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Andreas Heppel <aheppel@sysgo.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
+ */
+
+/*
+ * Date & Time support for the MK48T59 RTC
+ */
+
+#undef RTC_DEBUG
+
+#include <ppcboot.h>
+#include <command.h>
+#include <config.h>
+#include <rtc.h>
+#include <mk48t59.h>
+
+#if defined(CONFIG_RTC_MK48T59)
+
+static uchar rtc_read (short reg)
+{
+       out8(RTC_PORT_ADDR0, reg & 0xFF);
+       out8(RTC_PORT_ADDR1, (reg>>8) & 0xFF);
+       return in8(RTC_PORT_DATA);
+}
+
+static void rtc_write (short reg, uchar val)
+{
+       out8(RTC_PORT_ADDR0, reg & 0xFF);
+       out8(RTC_PORT_ADDR1, (reg>>8) & 0xFF);
+       out8(RTC_PORT_DATA, val);
+}
+
+static unsigned bcd2bin (uchar n)
+{
+       return ((((n >> 4) & 0x0F) * 10) + (n & 0x0F));
+}
+
+static unsigned char bin2bcd (unsigned int n)
+{
+       return (((n / 10) << 4) | (n % 10));
+}
+
+/* ------------------------------------------------------------------------- */
+
+void *nvram_read(void *dest, const short src, size_t count)
+{
+       uchar *d = (uchar *) dest;
+       short s = src;
+
+       while (count--)
+               *d++ = rtc_read(s++);
+       
+       return dest;
+}
+
+void nvram_write(short dest, const void *src, size_t count)
+{
+       short d = dest;
+       uchar *s = (uchar *) src;
+       
+       while (count--)
+               rtc_write(d++, *s++);
+}
+
+#if (CONFIG_COMMANDS & CFG_CMD_DATE)
+
+/* ------------------------------------------------------------------------- */
+
+void rtc_get (struct rtc_time *tmp)
+{
+       uchar save_ctrl_a;
+       uchar sec, min, hour, mday, wday, mon, year;
+       
+       /* Simple: freeze the clock, read it and allow updates again */
+       save_ctrl_a = rtc_read(RTC_CONTROLA);
+       
+       /* Set the register to read the value. */
+       save_ctrl_a |= RTC_CA_READ;
+       rtc_write(RTC_CONTROLA, save_ctrl_a);
+       
+       sec             = rtc_read (RTC_SECONDS);
+       min             = rtc_read (RTC_MINUTES);
+       hour    = rtc_read (RTC_HOURS);
+       mday    = rtc_read (RTC_DAY_OF_MONTH);
+       wday    = rtc_read (RTC_DAY_OF_WEEK);
+       mon             = rtc_read (RTC_MONTH);
+       year    = rtc_read (RTC_YEAR);
+       
+       /* re-enable update */
+       save_ctrl_a &= ~RTC_CA_READ;
+       rtc_write(RTC_CONTROLA, save_ctrl_a);
+       
+#ifdef RTC_DEBUG
+       printf ( "Get RTC year: %02x mon/cent: %02x mday: %02x wday: %02x "
+               "hr: %02x min: %02x sec: %02x\n",
+               year, mon, mday, wday,
+               hour, min, sec );
+#endif
+       tmp->tm_sec  = bcd2bin (sec  & 0x7F);
+       tmp->tm_min  = bcd2bin (min  & 0x7F);
+       tmp->tm_hour = bcd2bin (hour & 0x3F);
+       tmp->tm_mday = bcd2bin (mday & 0x3F);
+       tmp->tm_mon  = bcd2bin (mon & 0x1F);
+       tmp->tm_year = bcd2bin (year);
+       tmp->tm_wday = bcd2bin (wday & 0x07);
+       if(tmp->tm_year<70)
+               tmp->tm_year+=2000;
+       else
+               tmp->tm_year+=1900;
+       tmp->tm_yday = 0;
+       tmp->tm_isdst= 0;
+#ifdef RTC_DEBUG
+       printf ( "Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+               tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+               tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+#endif
+}
+
+void rtc_set (struct rtc_time *tmp)
+{
+       uchar save_ctrl_a;
+       
+#ifdef RTC_DEBUG
+       printf ( "Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+               tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+               tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+#endif
+       save_ctrl_a = rtc_read(RTC_CONTROLA);
+
+       save_ctrl_a |= RTC_CA_WRITE;
+       rtc_write(RTC_CONTROLA, save_ctrl_a); /* disables the RTC to update the regs */
+       
+       rtc_write (RTC_YEAR, bin2bcd(tmp->tm_year % 100));
+       rtc_write (RTC_MONTH, bin2bcd(tmp->tm_mon));
+
+       rtc_write (RTC_DAY_OF_WEEK, bin2bcd(tmp->tm_wday));
+       rtc_write (RTC_DAY_OF_MONTH, bin2bcd(tmp->tm_mday));
+       rtc_write (RTC_HOURS, bin2bcd(tmp->tm_hour));
+       rtc_write (RTC_MINUTES, bin2bcd(tmp->tm_min ));
+       rtc_write (RTC_SECONDS, bin2bcd(tmp->tm_sec ));
+       
+       save_ctrl_a &= ~RTC_CA_WRITE;
+       rtc_write(RTC_CONTROLA, save_ctrl_a); /* enables the RTC to update the regs */
+}
+
+void rtc_reset (void)
+{
+       uchar control_b;
+       
+       /*
+        * Start oscillator here.
+        */
+       control_b = rtc_read(RTC_CONTROLB); 
+
+       control_b &= ~RTC_CB_STOP;
+       rtc_write(RTC_CONTROLB, control_b);
+}
+
+void rtc_set_watchdog(short multi, short res)
+{
+       uchar wd_value;
+       
+       wd_value = RTC_WDS | ((multi & 0x1F) << 2) | (res & 0x3);
+       rtc_write(RTC_WATCHDOG, wd_value);
+}
+
+#endif /* (CONFIG_COMMANDS & CFG_CMD_DATE) */
+#endif /* CONFIG_RTC_MK48T59 */