]> www.infradead.org Git - users/rw/ppcboot.git/commitdiff
* Added support for PIP405 board, see "doc/README.PIP405".
authorwdenk <wdenk>
Thu, 5 Jul 2001 14:47:06 +0000 (14:47 +0000)
committerwdenk <wdenk>
Thu, 5 Jul 2001 14:47:06 +0000 (14:47 +0000)
  Supplied by Denis Peter, 4 Jul 2001
  This includes:

- SCSI Support (so far only for Symbios SYM53C810A chip)
- Floppy Disk Support
- CD-ROM Support
- ISO Parttion Support (boot from El-Torito bootable ISO CD-ROM)
- MC146818 RTC support
- Chips & Technologies 69000 Video Chip Support
- Standard (PC-Style) Keyboard Support
- Added IH_OS_PPCBOOT and IH_TYPE_FIRMWARE to the image definitions
  to allow PPCBoot updates with CRC check.

76 files changed:
CHANGELOG
CREDITS
MAKEALL
Makefile
README
board/lwmon/lwmon.c
board/pip405/Makefile [new file with mode: 0644]
board/pip405/cmd_pip405.c [new file with mode: 0644]
board/pip405/config.mk [new file with mode: 0644]
board/pip405/flash.c [new file with mode: 0644]
board/pip405/init.S [new file with mode: 0644]
board/pip405/kbd.c [new file with mode: 0644]
board/pip405/kbd.h [new file with mode: 0644]
board/pip405/pci_piix4.h [new file with mode: 0644]
board/pip405/pci_pip405.c [new file with mode: 0644]
board/pip405/pci_pip405.h [new file with mode: 0644]
board/pip405/pip405.c [new file with mode: 0644]
board/pip405/pip405.h [new file with mode: 0644]
board/pip405/pip405_isa.c [new file with mode: 0644]
board/pip405/pip405_isa.h [new file with mode: 0644]
board/pip405/ppcboot.lds [new file with mode: 0644]
board/pip405/ppcboot.lds.debug [new file with mode: 0644]
board/pip405/sym53c8xx.c [new file with mode: 0644]
board/pip405/sym53c8xx_defs.h [new file with mode: 0644]
board/pip405/vga_table.h [new file with mode: 0644]
board/pip405/video.c [new file with mode: 0644]
board/pip405/video.h [new file with mode: 0644]
common/Makefile
common/board.c
common/cmd_boot.c
common/cmd_bootm.c
common/cmd_date.c
common/cmd_fdc.c [new file with mode: 0644]
common/cmd_i2c.c
common/cmd_ide.c
common/cmd_scsi.c [new file with mode: 0644]
common/command.c
common/console.c
common/devices.c
common/main.c
cpu/mpc74xx/start.S
cpu/mpc8240/start.S
cpu/mpc8260/start.S
cpu/mpc8xx/start.S
cpu/ppc4xx/405gp_pci.c
cpu/ppc4xx/i2c.c
cpu/ppc4xx/speed.c
cpu/ppc4xx/start.S
disk/Makefile
disk/part.c
disk/part_dos.c
disk/part_iso.c [new file with mode: 0644]
disk/part_iso.h [new file with mode: 0644]
disk/part_mac.c
doc/README.PIP405 [new file with mode: 0644]
include/ata.h
include/cmd_bsp.h
include/cmd_confdefs.h
include/cmd_disk.h
include/cmd_fdc.h [new file with mode: 0644]
include/cmd_ide.h
include/cmd_scsi.h [new file with mode: 0644]
include/config_EVB64260.h
include/config_LANTEC.h
include/config_PIP405.h [new file with mode: 0644]
include/config_hymod.h
include/flash.h
include/i2c.h
include/image.h
include/part.h [new file with mode: 0644]
include/ppcboot.h
include/scsi.h [new file with mode: 0644]
include/version.h
rtc/Makefile
rtc/mc146818.c [new file with mode: 0644]
tools/mkimage.c

index de84b22800f1108982c86a558c321f2fbf41609a..d63c19d1164b0f1b719525ae0ee2396bb780d37e 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -56,6 +56,22 @@ To do:
 Modifications for 1.0.2:
 ======================================================================
 
+* Added support for PIP405 board, see "doc/README.PIP405".
+  Supplied by Denis Peter, 4 Jul 2001
+  This includes:
+
+- SCSI Support (so far only for Symbios SYM53C810A chip)
+- Floppy Disk Support
+- CD-ROM Support
+- ISO Partition Support (boot from El-Torito bootable ISO CD-ROM)
+- MC146818 RTC support
+- Chips & Technologies 69000 Video Chip Support
+- Standard (PC-Style) Keyboard Support
+- Added IH_OS_PPCBOOT and IH_TYPE_FIRMWARE to the image definitions
+  to allow PPCBoot updates with CRC check.
+
+* Added keyboard support to LWMON board (uses special I2C keyboard)
+
 * Fix bug in calculation of initrd size
   Patch by Hannes Fertala, 2 Jul 2001
 
diff --git a/CREDITS b/CREDITS
index b19027e40bc68833bb86d7af680b89e5b3e472ed..7a13d7d673dd515cce4c73ad4b6b2b7828a7cf62 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -113,8 +113,12 @@ N: Frank Morauf
 E: frank.morauf@salzbrenner.com
 D: Support for Embedded Planet RPX Super Board
 
+N: Denis Peter
+E: d.peter@mpl.ch
+D: Port to PIP405 board, support for SCSI, floppy, CDROM, CT69000 video, ...
+
 N: Bill Pitts
-D: wlp@mindspring.com
+E: wlp@mindspring.com
 D: BedBug embedded debugger code
 
 N: Stefan Roese
diff --git a/MAKEALL b/MAKEALL
index c5701002d5dd3531c14f4a60c16bfce499ca279a..dd5a9e11dc64f0d118a584907d4eac533ebae46b 100755 (executable)
--- a/MAKEALL
+++ b/MAKEALL
@@ -36,6 +36,7 @@ LIST="$LIST   \
        CPCI405 CPCIISER4               \
        WALNUT405                       \
        AR405 CANBT ADCIOP              \
+       PIP405                          \
        ERIC                            \
 "
 
index 814151100a73b09a04ff85ef2ebdbe1c6ce71754..a54e38b3eec0f5319c30e63553bf8a3b276dbe76 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -318,6 +318,15 @@ WALNUT405_config:unconfig
        echo "CPU   = ppc4xx"   >>config.mk ;   \
        echo "#include <config_$(@:_config=).h>" >config.h
 
+PIP405_config:unconfig
+       @echo "Configuring for $(@:_config=) Board..." ; \
+       cd include ;                            \
+       echo "ARCH  = ppc"      > config.mk ;   \
+       echo "BOARD = pip405">>config.mk ;      \
+       echo "CPU   = ppc4xx"   >>config.mk ;   \
+       echo "#include <config_$(@:_config=).h>" >config.h
+
+
 AR405_config:  unconfig
        @echo "Configuring for $(@:_config=) Board..." ; \
        cd include ;                            \
diff --git a/README b/README
index e5cc7ef821839f8fd72401bfff39952749eba12f..a0e8dc84e629180fb827f5c4c73d77f90ea917b6 100644 (file)
--- a/README
+++ b/README
@@ -95,22 +95,25 @@ Directory Hierarchy:
 - board/cpciiser4
                Files specific to CPCIISER4  boards
 - board/cu824  Files specific to CU824      boards
+- board/eric   Files specific to ERIC       boards
 - board/esteem192e
                Files specific to ESTEEM192E boards
 - board/etx094 Files specific to ETX_094    boards
 - board/evb64260
                Files specific to EVB64260   boards
 - board/fads   Files specific to FADS       boards
+- board/flagadm        Files specific to FLAGADM    boards
 - board/genietv Files specific to GENIETV    boards
 - board/gth    Files specific to GTH        boards
 - board/hermes Files specific to HERMES     boards
 - board/hymod  Files specific to HYMOD      boards
 - board/ip860  Files specific to IP860      boards
-- board/ivms8  Files specific to IVMS8      boards
+- board/ivms8  Files specific to IVMS8/IVML24 boards
 - board/lantec Files specific to LANTEC     boards
 - board/lwmon  Files specific to LWMON      boards
 - board/mbx8xx Files specific to MBX        boards
 - board/pcu_e  Files specific to PCU_E      boards
+- board/pip405 Files specific to PIP405     boards
 - board/RPXlite Files specific to RPXlite    boards
 - board/rpxsuper
                Files specific to RPXsuper   boards
@@ -122,6 +125,7 @@ Directory Hierarchy:
 
 - board/sixnet Files specific to SIXNET     boards
 - board/spd8xx Files specific to SPD8xxTS   boards
+- board/tqm8260        Files specific to TQM8260    boards
 - board/tqm8xx Files specific to TQM8xxL    boards
 - board/walnut405
                Files specific to Walnut405  boards
@@ -188,15 +192,18 @@ The following options need to be configured:
        or      CONFIG_MPC74xx
 
 - Board Type:  Define exactly one of
-               CONFIG_ADCIOP,  CONFIG_COGENT,  CONFIG_CPCI405, CONFIG_ETX094,
-               CONFIG_FADS,    CONFIG_FPS850L, CONFIG_HERMES,  CONFIG_IP860,
-               CONFIG_IVMS8,   CONFIG_MBX,     CONFIG_SM850,   CONFIG_SPD823TS,
-               CONFIG_TQM823L, CONFIG_TQM850L, CONFIG_TQM855L, CONFIG_TQM860L,
-               CONFIG_SXNI855T,CONFIG_EVB64260
---- FIXME --- not tested yet:
-               CONFIG_TQM860,  CONFIG_ADS,
-               CONFIG_RPXLITE, CONFIG_RPXCLASSIC, CONFIG_BSEIP,
-               CONFIG_HYMOD
+
+               CONFIG_ADCIOP,      CONFIG_FADS,        CONFIG_RPXSUPER,
+               CONFIG_ADS,         CONFIG_FPS850L,     CONFIG_SANDPOINT,
+               CONFIG_BSEIP,       CONFIG_HERMES,      CONFIG_SBC8260,
+               CONFIG_COGENT,      CONFIG_HYMOD,       CONFIG_SM850,
+               CONFIG_COGENT,      CONFIG_IP860,       CONFIG_SPD823TS,
+               CONFIG_CPCI405,     CONFIG_IVMS8,       CONFIG_SXNI855T,
+               CONFIG_CU824,       CONFIG_MBX,         CONFIG_TQM823L,
+               CONFIG_ERIC,        CONFIG_PIP405,      CONFIG_TQM8260,
+               CONFIG_ETX094,      CONFIG_RDSPROTO,    CONFIG_TQM850L,
+               CONFIG_EVB64260,    CONFIG_RPXCLASSIC,  CONFIG_TQM855L,
+               CONFIG_EVB64260,    CONFIG_RPXLITE,     CONFIG_TQM860L
 
 - CPU Module Type: (if CONFIG_COGENT is defined)
                Define exactly one of
@@ -308,6 +315,10 @@ The following options need to be configured:
                CFG_CMD_REGINFO * Register dump
                CFG_CMD_IMMAP   * IMMR dump support
                CFG_CMD_DATE    * support for RTC, date/time...
+               CFG_CMD_DHCP      DHCP support
+               CFG_CMD_BEDBUG    Include BedBug Debugger
+               CFG_CMD_FDC       Floppy Disk Support
+               CFG_CMD_SCSI      SCSI Support
                CFG_CMD_BSP     * Board SPecific functions
                -----------------------------------------------
                CFG_CMD_ALL     all
@@ -343,13 +354,53 @@ The following options need to be configured:
 
                CONFIG_RTC_MPC8xx       - use internal RTC of MPC8xx
                CONFIG_RTC_PCF8563      - use Philips PCF8563 RTC
+               CONFIG_RTC_MC146818     - use MC146818 RTC
 
 - Partition Support:
                CONFIG_MAC_PARTITION and/or CONFIG_DOS_PARTITION
+               and/or CONFIG_ISO_PARTITION
+
+                If IDE or SCSI support  is  enabled  (CFG_CMD_IDE  or
+                CFG_CMD_SCSI) you must configure support for at least
+                one partition type as well.
+
+- IDE Reset method:
+               CONFIG_IDE_RESET_ROUTINE
+
+                Set this to define that instead of a reset Pin, the
+                routine ide_set_reset(int idereset) will be used.
+
+- ATAPI Support:
+               CONFIG_ATAPI
+
+               Set this to enable ATAPI support.
+
+- SCSI Support:
+                At the moment only there is only support for the
+                SYM53C8XX SCSI controller; define
+                CONFIG_SCSI_SYM53C8XX to enable it.
+
+                CFG_SCSI_MAX_LUN [8], CFG_SCSI_MAX_SCSI_ID [7] and
+                CFG_SCSI_MAX_DEVICE [CFG_SCSI_MAX_SCSI_ID *
+                CFG_SCSI_MAX_LUN] can be adjusted to define the
+                maximum numbers of LUNs, SCSI ID's and target
+                devices.
+
+- Keyboard Support:
+               CONFIG_ISA_KEYBOARD
+
+                Define this to enable standard (PC-Style) keyboard
+               support
 
-               If IDE harddisk support is enabled (CFG_CMD_IDE) you
-               must configure support for at least one partition
-               type as well.
+- Video support:
+               CONFIG_VIDEO
+
+                Define this to enable  video  support  (for  instance
+               output to LCD).
+
+               CONFIG_VIDEO_CT69000
+
+               Enable Chips & Technologies 69000 Video chip
 
 - BOOTP Recovery Mode:
                CONFIG_BOOTP_RANDOM_DELAY
@@ -387,6 +438,19 @@ The following options need to be configured:
                 on those systems that support this (optional)
                 feature, like the TQM8xxL modules.
 
+- I2C Support: CONFIG_I2C
+
+               Enables I2C driver
+
+               CONFIG_I2C_X
+
+               Enables extended (16-bit) I2C addressing.
+
+               CONFIG_SOFT_I2C
+
+                Use software (aka bit-banging) driver instead of CPM
+                or similar hardware support for I2C
+
 - SPI Support: CONFIG_SPI
 
                Enables SPI driver (so far only tested with
@@ -397,6 +461,11 @@ The following options need to be configured:
                Enables extended (16-bit) SPI EEPROM addressing.
                (symmetrical to CONFIG_I2C_X)
 
+- Configuration Management:
+               CONFIG_IDENT_STRING
+
+                If defined, this string will be added to the PPCBoot
+                version information (PPCBOOT_VERSION)
 
 Configuration Settings:
 -----------------------
@@ -695,7 +764,7 @@ configurations; the following names are supported:
     FADS850SAR_config     SPD823TS_config       pcu_e_config
     FADS860T_config       SXNI855T_config       rsdproto_config
     FPS850L_config        Sandpoint8240_config  sbc8260_config
-    GENIETV_config        TQM823L_config
+    GENIETV_config        TQM823L_config       PIP405_config
 
 Finally, type "make all", and you should  get  some  working  PPCBoot
 images ready for downlod to / installation on your system:
index 16346e6271a847707015ad2fd2113b68fe3013da..c12f7f812da24f5d1d0f6d2397cdf97f7550f6a0 100644 (file)
@@ -271,6 +271,69 @@ void       reset_phy(void)
        udelay(1000);
 }
 
+/*-----------------------------------------------------------------------
+ * Keyboard Controller
+ */
+/* command codes */
+#define        KEYBD_CMD_READ_KEYS     0x01
+#define KEYBD_CMD_READ_VERSION 0x02
+#define KEYBD_CMD_READ_STATUS  0x03
+#define KEYBD_CMD_RESET_ERRORS 0x10
+
+/* Number of bytes returned from Keyboard Controller */
+#define KEYBD_VERSIONLEN       2       /* version information */
+#define        KEYBD_DATALEN           9       /* normal key scan data */
+
+static uchar kbd_addr = CFG_I2C_KEYBD_ADDR;
+static uchar kbd_data[KEYBD_DATALEN];
+uchar keybd_env[2*KEYBD_DATALEN+1];
+
+void misc_init_r (bd_t *bd)
+{
+       uchar val, errcd;
+       int i;
+
+       i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
+
+       /* Read initial keyboard error code */
+       val = KEYBD_CMD_READ_STATUS;
+       i2c_write (&kbd_addr, 1, &val, 1);
+       i2c_read  (&kbd_addr, 1, &errcd, 1);
+       if (errcd) {
+               printf ("  KEYBD: Error %02X\n", errcd);
+       }
+
+       /* Reset error code and verify */
+       val = KEYBD_CMD_RESET_ERRORS;
+       i2c_write (&kbd_addr, 1, &val, 1);
+       val = KEYBD_CMD_READ_STATUS;
+       i2c_write (&kbd_addr, 1, &val, 1);
+       i2c_read  (&kbd_addr, 1, &val, 1);
+
+       if (val) {      /* permanent error, report it */
+               printf ("*** Keyboard error code %02X ***\n", val);
+               sprintf (keybd_env, "%02X", val);
+               setenv ("keybd", keybd_env);
+               return;
+       }
+
+       /* Read Version */
+       val = KEYBD_CMD_READ_VERSION;
+       i2c_write (&kbd_addr, 1, &val, 1);
+       i2c_read  (&kbd_addr, 1, kbd_data, KEYBD_VERSIONLEN);
+       printf ("  KEYBD: Version %d.%d\n", kbd_data[0], kbd_data[1]);
+
+       /* Read keys */
+       val = KEYBD_CMD_READ_KEYS;
+       i2c_write (&kbd_addr, 1, &val, 1);
+       i2c_read  (&kbd_addr, 1, kbd_data, KEYBD_DATALEN);
+
+       for (i=0; i<KEYBD_DATALEN; ++i) {
+               sprintf(keybd_env+i+i, "%02X", kbd_data[i]);
+       }
+       setenv ("keybd", keybd_env);
+}
+
 /*-----------------------------------------------------------------------
  * Board Special Commands: PIC read/write
  */
diff --git a/board/pip405/Makefile b/board/pip405/Makefile
new file mode 100644 (file)
index 0000000..b157874
--- /dev/null
@@ -0,0 +1,47 @@
+#
+# (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 cmd_pip405.o pci_pip405.o pip405_isa.o kbd.o video.o sym53c8xx.o
+SOBJS  = init.o
+
+$(LIB):        $(OBJS) $(SOBJS)
+       $(AR) crv $@ $^
+
+clean:
+       rm -f $(SOBJS) $(OBJS)
+
+distclean:     clean
+       rm -f $(LIB) core *.bak .depend
+
+#########################################################################
+
+.depend:       Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c)
+               $(CC) -M $(CFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@
+
+sinclude .depend
+
+#########################################################################
diff --git a/board/pip405/cmd_pip405.c b/board/pip405/cmd_pip405.c
new file mode 100644 (file)
index 0000000..3ff5eb9
--- /dev/null
@@ -0,0 +1,218 @@
+/*
+ * (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
+ *
+ * hacked for PIP405
+ */
+
+#include <ppcboot.h>
+#include <command.h>
+#include "pip405.h"
+#include <rtc.h>
+#include "pip405_isa.h"
+#include "video.h"
+#include <i2c.h>
+
+extern flash_info_t flash_info[];      /* info for FLASH chips */
+
+int PCI_Write_CFG_Reg(int BusDevFunc, int Reg, unsigned int Value, int Width);
+unsigned int PCI_Read_CFG_Reg(int BusDevFunc, int Reg, int Width);
+
+
+#define TRUE 1
+#define FALSE 0
+
+#define IMAGE_SIZE 0x80000 
+
+image_header_t header;
+
+
+
+int pip405_prg(unsigned long src,unsigned long size)
+{
+       unsigned long start;
+       flash_info_t *info;
+       int i,rc;
+       unsigned long *magic = (unsigned long *)src;
+       
+       info = &flash_info[0];
+  start = 0 - size;
+       for(i=info->sector_count-1;i>0;i--)
+       {
+               info->protect[i] = 0; /* unprotect this sector */
+               if(start>=info->start[i])
+               break;
+       }
+       /* set-up flash location */
+       rc=switch_cs(FALSE);
+       /* now erase flash */
+       if(magic[0]!=IH_MAGIC) {
+               printf("Bad Magic number\n");
+               switch_cs(rc);
+               return(0);
+       }
+       printf("Start erasing at %lx (sector %d) (start %lx)\n",
+                               start,i,info->start[i]);
+       flash_erase (info, i, info->sector_count-1);
+       printf("flash erased, programming 0x%lx Bytes\n",size);
+       switch (rc = flash_write ((uchar *)src, start, size)) 
+       {
+               case 0: printf ("programming done\n"); return(1);
+               case 1: printf ("Timeout writing to Flash\n"); return(0);
+               case 2: printf ("Flash not Erased\n"); return(0);
+               case 4: printf ("Can't write to protected Flash sectors\n"); return(0);
+               case 8: printf ("Outside available Flash\n"); return(0);
+               default:        printf ("%s[%d] FIXME: rc=%d\n",__FILE__,__LINE__,rc); return(0);
+       }
+  return(0);
+}
+
+int pip405_prg_image(unsigned long load_addr)
+{
+       unsigned long data,len,checksum;
+       image_header_t *hdr=&header;  
+       /* Copy header so we can blank CRC field for re-calculation */
+       memcpy (&header, (char *)load_addr, sizeof(image_header_t));
+
+       if (hdr->ih_magic  != IH_MAGIC) {
+               printf ("Bad Magic Number\n");
+               return(0);
+       }
+       if (hdr->ih_os  != IH_OS_PPCBOOT) {
+               printf ("No PPCBOOT Image\n");
+               return(0);
+       }
+       if (hdr->ih_type  != IH_TYPE_FIRMWARE) {
+               printf ("No Firmware Image\n");
+               return(0);
+       }
+       data = (ulong)&header;
+       len  = sizeof(image_header_t);
+       checksum = hdr->ih_hcrc;
+       hdr->ih_hcrc = 0;
+       if (crc32 (0, (char *)data, len) != checksum) {
+               printf ("Bad Header Checksum\n");
+               return(0);
+       }
+       data = load_addr + sizeof(image_header_t);
+       len  = hdr->ih_size;
+       printf ("   Verifying Checksum ... ");
+       if (crc32 (0, (char *)data, len) != hdr->ih_dcrc) {
+               printf ("Bad Data CRC\n");
+               return(0);
+       }
+       printf ("OK\n");
+       return(pip405_prg(data,len));
+} 
+
+
+/* ------------------------------------------------------------------------- */
+
+
+void do_pip405(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
+{
+
+    ulong size,src,device,function,load_addr;
+    unsigned char i2c[3];
+               
+               src = MULTI_PURPOSE_SOCKET_ADDR;
+               size = IMAGE_SIZE;
+
+               if (strcmp(argv[1], "flash") == 0) 
+               {
+               
+                       if (strcmp(argv[2], "floppy") == 0) {
+                               char *local_args[3];
+                               extern void do_fdcboot (cmd_tbl_t *, bd_t *, int, int, char *[]);
+                               printf ("\nupdating bootloader image from floppy\n");
+                               local_args[0] = argv[0];
+               if(argc==4) {
+                                       local_args[1] = argv[3];
+                                       local_args[2] = NULL;
+                                       load_addr=simple_strtoul(argv[3], NULL, 16);
+                                       do_fdcboot(cmdtp, bd, 0, 2, local_args);
+                               }
+                               else {
+                                       local_args[1] = NULL;
+                                       load_addr=CFG_LOAD_ADDR;
+                                       do_fdcboot(cmdtp, bd, 0, 1, local_args);
+                               }
+                               pip405_prg_image(load_addr); 
+                               return;
+                       }
+                       if (strcmp(argv[2], "mem") == 0) {
+               if(argc==4) {
+                                       load_addr=simple_strtoul(argv[3], NULL, 16);
+                               }
+                               else {
+                                       load_addr=CFG_LOAD_ADDR;
+                               }
+                               printf ("\nupdating bootloader image from memory at %lX\n",load_addr);
+                               pip405_prg_image(load_addr); 
+                               return;
+                       }
+                       if (strcmp(argv[2], "mps") == 0) {
+                               printf ("\nupdating bootloader image from MSP\n");
+                               pip405_prg(src,size);
+                               return;
+                       }
+               }
+               if (strcmp(argv[1], "prg") == 0) 
+               {
+           if(argc==3)
+           {
+                   size = (ulong)simple_strtoul(argv[2], NULL, 16);
+                   printf("image size is 0x%lx\n",size);
+           }
+                       pip405_prg(src,size);
+                       return;
+               }
+               if (strcmp(argv[1], "info") == 0) 
+               {
+           printf("argc %d\n",argc);
+                       print_pip405_info();
+                       return;
+       }
+               if (strcmp(argv[1], "i2c") == 0) 
+               {
+           printf("argc %d\n",argc);
+           i2c[0]=CFG_I2C_EEPROM_ADDR;
+           i2c[1]=0;
+           i2c[2]=0;
+           i2c_read(&i2c[0],3,(unsigned char *)CFG_LOAD_ADDR,512);
+                       return;
+       }
+               if (strcmp(argv[1], "led") == 0) 
+               {
+           printf("argc %d\n",argc);
+           device = (ulong)simple_strtoul(argv[2], NULL, 10);
+           function = (ulong)simple_strtoul(argv[3], NULL, 10);
+                       if(device==0)
+                               user_led0((function==1));
+                       else
+                               user_led1((function==1));
+                       return;
+       }
+    printf("Usage:\n%s\n", cmdtp->usage);
+    return;
+}
+
+/* ------------------------------------------------------------------------- */
diff --git a/board/pip405/config.mk b/board/pip405/config.mk
new file mode 100644 (file)
index 0000000..9fe451d
--- /dev/null
@@ -0,0 +1,29 @@
+#
+# (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
+#
+
+#
+# esd ADCIOP boards
+#
+
+#TEXT_BASE = 0xFFFE0000
+TEXT_BASE = 0xFFF80000
diff --git a/board/pip405/flash.c b/board/pip405/flash.c
new file mode 100644 (file)
index 0000000..bb16f4d
--- /dev/null
@@ -0,0 +1,840 @@
+/*
+ * (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
+ */
+
+/*
+ * Modified 4/5/2001
+ * Wait for completion of each sector erase command issued
+ * 4/5/2001
+ * Chris Hallinan - DS4.COM, Inc. - clh@net1plus.com
+ */
+
+/*
+ * Modified 3/7/2001
+ * - adopted for pip405, Denis Peter, MPL AG Switzerland
+ * TODO:
+ * clean-up
+ */
+
+#include <ppcboot.h>
+#include <ppc4xx.h>
+#include <asm/processor.h>
+#include "pip405.h"
+
+flash_info_t   flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips        */
+/*-----------------------------------------------------------------------
+ * Functions
+ */
+static ulong flash_get_size (vu_long *addr, flash_info_t *info);
+static int write_word (flash_info_t *info, ulong dest, ulong data);
+static void flash_get_offsets (ulong base, flash_info_t *info);
+
+void unlock_intel_sectors(flash_info_t *info,ulong addr,ulong cnt);
+
+
+#ifdef CONFIG_ADCIOP
+#define ADDR0           0x0aa9
+#define ADDR1           0x0556
+#define FLASH_WORD_SIZE unsigned char
+#endif
+
+#ifdef CONFIG_CPCI405
+#define ADDR0           0x5555
+#define ADDR1           0x2aaa
+#define FLASH_WORD_SIZE unsigned short
+#endif
+
+#ifdef CONFIG_PIP405
+#define ADDR0           0x5555
+#define ADDR1           0x2aaa
+#define FLASH_WORD_SIZE unsigned short
+#endif
+
+#define FALSE           0
+#define TRUE            1
+
+/*-----------------------------------------------------------------------
+ */
+
+
+unsigned long flash_init (void)
+{
+       unsigned long size_b0, size_b1;
+       int i;
+  unsigned long pbcr;
+  unsigned long base_b0, base_b1;
+
+       if(switch_cs(FALSE)==TRUE) /* map Flash High */
+               printf("(MPS Boot) ");
+       else
+               printf("(Flash Boot) ");
+       /* Init: no FLASHes known */
+       for (i=0; i<CFG_MAX_FLASH_BANKS; ++i) {
+               flash_info[i].flash_id = FLASH_UNKNOWN;
+       }
+
+       /* Static FLASH Bank configuration here - FIXME XXX */
+
+       size_b0 = 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",
+                       size_b0, size_b0<<20);
+       }
+       /* Only one bank */
+       if (CFG_MAX_FLASH_BANKS == 1)
+         {
+           /* Setup offsets */
+                       /*  flash_get_offsets (FLASH_BASE0_PRELIM, &flash_info[0]); */
+           /* Monitor protection ON by default */
+#if CFG_MONITOR_BASE >= CFG_FLASH_BASE
+                   flash_protect(FLAG_PROTECT_SET, 
+                               CFG_MONITOR_BASE,
+                               CFG_MONITOR_BASE+CFG_MONITOR_LEN-1, 
+                               &flash_info[0]);
+#endif
+           size_b1 = 0 ;
+           flash_info[0].size = size_b0;
+         }
+
+       /* 2 banks */
+       else
+         {
+           size_b1 = flash_get_size((vu_long *)FLASH_BASE1_PRELIM, &flash_info[1]);
+           
+           /* Re-do sizing to get full correct info */
+           
+           if (size_b1)
+             {
+               mtdcr(ebccfga, pb0cr);
+               pbcr = mfdcr(ebccfgd);
+               mtdcr(ebccfga, pb0cr);
+               base_b1 = -size_b1;
+               pbcr = (pbcr & 0x0001ffff) | base_b1 | (((size_b1/1024/1024)-1)<<17);
+               mtdcr(ebccfgd, pbcr);
+               /*          printf("pb1cr = %x\n", pbcr); */
+             }
+           
+           if (size_b0)
+             {
+               mtdcr(ebccfga, pb1cr);
+               pbcr = mfdcr(ebccfgd);
+               mtdcr(ebccfga, pb1cr);
+               base_b0 = base_b1 - size_b0;
+               pbcr = (pbcr & 0x0001ffff) | base_b0 | (((size_b0/1024/1024)-1)<<17);
+               mtdcr(ebccfgd, pbcr);
+               /*            printf("pb0cr = %x\n", pbcr); */
+             }
+           
+           size_b0 = flash_get_size((vu_long *)base_b0, &flash_info[0]);
+           
+           flash_get_offsets (base_b0, &flash_info[0]);
+           
+           /* monitor protection ON by default */
+           (void)flash_protect(FLAG_PROTECT_SET,
+                               base_b0+size_b0-CFG_MONITOR_LEN,
+                               base_b0+size_b0-1,
+                               &flash_info[0]);
+           
+           if (size_b1) {
+             /* Re-do sizing to get full correct info */
+             size_b1 = flash_get_size((vu_long *)base_b1, &flash_info[1]);
+             
+             flash_get_offsets (base_b1, &flash_info[1]);
+             
+             /* monitor protection ON by default */
+             (void)flash_protect(FLAG_PROTECT_SET,
+                                 base_b1+size_b1-CFG_MONITOR_LEN,
+                                 base_b1+size_b1-1,
+                                 &flash_info[1]);
+             /* monitor protection OFF by default (one is enough) */
+             (void)flash_protect(FLAG_PROTECT_CLEAR,
+                                 base_b0+size_b0-CFG_MONITOR_LEN,
+                                 base_b0+size_b0-1,
+                                 &flash_info[0]);
+           } else {
+             flash_info[1].flash_id = FLASH_UNKNOWN;
+             flash_info[1].sector_count = -1;
+           }
+           
+           flash_info[0].size = size_b0;
+           flash_info[1].size = size_b1;
+         }/* else 2 banks */
+       switch_cs(TRUE); /* switch to boot mode */
+       return (size_b0 + size_b1);
+}
+
+
+static void flash_get_offsets (ulong base, flash_info_t *info)
+{
+       return;
+}
+#if 0
+/*-----------------------------------------------------------------------
+ */
+static void flash_get_offsets (ulong base, flash_info_t *info)
+{
+       int i;
+
+       /* set up sector start address table */
+  if (((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) || 
+           (info->flash_id  == FLASH_AM040)){
+               for (i = 0; i < info->sector_count; i++)
+                       info->start[i] = base + (i * 0x00010000);
+  } 
+  else {
+               if (info->flash_id & FLASH_BTYPE) {
+               /* set sector offsets for bottom boot block type        */
+               info->start[0] = base + 0x00000000;
+               info->start[1] = base + 0x00004000;
+               info->start[2] = base + 0x00006000;
+               info->start[3] = base + 0x00008000;
+               for (i = 4; i < info->sector_count; i++) {
+                       info->start[i] = base + (i * 0x00010000) - 0x00030000;
+               }
+           } else {
+               /* set sector offsets for top boot block type           */
+               i = info->sector_count - 1;
+               info->start[i--] = base + info->size - 0x00004000;
+               info->start[i--] = base + info->size - 0x00006000;
+               info->start[i--] = base + info->size - 0x00008000;
+               for (; i >= 0; i--) {
+                       info->start[i] = base + i * 0x00010000;
+               }
+           }
+       }
+}
+
+#endif
+/*-----------------------------------------------------------------------
+ */
+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");
+               return;
+       }
+
+       switch (info->flash_id & FLASH_VENDMASK) {
+       case FLASH_MAN_AMD:     printf ("AMD ");                break;
+       case FLASH_MAN_FUJ:     printf ("FUJITSU ");            break;
+       case FLASH_MAN_SST:     printf ("SST ");                break;
+       case FLASH_MAN_INTEL:   printf ("Intel ");              break;
+       default:                printf ("Unknown Vendor ");     break;
+       }
+
+       switch (info->flash_id & FLASH_TYPEMASK) {
+       case FLASH_AM040:       printf ("AM29F040 (512 Kbit, uniform sector size)\n");
+                               break;
+       case FLASH_AM400B:      printf ("AM29LV400B (4 Mbit, bottom boot sect)\n");
+                               break;
+       case FLASH_AM400T:      printf ("AM29LV400T (4 Mbit, top boot sector)\n");
+                               break;
+       case FLASH_AM800B:      printf ("AM29LV800B (8 Mbit, bottom boot sect)\n");
+                               break;
+       case FLASH_AM800T:      printf ("AM29LV800T (8 Mbit, top boot sector)\n");
+                               break;
+       case FLASH_AM160B:      printf ("AM29LV160B (16 Mbit, bottom boot sect)\n");
+                               break;
+       case FLASH_AM160T:      printf ("AM29LV160T (16 Mbit, top boot sector)\n");
+                               break;
+       case FLASH_AM320B:      printf ("AM29LV320B (32 Mbit, bottom boot sect)\n");
+                               break;
+       case FLASH_AM320T:      printf ("AM29LV320T (32 Mbit, top boot sector)\n");
+                               break;
+       case FLASH_SST800A:     printf ("SST39LF/VF800 (8 Mbit, uniform sector size)\n");
+                               break;
+       case FLASH_SST160A:     printf ("SST39LF/VF160 (16 Mbit, uniform sector size)\n");
+                               break;
+       case FLASH_INTEL320T:   printf ("TE28F320C3 (32 Mbit, top sector size)\n");
+                               break;
+       default:                printf ("Unknown Chip Type\n");
+                               break;
+       }
+       
+       printf ("  Size: %ld KB in %d Sectors\n",
+               info->size >> 10, info->sector_count);
+
+       printf ("  Sector Start Addresses:");
+       for (i=0; i<info->sector_count; ++i) {
+       /*
+     * 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   ");
+#if 0 /* test-only */
+               printf (" %08lX%s",
+                       info->start[i],
+                       info->protect[i] ? " (RO)" : "     "
+#else
+               printf (" %08lX%s%s",
+                       info->start[i],
+                       erased ? " E" : "  ",
+                       info->protect[i] ? "RO " : "   "
+#endif
+               );
+       }
+       printf ("\n");
+}
+
+/*-----------------------------------------------------------------------
+ */
+
+
+/*-----------------------------------------------------------------------
+ */
+
+/*
+ * The following code cannot be run from FLASH!
+ */
+static ulong flash_get_size (vu_long *addr, flash_info_t *info)
+{
+       short i;
+       FLASH_WORD_SIZE value;
+       ulong base = (ulong)addr;
+  volatile FLASH_WORD_SIZE *addr2 = (FLASH_WORD_SIZE *)addr;
+
+       /* Write auto select command: read Manufacturer ID */
+       addr2[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA;
+       addr2[ADDR1] = (FLASH_WORD_SIZE)0x00550055;
+       addr2[ADDR0] = (FLASH_WORD_SIZE)0x00900090;
+
+       value = addr2[0];
+       /*      printf("flash_get_size value: %x\n",value); */
+       switch (value) {
+       case (FLASH_WORD_SIZE)AMD_MANUFACT:
+               info->flash_id = FLASH_MAN_AMD;
+               break;
+       case (FLASH_WORD_SIZE)FUJ_MANUFACT:
+               info->flash_id = FLASH_MAN_FUJ;
+               break;
+       case (FLASH_WORD_SIZE)INTEL_MANUFACT:
+               info->flash_id = FLASH_MAN_INTEL;
+               break;
+       case (FLASH_WORD_SIZE)SST_MANUFACT:
+               info->flash_id = FLASH_MAN_SST;
+               break;
+       default:
+               info->flash_id = FLASH_UNKNOWN;
+               info->sector_count = 0;
+               info->size = 0;
+               return (0);                     /* no or unknown flash  */
+       }
+       value = addr2[1];                       /* device ID            */
+       /*      printf("Device value %x\n",value); */
+       switch (value) {
+       case (FLASH_WORD_SIZE)AMD_ID_F040B:
+               info->flash_id += FLASH_AM040;
+               info->sector_count = 8;
+               info->size = 0x0080000; /* => 512 ko */
+               break;
+       case (FLASH_WORD_SIZE)AMD_ID_LV400T:
+               info->flash_id += FLASH_AM400T;
+               info->sector_count = 11;
+               info->size = 0x00080000;
+               break;                          /* => 0.5 MB            */
+
+       case (FLASH_WORD_SIZE)AMD_ID_LV400B:
+               info->flash_id += FLASH_AM400B;
+               info->sector_count = 11;
+               info->size = 0x00080000;
+               break;                          /* => 0.5 MB            */
+
+       case (FLASH_WORD_SIZE)AMD_ID_LV800T:
+               info->flash_id += FLASH_AM800T;
+               info->sector_count = 19;
+               info->size = 0x00100000;
+               break;                          /* => 1 MB              */
+
+       case (FLASH_WORD_SIZE)AMD_ID_LV800B:
+               info->flash_id += FLASH_AM800B;
+               info->sector_count = 19;
+               info->size = 0x00100000;
+               break;                          /* => 1 MB              */
+
+       case (FLASH_WORD_SIZE)AMD_ID_LV160T:
+               info->flash_id += FLASH_AM160T;
+               info->sector_count = 35;
+               info->size = 0x00200000;
+               break;                          /* => 2 MB              */
+
+       case (FLASH_WORD_SIZE)AMD_ID_LV160B:
+               info->flash_id += FLASH_AM160B;
+               info->sector_count = 35;
+               info->size = 0x00200000;
+               break;                          /* => 2 MB              */
+#if 0  /* enable when device IDs are available */
+       case (FLASH_WORD_SIZE)AMD_ID_LV320T:
+               info->flash_id += FLASH_AM320T;
+               info->sector_count = 67;
+               info->size = 0x00400000;
+               break;                          /* => 4 MB              */
+
+       case (FLASH_WORD_SIZE)AMD_ID_LV320B:
+               info->flash_id += FLASH_AM320B;
+               info->sector_count = 67;
+               info->size = 0x00400000;
+               break;                          /* => 4 MB              */
+#endif
+       case (FLASH_WORD_SIZE)SST_ID_xF800A:
+               info->flash_id += FLASH_SST800A;
+               info->sector_count = 16;
+               info->size = 0x00100000;
+               break;                          /* => 1 MB              */
+       case (FLASH_WORD_SIZE)INTEL_ID_28F320C3T:
+               info->flash_id += FLASH_INTEL320T;
+               info->sector_count = 71;
+               info->size = 0x00400000;
+               break;                          /* => 4 MB              */
+
+
+       case (FLASH_WORD_SIZE)SST_ID_xF160A:
+               info->flash_id += FLASH_SST160A;
+               info->sector_count = 32;
+               info->size = 0x00200000;
+               break;                          /* => 2 MB              */
+
+       default:
+               info->flash_id = FLASH_UNKNOWN;
+               return (0);                     /* => no or unknown flash */
+
+       }
+
+       /* set up sector start address table */
+  if (((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) ||
+           (info->flash_id  == FLASH_AM040)){
+               for (i = 0; i < info->sector_count; i++)
+                       info->start[i] = base + (i * 0x00010000);
+  } else {
+               if (info->flash_id & FLASH_BTYPE) {
+               /* set sector offsets for bottom boot block type        */
+               info->start[0] = base + 0x00000000;
+               info->start[1] = base + 0x00004000;
+               info->start[2] = base + 0x00006000;
+               info->start[3] = base + 0x00008000;
+               for (i = 4; i < info->sector_count; i++) 
+                       info->start[i] = base + (i * 0x00010000) - 0x00030000;
+         } 
+         else {
+                       /* set sector offsets for top boot block type           */
+                       i = info->sector_count - 1;
+                       if(info->sector_count==71) {
+                               
+                               info->start[i--] = base + info->size - 0x00002000;
+                               info->start[i--] = base + info->size - 0x00004000;
+                               info->start[i--] = base + info->size - 0x00006000;
+                               info->start[i--] = base + info->size - 0x00008000;
+                               info->start[i--] = base + info->size - 0x0000A000;
+                               info->start[i--] = base + info->size - 0x0000C000;
+                               info->start[i--] = base + info->size - 0x0000E000;
+                               for (; i >= 0; i--) 
+                                       info->start[i] = base + i * 0x000010000;
+                       }
+                       else {
+                               info->start[i--] = base + info->size - 0x00004000;
+                               info->start[i--] = base + info->size - 0x00006000;
+                               info->start[i--] = base + info->size - 0x00008000;
+                               for (; i >= 0; i--) 
+                                       info->start[i] = base + i * 0x00010000;
+                       }
+               }
+       }
+
+       /* check for protected sectors */
+       for (i = 0; i < info->sector_count; i++) {
+               /* read sector protection at sector address, (A7 .. A0) = 0x02 */
+               /* D0 = 1 if protected */
+               addr2 = (volatile FLASH_WORD_SIZE *)(info->start[i]);
+       if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL)
+       info->protect[i] = 0;
+      else
+        info->protect[i] = addr2[2] & 1;
+       }
+
+       /*
+        * Prevent writes to uninitialized FLASH.
+        */
+       if (info->flash_id != FLASH_UNKNOWN) {
+#if 0 /* test-only */
+#ifdef CONFIG_ADCIOP
+               addr2 = (volatile unsigned char *)info->start[0];
+                addr2[ADDR0] = 0xAA;
+                addr2[ADDR1] = 0x55;
+                addr2[ADDR0] = 0xF0;  /* reset bank */
+#else
+               addr2 = (FLASH_WORD_SIZE *)info->start[0];
+               *addr2 = (FLASH_WORD_SIZE)0x00F000F0;   /* reset bank */
+#endif
+#else /* test-only */
+               addr2 = (FLASH_WORD_SIZE *)info->start[0];
+               *addr2 = (FLASH_WORD_SIZE)0x00F000F0;   /* reset bank */
+#endif /* test-only */
+       }
+
+       return (info->size);
+}
+
+int wait_for_DQ7(flash_info_t *info, int sect)
+{
+       ulong start, now, last;
+       volatile FLASH_WORD_SIZE *addr = (FLASH_WORD_SIZE *)(info->start[sect]);
+
+       start = get_timer (0);
+    last  = start;
+    while ((addr[0] & (FLASH_WORD_SIZE)0x00800080) != (FLASH_WORD_SIZE)0x00800080) {
+        if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
+            printf ("Timeout\n");
+            return -1;
+        }
+        /* show that we're waiting */
+        if ((now - last) > 1000) {  /* every second */
+                               putc ('.');
+            last = now;
+        }
+    }
+       return 0;
+}
+
+int intel_wait_for_DQ7(flash_info_t *info, int sect)
+{
+       ulong start, now, last;
+       volatile FLASH_WORD_SIZE *addr = (FLASH_WORD_SIZE *)(info->start[sect]);
+
+               start = get_timer (0);
+    last  = start;
+    while ((addr[0] & (FLASH_WORD_SIZE)0x00800080) != (FLASH_WORD_SIZE)0x00800080) {
+        if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
+            printf ("Timeout\n");
+            return -1;
+        }
+        /* show that we're waiting */
+        if ((now - last) > 1000) {  /* every second */
+                               putc ('.');
+            last = now;
+        }
+    }
+    addr[0]=(FLASH_WORD_SIZE)0x00500050;
+       return 0;
+}
+
+/*-----------------------------------------------------------------------
+ */
+
+void   flash_erase (flash_info_t *info, int s_first, int s_last)
+{
+       volatile FLASH_WORD_SIZE *addr = (FLASH_WORD_SIZE *)(info->start[0]);
+       volatile FLASH_WORD_SIZE *addr2;
+       int flag, prot, sect, l_sect;
+       int i;
+
+       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;
+       }
+
+       if (info->flash_id == FLASH_UNKNOWN) {
+               printf ("Can't erase unknown flash type - aborted\n");
+               return;
+       }
+
+       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();
+
+       /* Start erase on unprotected sectors */
+       for (sect = s_first; sect<=s_last; sect++) {
+               if (info->protect[sect] == 0) { /* not protected */
+                       addr2 = (FLASH_WORD_SIZE *)(info->start[sect]);
+                       /*  printf("Erasing sector %p\n", addr2); */ /* CLH */
+           if ((info->flash_id & FLASH_VENDMASK) == 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;
+                               addr2[0] = (FLASH_WORD_SIZE)0x00500050;  /* block erase */
+                               for (i=0; i<50; i++)
+                                       udelay(1000);  /* wait 1 ms */
+                   wait_for_DQ7(info, sect);
+                 } 
+                 else {
+                       if((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL){
+                                       addr2[0] = (FLASH_WORD_SIZE)0x00600060;  /* unlock sector */
+                                       addr2[0] = (FLASH_WORD_SIZE)0x00D000D0;  /* sector erase */
+                           intel_wait_for_DQ7(info, sect);
+                                       addr2[0] = (FLASH_WORD_SIZE)0x00200020;  /* sector erase */
+                                       addr2[0] = (FLASH_WORD_SIZE)0x00D000D0;  /* sector erase */
+                           intel_wait_for_DQ7(info, sect);
+                               }
+                               else {
+                                       addr[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA;
+                                       addr[ADDR1] = (FLASH_WORD_SIZE)0x00550055;
+                                       addr[ADDR0] = (FLASH_WORD_SIZE)0x00800080;
+                                       addr[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA;
+                                       addr[ADDR1] = (FLASH_WORD_SIZE)0x00550055;
+                                       addr2[0] = (FLASH_WORD_SIZE)0x00300030;  /* sector erase */
+                           wait_for_DQ7(info, sect);
+                               }
+                }
+                l_sect = sect;
+                   /*
+                    * Wait for each sector to complete, it's more 
+                    * reliable.  According to AMD Spec, you must 
+                    * issue all erase commands within a specified
+                    * timeout.  This has been seen to fail, especially
+                    * if printf()s are included (for debug)!!
+                    */
+                /*   wait_for_DQ7(info, sect); */
+               }
+       }
+
+       /* re-enable interrupts if necessary */
+       if (flag)
+               enable_interrupts();
+
+       /* wait at least 80us - let's wait 1 ms */
+       udelay (1000);
+
+#if 0
+       /*
+        * We wait for the last triggered sector
+        */
+       if (l_sect < 0)
+               goto DONE;
+       wait_for_DQ7(info, l_sect);
+
+DONE:
+#endif
+       /* reset to read mode */
+       addr = (FLASH_WORD_SIZE *)info->start[0];
+       addr[0] = (FLASH_WORD_SIZE)0x00F000F0;  /* reset bank */
+
+       printf (" done\n");
+}
+
+void unlock_intel_sectors(flash_info_t *info,ulong addr,ulong cnt)
+{
+       int i;
+       volatile FLASH_WORD_SIZE *addr2;
+       long c;
+       c= (long)cnt;
+       for(i=info->sector_count-1;i>0;i--)
+       {
+               if(addr>=info->start[i])
+                       break;
+       }
+       do {
+               addr2 = (FLASH_WORD_SIZE *)(info->start[i]);
+               addr2[0] = (FLASH_WORD_SIZE)0x00600060;  /* unlock sector setup */
+               addr2[0] = (FLASH_WORD_SIZE)0x00D000D0;  /* unlock sector */
+               intel_wait_for_DQ7(info, i);
+               i++;
+               c-=(info->start[i]-info->start[i-1]);
+       }while(c>0);
+               
+
+}
+
+
+/*-----------------------------------------------------------------------
+ * Copy memory to flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ */
+
+int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
+{
+       ulong cp, wp, data;
+       int i, l, rc;
+
+       
+       if((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL){
+               unlock_intel_sectors(info,addr,cnt);
+       }
+       
+       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;
+               if((wp % 0x10000)==0)
+                       printf("."); /* show Progress */
+               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++)
+  {
+               if((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL){
+                       /* intel style writting */
+                       dest2[i] = (FLASH_WORD_SIZE)0x00400040;
+      dest2[i] = data2[i];
+      if (flag)
+       enable_interrupts();
+      /* data polling for D7 */
+      start = get_timer (0);
+      while ((dest2[i] & (FLASH_WORD_SIZE)0x00800080) != (FLASH_WORD_SIZE)0x00800080) 
+      {
+       if (get_timer(start) > CFG_FLASH_WRITE_TOUT) 
+               return (1);
+                       }
+                       dest2[i] = (FLASH_WORD_SIZE)0xFFFFFFFF; /* return to read mode */
+                       
+               }
+               else {
+               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/pip405/init.S b/board/pip405/init.S
new file mode 100644 (file)
index 0000000..1723d54
--- /dev/null
@@ -0,0 +1,242 @@
+/*------------------------------------------------------------------------------+
+ *
+ *      This source code has been made available to you by IBM on an AS-IS
+ *      basis.  Anyone receiving this source is licensed under IBM
+ *      copyrights to use it in any way he or she deems fit, including
+ *      copying it, modifying it, compiling it, and redistributing it either
+ *      with or without modifications.  No license under IBM patents or
+ *      patent applications is to be implied by the copyright license.
+ *
+ *      Any user of this software should understand that IBM cannot provide
+ *      technical support for this software and will not be responsible for
+ *      any consequences resulting from the use of this software.
+ *
+ *      Any person who transfers this source code or any derivative work
+ *      must include the IBM copyright notice, this paragraph, and the
+ *      preceding two paragraphs in the transferred software.
+ *
+ *      COPYRIGHT   I B M   CORPORATION 1995
+ *      LICENSED MATERIAL  -  PROGRAM PROPERTY OF I B M
+ *-------------------------------------------------------------------------------*/
+
+/*-----------------------------------------------------------------------------
+ * Function:     ext_bus_cntlr_init
+ * Description:  Initializes the External Bus Controller for the external 
+ *             peripherals. IMPORTANT: For pass1 this code must run from 
+ *             cache since you can not reliably change a peripheral banks
+ *             timing register (pbxap) while running code from that bank.
+ *             For ex., since we are running from ROM on bank 0, we can NOT 
+ *             execute the code that modifies bank 0 timings from ROM, so
+ *             we run it from cache.
+ *     Bank 0 - Flash or Multi Purpose Socket
+ *     Bank 1 - Multi Purpose Socket or Flash
+ *     Bank 2 - not used
+ *     Bank 3 - not used
+ *     Bank 4 - not used
+ *     Bank 5 - not used
+ *     Bank 6 - used to switch on the 12V for the Multipurpose socket
+ *     Bank 7 - Config Register
+ *-----------------------------------------------------------------------------*/
+#include <ppc4xx.h>
+
+#define _LINUX_CONFIG_H 1      /* avoid reading Linux autoconf.h file  */
+
+#include "config_PIP405.h"
+#include <ppc_asm.tmpl>
+#include <ppc_defs.h>
+
+#include <asm/cache.h>
+#include <asm/mmu.h>
+        
+        
+       .globl  ext_bus_cntlr_init
+ext_bus_cntlr_init:
+  mflr    r4                      /* save link register */
+  bl      ..getAddr
+..getAddr:
+  mflr    r3                      /* get address of ..getAddr */
+  mtlr    r4                      /* restore link register */
+  addi    r4,0,14                 /* set ctr to 14; used to prefetch */
+  mtctr   r4                      /* 14 cache lines to fit this function */
+                                   /* in cache (gives us 8x14=112 instrctns) */
+..ebcloop:
+  icbt    r0,r3                   /* prefetch cache line for addr in r3 */
+  addi    r3,r3,32                                                             /* move to next cache line */
+  bdnz    ..ebcloop               /* continue for 14 cache lines */
+
+   /*-------------------------------------------------------------------
+    * Delay to ensure all accesses to ROM are complete before changing
+    * bank 0 timings.
+    *------------------------------------------------------------------- */
+       addis   r3,0,0x0
+  ori     r3,r3,0xA000
+  mtctr   r3
+..spinlp:
+  bdnz    ..spinlp                /* spin loop */
+
+       /*-----------------------------------------------------------------------
+        * decide boot up mode
+        *----------------------------------------------------------------------- */
+       addi            r4,0,pb0cr
+       mtdcr           ebccfga,r4
+       mfdcr           r4,ebccfgd
+                               
+       andi.           r0, r4, 0x2000                  /* mask out irrelevant bits */
+       beq                     0f                                                                      /* jump if 8 bit bus width */
+                               
+       /* setup 16 bit things
+   *-----------------------------------------------------------------------
+   * Memory Bank 0 (16 Bit Flash) initialization
+   *---------------------------------------------------------------------- */
+        
+       addi    r4,0,pb0ap
+  mtdcr   ebccfga,r4
+  addis   r4,0,0x9B01
+  ori     r4,r4,0x5480
+  mtdcr   ebccfgd,r4
+
+  addi    r4,0,pb0cr
+  mtdcr   ebccfga,r4
+       /* BS=0x011(8MB),BU=0x3(R/W), */
+  addis   r4,0,((FLASH_BASE0_PRELIM & 0xFFF00000) | 0x00050000)@h 
+  ori     r4,r4,0xA000          /* BW=0x01(16 bits) */
+  mtdcr   ebccfgd,r4
+
+  /*-----------------------------------------------------------------------
+   * Memory Bank 1 (Multi Purpose Socket) initialization
+   *----------------------------------------------------------------------*/
+  addi    r4,0,pb1ap
+  mtdcr   ebccfga,r4
+  addis   r4,0,0x0281         
+  ori     r4,r4,0x5480
+  mtdcr   ebccfgd,r4
+
+  addi    r4,0,pb1cr
+  mtdcr   ebccfga,r4
+  /* BS=0x011(8MB),BU=0x3(R/W), */
+  addis   r4,0,((MULTI_PURPOSE_SOCKET_ADDR & 0xFFF00000) | 0x00050000)@h 
+  ori     r4,r4,0x8000          /* BW=0x0( 8 bits) */
+  mtdcr   ebccfgd,r4
+       b                               1f      
+                               
+0:
+  /* 8Bit boot mode: */        
+       /*-----------------------------------------------------------------------
+   * Memory Bank 0 Multi Purpose Socket initialization
+   *----------------------------------------------------------------------- */
+        
+       addi    r4,0,pb0ap
+  mtdcr   ebccfga,r4
+  addis   r4,0,0x9B01
+  ori     r4,r4,0x5480
+  mtdcr   ebccfgd,r4
+
+  addi    r4,0,pb0cr
+  mtdcr   ebccfga,r4
+       /* BS=0x011(4MB),BU=0x3(R/W), */
+  addis   r4,0,((FLASH_BASE0_PRELIM & 0xFFF00000) | 0x00050000)@h 
+  ori     r4,r4,0x8000          /* BW=0x0( 8 bits) */
+  mtdcr   ebccfgd,r4
+
+  /*-----------------------------------------------------------------------
+   * Memory Bank 1 (Flash) initialization
+   *-----------------------------------------------------------------------*/
+  addi    r4,0,pb1ap
+  mtdcr   ebccfga,r4
+  addis   r4,0,0x0281         
+  ori     r4,r4,0x5480
+  mtdcr   ebccfgd,r4
+
+  addi    r4,0,pb1cr
+  mtdcr   ebccfga,r4
+  /* BS=0x011(8MB),BU=0x3(R/W), */
+  addis   r4,0,((MULTI_PURPOSE_SOCKET_ADDR & 0xFFF00000) | 0x00050000)@h 
+  ori     r4,r4,0xA000          /* BW=0x0( 8 bits) */
+  mtdcr   ebccfgd,r4
+
+1:
+  /*-----------------------------------------------------------------------
+   * Memory Bank 2-3-4-5-6 (not used) initialization
+   *-----------------------------------------------------------------------*/
+  addi    r4,0,pb2cr
+  mtdcr   ebccfga,r4
+  addis   r4,0,0x0000
+  ori     r4,r4,0x0000
+  mtdcr   ebccfgd,r4
+
+  addi    r4,0,pb3cr
+  mtdcr   ebccfga,r4
+  addis   r4,0,0x0000
+  ori     r4,r4,0x0000
+  mtdcr   ebccfgd,r4
+
+  addi    r4,0,pb4cr
+  mtdcr   ebccfga,r4
+  addis   r4,0,0x0000
+  ori     r4,r4,0x0000
+  mtdcr   ebccfgd,r4
+
+  addi    r4,0,pb5cr
+  mtdcr   ebccfga,r4
+  addis   r4,0,0x0000
+  ori     r4,r4,0x0000
+  mtdcr   ebccfgd,r4
+        
+       addi    r4,0,pb6cr
+  mtdcr   ebccfga,r4
+  addis   r4,0,0x0000
+  ori     r4,r4,0x0000
+  mtdcr   ebccfgd,r4
+               
+       /*-----------------------------------------------------------------------
+   * Memory Bank 7 (Config Register) initialization
+   *----------------------------------------------------------------------- */
+  addi    r4,0,pb7ap
+  mtdcr   ebccfga,r4
+  addis   r4,0,0x0181        /* Doc says TWT=3 and Openios TWT=3!! */
+  ori     r4,r4,0x5280          /* disable Ready, BEM=0 */
+  mtdcr   ebccfgd,r4
+
+  addi    r4,0,pb7cr
+  mtdcr   ebccfga,r4
+       /* BS=0x0(1MB),BU=0x3(R/W), */
+  addis   r4,0,((CONFIG_PORT_ADDR & 0xFFF00000) | 0x00010000)@h 
+  ori     r4,r4,0x8000            /* BW=0x0(8 bits) */
+  mtdcr   ebccfgd,r4
+       nop                             /* pass2 DCR errata #8 */
+  blr
+
+/*-----------------------------------------------------------------------------
+ * Function:     sdram_init
+ * Description:  Configures the internal SRAM memory. and setup the 
+ *               Stackpointer in it.
+ *----------------------------------------------------------------------------- */
+        .globl  sdram_init
+
+sdram_init:
+
+       /*-------------------------------------------------------------------
+        * init OnChip Memory for a temporary stack
+        *------------------------------------------------------------------- */
+
+       lis     r0, 0x7FFF
+       ori     r0, r0, 0xFFFF
+       mfdcr   r3, ocmiscntl           /* get instr-side IRAM config */
+       mfdcr   r4, ocmdscntl   /* get data-side IRAM config */
+       and     r3, r3, r0      /* disable data-side IRAM */
+       and     r4, r4, r0      /* disable data-side IRAM */
+       mtdcr   ocmiscntl, r3   /* set instr-side IRAM config */
+       mtdcr   ocmdscntl, r4   /* set data-side IRAM config */
+       isync
+       lis     r0, OCM_DATA_ADDR@h/* IRAM is mapped here */
+       mtdcr   ocmdsarc, r0    /* set data-side IRAM address */
+       oris    r4, r4, 0xC000  /* enable data-side IRAM */
+       mtdcr   ocmdscntl, r4   /* set data-side IRAM config */
+       isync
+
+       mfdcr   r3, ocmdsarc    /* set temp stackpointer (needed by CONS_Init) */
+       andis.  r3, r3, 0xFC00
+       addi    r1, r3, 0x1000-16
+
+  blr
+
diff --git a/board/pip405/kbd.c b/board/pip405/kbd.c
new file mode 100644 (file)
index 0000000..1c538cb
--- /dev/null
@@ -0,0 +1,628 @@
+/*
+ * (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
+ *
+ *
+ * Source partly derived from:
+ * linux/drivers/char/pc_keyb.c
+ *
+ *
+ */
+#include <ppcboot.h>
+#include <asm/processor.h>
+#include <devices.h>
+#include "pip405_isa.h"
+#include "kbd.h"
+
+
+unsigned char kbd_read_status(void);
+unsigned char kbd_read_input(void);
+void kbd_send_data(unsigned char data);
+void disable_8259A_irq(unsigned int irq);
+void enable_8259A_irq(unsigned int irq);
+
+/* used only by send_data - set by keyboard_interrupt */
+
+
+#undef KBG_DEBUG
+
+#ifdef KBG_DEBUG
+#define        PRINTF(fmt,args...)     printf (fmt ,##args)
+#else
+#define PRINTF(fmt,args...)
+#endif
+
+#define KBD_STAT_KOBF          0x01
+#define KBD_STAT_IBF           0x02
+#define KBD_STAT_SYS           0x04
+#define KBD_STAT_CD                    0x08
+#define KBD_STAT_LOCK          0x10
+#define KBD_STAT_MOBF          0x20
+#define KBD_STAT_TI_OUT        0x40
+#define KBD_STAT_PARERR        0x80
+
+#define KBD_INIT_TIMEOUT 1000          /* Timeout in ms for initializing the keyboard */
+#define KBC_TIMEOUT 250                        /* Timeout in ms for sending to keyboard controller */
+#define KBD_TIMEOUT 1000               /* Timeout in ms for keyboard command acknowledge */
+/*
+ *     Keyboard Controller Commands
+ */
+
+#define KBD_CCMD_READ_MODE                     0x20    /* Read mode bits */
+#define KBD_CCMD_WRITE_MODE                    0x60    /* Write mode bits */
+#define KBD_CCMD_GET_VERSION           0xA1    /* Get controller version */
+#define KBD_CCMD_MOUSE_DISABLE 0xA7    /* Disable mouse interface */
+#define KBD_CCMD_MOUSE_ENABLE          0xA8    /* Enable mouse interface */
+#define KBD_CCMD_TEST_MOUSE                    0xA9    /* Mouse interface test */
+#define KBD_CCMD_SELF_TEST                     0xAA    /* Controller self test */
+#define KBD_CCMD_KBD_TEST                              0xAB    /* Keyboard interface test */
+#define KBD_CCMD_KBD_DISABLE           0xAD    /* Keyboard interface disable */
+#define KBD_CCMD_KBD_ENABLE                    0xAE    /* Keyboard interface enable */
+#define KBD_CCMD_WRITE_AUX_OBUF        0xD3    /* Write to output buffer as if
+                                          initiated by the auxiliary device */
+#define KBD_CCMD_WRITE_MOUSE           0xD4    /* Write the following byte to the mouse */
+
+/*
+ *     Keyboard Commands
+ */
+
+#define KBD_CMD_SET_LEDS                               0xED    /* Set keyboard leds */
+#define KBD_CMD_SET_RATE                               0xF3    /* Set typematic rate */
+#define KBD_CMD_ENABLE                                 0xF4    /* Enable scanning */
+#define KBD_CMD_DISABLE                                        0xF5    /* Disable scanning */
+#define KBD_CMD_RESET                                          0xFF    /* Reset */
+
+/*
+ *     Keyboard Replies
+ */
+
+#define KBD_REPLY_POR                                          0xAA    /* Power on reset */
+#define KBD_REPLY_ACK                                          0xFA    /* Command ACK */
+#define KBD_REPLY_RESEND                               0xFE    /* Command NACK, send the cmd again */
+
+/*
+ *     Status Register Bits
+ */
+
+#define KBD_STAT_OBF                                           0x01    /* Keyboard output buffer full */
+#define KBD_STAT_IBF                                           0x02    /* Keyboard input buffer full */
+#define KBD_STAT_SELFTEST                              0x04    /* Self test successful */
+#define KBD_STAT_CMD                                           0x08    /* Last write was a command write (0=data) */
+#define KBD_STAT_UNLOCKED                              0x10    /* Zero if keyboard locked */
+#define KBD_STAT_MOUSE_OBF                     0x20    /* Mouse output buffer full */
+#define KBD_STAT_GTO                                           0x40    /* General receive/xmit timeout */
+#define KBD_STAT_PERR                                  0x80    /* Parity error */
+
+#define AUX_STAT_OBF (KBD_STAT_OBF | KBD_STAT_MOUSE_OBF)
+
+/*
+ *     Controller Mode Register Bits
+ */
+
+#define KBD_MODE_KBD_INT                               0x01    /* Keyboard data generate IRQ1 */
+#define KBD_MODE_MOUSE_INT                     0x02    /* Mouse data generate IRQ12 */
+#define KBD_MODE_SYS                                           0x04    /* The system flag (?) */
+#define KBD_MODE_NO_KEYLOCK                    0x08    /* The keylock doesn't affect the keyboard if set */
+#define KBD_MODE_DISABLE_KBD           0x10    /* Disable keyboard interface */
+#define KBD_MODE_DISABLE_MOUSE 0x20    /* Disable mouse interface */
+#define KBD_MODE_KCC                                           0x40    /* Scan code conversion to PC format */
+#define KBD_MODE_RFU                                           0x80
+
+
+#define KDB_DATA_PORT                  0x60
+#define KDB_COMMAND_PORT       0x64
+
+#define        LED_SCR         0x01    /* scroll lock led */
+#define        LED_CAP         0x04    /* caps lock led */
+#define        LED_NUM         0x02    /* num lock led */
+
+#define        KBD_BUFFER_LEN 0x20  /* size of the keyboardbuffer */
+
+
+
+
+static volatile char kbd_buffer[KBD_BUFFER_LEN];
+static volatile int in_pointer = 0;
+static volatile int out_pointer = 0;
+
+
+static unsigned char num_lock = 0;
+static unsigned char caps_lock = 0;
+static unsigned char scroll_lock = 0;
+static unsigned char shift = 0;
+static unsigned char ctrl = 0;
+static unsigned char alt = 0;
+static unsigned char e0 = 0;
+static unsigned char leds = 0;
+
+/* Simple translation table for the keys */
+
+static unsigned char kbd_plain_xlate[] = {
+       0xff,0x1b, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=','\b','\t',        /* 0x00 - 0x0f */
+        'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']','\r',0xff, 'a', 's',        /* 0x10 - 0x1f */
+        'd', 'f', 'g', 'h', 'j', 'k', 'l', ';','\'', '`',0xff,'\\', 'z', 'x', 'c', 'v',        /* 0x20 - 0x2f */
+        'b', 'n', 'm', ',', '.', '/',0xff,0xff,0xff, ' ',0xff,0xff,0xff,0xff,0xff,0xff,        /* 0x30 - 0x3f */
+       0xff,0xff,0xff,0xff,0xff,0xff,0xff, '7', '8', '9', '-', '4', '5', '6', '+', '1',        /* 0x40 - 0x4f */
+        '2', '3', '0', '.',0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,  /* 0x50 - 0x5F */
+       '\r',0xff,0xff
+       };
+                 
+static unsigned char kbd_shift_xlate[] = {
+       0xff,0x1b, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+','\b','\t',        /* 0x00 - 0x0f */
+        'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}','\r',0xff, 'A', 'S',        /* 0x10 - 0x1f */
+        'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '"', '~',0xff, '|', 'Z', 'X', 'C', 'V',        /* 0x20 - 0x2f */
+        'B', 'N', 'M', '<', '>', '?',0xff,0xff,0xff, ' ',0xff,0xff,0xff,0xff,0xff,0xff,        /* 0x30 - 0x3f */
+       0xff,0xff,0xff,0xff,0xff,0xff,0xff, '7', '8', '9', '-', '4', '5', '6', '+', '1',        /* 0x40 - 0x4f */
+        '2', '3', '0', '.',0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,  /* 0x50 - 0x5F */
+       '\r',0xff,0xff
+       };
+
+static unsigned char kbd_ctrl_xlate[] = {
+       0xff,0x1b, '1',0x00, '3', '4', '5',0x1E, '7', '8', '9', '0',0x1F, '=','\b','\t',        /* 0x00 - 0x0f */
+       0x11,0x17,0x05,0x12,0x14,0x18,0x15,0x09,0x0f,0x10,0x1b,0x1d,'\n',0xff,0x01,0x13,        /* 0x10 - 0x1f */
+       0x04,0x06,0x08,0x09,0x0a,0x0b,0x0c, ';','\'', '~',0x00,0x1c,0x1a,0x18,0x03,0x16,        /* 0x20 - 0x2f */
+       0x02,0x0e,0x0d, '<', '>', '?',0xff,0xff,0xff,0x00,0xff,0xff,0xff,0xff,0xff,0xff,        /* 0x30 - 0x3f */
+       0xff,0xff,0xff,0xff,0xff,0xff,0xff, '7', '8', '9', '-', '4', '5', '6', '+', '1',        /* 0x40 - 0x4f */
+        '2', '3', '0', '.',0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,  /* 0x50 - 0x5F */
+       '\r',0xff,0xff
+       };
+
+
+
+/******************************************************************
+ * Init 
+ ******************************************************************/
+int isa_kbd_init(void)
+{
+       char* result;
+       result=kbd_initialize();
+       if(result==NULL) {
+               PRINTF("AT Keyboard initialized\n");
+               irq_install_handler(25, (interrupt_handler_t *)handle_isa_int, NULL);
+               isa_irq_install_handler(KBD_INTERRUPT, (interrupt_handler_t *)kbd_interrupt, NULL);
+               return (1);
+       }
+       else {
+               printf("%s\n",result);
+               return (-1);
+       }
+}
+
+int drv_isa_kbd_init (void)
+{
+  int error, devices = 1 ;
+  device_t kbddev ;
+
+       if(isa_kbd_init()==-1)
+               return -1;
+  memset (&kbddev, 0, sizeof(kbddev));
+  strcpy(kbddev.name, "kbd");
+  kbddev.flags =  DEV_FLAGS_INPUT | DEV_FLAGS_SYSTEM;
+  kbddev.putc = NULL ;
+  kbddev.puts = NULL ;
+  kbddev.getc = kbd_getc ;
+  kbddev.tstc = kbd_testc ;
+
+  error = device_register (&kbddev);
+       
+  return (error == 0) ? devices : error ;
+}
+
+/******************************************************************
+ * Queue handling 
+ ******************************************************************/
+/* puts character in the queue and sets up the in and out pointer */
+void kbd_put_queue(char data)
+{
+       if((in_pointer+1)==KBD_BUFFER_LEN) {
+               if(out_pointer==0) {
+                       return; /* buffer full */
+               } else{
+                       in_pointer=0;
+               }
+       } else {
+               if((in_pointer+1)==out_pointer)
+                       return; /* buffer full */
+               in_pointer++;
+       }
+       kbd_buffer[in_pointer]=data;
+       return;
+}
+
+/* test if a character is in the queue */
+int kbd_testc(void)
+{
+       if(in_pointer==out_pointer)
+               return(0); /* no data */
+       else
+               return(1);      
+}
+/* gets the character from the queue */
+int kbd_getc(void)
+{
+       char c;
+       while(in_pointer==out_pointer);
+       if((out_pointer+1)==KBD_BUFFER_LEN) 
+               out_pointer=0;
+       else
+               out_pointer++;
+       c=kbd_buffer[out_pointer];
+       return (int)c;
+       
+}
+
+
+/* set LEDs */
+
+void kbd_set_leds(void)
+{
+       if(caps_lock==0)
+               leds&=~LED_CAP; /* switch caps_lock off */
+       else
+               leds|=LED_CAP; /* switch on LED */
+       if(num_lock==0)
+               leds&=~LED_NUM; /* switch LED off */
+       else
+               leds|=LED_NUM;  /* switch on LED */
+       if(scroll_lock==0)
+               leds&=~LED_SCR; /* switch LED off */
+       else
+               leds|=LED_SCR; /* switch on LED */
+       kbd_send_data(KBD_CMD_SET_LEDS);
+       kbd_send_data(leds);
+}
+       
+
+void handle_keyboard_event(unsigned char scancode)
+{
+       unsigned char keycode;
+
+       /*  Convert scancode to keycode */
+       PRINTF("scancode %x\n",scancode);
+       if(scancode==0xe0) {
+               e0=1; /* special charakters */
+               return;
+       }
+       if(e0==1) {
+               e0=0; /* delete flag */
+               if(!(   ((scancode&0x7F)==0x38)|| /* the right ctrl key */
+                                       ((scancode&0x7F)==0x1D)|| /* the right alt key */
+                                       ((scancode&0x7F)==0x35)||       /* the right '/' key */
+                                       ((scancode&0x7F)==0x1C) ))  /* the right enter key */
+                       /* we swallow unknown e0 codes */
+                       return;
+       }
+       /* special cntrl keys */
+       switch(scancode)
+       {
+               case 0x2A: 
+               case 0x36: /* shift pressed */
+                       shift=1;
+                       return; /* do nothing else */
+               case 0xAA: 
+               case 0xB6: /* shift released */
+                       shift=0;
+                       return; /* do nothing else */
+               case 0x38: /* alt pressed */
+                       alt=1;
+                       return; /* do nothing else */
+               case 0xB8: /* alt released */
+                       alt=0;
+                       return; /* do nothing else */
+               case 0x1d: /* ctrl pressed */
+                       ctrl=1;
+                       return; /* do nothing else */
+               case 0x9d: /* ctrl released */
+                       ctrl=0;
+                       return; /* do nothing else */
+               case 0x46: /* scrollock pressed */
+                       scroll_lock=~scroll_lock;
+                       kbd_set_leds();
+                       return; /* do nothing else */
+               case 0x3A: /* capslock pressed */
+                       caps_lock=~caps_lock;
+                       kbd_set_leds();
+                       return; 
+               case 0x45: /* numlock pressed */
+                       num_lock=~num_lock;
+                       kbd_set_leds();
+                       return; 
+               case 0xC6: /* scroll lock released */
+               case 0xC5: /* num lock released */
+               case 0xBA: /* caps lock released */
+                       return; /* just swallow */ 
+       }
+       if((scancode&0x80)==0x80) /* key released */
+               return;
+       /* now, decide which table we need */
+       if(scancode > (sizeof(kbd_plain_xlate)/sizeof(kbd_plain_xlate[0]))) { /* scancode not in list */
+               PRINTF("unkown scancode %X\n",scancode);
+               return; /* swallow it */
+       }
+       /* setup plain code first */
+       keycode=kbd_plain_xlate[scancode];
+       if(caps_lock==1) { /* caps_lock is pressed, overwrite plain code */
+               if(scancode > (sizeof(kbd_shift_xlate)/sizeof(kbd_shift_xlate[0]))) { /* scancode not in list */
+                       PRINTF("unkown caps-locked scancode %X\n",scancode);
+                       return; /* swallow it */
+               }
+               keycode=kbd_shift_xlate[scancode];
+               if(keycode<'A') { /* we only want the alphas capital */
+                       keycode=kbd_plain_xlate[scancode];
+               }
+       }
+       if(shift==1) { /* shift overwrites caps_lock */
+               if(scancode > (sizeof(kbd_shift_xlate)/sizeof(kbd_shift_xlate[0]))) { /* scancode not in list */
+                       PRINTF("unkown shifted scancode %X\n",scancode);
+                       return; /* swallow it */
+               }
+               keycode=kbd_shift_xlate[scancode];
+       }
+       if(ctrl==1) { /* ctrl overwrites caps_lock and shift */
+               if(scancode > (sizeof(kbd_ctrl_xlate)/sizeof(kbd_ctrl_xlate[0]))) { /* scancode not in list */
+                       PRINTF("unkown ctrl scancode %X\n",scancode);
+                       return; /* swallow it */
+               }
+               keycode=kbd_ctrl_xlate[scancode];
+       }
+       /* check if valid keycode */
+       if(keycode==0xff) {
+               PRINTF("unkown scancode %X\n",scancode);
+               return; /* swallow unknown codes */
+       }
+       
+       kbd_put_queue(keycode);
+       PRINTF("%x\n",keycode);
+}
+
+/*
+ * This reads the keyboard status port, and does the
+ * appropriate action.
+ *
+ */
+unsigned char handle_kbd_event(void)
+{
+       unsigned char status = kbd_read_status();
+       unsigned int work = 10000;
+
+       while ((--work > 0) && (status & KBD_STAT_OBF)) {
+               unsigned char scancode;
+
+               scancode = kbd_read_input();
+
+               /* Error bytes must be ignored to make the
+                  Synaptics touchpads compaq use work */
+               /* Ignore error bytes */
+               if (!(status & (KBD_STAT_GTO | KBD_STAT_PERR)))
+               {
+                       if (status & KBD_STAT_MOUSE_OBF)
+                               ; /* not supported: handle_mouse_event(scancode); */
+                       else
+                               handle_keyboard_event(scancode);
+               }
+               status = kbd_read_status();
+       }
+       if (!work)
+               PRINTF("pc_keyb: controller jammed (0x%02X).\n", status);
+       return status;
+}
+
+
+
+/******************************************************************************
+ * Lowlevel Part of keyboard section
+ */  
+unsigned char kbd_read_status(void)
+{
+       return(in8(CFG_ISA_IO_BASE_ADDRESS + KDB_COMMAND_PORT));
+} 
+  
+unsigned char kbd_read_input(void)
+{
+       return(in8(CFG_ISA_IO_BASE_ADDRESS + KDB_DATA_PORT));
+} 
+
+void kbd_write_command(unsigned char cmd)
+{
+       out8(CFG_ISA_IO_BASE_ADDRESS + KDB_COMMAND_PORT,cmd);
+} 
+  
+void kbd_write_output(unsigned char data)
+{
+       out8(CFG_ISA_IO_BASE_ADDRESS + KDB_DATA_PORT, data);
+} 
+int kbd_read_data(void)
+{
+       int val;
+       unsigned char status;
+
+       val=-1;
+       status = kbd_read_status();
+       if (status & KBD_STAT_OBF) {
+               val = kbd_read_input();
+               if (status & (KBD_STAT_GTO | KBD_STAT_PERR))
+                       val = -2;
+       }
+       return val;
+}
+
+int kbd_wait_for_input(void)
+{
+       unsigned long timeout;
+       int val;
+       
+       timeout = KBD_TIMEOUT;
+       val=kbd_read_data();
+       while(val < 0)
+       {
+               if(timeout--==0)
+                       return -1;
+               udelay(1000);
+               val=kbd_read_data();
+       }
+       return val;
+}
+
+void kb_wait(void)
+{
+       unsigned long timeout = KBC_TIMEOUT;
+
+       do {
+               unsigned char status = handle_kbd_event();
+               if (! (status & KBD_STAT_IBF))
+                       return;
+               udelay(50000);
+               timeout--;
+       } while (timeout);
+}
+
+void kbd_write_command_w(int data)
+{
+       kb_wait();
+       kbd_write_command(data);
+}
+
+void kbd_write_output_w(int data)
+{
+       kb_wait();
+       kbd_write_output(data);
+}
+
+void kbd_send_data(unsigned char data)
+{
+       unsigned char status;
+       disable_8259A_irq(1); /* disable interrupt */
+       kbd_write_output_w(data);
+       status = kbd_wait_for_input();
+       if (status == KBD_REPLY_ACK)
+               enable_8259A_irq(1); /* enable interrupt */
+}
+
+
+char * kbd_initialize(void)
+{
+       int status;
+
+       in_pointer = 0; /* delete in Buffer */
+       out_pointer = 0;
+       /*
+        * Test the keyboard interface.
+        * This seems to be the only way to get it going.
+        * If the test is successful a x55 is placed in the input buffer.
+        */
+       kbd_write_command_w(KBD_CCMD_SELF_TEST);
+       if (kbd_wait_for_input() != 0x55) 
+               return "Keyboard failed self test";
+       /*
+        * Perform a keyboard interface test.  This causes the controller
+        * to test the keyboard clock and data lines.  The results of the
+        * test are placed in the input buffer.
+        */
+       kbd_write_command_w(KBD_CCMD_KBD_TEST);
+       if (kbd_wait_for_input() != 0x00) 
+               return "Keyboard interface failed self test";
+       /*
+        * Enable the keyboard by allowing the keyboard clock to run.
+        */
+       kbd_write_command_w(KBD_CCMD_KBD_ENABLE);
+       /*
+        * Reset keyboard. If the read times out
+        * then the assumption is that no keyboard is
+        * plugged into the machine.
+        * This defaults the keyboard to scan-code set 2.
+        *
+        * Set up to try again if the keyboard asks for RESEND.
+        */
+       do {
+               kbd_write_output_w(KBD_CMD_RESET);
+               status = kbd_wait_for_input();
+               if (status == KBD_REPLY_ACK)
+                       break;
+               if (status != KBD_REPLY_RESEND)
+               {
+                       PRINTF("status: %X\n",status);
+                       return "Keyboard reset failed, no ACK";
+               }
+       } while (1);
+
+       if (kbd_wait_for_input() != KBD_REPLY_POR)
+               return "Keyboard reset failed, no POR";
+
+       /*
+        * Set keyboard controller mode. During this, the keyboard should be
+        * in the disabled state.
+        *
+        * Set up to try again if the keyboard asks for RESEND.
+        */
+       do {
+               kbd_write_output_w(KBD_CMD_DISABLE);
+               status = kbd_wait_for_input();
+               if (status == KBD_REPLY_ACK)
+                       break;
+               if (status != KBD_REPLY_RESEND)
+                       return "Disable keyboard: no ACK";
+       } while (1);
+
+       kbd_write_command_w(KBD_CCMD_WRITE_MODE);
+       kbd_write_output_w(KBD_MODE_KBD_INT
+                             | KBD_MODE_SYS
+                             | KBD_MODE_DISABLE_MOUSE
+                             | KBD_MODE_KCC);
+
+       /* ibm powerpc portables need this to use scan-code set 1 -- Cort */
+       kbd_write_command_w(KBD_CCMD_READ_MODE);
+       if (!(kbd_wait_for_input() & KBD_MODE_KCC)) {
+               /*
+                * If the controller does not support conversion,
+                * Set the keyboard to scan-code set 1.
+                */
+               kbd_write_output_w(0xF0);
+               kbd_wait_for_input();
+               kbd_write_output_w(0x01);
+               kbd_wait_for_input();
+       }
+       kbd_write_output_w(KBD_CMD_ENABLE);
+       if (kbd_wait_for_input() != KBD_REPLY_ACK)
+               return "Enable keyboard: no ACK";
+
+       /*
+        * Finally, set the typematic rate to maximum.
+        */
+       kbd_write_output_w(KBD_CMD_SET_RATE);
+       if (kbd_wait_for_input() != KBD_REPLY_ACK)
+               return "Set rate: no ACK";
+       kbd_write_output_w(0x00);
+       if (kbd_wait_for_input() != KBD_REPLY_ACK)
+               return "Set rate: no ACK";
+       return NULL;
+}
+
+void kbd_interrupt(void)
+{
+       handle_kbd_event();
+}
+
+
+
+/* eof */
+
diff --git a/board/pip405/kbd.h b/board/pip405/kbd.h
new file mode 100644 (file)
index 0000000..e2cdf37
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * (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
+ *
+ */
+
+#ifndef _KBD_H_
+#define _KBD_H_
+   
+extern int kbd_testc(void);
+extern int kbd_getc(void);
+extern void kbd_interrupt(void);
+extern char *kbd_initialize(void);
+
+unsigned char kbd_is_init(void);
+#define KBD_INTERRUPT 1
+#endif
diff --git a/board/pip405/pci_piix4.h b/board/pip405/pci_piix4.h
new file mode 100644 (file)
index 0000000..2974fc2
--- /dev/null
@@ -0,0 +1,179 @@
+/*
+ * (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
+ *
+ *
+ */
+#ifndef _PCI_PIXX4_H
+#define _PCI_PIXX4_H
+
+/***************************************************************************
+* Defines PIIX4 Config Registers
+****************************************************************************/
+
+/* Function 0 ISA Bridge */
+#define        PCI_CFG_PIIX4_IORT              0x4C    /* 8 bit ISA Recovery Timer Reg (default 0x4D) */
+#define        PCI_CFG_PIIX4_XBCS              0x4E    /* 16 bit XBus Chip select reg (default 0x0003) */
+#define        PCI_CFG_PIIX4_PIRQC             0x60  /* PCI IRQ Route Register 4 x 8bit (default )*/
+#define        PCI_CFG_PIIX4_SERIRQ    0x64
+#define        PCI_CFG_PIIX4_TOM                       0x69
+#define        PCI_CFG_PIIX4_MSTAT             0x6A
+#define        PCI_CFG_PIIX4_MBDMA             0x76
+#define        PCI_CFG_PIIX4_APICBS    0x80
+#define        PCI_CFG_PIIX4_DLC                       0x82
+#define        PCI_CFG_PIIX4_PDMACFG   0x90
+#define        PCI_CFG_PIIX4_DDMABS    0x92
+#define        PCI_CFG_PIIX4_GENCFG    0xB0
+#define        PCI_CFG_PIIX4_RTCCFG    0xCB
+
+/* IO Addresses */
+#define PIIX4_ISA_DMA1_CH0BA   0x00
+#define PIIX4_ISA_DMA1_CH0CA   0x01
+#define PIIX4_ISA_DMA1_CH1BA   0x02
+#define PIIX4_ISA_DMA1_CH1CA   0x03
+#define PIIX4_ISA_DMA1_CH2BA   0x04
+#define PIIX4_ISA_DMA1_CH2CA   0x05
+#define PIIX4_ISA_DMA1_CH3BA   0x06
+#define PIIX4_ISA_DMA1_CH3CA   0x07
+#define PIIX4_ISA_DMA1_CMDST   0x08
+#define PIIX4_ISA_DMA1_REQ             0x09
+#define PIIX4_ISA_DMA1_WSBM            0x0A
+#define PIIX4_ISA_DMA1_CH_MOD  0x0B
+#define PIIX4_ISA_DMA1_CLR_PT  0x0C
+#define PIIX4_ISA_DMA1_M_CLR   0x0D
+#define PIIX4_ISA_DMA1_CLR_M   0x0E
+#define PIIX4_ISA_DMA1_RWAMB   0x0F
+
+#define PIIX4_ISA_DMA2_CH0BA   0xC0
+#define PIIX4_ISA_DMA2_CH0CA   0xC1
+#define PIIX4_ISA_DMA2_CH1BA   0xC2
+#define PIIX4_ISA_DMA2_CH1CA   0xC3
+#define PIIX4_ISA_DMA2_CH2BA   0xC4
+#define PIIX4_ISA_DMA2_CH2CA   0xC5
+#define PIIX4_ISA_DMA2_CH3BA   0xC6
+#define PIIX4_ISA_DMA2_CH3CA   0xC7
+#define PIIX4_ISA_DMA2_CMDST   0xD0
+#define PIIX4_ISA_DMA2_REQ             0xD2
+#define PIIX4_ISA_DMA2_WSBM            0xD4
+#define PIIX4_ISA_DMA2_CH_MOD  0xD6
+#define PIIX4_ISA_DMA2_CLR_PT  0xD8
+#define PIIX4_ISA_DMA2_M_CLR   0xDA
+#define PIIX4_ISA_DMA2_CLR_M   0xDC
+#define PIIX4_ISA_DMA2_RWAMB   0xDE
+
+#define PIIX4_ISA_INT1_ICW1            0x20
+#define PIIX4_ISA_INT1_OCW2            0x20
+#define PIIX4_ISA_INT1_OCW3            0x20
+#define PIIX4_ISA_INT1_ICW2            0x21
+#define PIIX4_ISA_INT1_ICW3            0x21
+#define PIIX4_ISA_INT1_ICW4            0x21
+#define PIIX4_ISA_INT1_OCW1            0x21
+
+#define PIIX4_ISA_INT1_ELCR            0x4D0
+
+#define PIIX4_ISA_INT2_ICW1            0xA0 
+#define PIIX4_ISA_INT2_OCW2            0xA0
+#define PIIX4_ISA_INT2_OCW3            0xA0
+#define PIIX4_ISA_INT2_ICW2            0xA1
+#define PIIX4_ISA_INT2_ICW3            0xA1
+#define PIIX4_ISA_INT2_ICW4            0xA1
+#define PIIX4_ISA_INT2_OCW1            0xA1
+#define PIIX4_ISA_INT2_IMR             0xA1 /* read only */
+
+#define PIIX4_ISA_INT2_ELCR            0x4D1
+
+#define PIIX4_ISA_TMR0_CNT_ST  0x40
+#define PIIX4_ISA_TMR1_CNT_ST  0x41
+#define PIIX4_ISA_TMR2_CNT_ST  0x42
+#define PIIX4_ISA_TMR_TCW                      0x43
+
+#define PIIX4_ISA_RST_XBUS             0x60
+
+#define PIIX4_ISA_NMI_CNT_ST   0x61
+#define PIIX4_ISA_NMI_ENABLE   0x70
+
+#define PIIX4_ISA_RTC_INDEX            0x70
+#define PIIX4_ISA_RTC_DATA             0x71
+#define PIIX4_ISA_RTCEXT_IND   0x70
+#define PIIX4_ISA_RTCEXT_DATA  0x71
+
+#define PIIX4_ISA_DMA1_CH2LPG  0x81
+#define PIIX4_ISA_DMA1_CH3LPG  0x82
+#define PIIX4_ISA_DMA1_CH1LPG  0x83
+#define PIIX4_ISA_DMA1_CH0LPG  0x87
+#define PIIX4_ISA_DMA2_CH2LPG  0x89
+#define PIIX4_ISA_DMA2_CH3LPG  0x8A
+#define PIIX4_ISA_DMA2_CH1LPG  0x8B
+#define PIIX4_ISA_DMA2_LPGRFR  0x8F
+
+#define PIIX4_ISA_PORT_92                      0x92
+
+#define PIIX4_ISA_APM_CONTRL   0xB2
+#define PIIX4_ISA_APM_STATUS   0xB3
+
+#define PIIX4_ISA_COCPU_ERROR  0xF0
+
+/* Function 1 IDE Controller */
+#define        PCI_CFG_PIIX4_BMIBA             0x20
+#define        PCI_CFG_PIIX4_IDETIM    0x40
+#define        PCI_CFG_PIIX4_SIDETIM   0x44
+#define        PCI_CFG_PIIX4_UDMACTL   0x48
+#define        PCI_CFG_PIIX4_UDMATIM 0x4A
+
+/* Function 2 USB Controller */
+#define        PCI_CFG_PIIX4_SBRNUM    0x60
+#define        PCI_CFG_PIIX4_LEGSUP    0xC0
+
+/* Function 3 Power Management */
+#define        PCI_CFG_PIIX4_PMAB              0x40
+#define        PCI_CFG_PIIX4_CNTA              0x44
+#define        PCI_CFG_PIIX4_CNTB              0x48
+#define        PCI_CFG_PIIX4_GPICTL    0x4C
+#define        PCI_CFG_PIIX4_DEVRESD   0x50
+#define        PCI_CFG_PIIX4_DEVACTA   0x54
+#define        PCI_CFG_PIIX4_DEVACTB   0x58
+#define        PCI_CFG_PIIX4_DEVRESA   0x5C
+#define        PCI_CFG_PIIX4_DEVRESB   0x60
+#define        PCI_CFG_PIIX4_DEVRESC   0x64
+#define        PCI_CFG_PIIX4_DEVRESE   0x68
+#define        PCI_CFG_PIIX4_DEVRESF   0x6C
+#define        PCI_CFG_PIIX4_DEVRESG   0x70
+#define        PCI_CFG_PIIX4_DEVRESH   0x74
+#define        PCI_CFG_PIIX4_DEVRESI   0x78
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#endif
+
diff --git a/board/pip405/pci_pip405.c b/board/pip405/pci_pip405.c
new file mode 100644 (file)
index 0000000..e4dbd33
--- /dev/null
@@ -0,0 +1,1505 @@
+/*-----------------------------------------------------------------------------+
+|
+|       This source code has been made available to you by IBM on an AS-IS
+|       basis.  Anyone receiving this source is licensed under IBM
+|       copyrights to use it in any way he or she deems fit, including
+|       copying it, modifying it, compiling it, and redistributing it either
+|       with or without modifications.  No license under IBM patents or
+|       patent applications is to be implied by the copyright license.
+|
+|       Any user of this software should understand that IBM cannot provide
+|       technical support for this software and will not be responsible for
+|       any consequences resulting from the use of this software.
+|
+|       Any person who transfers this source code or any derivative work
+|       must include the IBM copyright notice, this paragraph, and the
+|       preceding two paragraphs in the transferred software.
+|
+|       COPYRIGHT   I B M   CORPORATION 1995
+|       LICENSED MATERIAL  -  PROGRAM PROPERTY OF I B M
++-----------------------------------------------------------------------------*/
+/*
+ * Adopted for PIP405 03.07.01
+ * Denis Peter, MPL AG Switzerland, d.peter@mpl.ch
+ *
+ * TODO: Clean-up
+ */
+
+#include <ppcboot.h>
+#include <command.h>
+#include <cmd_boot.h>
+#include "pci_pip405.h"
+#include <asm/processor.h>
+#include "pci_piix4.h"
+#include "pip405_isa.h"
+#include "pip405.h"
+#include <scsi.h>
+#include "video.h"
+
+
+void pciinfo(int bus_no);
+#ifdef CONFIG_PPC405GP
+
+#ifdef CONFIG_PCI
+
+#undef PCI_DEBUG
+
+/*------------------------------------------------------------------------
+| 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 = MIN_PCI_MEMADDR1;
+unsigned long    LowestMemAddr2 = MIN_PCI_MEMADDR2;
+unsigned long    LowestIOAddr   = MIN_PCI_PCI_IOADDR1;
+
+unsigned long    MaxBusNum = 0;
+
+
+
+void PCI_Config_SCSI_contrl(int BusDevFunc); /* forward declaration */
+
+
+/*-----------------------------------------------------------------------------+
+| pci_init.  Initializes the 405GP PCI Configuration regs.
++-----------------------------------------------------------------------------*/
+void pci_init(void)
+{
+   unsigned short temp_short;
+
+#ifdef CONFIG_PCI_HOST
+   /*--------------------------------------------------------------------------+
+   | 405GP PCI Master configuration.
+   | Map one 512 MB range of PLB/processor addresses to PCI memory space.
+   |   PLB address 0x80000000-0x9FFFFFFF ==> PCI address 0x80000000-0x9FFFFFFF
+   |   Use byte reversed out routines to handle endianess.
+   +--------------------------------------------------------------------------*/
+   out32r(PMM0MA,    0x00000000);        /* ensure disabled b4 setting PMM0LA */
+   out32r(PMM0LA,    PCI_M0_LOCAL_ADDR);
+   out32r(PMM0PCILA, PCI_M0_PCI_LOW_ADDR);
+   out32r(PMM0PCIHA, PCI_M0_PCI_HIGH_ADDR);
+   out32r(PMM0MA,    PCI_M0_MASK_ATTRIB);        /* no prefetching, and enable region */
+   /*--------------------------------------------------------------------------+
+   | Map one 512 MB range of PLB/processor addresses to PCI memory space.
+   |   PLB address 0xA0000000-0xBFFFFFFF ==> PCI address 0x00000000-0x1FFFFFFF
+   |   Use byte reversed out routines to handle endianess.
+   | This space is for the VGA card.
+   +--------------------------------------------------------------------------*/
+   out32r(PMM1MA,    0x00000000);        /* ensure disabled b4 setting PMM1LA */
+   out32r(PMM1LA,    PCI_M1_LOCAL_ADDR);
+   out32r(PMM1PCILA, PCI_M1_PCI_LOW_ADDR);
+   out32r(PMM1PCIHA, PCI_M1_PCI_HIGH_ADDR);
+   out32r(PMM1MA,    PCI_M1_MASK_ATTRIB);        /* no prefetching, and enable region */
+   /*--------------------------------------------------------------------------+
+   | PMM2 is not used.  Initialize them to zero.
+   +--------------------------------------------------------------------------*/
+   out32r(PMM2MA,    0x00000000);        /* ensure disabled b4 setting PMM2LA */
+   out32r(PMM2LA,    PCI_M2_LOCAL_ADDR);
+   out32r(PMM2PCILA, PCI_M2_PCI_LOW_ADDR);
+   out32r(PMM2PCIHA, PCI_M2_PCI_HIGH_ADDR);
+   out32r(PMM2MA,    PCI_M2_MASK_ATTRIB);        /* not enabled */
+#endif
+
+   /*--------------------------------------------------------------------------+
+   | 405GP PCI Target configuration.  (PTM1)
+   | Note: PTM1MS is hardwire enabled but we set the enable bit anyway.
+   +--------------------------------------------------------------------------*/
+   out32r(PTM1LA,    CFG_PCI_PTM1LA);   /* insert address                     */
+   out32r(PTM1MS,    CFG_PCI_PTM1MS);   /* insert size, enable bit is 1       */
+
+   /*--------------------------------------------------------------------------+
+   | 405GP PCI Target configuration.  (PTM2)
+   +--------------------------------------------------------------------------*/
+   out32r(PTM2LA,    CFG_PCI_PTM2LA);   /* insert address                     */
+   if (CFG_PCI_PTM2MS == 0)
+     {
+       out32r(PTM2MS,    0x00000001);   /* set enable bit                     */
+       PCI_Write_CFG_Reg(PCIDEVID_405GP, PCIBASEADDR2, 0x00000000, 4);
+       out32r(PTM2MS,    0x00000000);   /* disable                            */
+     }
+   else
+     out32r(PTM2MS,    CFG_PCI_PTM2MS); /* insert size, enable bit is 1       */
+
+   /*
+    * Insert Subsystem Vendor and Device ID
+    */
+   PCI_Write_CFG_Reg(PCIDEVID_405GP, PCISSVENDORID, CFG_PCI_SUBSYS_VENDORID, 2);
+   PCI_Write_CFG_Reg(PCIDEVID_405GP, PCISSDEVICEID, CFG_PCI_SUBSYS_DEVICEID, 2);
+
+#ifdef CONFIG_PCI_HOST
+   /*--------------------------------------------------------------------------+
+   | Write the 405GP PCI Configuration regs.
+   |   Enable 405GP to be a master on the PCI bus (PMM).
+   |   Enable 405GP to act as a PCI memory target (PTM).
+   +--------------------------------------------------------------------------*/
+   temp_short = PCI_Read_CFG_Reg(PCIDEVID_405GP, PCICMD, 2);
+   PCI_Write_CFG_Reg(PCIDEVID_405GP, PCICMD, temp_short | BM_EN | MEM_EN, 2);
+#endif
+
+#if 0  /* test-only: no need yet! */
+   /*--------------------------------------------------------------------------+
+   | If PCI speed = 66Mhz, set 66Mhz capable bit.
+   +--------------------------------------------------------------------------*/
+   if (board_cfg.pci_speed==66666666) {
+      temp_short = PCI_Read_CFG_Reg(PCIDEVID_405GP, PCISTATUS, 2);
+      PCI_Write_CFG_Reg(PCIDEVID_405GP,PCISTATUS,(temp_short|CAPABLE_66MHZ), 2);
+   }
+#endif
+
+   /*
+    * Set HCE bit (Host Configuration Enabled)
+    */
+   temp_short = PCI_Read_CFG_Reg(PCIDEVID_405GP, PCIBRDGOPT2, 2);
+   PCI_Write_CFG_Reg(PCIDEVID_405GP, PCIBRDGOPT2,(temp_short | 0x0001), 2);
+
+#ifdef CONFIG_PCI_PNP
+   /*--------------------------------------------------------------------------+
+   | Scan the PCI bus and configure devices found.
+   +--------------------------------------------------------------------------*/
+#if 0
+   pciScanForDevices(0);
+#endif
+   PCI_Scan(0);
+   isa_sio_setup();
+   
+#endif  /* CONFIG_PCI_PNP */
+
+}
+
+/*-----------------------------------------------------------------------------+
+|  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:
+|               (unsigned int)  Value of the configuration register read.
+|                      For reads shorter than 4 bytes, return value
+|                      is LSB-justified
++-----------------------------------------------------------------------------*/
+unsigned long     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 = 0x80000000 | ((Reg|BusDevFunc) & 0xFFFFFFFC);
+
+   /*--------------------------------------------------------------------------+
+   | Write reg to PCI Config Address
+   +--------------------------------------------------------------------------*/
+   out32r(PCICFGADR, RegAddr);
+
+   /*--------------------------------------------------------------------------+
+   | Read reg value from PCI Config Data
+   +--------------------------------------------------------------------------*/
+   switch (Width)
+   {
+      case 1: return ((unsigned int) in8(PCICFGDATA | (Reg & 0x3)));
+      case 2: return ((unsigned int) in16r(PCICFGDATA | (Reg & 0x3)));
+      case 4: return (in32r(PCICFGDATA | (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 value:
+|               0       Successful
+| Updated for pass2 errata #6. Need to disable interrupts and clear the
+| PCICFGADR reg after writing the PCICFGDATA reg.  
++-----------------------------------------------------------------------------*/
+int    PCI_Write_CFG_Reg(int BusDevFunc, int Reg, unsigned long Value, int Width)
+{
+   unsigned int    RegAddr;
+   unsigned int    msr;
+
+   /*--------------------------------------------------------------------------+
+   | Ensure interrupts disabled for pass2 errata #6.
+   +--------------------------------------------------------------------------*/
+   msr = mfmsr();
+   mtmsr(msr & ~(MSR_EE|MSR_CE));
+
+   /*--------------------------------------------------------------------------+
+   | bit 31 must be 1 and bits 1:0 must be 0 (note Little Endian bit notation)
+   +--------------------------------------------------------------------------*/
+   RegAddr = 0x80000000 | ((Reg|BusDevFunc) & 0xFFFFFFFC);
+
+   /*--------------------------------------------------------------------------+
+   | Write reg to PCI Config Address
+   +--------------------------------------------------------------------------*/
+   out32r(PCICFGADR, RegAddr);
+
+   /*--------------------------------------------------------------------------+
+   | Write reg value to PCI Config Data
+   +--------------------------------------------------------------------------*/
+   switch (Width)
+   {
+      case 1: out8(PCICFGDATA | (Reg & 0x3), (unsigned char)(Value & 0xFF));
+              break;
+      case 2: out16r(PCICFGDATA | (Reg & 0x3),(unsigned short)(Value & 0xFFFF));
+              break;
+      case 4: out32r(PCICFGDATA | (Reg & 0x3), Value);
+              break;
+   }
+
+   /*--------------------------------------------------------------------------+
+   | Write PCI Config Address after writing PCICFGDATA for pass2 errata #6.
+   +--------------------------------------------------------------------------*/
+   out32r(PCICFGADR, 0x00000000);
+
+   /*--------------------------------------------------------------------------+
+   | Restore msr (for pass2 errata #6).
+   +--------------------------------------------------------------------------*/
+   mtmsr(msr);
+
+   return (0);
+}
+
+/*-----------------------------------------------------------------------
+|
+|  Subroutine:  PCI_Scan
+|
+|  Prototype:   void    PCI_Scan(int BusNum)
+|
+|  Description: Scan through all 16 allowable PCI IDs and configure
+|               those for which the vendor ID indicates there is a
+|               device present.
+|
+|  Inputs:
+|               BusNum  Bus number where scanning begins
+|
+|  Return value:
+|               None
+|
++----------------------------------------------------------------------*/
+void    PCI_Scan(int BusNum)
+{
+   int                     Device;
+   int                     BusDevFunc;
+        int    isabridgeDev;
+   /*--------------------------------------------------------------------------+
+   | Start with device 1, the 405GP is device 0.  MCG 01/04/99
+   +--------------------------------------------------------------------------*/
+        /***************************************************************************
+        * Since the IO and Memory Area of the ISA Bridge is not relocable, config it
+        * first.
+        ****************************************************************************/
+   isabridgeDev=0;
+   for (Device = 1; Device < MAX_PCI_DEVICES; Device++)
+   {
+      BusDevFunc = (BusNum << 16) | (Device << 11);
+
+      if (PCI_Read_CFG_Reg(BusDevFunc, PCIVENDORID,2) != 0xFFFF)
+      {
+         if(PCI_Read_CFG_Reg(BusDevFunc, PCICLASSCODE,2) == 0x0601)
+         {
+                                               isabridgeDev=Device;
+            PCI_Config_ISABridge(BusDevFunc);
+                               break; /* do not scan further  */
+                                       }
+                       }
+               }
+   /*--------------------------------------------------------------------------+
+   | Start with device 1, the 405GP is device 0.  MCG 01/04/99
+   +--------------------------------------------------------------------------*/
+   for (Device = 1; Device < MAX_PCI_DEVICES; Device++)
+   {
+      if(Device==isabridgeDev)
+       continue; /* skip ISA Bridge */
+      BusDevFunc = (BusNum << 16) | (Device << 11);
+
+      if (PCI_Read_CFG_Reg(BusDevFunc, PCIVENDORID,2) != 0xFFFF)
+      {
+#ifdef PCI_DEBUG
+         printf("Device %d is present\n",Device);
+#endif
+         switch( PCI_Read_CFG_Reg(BusDevFunc, PCICLASSCODE, 2) )
+         {
+            case 0x0604:   /*  PCI-PCI Bridge */
+#ifdef PCI_DEBUG
+                               printf("Device %d is PCI Bridge\n",Device);
+#endif
+                        PCI_Config_Device(BusDevFunc, 2);
+               PCI_Config_Bridge(BusDevFunc);
+               break;
+            case 0x0100:   /*  PCI-PCI Bridge */
+#ifdef PCI_DEBUG
+                               printf("Device %d is SCSI Controller\n",Device);
+#endif
+               PCI_Config_SCSI_contrl(BusDevFunc);
+               break;
+
+            case 0x0300:   /*  VGA Display controller */
+            case 0x0001:   /*  VGA Display controller (pre PCI rev 2.0)*/
+#ifdef PCI_DEBUG
+                               printf("Device %d is VGA\n",Device);
+#endif
+               PCI_Config_VGA_contrl(BusDevFunc);
+               break;
+
+            default:
+#ifdef PCI_DEBUG
+                               printf("Device %d is a 0x%04X\n",Device,PCI_Read_CFG_Reg(BusDevFunc, PCICLASSCODE, 2));
+#endif
+/*               PCI_Config_Device(BusDevFunc, 6); */
+         }
+      }
+      else
+      {
+#ifdef DEBUG
+         printf("Device %d not present\n",Device);
+#endif
+      }
+   }
+}
+
+/* ISA Bus (logical device 0) */
+static PCI_CFG_TABLE piix4_fn0[] = {
+       {PCI_CFG_PIIX4_SERIRQ, 0xD0,       1},/* enable Continous SERIRQ Pin */
+       {PCI_CFG_PIIX4_GENCFG, 0x00010000, 4},/* enable SERIRQs  */
+       {PCI_CFG_PIIX4_XBCS,                     0x0000, 2}, /* disable all peri CS */
+       {PCI_CFG_PIIX4_RTCCFG,       0x21, 1}, /* enable RTC       */
+       {0xFFFF, 0,0}                           /* end of device table */
+};
+/* IDE Controller (logical device 1) */
+static PCI_CFG_TABLE piix4_fn1[] = {
+       {PCI_CFG_COMMAND,      0x0001,     2},/* enable IO access */
+       {PCI_CFG_PIIX4_IDETIM, 0x80008000, 4},/* enable Both IDE channels        */       
+       {0xFFFF, 0,0}                           /* end of device table */
+};
+
+
+
+/*-----------------------------------------------------------------------
+|  Subroutine:  PCI_Config_ISABridge
+|
+|  Description: Configure a PCI to ISA Bridge
+|               Since there address space is not relocable, we have 
+|                                                        to set it up manually
+|
+|  Inputs:
+|               BusDevFunc    Bus+Device+Function number
+|  Return value:
+|               None
++----------------------------------------------------------------------*/
+void PCI_Config_ISABridge(int BusDevFunc)
+{
+
+    PCI_CFG_TABLE *pCT;
+    
+               if(PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_DEVICE_ID, 2)==0x7110) { 
+                       /* OK this is a PIIX4
+                         Memory size is 16M (ISA Memory) */
+                       LowestMemAddr1+=0x1000000;
+                       /* IOSize is 64Kb (ISA IO) */
+                       LowestIOAddr+=0x10000;
+                       if(LowestIOAddr>=MAX_PCI_PCI_IOADDR1)
+                               LowestIOAddr=MIN_PCI_PCI_IOADDR2;
+                       /* Fill in Function 0 Config */
+                       pCT = piix4_fn0;
+                       while (pCT->with>0) 
+                       {
+                               PCI_Write_CFG_Reg(BusDevFunc,pCT->index,pCT->val,pCT->with); /* Config Func 0 */
+                               pCT++;
+                       }
+                       /* init Function 1 */
+                       BusDevFunc|= (1<<8);
+                       pCT = piix4_fn1;
+                       while (pCT->with>0)
+                       {
+                               PCI_Write_CFG_Reg(BusDevFunc,pCT->index,pCT->val,pCT->with); /* Config Func 1 */
+                               pCT++;
+                       }
+                       printf("  Rev:   PCB Rev: %c PLD%d Rev %d PLD%d Rev %d\n\n",(in8(PLD_BOARD_CFG_REG)&0xf)+'A',
+                               in8(PLD_PART_REG)&0xf,in8(PLD_VERS_REG)&0xf,
+                               (in8(PLD_PART_REG)>>4)&0xf,(in8(PLD_VERS_REG)>>4)&0xf);         
+                       
+                       
+               }
+}
+
+/* VGA Controller (logical device 0) */
+static PCI_CFG_TABLE ct69000_fn0[] = {
+       {PCI_CFG_BASE_ADDRESS_0, 0x80000000, 4},/* Frame buffer access */
+       {PCI_CFG_EXPANSION_ROM,  0x00000000, 4},/* disable ROM */
+       {PCI_CFG_DEV_INT_LINE,           29, 1},/* Int vector = 29 */
+       {PCI_CFG_COMMAND,            0x0003, 2},/* enable IO access */
+       {0xFFFF, 0,0}                           /* end of device table */
+};
+
+/*-----------------------------------------------------------------------
+|  Subroutine:  PCI_Config_VGA_contrl
+|
+|  Description: Configure a PCI to ISA Bridge
+|               Since there address space is not relocable, we have 
+|                                                        to set it up manually
+|
+|  Inputs:
+|               BusDevFunc    Bus+Device+Function number
+|  Return value:
+|               None
++----------------------------------------------------------------------*/
+void PCI_Config_VGA_contrl(int BusDevFunc)
+{
+    PCI_CFG_TABLE *pCT;
+   
+               /*printf(" VGA ID %04X, busdecfunc %x\n",(short)PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_DEVICE_ID, 2),(int)BusDevFunc);*/
+               if(PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_DEVICE_ID, 2)==0x00C0) { 
+                       /* OK this is the ct69000
+                        * Memory size is 16M (ISA Memory) */
+                       /*      printf("C&T69000 found\n"); */
+                       /* configuration:
+                       LOW_Memory: PCI Address 0x000A0000..0x000CFFFF Loc Addr. 0x800A0000..0x800CFFFF
+                       FB_Memory:      PCI Address 0x20000000..0x21000000 Loc Addr. 0xA0000000..0xA1000000
+                       IO_Addresses: 3B0..3DF
+                       */
+                                               
+                       /* Fill in Function 0 Config */
+                       pCT = ct69000_fn0;
+                       while (pCT->with>0)  {
+                               PCI_Write_CFG_Reg(BusDevFunc,pCT->index,pCT->val,pCT->with); /* Config Func 0 */
+                               pCT++;
+                       }
+                       /*printf("configured\n"); */
+                       /*video_init(BusDevFunc); */
+               }
+}
+
+static PCI_CFG_TABLE sym810_fn0[] = {
+       {PCI_CFG_BASE_ADDRESS_0, 0x00001001, 4},/* IO Base address */
+       {PCI_CFG_BASE_ADDRESS_1, 0x81000000, 4},/* Memory Base address */
+       {PCI_CFG_DEV_INT_LINE,           30, 1},/* Int vector = 30 */
+       {PCI_CFG_COMMAND,            0x0006, 2},/* enable Memory access and busmaster */
+       {0xFFFF, 0,0}                           /* end of device table */
+};
+
+/*-----------------------------------------------------------------------
+|  Subroutine:  PCI_Config_VGA_contrl
+|
+|  Description: Configure a PCI to ISA Bridge
+|               Since there address space is not relocable, we have 
+|                                                        to set it up manually
+|
+|  Inputs:
+|               BusDevFunc    Bus+Device+Function number
+|  Return value:
+|               None
++----------------------------------------------------------------------*/
+void PCI_Config_SCSI_contrl(int BusDevFunc)
+{
+    PCI_CFG_TABLE *pCT;
+   
+               /*printf(" SCSI ID %04X, busdecfunc %x\n",(short)PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_DEVICE_ID, 2),(int)BusDevFunc);*/
+               if((unsigned short)PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_DEVICE_ID, 2)==0x0001) { 
+                       /* OK this is a Symbois 810
+                        * Fill in Function 0 Config */
+                       pCT = sym810_fn0;
+                       while (pCT->with>0) 
+                       {
+                               PCI_Write_CFG_Reg(BusDevFunc,pCT->index,pCT->val,pCT->with); /* Config Func 0 */
+                               pCT++;
+                       }
+                       /*scsi_init(BusDevFunc);*/
+               }
+}
+
+/*-----------------------------------------------------------------------
+|  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 value:
+|               None
++----------------------------------------------------------------------*/
+void    PCI_Config_Device(int BusDevFunc, int NumBaseAddr)
+{
+    int     AddrSlot, i;
+    unsigned long  AddrDesc, AddrProg, Min_Gnt_Val, int_line;
+
+    for (AddrSlot = 0; AddrSlot < NumBaseAddr; AddrSlot++)
+    {
+       PCI_Write_CFG_Reg(BusDevFunc, PCIBASEADDR0 + (4*AddrSlot), 0xFFFFFFFF,4);
+
+       AddrDesc = PCI_Read_CFG_Reg(BusDevFunc, PCIBASEADDR0 + (4*AddrSlot), 4);
+
+       if (AddrDesc == 0)                   /* unimplemented, stop looking */
+          continue;                         /* 01/04/99 MCG */
+
+#ifdef PCI_DEBUG
+       printf("Read Base Addr Reg %d = 0x%08x\n",AddrSlot,AddrDesc);
+#endif
+
+       if ((AddrDesc & 1) == 0)        /* Memory */
+       {
+          AddrDesc &= 0xFFFFFFF0;
+
+          for (i = 0; (AddrDesc & 1) != 1; i++)
+             AddrDesc = AddrDesc >> 1;
+
+          AddrDesc = 1 << i;
+
+          if ((unsigned long)AddrDesc < 4096)
+             AddrDesc = 4096;
+#ifdef PCI_DEBUG
+          printf("    PCI Memory space = 0x%x bytes \n",AddrDesc);
+#endif
+          for (AddrProg = MIN_PCI_MEMADDR1; AddrProg < LowestMemAddr1; AddrProg += AddrDesc);
+
+          PCI_Write_CFG_Reg(BusDevFunc, PCIBASEADDR0 + (4*AddrSlot),AddrProg,4);
+          LowestMemAddr1 = AddrProg + AddrDesc;
+       }
+       else                            /* I/O */
+       {
+          AddrDesc &= 0xFFFFFFFC;
+
+          for (i = 0; (AddrDesc & 1) != 1; i++)
+             AddrDesc = AddrDesc >> 1;
+
+          AddrDesc = 1 << i;
+#ifdef PCI_DEBUG
+          printf("    PCI I/O space = 0x%x bytes \n",AddrDesc);
+#endif
+          for (AddrProg = MIN_PCI_PCI_IOADDR2; AddrProg < LowestIOAddr; AddrProg += AddrDesc);
+
+          PCI_Write_CFG_Reg(BusDevFunc, PCIBASEADDR0 + (4*AddrSlot),AddrProg,4);
+          LowestIOAddr = AddrProg + AddrDesc;
+       }
+
+    }
+
+    Min_Gnt_Val = 0x80;
+    PCI_Write_CFG_Reg(BusDevFunc, PCILATENCYTIM, Min_Gnt_Val, 1);
+
+    /*
+     * Write pci interrupt line register (cpci405 specific)
+     */
+    switch ((BusDevFunc >> 11) & 0x03)
+      {
+      case 0:
+        int_line = 27 + 2;
+        break;
+      case 1:
+        int_line = 27 + 3;
+        break;
+      case 2:
+        int_line = 27 + 0;
+        break;
+      case 3:
+        int_line = 27 + 1;
+        break;
+      }
+    PCI_Write_CFG_Reg(BusDevFunc, PCIINTLINE, int_line, 1);
+
+    /*
+     * Enable i/o space, memory space and master on this device
+     */
+    PCI_Write_CFG_Reg(BusDevFunc, PCICMD, 7, 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 value:
+|               None
++----------------------------------------------------------------------*/
+void    PCI_Config_VGA_Device(int BusDevFunc, int NumBaseAddr)
+{
+    int     AddrSlot, i;
+    unsigned long  AddrDesc, AddrProg, Min_Gnt_Val;
+
+    for (AddrSlot = 0; AddrSlot < NumBaseAddr; AddrSlot++)
+    {
+       PCI_Write_CFG_Reg(BusDevFunc, PCIBASEADDR0 + (4*AddrSlot), 0xFFFFFFFF,4);
+
+       AddrDesc = PCI_Read_CFG_Reg(BusDevFunc, PCIBASEADDR0 + (4*AddrSlot), 4);
+
+       if (AddrDesc == 0)                   /* unimplemented, stop looking */
+          continue;                         /* 01/04/99 MCG */
+
+#ifdef PCI_DEBUG
+       printf("VGA Device Read Base Addr Reg %d = 0x%08x\n",AddrSlot,AddrDesc);
+#endif
+
+       if ((AddrDesc & 1) == 0)        /* Memory */
+       {
+          AddrDesc &= 0xFFFFFFF0;
+
+          for (i = 0; (AddrDesc & 1) != 1; i++)
+             AddrDesc = AddrDesc >> 1;
+
+          AddrDesc = 1 << i;
+
+          if ((unsigned long)AddrDesc < 4096)
+             AddrDesc = 4096;
+#ifdef PCI_DEBUG
+          printf("    PCI Memory space = 0x%x bytes \n",AddrDesc);
+#endif
+          for (AddrProg = MIN_PCI_MEMADDR2; AddrProg < LowestMemAddr2; AddrProg += AddrDesc);
+
+          PCI_Write_CFG_Reg(BusDevFunc, PCIBASEADDR0 + (4*AddrSlot),AddrProg,4);
+          LowestMemAddr2 = AddrProg + AddrDesc;
+       }
+       else                            /* I/O */
+       {
+          AddrDesc &= 0xFFFFFFFC;
+
+          for (i = 0; (AddrDesc & 1) != 1; i++)
+             AddrDesc = AddrDesc >> 1;
+
+          AddrDesc = 1 << i;
+#ifdef PCI_DEBUG
+          printf("    PCI I/O space = 0x%x bytes \n",AddrDesc);
+#endif
+          for (AddrProg = MIN_PCI_PCI_IOADDR2; AddrProg < LowestIOAddr; AddrProg
++= AddrDesc);
+
+          PCI_Write_CFG_Reg(BusDevFunc, PCIBASEADDR0 + (4*AddrSlot),AddrProg,4);
+          LowestIOAddr = AddrProg + AddrDesc;
+       }
+
+    }
+
+    Min_Gnt_Val = 0x80;
+    PCI_Write_CFG_Reg(BusDevFunc, PCILATENCYTIM, Min_Gnt_Val, 1);
+}
+
+/*-----------------------------------------------------------------------
+|
+|  Subroutine:  PCI_Config_Bridge
+|
+|  Prototype:   void    PCI_Config_Bridge(int BusDevFunc)
+|
+|  Description: Configure a PCI-PCI bridge
+|
+|  Inputs:
+|               BusDevFunc      Bus+Device+Function number
+|
+|  Return value:
+|               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 = (unsigned short)PCI_Read_CFG_Reg(BusDevFunc, PCICMD, 2);
+
+   /* Configure bridge's base address registers */
+
+   PCI_Config_Device(BusDevFunc, 2);
+
+   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;
+
+   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, PCICMD, CommandReg_Val, 2);
+
+}
+
+/*-----------------------------------------------------------------------
+|  Subroutine:  PCI_Find_Device
+|
+|  Prototype:   int     PCI_Find_Device(hword VendorID, hword DeviceID);
+|
+|  Description:
+|               Locate a PCI device by vendor and device number
+|
+|  Inputs:
+|               VendorID        Value of the device's Vendor ID field
+|               DeviceID        Value of the device's Device ID field
+|
+|  Return value:
+|               < 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;
+   int          Funct;
+
+   for (BusNum = MaxBusNum; BusNum >= 0; BusNum--)
+      for (Device = 0; Device < MAX_PCI_DEVICES; Device++)
+      {
+       for(Funct=0;Funct<MAX_PCI_FUNCTIONS;Funct++)
+                               {
+                                       BusDevFunc = (BusNum << 16) | (Device << 11) | (Funct<<8);
+               if ((unsigned short)PCI_Read_CFG_Reg(BusDevFunc, PCIVENDORID, 2) == VendorID
+               && (unsigned short)PCI_Read_CFG_Reg(BusDevFunc, PCIDEVICEID, 2) == DeviceID)
+               return (BusDevFunc);
+                               }
+      }
+
+   return (-1);
+}
+
+
+#if (CONFIG_COMMANDS & CFG_CMD_PCI)
+
+void
+do_pciinfo(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
+{
+  int bus_no = 0;
+
+  if (argc == 2)
+    {
+      bus_no = (int)simple_strtoul(argv[1], NULL, 10);
+    }
+
+  pciinfo(bus_no);
+}
+
+
+/*******************************************************************************
+*
+* pciinfo - print information about PCI devices
+*
+*/
+void
+pciinfo(int bus_no)
+{
+  int device_no;
+  unsigned short vendor_id,vendor2_id;
+  int BusDevFunc,funct;
+  int device_no_start = 1;
+  
+  printf ("Scanning all functions of each PCI device on bus %d\n", bus_no);
+
+  if (bus_no == 0)
+    device_no_start = 1;
+  for (device_no=device_no_start; device_no < MAX_PCI_DEVICES; device_no++)
+    {
+      BusDevFunc = (bus_no << 16) | (device_no << 11);
+      vendor_id = (unsigned short)PCI_Read_CFG_Reg(BusDevFunc, PCIVENDORID, 2);
+
+      if (vendor_id != 0xffff)
+      {
+          printf("\nFound PCI device %d: Function 0\n", device_no);
+          pciHeaderShow(BusDevFunc);
+                               if(((unsigned char)PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_HEADER_TYPE,1)&0x80)==0x80)
+                                       {
+                                       for(funct=1;funct<MAX_PCI_FUNCTIONS;funct++)
+                                               {
+                                     BusDevFunc = (bus_no << 16) | (device_no << 11) | (funct << 8);
+                                       vendor2_id = PCI_Read_CFG_Reg(BusDevFunc, PCIVENDORID, 2);
+                                       if (vendor2_id != vendor_id)
+                                       break;
+                       printf("\nFound PCI device %d: Function %d\n", device_no,funct);
+                       pciHeaderShow(BusDevFunc);
+                                               }
+                                       }
+       }
+    }
+}
+
+
+/*******************************************************************************
+*
+* pciHeaderShow - print a header of the specified PCI device
+*
+* This routine prints a header of the PCI device specified by BusDevFunc.
+*
+*/
+void
+pciHeaderShow(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);
+      pciBheaderPrint(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);
+      pciDheaderPrint(pD);
+    }
+}
+
+/*******************************************************************************
+*
+* pciDheaderPrint - print a PCI device header
+*
+* This routine prints a PCI device header.
+*
+*/
+void
+pciDheaderPrint(PCI_HEADER_DEVICE * pD)
+{
+  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\n", (uchar)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);
+}
+
+/*******************************************************************************
+*
+* pciBheaderPrint - print a PCI-to-PCI bridge header
+*
+* This routine prints a PCI-to-PCI bridge header.
+*
+*/
+void
+pciBheaderPrint(PCI_HEADER_BRIDGE * pB)
+{
+  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\n", (uchar)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);
+}
+
+
+
+
+/*******************************************************************************
+*
+* pciGetHeader0 - gets the header of the specified PCI device
+*
+* only header 0 .
+*
+*/
+
+int pciGetHeader0(PCI_HEADER_DEVICE * pD,int BusDevFunc)
+{
+  pD->headerType = PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_HEADER_TYPE, 1);
+
+  if ((pD->headerType&0x7F)!=0)                /* Not a Header 0 type */
+       return FALSE;
+  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);
+  }
+  return TRUE;
+}
+
+/*******************************************************************************
+*
+* pciGetResource - gets the Resource information of the specified PCI device
+*
+* 
+*
+*/
+int pciGetResource(PCI_RESOURCE_DESC * pR)
+{
+       PCI_HEADER_DEVICE headerDevice;
+  int                                                  basereg, i;
+  unsigned long  AddrDesc;
+  
+
+       if(pciGetHeader0(&headerDevice,pR->BusDevFunc)==FALSE)
+               return FALSE; /* no header 0 type */
+       /* fill in read only fields */
+       pR->vendorId = headerDevice.vendorId;
+       pR->deviceId = headerDevice.deviceId;
+       pR->revisionId = headerDevice.revisionId;
+       pR->classCode = headerDevice.classCode;
+       pR->subClass = headerDevice.subClass;
+       pR->progIf = headerDevice.progIf;
+       pR->intLine = headerDevice.intLine;
+       pR->intPin = headerDevice.intPin;
+       pR->headerType = headerDevice.headerType;
+       pR->pciInt = 0; /* no Interrupt as default */
+       /* calculate the PCI Interrupt if any.. */
+       if(pR->intPin!=0)
+       {       
+               /* interrupts are routed as follows:
+                  - Device 6, INTA# = INTA#
+                  - Device 7, INTA# = INTB#
+                  - Device 8, INTA# = INTC#
+                  - Device 9, INTA# = INTD#
+                  - Device A, INTA# = INTA#
+                  - Device 0 must be INTA# = INTC# */
+               i=(pR->BusDevFunc >> 11) & 0x1F; /* max 32 devices (Bus nr not yet implemented) */
+               i=i%4; /* dev0 and INTA# = INTC#  */
+               i+=1; /* Adjust it (first step) */
+               i+=pR->intPin;
+               pR->pciInt=(char)((i%4)+1); /* 2nd step  */
+       }
+       /* try to get memory or io descriptions */
+       for (basereg = 0; basereg < MAX_PCI_BASE_REG; basereg++)
+  {
+       pR->size[basereg]=0; /* delete size */
+               pR->attr[basereg]=DESC_IS_NOT_VALID;
+               PCI_Write_CFG_Reg(pR->BusDevFunc, PCIBASEADDR0 + (4*basereg), 0xFFFFFFFF,4);
+    AddrDesc = PCI_Read_CFG_Reg(pR->BusDevFunc, PCIBASEADDR0 + (4*basereg), 4);
+    if (AddrDesc == 0)                   /* unimplemented, stop looking */
+                       continue;               
+               if ((AddrDesc&0x3)==0x1) /* is IO */
+               {
+                       pR->attr[basereg]=DESC_IS_IO;
+                       /* determine size, all bytes which are don't care are 0 */
+                       AddrDesc&=0xFFFFFFFC; /* delete Atributes */
+                       AddrDesc=~AddrDesc;
+                       AddrDesc&=0x0000FFFF; /* Mask unused bits                        */
+                       pR->size[basereg]=AddrDesc+1; /* size  */
+               } 
+               else
+               {
+                       pR->attr[basereg]=DESC_IS_MEM;
+                       switch((AddrDesc&0x6)>>1)
+                       {
+                               case 0x1: 
+                                       pR->attr[basereg]|=DESC_IS_LOWMEM;  /* locate it below 1M */
+                                       break;
+                               case 0x2:
+                                       pR->attr[basereg]|=DESC_IS_64BIT;  /* dual Address.. increment base reg later */
+                                       break;
+                               case 0x3:
+                                       pR->attr[basereg]=DESC_IS_NOT_VALID;  /* Error */
+                                       break;
+                       } /* case */
+                       if((AddrDesc&0x8)==0x8) /* is prefetchable */
+                               pR->attr[basereg]|=DESC_IS_PREFETCH;
+                       /* 64Bit addressing not implemented */
+                       if((pR->attr[basereg]&DESC_IS_64BIT)==DESC_IS_64BIT)
+                       {
+                               basereg++;
+                               if(basereg<MAX_PCI_BASE_REG)
+                               {
+                               pR->size[basereg]=0; /* delete size */
+                                       pR->attr[basereg]=DESC_IS_NOT_VALID;
+                               }
+                               continue;
+                       } /* if DESC_IS_64BIT */
+                       /* determine size                        */
+                       AddrDesc&=0xFFFFFFF0;/* delete attributes */
+                       AddrDesc=~AddrDesc; 
+                       pR->size[basereg]=AddrDesc+1; /* size  */
+               } /* else  */
+       } /* for        basereg */
+       return TRUE;    
+}
+
+#if 0
+/*************************************************************************************
+* pcishowrees
+*/
+void pciShowRes(PCI_RESOURCE_DESC *pD)
+{
+       int i, match;
+       printf("%02d:%02d:%02d ",(char)(pD->BusDevFunc>>16)&0xFF,
+       (char)(pD->BusDevFunc>>11)&0x1F,(char)(pD->BusDevFunc>>8)&0x3);
+
+       /* search memory desc */
+       match=0;
+       for(i=0;i<MAX_PCI_BASE_REG;i++)
+       {
+               if((pD->attr[i]&DESC_IS_IO)==DESC_IS_IO)
+               {
+                       printf("%4lX ",pD->size[i]);
+                       match=1;
+               }       
+       }
+       if(match==0)
+               printf("     ");
+       match=0;
+       for(i=0;i<MAX_PCI_BASE_REG;i++)
+       {
+               if((pD->attr[i]&DESC_IS_MEM)==DESC_IS_MEM)
+               {
+                       printf("%8lX ",pD->size[i]);
+                       match=1;
+               }       
+       }
+       if(match==0)
+               printf("         ");
+       if(pD->intPin==0)
+               printf("      ");
+       else 
+               printf("INT%c# ",(pD->pciInt + 'A')-1);
+       switch (pD->classCode)
+       {
+               case 0x00: 
+                       switch(pD->subClass)
+                       {
+                               case 0: printf("not VGA"); break;
+                               case 1: printf("VGA"); break;
+                               default: printf("unknown"); break;
+                       }
+                       printf("Pre Class: "); 
+                       break;
+               case 0x01: 
+                       switch(pD->subClass)
+                       {
+                               case 0x00: printf("SCSI "); break;
+                               case 0x01: printf("IDE "); break;
+                               case 0x02: printf("Floppy "); break;
+                               case 0x03: printf("IPI "); break;
+                               case 0x04: printf("RAID "); break;
+                               case 0x88: printf("other "); break;
+                               default: printf("unknown "); break;
+                       }
+                       printf("Mass Storage ");
+                       break;
+               case 0x02: 
+                       switch(pD->subClass)
+                       {
+                               case 0x00: printf("Ethernet"); break;
+                               case 0x01: printf("Token Ring"); break;
+                               case 0x02: printf("FDDI"); break;
+                               case 0x03: printf("ATM"); break;
+                               case 0x80: printf("other"); break;
+                               default: printf("unknown"); break;
+                       }
+                       printf(" Network Controller ");
+                       break;
+               case 0x03: 
+                       switch(pD->subClass)
+                       {
+                               case 0x00: printf("%s",((pD->progIf&0x1)==0x1)? "8514 comp":"VGA"); break;
+                               case 0x01: printf("XGA"); break;
+                               case 0x80: printf("other"); break;
+                               default: printf("unknown"); break;
+                       }
+                       printf(" Display Cont. ");
+                       break;
+               case 0x04: 
+                       switch(pD->subClass)
+                       {
+                               case 0x00: printf("Video"); break;
+                               case 0x01: printf("Audio"); break;
+                               case 0x80: printf("other"); break;
+                               default: printf("unknown"); break;
+                       }
+                       printf(" Multimedia Device ");
+                       break;
+               case 0x05: 
+                       switch(pD->subClass)
+                       {
+                               case 0x00: printf("RAM"); break;
+                               case 0x01: printf("Flash"); break;
+                               case 0x80: printf("other"); break;
+                               default: printf("unknown"); break;
+                       }
+                       printf(" Memory Device ");
+                       break;
+               case 0x06: 
+                       switch(pD->subClass)
+                       {
+                               case 0x00: printf("HostBridge"); break;
+                               case 0x01: printf("ISA"); break;
+                               case 0x02: printf("EISA"); break;
+                               case 0x03: printf("MCA"); break;
+                               case 0x04: printf("PCI-PCI"); break;
+                               case 0x05: printf("PCMCIA"); break;
+                               case 0x06: printf("NuBus"); break;
+                               case 0x07: printf("CardBus"); break;
+                               case 0x80: printf("other"); break;
+                               default: printf("unknown"); break;
+                       }
+                       printf(" Bridge ");
+                       break;
+               case 0x07: 
+                       switch(pD->subClass)
+                       {
+                               case 0x00:
+                                       switch(pD->progIf)
+                                       {
+                                               case 0: printf("Generic XT Serial Controller ");break;
+                                               case 1: printf("16450 Serial Controller ");break;
+                                               case 2: printf("16550 Serial Controller ");break;
+                                               default:        printf("unknown Serial Controller ");break;
+                                       }
+                                       break;
+                               case 0x01:
+                                       switch(pD->progIf)
+                                       {
+                                               case 0: printf("Paralell Port ");break;
+                                               case 1: printf("Bidirectional Paralell Port ");break;
+                                               case 2: printf("ECP 1.X Paralell Port ");break;
+                                               default:        printf("unknown Paralall Port ");break;
+                                       }
+                                       break;
+                               case 0x80: printf("other Simple Communications Controller "); break;
+                               default: printf("unknown Simple Communications Controller "); break;
+                       }
+                       break;
+               case 0x08: 
+                       switch(pD->subClass)
+                       {
+                               case 0x00:
+                                       switch(pD->progIf)
+                                       {
+                                               case 0: printf("Generic 8259 PIC ");break;
+                                               case 1: printf("ISA PIC ");break;
+                                               case 2: printf("EISA PIC ");break;
+                                               default:        printf("unknown PIC ");break;
+                                       }
+                                       break;
+                               case 0x01:
+                                       switch(pD->progIf)
+                                       {
+                                               case 0: printf("Generic 8237 DMA ");break;
+                                               case 1: printf("ISA DMA ");break;
+                                               case 2: printf("EISA DMA ");break;
+                                               default:        printf("unknown DMA ");break;
+                                       }
+                                       break;
+                               case 0x02:
+                                       switch(pD->progIf)
+                                       {
+                                               case 0: printf("Generic 8254 Timer ");break;
+                                               case 1: printf("ISA Timer ");break;
+                                               case 2: printf("EISA Timer ");break;
+                                               default:        printf("unknown Timer ");break;
+                                       }
+                                       break;
+                               case 0x03:
+                                       switch(pD->progIf)
+                                       {
+                                               case 0: printf("Generic RTC ");break;
+                                               case 1: printf("ISA RTC ");break;
+                                               default:        printf("unknown RTC ");break;
+                                       }
+                                       break;
+                               case 0x80: printf("other Generic System Peripherals "); break;
+                               default: printf("unknown Generic System Peripherals "); break;
+                       }
+                       break;
+               case 0x09: 
+                       switch(pD->subClass)
+                       {
+                               case 0x00: printf("Keyboard Controller "); break;
+                               case 0x01: printf("Digitizer "); break;
+                               case 0x02: printf("Mouse "); break;
+                               case 0x80: printf("other Input Device "); break;
+                               default: printf("unknown Input Device "); break;
+                       }
+                       break;
+               case 0x0A: 
+                       switch(pD->subClass)
+                       {
+                               case 0x00: printf("Generic Docking Station "); break;
+                               case 0x80: printf("other Docking Device "); break;
+                               default: printf("unknown Docking Device "); break;
+                       }
+                       break;
+               case 0x0B: 
+                       switch(pD->subClass)
+                       {
+                               case 0x00: printf("386 "); break;
+                               case 0x01: printf("486 "); break;
+                               case 0x02: printf("Pentium "); break;
+                               case 0x10: printf("Alpha "); break;
+                               case 0x20: printf("PowerPC "); break;
+                               case 0x40: printf("Co-"); break;
+                               default: printf("unknown "); break;
+                       }
+                       printf("Processor ");
+                       break;
+               case 0x0C: 
+                       switch(pD->subClass)
+                       {
+                               case 0x00: printf("FireWire "); break;
+                               case 0x01: printf("ACCESS.bus "); break;
+                               case 0x02: printf("SSA "); break;
+                               case 0x03: printf("USB "); break;
+                               case 0x04: printf("Fibre Channel "); break;
+                               default: printf("unknown Serial Bus "); break;
+                       }
+                       break;
+       } /* Switch */
+       printf("\n");
+}
+
+#endif
+
+#if 0
+/**************************************************************************************
+* pciScanforDevices
+*/
+
+void pciScanForDevices(int BusNum)
+{
+       
+       PCI_RESOURCE_DESC resourcedesc;
+  int Device,Function,BusDevFunc;
+  unsigned short vendor_id,vendor_id2;
+  
+  printf("PCI        IO   Memory   IRQ Device\n");
+  /*      00:00:00 1234 12345678 INTA# DD */
+       for (Device = 1; Device < MAX_PCI_DEVICES; Device++)
+       {
+               BusDevFunc = (BusNum << 16) | (Device << 11); /* scan only function 0 */
+               vendor_id = PCI_Read_CFG_Reg(BusDevFunc, PCIVENDORID,2);
+               if (vendor_id != 0xFFFF)
+               {
+                       
+                       for(Function=0;Function<MAX_PCI_FUNCTIONS; Function++)
+                       {
+                               BusDevFunc=(BusNum << 16) | (Device << 11) | (Function << 8);
+                               vendor_id2=PCI_Read_CFG_Reg(BusDevFunc, PCIVENDORID,2);
+                               if(vendor_id!=vendor_id2)
+                                       break;  
+                               resourcedesc.BusDevFunc=BusDevFunc;
+                               /* found a device, get resource desc */
+                               if(pciGetResource(&resourcedesc)==FALSE) /* no Header type 0 */
+                               {
+                                       printf("%02d:%02d:%02d No compatible Header\n",
+                                               BusNum,Device,Function);
+                                       /* Function = MAX_PCI_FUNTIONS; */ /* to prevent further scanning on this dev */
+                                       break;
+                               }
+                               pciShowRes(&resourcedesc);
+                               
+                               if(((resourcedesc.headerType&0x80)!=0x80)&&(Function==0))
+                                       break; /* single function Device */
+                       } /* for Function */
+               } /* if device found */
+       } /* for Device */
+}                      
+#endif
+
+
+
+
+
+#endif /* CONFIG_COMMANDS & CFG_CMD_PCI */
+
+#endif /* CONFIG_PCI */
+
+#endif /* CONFIG_PPC405GP */
diff --git a/board/pip405/pci_pip405.h b/board/pip405/pci_pip405.h
new file mode 100644 (file)
index 0000000..06347d8
--- /dev/null
@@ -0,0 +1,338 @@
+/*
+ * (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
+ */
+
+
+
+#ifndef _PCI_PIP405_H
+#define _PCI_PIP405_H
+
+
+
+#define TRUE 1
+#define FALSE 0                
+#define MAX_PCI_BASE_REG       6 /* max six mem description per PCI dev */
+#define DESC_IS_IO                             1 /* IO Attribute */
+#define DESC_IS_MEM                            2 /* Memory attribute     */
+#define DESC_IS_PREFETCH       4 /* Memory is Prefetchable */
+#define DESC_IS_LOWMEM         8 /* locate below 1M */
+#define DESC_IS_64BIT                  0x10 /* dual address cycles */
+#define DESC_IS_NOT_VALID      0 /* Memory description is nat valid    */
+
+/*----------------------------------------------------------------------------+
+| 405GP PCI core memory map defines.
++----------------------------------------------------------------------------*/
+#define MIN_PCI_MEMADDR1    0x80000000
+#define MIN_PCI_MEMADDR2    0x00000000
+#define MIN_PLB_PCI_IOADDR  0xE8000000  /* PLB side of PCI I/O address space */
+#define MIN_PCI_PCI_IOADDR1 0x00000000  /* PCI side of PCI I/O address space */
+#define MAX_PCI_PCI_IOADDR1 0x00010000  /* PCI side of PCI I/O address space */
+#define MIN_PCI_PCI_IOADDR2 0x00800000  /* PCI side of PCI I/O address space */
+#define MAX_PCI_DEVICES     32
+#define MAX_PCI_FUNCTIONS              7
+/*----------------------------------------------------------------------------+
+| Defines for the 405GP PCI Config address and data registers followed by
+| defines for the standard PCI device configuration header.
++----------------------------------------------------------------------------*/
+#define PCICFGADR       0xEEC00000
+#define PCICFGDATA      0xEEC00004
+
+#define PCIVENDORID     0x00
+#define PCIDEVICEID     0x02
+#define PCICMD          0x04
+  #define SERR_EN       0x0100
+  #define BM_EN         0x0004
+  #define MEM_EN        0x0002
+  #define IO_EN         0x0001
+#define PCISTATUS       0x06
+  #define CAPABLE_66MHZ 0x0020
+#define PCIREVID        0x08
+#define PCICLASSPI      0x09
+#define PCICLASSCODE    0x0A
+#define PCICACHELINE    0x0C
+#define PCILATENCYTIM   0x0D
+#define PCIHEADERTYPE   0x0E
+#define PCIBIST         0x0F
+#define PCIBASEADDR0    0x10
+#define PCIBASEADDR1    0x14
+#define PCIBASEADDR2    0x18
+#define PCISSVENDORID   0x2C
+#define PCISSDEVICEID   0x2E
+#define PCIINTLINE      0x3C
+#define PCIINTPIN       0x3D
+#define PCIMINGRANT     0x3E
+#define PCIMAXLATENCY   0x3F
+
+#define PCIBUSNUM       0x40        /* 405GP specific parameters */
+#define PCISUBBUSNUM    0x41
+#define PCIDISCOUNT     0x42
+#define PCIBRDGOPT1     0x4A
+#define PCIBRDGOPT2     0x60
+
+/*----------------------------------------------------------------------------+
+| Defines for 405GP PCI Master local configuration regs.
++----------------------------------------------------------------------------*/
+#define PMM0LA          0xEF400000
+#define PMM0MA          0xEF400004
+#define PMM0PCILA       0xEF400008
+#define PMM0PCIHA       0xEF40000C
+#define PMM1LA          0xEF400010
+#define PMM1MA          0xEF400014
+#define PMM1PCILA       0xEF400018
+#define PMM1PCIHA       0xEF40001C
+#define PMM2LA          0xEF400020
+#define PMM2MA          0xEF400024
+#define PMM2PCILA       0xEF400028
+#define PMM2PCIHA       0xEF40002C
+
+/*----------------------------------------------------------------------------+
+| Defines for 405GP PCI Target local configuration regs.
++----------------------------------------------------------------------------*/
+#define PTM1MS          0xEF400030
+#define PTM1LA          0xEF400034
+#define PTM2MS          0xEF400038
+#define PTM2LA          0xEF40003C
+
+/*-----------------------------------------------------------------------------+
+|       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
+
+#define PCIDEVID_405GP         0x0
+
+/* 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
+
+
+/***********************************************************************
+ * 405GP PCI Master configuration.
+ * Map one 512 MB range of PLB/processor addresses to PCI memory space.
+ *   PLB address 0x80000000-0x9FFFFFFF ==> PCI address 0x80000000-0x9FFFFFFF
+ *   Use byte reversed out routines to handle endianess.
+ ***********************************************************************/
+#define PCI_M0_LOCAL_ADDR                      0x80000000
+#define PCI_M0_PCI_LOW_ADDR            0x80000000
+#define PCI_M0_PCI_HIGH_ADDR   0x00000000
+#define PCI_M0_MASK_ATTRIB             0xE0000001  /* no prefetching, and enable region */
+/**************************************************************************
+ * Map one 512 MB range of PLB/processor addresses to PCI memory space.
+ * PLB address 0xA0000000-0xBFFFFFFF ==> PCI address 0x00000000-0x1FFFFFFF
+ * This space is for the VGA card.
+ **************************************************************************/
+#define PCI_M1_LOCAL_ADDR                      0xA0000000
+#define PCI_M1_PCI_LOW_ADDR            0x00000000
+#define PCI_M1_PCI_HIGH_ADDR   0x00000000
+#define PCI_M1_MASK_ATTRIB             0xE0000001  /* no prefetching, and enable region */
+/***************************************************************************
+ * PMM2 is not used.  Initialize them to zero.
+ *****************************************************************************/
+#define PCI_M2_LOCAL_ADDR                      0x00000000
+#define PCI_M2_PCI_LOW_ADDR            0x00000000
+#define PCI_M2_PCI_HIGH_ADDR   0x00000000
+#define PCI_M2_MASK_ATTRIB             0x00000000  /* not enabled */
+
+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;
+
+
+typedef struct pciRecourceDesc
+       {
+       unsigned long   BusDevFunc; /* location of the device */
+       short   vendorId;               /* vendor ID */
+       short   deviceId;               /* device ID */
+  char revisionId;     /* revision ID */
+  char classCode;      /* class code */
+  char subClass;               /* sub class code */
+  char progIf;         /* programming interface */
+  char headerType;     /* header type */
+  unsigned long                size[MAX_PCI_BASE_REG];         /* memory sizes */
+  char attr[MAX_PCI_BASE_REG];         /* memory attributes */
+  char intLine;        /* interrupt line */
+  char intPin;         /* interrupt pin */
+       char    pciInt;         /* Pci Interrupt Line ( 0 = no, 1 = A...)*/
+       } PCI_RESOURCE_DESC;
+
+
+/* table fore PCI Initialization */
+typedef struct {
+       const int index;
+       const unsigned long val;
+       const int with;
+} PCI_CFG_TABLE;
+
+
+
+unsigned long    PCI_Read_CFG_Reg(int BusDevFunc, int Reg, int Width);
+int    PCI_Write_CFG_Reg(int BusDevFunc, int Reg, unsigned long Value, int Width);
+void  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);
+void  PCI_Dump_Device(int BusDevFunc);
+int   PCI_Find_Device(unsigned short VendorID, unsigned short DeviceID);
+void  pciHeaderShow(int BusDevFunc);
+void  pciDheaderPrint(PCI_HEADER_DEVICE * pD);
+void  pciBheaderPrint(PCI_HEADER_BRIDGE * pB);
+void  PCI_Config_ISABridge(int BusDevFunc);
+void  PCI_Config_VGA_contrl(int BusDevFunc);
+
+void pciScanForDevices(int BusNum);
+void pciShowRes(PCI_RESOURCE_DESC *pd);
+int pciGetResource(PCI_RESOURCE_DESC * pR);
+int pciGetHeader0(PCI_HEADER_DEVICE * pD,int BusDevFunc);
+
+
+#endif
diff --git a/board/pip405/pip405.c b/board/pip405/pip405.c
new file mode 100644 (file)
index 0000000..6a8268a
--- /dev/null
@@ -0,0 +1,889 @@
+/*
+ * (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
+ *
+ *
+ * TODO: clean-up
+ */
+
+#include <ppcboot.h>
+#include "pip405.h"
+#include <asm/processor.h>
+#include <405gp_i2c.h>
+#include "pip405_isa.h"
+#include "video.h"
+
+
+extern block_dev_desc_t * scsi_get_dev(int dev);
+extern block_dev_desc_t * ide_get_dev(int dev);
+
+#undef SDRAM_DEBUG
+
+#define FALSE           0
+#define TRUE            1
+
+/* stdlib.h causes some compatibility problems; should fixe these! -- wd */
+#ifndef __ldiv_t_defined
+typedef struct {
+       long int quot;          /* Quotient     */
+       long int rem;           /* Remainder    */
+} ldiv_t;
+extern ldiv_t ldiv (long int __numer, long int __denom);
+# define __ldiv_t_defined      1
+#endif
+
+
+
+
+typedef enum {
+  SDRAM_NO_ERR,
+  SDRAM_SPD_COMM_ERR,
+  SDRAM_SPD_CHKSUM_ERR,
+  SDRAM_UNSUPPORTED_ERR,
+  SDRAM_UNKNOWN_ERR
+} SDRAM_ERR;
+
+typedef struct {
+  const unsigned char mode;
+  const unsigned char row;
+  const unsigned char col;
+  const unsigned char bank;
+} SDRAM_SETUP;
+
+static const SDRAM_SETUP sdram_setup_table[] = {
+  {1, 11,  9, 2},
+  {1, 11, 10, 2},
+  {2, 12,  9, 4},
+  {2, 12, 10, 4},
+  {3, 13,  9, 4},
+  {3, 13, 10, 4},
+  {3, 13, 11, 4},
+  {4, 12,  8, 2},
+  {4, 12,  8, 4},
+  {5, 11,  8, 2},
+  {5, 11,  8, 4},
+  {6, 13,  8, 2},
+  {6, 13,  8, 4},
+  {7, 13,  9, 2},
+  {7, 13, 10, 2},
+  {0,  0,  0, 0}
+};
+
+static const unsigned char cal_indextable[] = {
+  9, 23, 25
+};
+
+
+/*
+ * translate ns.ns/10 coding of SPD timing values
+ * into 10 ps unit values
+ */
+
+unsigned short NS10to10PS(unsigned char spd_byte, unsigned char spd_version)
+{
+  unsigned short ns, ns10;
+
+  /* isolate upper nibble */
+  ns = (spd_byte >> 4) & 0x0F;
+  /* isolate lower nibble */
+  ns10 = (spd_byte & 0x0F);
+
+  return(ns*100 + ns10*10);
+}
+
+/*
+ * translate ns.ns/4 coding of SPD timing values
+ * into 10 ps unit values
+ */
+
+unsigned short NS4to10PS(unsigned char spd_byte, unsigned char spd_version)
+{
+  unsigned short ns, ns4;
+
+  /* isolate upper 6 bits */
+  ns = (spd_byte >> 2) & 0x3F;
+  /* isloate lower 2 bits */
+  ns4 = (spd_byte & 0x03);
+
+  return(ns*100 + ns4*25);
+}
+
+/*
+ * translate ns coding of SPD timing values
+ * into 10 ps unit values
+ */
+
+unsigned short NSto10PS(unsigned char spd_byte)
+{
+  return(spd_byte*100);
+}
+
+#ifdef SDRAM_DEBUG
+
+void write_hex(unsigned char i)
+{
+       char cc;
+       cc=i>>4;
+       cc&=0xf;
+       if(cc>9) 
+               serial_putc(cc+55);
+       else
+               serial_putc(cc+48);
+       cc=i&0xf;
+       if(cc>9) 
+               serial_putc(cc+55);
+       else
+               serial_putc(cc+48);
+}
+#endif
+
+int board_pre_init (void)
+{
+  unsigned char dataout[1];
+  unsigned char datain[128];
+  unsigned long sdram_size;
+  SDRAM_SETUP *t = (SDRAM_SETUP *)sdram_setup_table;
+  unsigned long memclk;
+  unsigned long tmemclk;
+  unsigned long tmp, bank, baseaddr, bank_size;
+  unsigned short i;
+  unsigned char rows, cols, banks, sdram_banks, density;
+  unsigned char supported_cal, trp_clocks, trcd_clocks, tras_clocks, trc_clocks;
+  unsigned char cal_index, cal_val, spd_version, spd_chksum;
+  unsigned char buf[8];
+       
+       memclk = get_bus_freq(tmemclk);
+       tmemclk = 1000000000 / (memclk / 100);  /* in 10 ps units */
+
+#ifdef SDRAM_DEBUG
+  serial_init(198000000,9600);
+  serial_puts("\nstart SDRAM Setup\n");
+#endif
+
+  /* Read Serial Presence Detect Information */
+  dataout[0] = 0;
+  for (i=0; i<128;i++)
+    datain[i] = 127;
+  i2c_send(SDRAM_EEPROM_WRITE_ADDRESS,1,dataout);
+  i2c_receive(SDRAM_EEPROM_READ_ADDRESS,128,datain);
+#if 0
+    for (i=0;i<128;i++)
+  {
+      write_hex(datain[i]);
+      serial_puts(" ");
+      if (((i+1)%16) == 0)
+                               serial_puts("\n");
+  }
+  serial_puts("\n");
+#endif
+  spd_chksum = 0;
+  for (i = 0; i < 63; i++) {
+        spd_chksum += datain[i];
+  } /* endfor */
+  if (datain[63] != spd_chksum) {
+#ifdef SDRAM_DEBUG
+    serial_puts("SPD chksum: 0x"); 
+    write_hex(datain[63]);
+    serial_puts(" != calc. chksum: 0x");
+    write_hex(spd_chksum);
+    serial_puts("\n");
+#endif
+   }
+  /* SPD seems to be ok, use it */
+
+  /* get SPD version */
+  spd_version = datain[62];
+
+  /* do some sanity checks on the kind of RAM */
+  if ((datain[0] < 0x80) ||       /* less than 128 valid bytes in SPD */
+      (datain[2] != 0x04) ||      /* if not SDRAM */
+      (!((datain[6] == 0x40) ||
+                       (datain[6] == 0x48))) || /* or not (64 Bit or 72 Bit)  */
+      (datain[7] != 0x00) ||
+      (datain[8] != 0x01) ||      /* or not LVTTL signal levels */
+      (datain[126] == 0x66))        /* or a 66Mhz modules */
+    serial_puts("\nunsupported SDRAM\n");
+#ifdef SDRAM_DEBUG
+  serial_puts("SDRAM sanity ok\n");
+#endif
+
+  /* get number of rows/cols/banks out of byte 3+4+5 */
+  rows = datain[3]; cols = datain[4]; banks = datain[5];
+
+  /* get number of SDRAM banks out of byte 17 and  
+     supported CAS latencies out of byte 18 */
+  sdram_banks = datain[17]; supported_cal = datain[18] & ~0x81;
+
+  while (t->mode != 0) {
+       if ((t->row == rows) && (t->col == cols) && (t->bank == sdram_banks))
+      break;
+    t++;
+  } /* endwhile */
+
+#ifdef SDRAM_DEBUG
+  serial_puts("mode: "); 
+  write_hex(t->mode);
+  serial_puts("\n");
+#endif
+  if (t->mode == 0)
+    puts("\nunsupported SDRAM\n");
+  /* get tRP, tRCD, tRAS and density from byte 27+29+30+31 */
+#ifdef SDRAM_DEBUG
+  serial_puts("tRP: ");
+  write_hex(datain[27]); 
+  serial_puts("\ntRCD: ");
+  write_hex(datain[29]);
+  serial_puts("\ntRAS: ");
+  write_hex(datain[30]); 
+  serial_puts("\n");
+#endif
+
+  trp_clocks = (NSto10PS(datain[27])+(tmemclk-1)) / tmemclk;
+  trcd_clocks = (NSto10PS(datain[29])+(tmemclk-1)) / tmemclk;
+  tras_clocks = (NSto10PS(datain[30])+(tmemclk-1)) / tmemclk;
+  density = datain[31];
+
+  /* trc_clocks is sum of trp_clocks + tras_clocks */
+  trc_clocks = trp_clocks + tras_clocks;
+  
+  cal_val = 255;
+  for (i = 6, cal_index = 0; (i > 0) && (cal_index < 3); i--) {
+    /* is this CAS latency supported ? */
+    if ((supported_cal >> i) & 0x01) {
+      buf[0]=datain[cal_indextable[cal_index]];
+      if (cal_index < 2) {
+                               if (NS10to10PS(buf[0], spd_version) <= tmemclk)
+                       cal_val = i;
+      } 
+      else {
+                               /* SPD bytes 25+26 have another format */
+                               if (NS4to10PS(buf[0], spd_version) <= tmemclk)
+                               cal_val = i;
+      } /* endif */
+      cal_index++;
+    } /* endif */
+  } /* endfor */
+#ifdef SDRAM_DEBUG
+  serial_puts("CAL: ");
+  write_hex(cal_val+1); 
+  serial_puts("\n");
+#endif
+
+  if (cal_val == 255)
+               puts("\nunsupported SDRAM\n");
+
+  /* get SDRAM timing register */
+  mtdcr(memcfga,mem_sdtr1);
+  tmp=mfdcr(memcfgd) & ~0x018FC01F;
+  /* insert CASL value */
+  tmp |= ((unsigned long)cal_val) << 23;
+  /* insert PTA value */
+  tmp |= ((unsigned long)(trp_clocks - 1)) << 18;
+  /* insert CTP value */
+  tmp |= ((unsigned long)(trc_clocks - trp_clocks - trcd_clocks - 1)) << 16;
+  /* insert LDF (always 01) */
+  tmp |= ((unsigned long)0x01) << 14;
+  /* insert RFTA value */
+  tmp |= ((unsigned long)(trc_clocks - 4)) << 2;
+  /* insert RCD value */
+  tmp |= ((unsigned long)(trcd_clocks - 1)) << 0;
+
+  /* write SDRAM timing register */
+  mtdcr(memcfga,mem_sdtr1);
+  mtdcr(memcfgd,tmp);
+       baseaddr=CFG_SDRAM_BASE;
+  bank_size = (((unsigned long)density) << 22) / 2;
+  /* insert AM value */
+  tmp = ((unsigned long)t->mode-1) << 13;
+  /* insert SZ value; */
+  switch (bank_size) {
+    case 0x00400000: tmp |= ((unsigned long)0x00) << 17; break;
+    case 0x00800000: tmp |= ((unsigned long)0x01) << 17; break;
+    case 0x01000000: tmp |= ((unsigned long)0x02) << 17; break;
+    case 0x02000000: tmp |= ((unsigned long)0x03) << 17; break;
+    case 0x04000000: tmp |= ((unsigned long)0x04) << 17; break;
+    case 0x08000000: tmp |= ((unsigned long)0x05) << 17; break;
+    case 0x10000000: tmp |= ((unsigned long)0x06) << 17; break;
+    default: serial_puts("unsupported SDRAM\n");
+  } /* endswitch */
+  
+  /* get SDRAM bank 0 register */
+  mtdcr(memcfga,mem_mb0cf);
+  bank = mfdcr(memcfgd) & ~0xFFCEE001;
+  bank |= (baseaddr | tmp | 0x01);
+  baseaddr += bank_size;
+  sdram_size += bank_size;
+
+  /* write SDRAM bank 0 register */
+  mtdcr(memcfga,mem_mb0cf);
+  mtdcr(memcfgd,bank);
+
+  /* get SDRAM bank 1 register */
+  mtdcr(memcfga,mem_mb1cf);
+  bank = mfdcr(memcfgd) & ~0xFFCEE001;
+       sdram_size=0;
+  if (banks == 2) {
+    bank |= (baseaddr | tmp | 0x01);
+    baseaddr += bank_size;
+    sdram_size += bank_size;
+  } /* endif */
+
+  /* write SDRAM bank 1 register */
+  mtdcr(memcfga,mem_mb1cf);
+  mtdcr(memcfgd,bank);
+
+
+  /* get SDRAM bank 2 register */
+  mtdcr(memcfga,mem_mb2cf);
+  bank = mfdcr(memcfgd) & ~0xFFCEE001;
+
+  bank |= (baseaddr | tmp | 0x01);
+  baseaddr += bank_size;
+  sdram_size += bank_size;
+
+  /* write SDRAM bank 2 register */
+  mtdcr(memcfga,mem_mb2cf);
+  mtdcr(memcfgd,bank);
+
+
+  /* get SDRAM bank 3 register */
+  mtdcr(memcfga,mem_mb3cf);
+  bank = mfdcr(memcfgd) & ~0xFFCEE001;
+
+  if (banks == 2) {
+    bank |= (baseaddr | tmp | 0x01);
+    baseaddr += bank_size;
+    sdram_size += bank_size;
+  } /* endif */
+
+  /* write SDRAM bank 3 register */
+  mtdcr(memcfga,mem_mb3cf);
+  mtdcr(memcfgd,bank);
+
+
+  /* get SDRAM refresh interval register */
+  mtdcr(memcfga,mem_rtr);
+  tmp = mfdcr(memcfgd) & ~0x3FF80000;
+
+  if (tmemclk < NSto10PS(16))
+    tmp |= 0x05F00000;
+  else
+    tmp |= 0x03F80000;
+
+  /* write SDRAM refresh interval register */
+  mtdcr(memcfga,mem_rtr);
+  mtdcr(memcfgd,tmp);
+
+  /* enable SDRAM controller with no ECC, 32-bit SDRAM width, 16 byte burst */
+  mtdcr(memcfga,mem_mcopt1);
+  tmp = (mfdcr(memcfgd) &  ~0xFFE00000) | 0x80C00000;
+  mtdcr(memcfga,mem_mcopt1);
+  mtdcr(memcfgd,tmp);
+
+
+  
+   /*-------------------------------------------------------------------------+
+   | Interrupt controller setup for the PIP405 board.
+   | Note: IRQ 0-15  405GP internally generated; active high; level sensitive
+   |       IRQ 16    405GP internally generated; active low; level sensitive
+   |       IRQ 17-24 RESERVED
+   |       IRQ 25 (EXT IRQ 0) SouthBridg; active low; level sensitive
+   |       IRQ 26 (EXT IRQ 1) NMI: active low; level sensitive
+   |       IRQ 27 (EXT IRQ 2) SMI: active Low; level sensitive                          
+   |       IRQ 28 (EXT IRQ 3) PCI SLOT 3; active low; level sensitive
+   |       IRQ 29 (EXT IRQ 4) PCI SLOT 2; active low; level sensitive
+   |       IRQ 30 (EXT IRQ 5) PCI SLOT 1; active low; level sensitive
+   |       IRQ 31 (EXT IRQ 6) PCI SLOT 0; active low; level sensitive
+   | Note for PIP405 board:
+   |       An interrupt taken for the SouthBridge (IRQ 25) indicates that   
+   |       the Interrupt Controller in the South Bridge has caused the 
+   |       interrupt. The IC must be read to determine which device
+   |       caused the interrupt.
+   |          
+   +-------------------------------------------------------------------------*/
+  mtdcr(uicsr, 0xFFFFFFFF);        /* clear all ints */
+  mtdcr(uicer, 0x00000000);        /* disable all ints */
+  mtdcr(uiccr, 0x00000000);        /* set all to be non-critical (for now)*/
+  mtdcr(uicpr, 0xFFFFFF80);        /* set int polarities */
+  mtdcr(uictr, 0x10000000);        /* set int trigger levels */
+  mtdcr(uicvcr, 0x00000001);       /* set vect base=0,INT0 highest priority*/
+  mtdcr(uicsr, 0xFFFFFFFF);        /* clear all ints */
+
+  return 0;
+}
+
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * Check Board Identity:
+ */
+
+int checkboard (void)
+{
+    unsigned char s[32];
+               unsigned char bc;
+               int i;
+               i=getenv_r("serial#",s,32);
+    if ((i==0) || strncmp(s, "PIP405", 6)) {
+                       printf ("### No HW ID - assuming PIP405 ");
+    }
+    else {
+       s[6]=0;
+       printf("%s SN: %s",s,&s[7]);
+               }
+               bc=in8(CONFIG_PORT_ADDR);
+               printf(" Boot Config: 0x%x\n",bc);
+    return (0);
+}
+
+
+/* ------------------------------------------------------------------------- */
+/* ------------------------------------------------------------------------- */
+/*
+  initdram(int board_type) reads EEPROM via I2c. EEPROM contains all of  
+  the necessary info for SDRAM controller configuration
+*/
+/* ------------------------------------------------------------------------- */
+/* ------------------------------------------------------------------------- */
+long int initdram (int board_type)
+{
+  unsigned long bank_reg[4],tmp,bank_size;
+       int i,ds;
+  unsigned long TotalSize;
+
+       ds=0;
+       /* since the DRAM controller is allready set up, calculate the size with the 
+         bank registers         */
+       mtdcr(memcfga,mem_mb0cf);
+  bank_reg[0] = mfdcr(memcfgd);
+       mtdcr(memcfga,mem_mb1cf);
+  bank_reg[1] = mfdcr(memcfgd);
+       mtdcr(memcfga,mem_mb2cf);
+  bank_reg[2] = mfdcr(memcfgd);
+       mtdcr(memcfga,mem_mb3cf);
+  bank_reg[3] = mfdcr(memcfgd);
+  TotalSize=0;
+       for(i=0;i<4;i++)
+       {
+               if((bank_reg[i]&0x1)==0x1)
+               {
+                       tmp=(bank_reg[i]>>17)&0x7;
+                       bank_size=4<<tmp;
+                       TotalSize+=bank_size;
+               }
+               else
+                       ds=1;
+       }
+       if(ds==1)
+      printf("single-sided DIMM ");
+  else
+    printf("double-sided DIMM ");
+  /* return size in Mb unit => *(1024*1024) */
+  return (TotalSize*1024*1024);
+}
+
+/* ------------------------------------------------------------------------- */
+
+int testdram (void)
+{
+    /* TODO: XXX XXX XXX */
+    printf ("test: xxx MB - ok\n");
+
+    return (0);
+}
+
+/* ------------------------------------------------------------------------- */
+
+       /* switches the cs0 and the cs1 to the locations. 
+          When boot is TRUE, the the mapping is switched 
+          to the boot configuration, If it is FALSE, the
+          flash will be switched in the boot area */
+
+
+int switch_cs(unsigned char boot)
+{
+  unsigned long pbcr;
+       mtdcr(ebccfga, pb0cr); /* get cs0 config reg */
+       pbcr = mfdcr(ebccfgd);
+       if((pbcr&0x00002000)==0) {  
+               /* we need only to switch if boot from MPS */
+               /*printf(" MPS boot mode detected. ");*/ 
+               /* printf("cs0 cfg: %lx\n",pbcr); */
+               if(boot==TRUE) { 
+                       /* switch to boot configuration */
+                       /* this is a 8bit boot, switch cs0 to flash location */
+                       /* printf("switch to boot mode (MPS on High address\n"); */ 
+                       pbcr&=0x000FFFFF; /*mask base address of the cs0 */
+                       pbcr|=(FLASH_BASE0_PRELIM & 0xFFF00000);
+                       mtdcr(ebccfga, pb0cr);
+                       mtdcr(ebccfgd, pbcr);
+                       /* printf("  new cs0 cfg: %lx\n",pbcr); */
+                       mtdcr(ebccfga, pb1cr); /* get cs1 config reg (flash) */
+                       pbcr = mfdcr(ebccfgd);
+       /*              printf(" old cs1 cfg: %lx\n",pbcr); */
+                       pbcr&=0x000FFFFF; /*mask base address of the cs1 */
+                       pbcr|=(MULTI_PURPOSE_SOCKET_ADDR & 0xFFF00000);
+                       mtdcr(ebccfga, pb1cr);
+                       mtdcr(ebccfgd, pbcr);
+       /*              printf("  new cs1 cfg: %lx, MPS is on High Address\n",pbcr); */
+               }
+               else 
+               { 
+                       /* map flash to boot area, */
+                       /*printf("map Flash to boot area\n"); */
+                       pbcr&=0x000FFFFF; /*mask base address of the cs0 */
+                       pbcr|=(MULTI_PURPOSE_SOCKET_ADDR & 0xFFF00000);
+                       mtdcr(ebccfga, pb0cr);
+                       mtdcr(ebccfgd, pbcr);
+/*                     printf("  new cs0 cfg: %lx\n",pbcr); */
+                       mtdcr(ebccfga, pb1cr); /* get cs1 config reg (flash) */
+                       pbcr = mfdcr(ebccfgd);
+/*                     printf("  cs1 cfg: %lx\n",pbcr); */
+                       pbcr&=0x000FFFFF; /*mask base address of the cs1 */
+                       pbcr|=(FLASH_BASE0_PRELIM & 0xFFF00000);
+                       mtdcr(ebccfga, pb1cr);
+                       mtdcr(ebccfgd, pbcr);
+/*                     printf("  new cs1 cfg: %lx Flash is on High Address\n",pbcr); */
+               }
+               return TRUE;
+       }
+       else
+               return FALSE;
+/*                             printf("Normal boot, no switching necessary\n"); */
+}
+
+/************************************************************************
+* Print PIP405 Info
+************************************************************************/
+void print_pip405_info(void)
+{
+       unsigned char part,vers,cfg,ledu,sysman,flashcom,can,serpwr,compwr,nicvga,scsirst;
+
+       part=in8(PLD_PART_REG); 
+       vers=in8(PLD_VERS_REG); 
+       cfg=in8(PLD_BOARD_CFG_REG);
+       ledu=in8(PLD_LED_USER_REG);
+       sysman=in8(PLD_SYS_MAN_REG);
+       flashcom=in8(PLD_FLASH_COM_REG);
+       can=in8(PLD_CAN_REG);
+       serpwr=in8(PLD_SER_PWR_REG);
+       compwr=in8(PLD_COM_PWR_REG);
+       nicvga=in8(PLD_NIC_VGA_REG);
+       scsirst=in8(PLD_SCSI_RST_REG);
+       printf("PLD Part %d version %d\n",part&0xf,vers&0xf);
+       printf("PLD Part %d version %d\n",(part>>4)&0xf,(vers>>4)&0xf);
+       printf("Board Revision %c\n",(cfg&0xf)+'A');
+       printf("Population Options %d %d %d %d\n",(cfg>>4)&0x1,(cfg>>5)&0x1,(cfg>>6)&0x1,(cfg>>7)&0x1);
+       printf("User LED0 %s User LED1 %s\n",((ledu&0x1)==0x1) ? "on" : "off",((ledu&0x2)==0x2) ? "on" : "off");
+       printf("Additionally Options %d %d\n",(ledu>>2)&0x1,(ledu>>3)&0x1);
+       printf("User Config Switch %d %d %d %d\n",(ledu>>4)&0x1,(ledu>>5)&0x1,(ledu>>6)&0x1,(ledu>>7)&0x1);
+       switch(sysman&0x3)
+       {
+               case 0: printf("PCI Clocks are running\n"); break;
+               case 1: printf("PCI Clocks are stopped in POS State\n"); break;
+               case 2: printf("PCI Clocks are stopped when PCI_STP# is asserted\n"); break;
+               case 3: printf("PCI Clocks are stopped\n"); break;
+       }
+       switch((sysman>>2)&0x3)
+       {
+               case 0: printf("Main Clocks are running\n"); break;
+               case 1: printf("Main Clocks are stopped in POS State\n"); break;
+               case 2: 
+               case 3: printf("PCI Clocks are stopped\n"); break;
+       }
+       printf("INIT asserts %sINT2# (SMI)\n",((sysman&0x10)==0x10) ? "" : "not ");
+       printf("INIT asserts %sINT1# (NMI)\n",((sysman&0x20)==0x20) ? "" : "not ");
+       printf("INIT occured %d\n",(sysman>>6)&0x1);
+       printf("SER1 is routed to %s\n",((flashcom&0x1)==0x1) ? "RS485" : "RS232");
+       printf("COM2 is routed to %s\n",((flashcom&0x2)==0x2) ? "RS485" : "RS232");
+       printf("RS485 is configured as %s duplex\n",((flashcom&0x4)==0x4) ? "full" : "half");
+       printf("RS485 is connected to %s\n",((flashcom&0x8)==0x8) ? "COM1" : "COM2");
+       printf("SER1 uses handshakes %s\n",((flashcom&0x10)==0x10) ? "DTR/DSR" : "RTS/CTS");
+       printf("Bootflash is %swriteprotected\n",((flashcom&0x20)==0x20) ? "not " : "");
+       printf("Bootflash VPP is %s\n",((flashcom&0x40)==0x40) ? "on" : "off");
+       printf("Bootsector is %swriteprotected\n",((flashcom&0x80)==0x80) ? "not " : "");
+       switch((can)&0x3)
+       {
+               case 0: printf("CAN Controller is on address 0x1000..0x10FF\n"); break;
+               case 1: printf("CAN Controller is on address 0x8000..0x80FF\n"); break;
+               case 2: printf("CAN Controller is on address 0xE000..0xE0FF\n"); break;
+               case 3: printf("CAN Controller is disabled\n"); break;
+       }
+       switch((can>>2)&0x3)
+       {
+               case 0: printf("CAN Controller Reset is ISA Reset\n"); break;
+               case 1: printf("CAN Controller Reset is ISA Reset and POS State\n"); break;
+               case 2: 
+               case 3: printf("CAN Controller is in reset\n"); break;
+       }
+       if(((can>>4)<3)||((can>>4)==8)||((can>>4)==13))
+               printf("CAN Interrupt is disabled\n");
+       else
+               printf("CAN Interrupt is ISA INT%d\n",(can>>4)&0xf);
+       switch(serpwr&0x3)
+       {
+               case 0: printf("SER0 Drivers are enabled\n"); break;
+               case 1: printf("SER0 Drivers are disabled in the POS state\n"); break;
+               case 2: 
+               case 3: printf("SER0 Drivers are disabled\n"); break;
+       }
+       switch((serpwr>>2)&0x3)
+       {
+               case 0: printf("SER1 Drivers are enabled\n"); break;
+               case 1: printf("SER1 Drivers are disabled in the POS state\n"); break;
+               case 2: 
+               case 3: printf("SER1 Drivers are disabled\n"); break;
+       }
+       switch(compwr&0x3)
+       {
+               case 0: printf("COM1 Drivers are enabled\n"); break;
+               case 1: printf("COM1 Drivers are disabled in the POS state\n"); break;
+               case 2: 
+               case 3: printf("COM1 Drivers are disabled\n"); break;
+       }
+       switch((compwr>>2)&0x3)
+       {
+               case 0: printf("COM2 Drivers are enabled\n"); break;
+               case 1: printf("COM2 Drivers are disabled in the POS state\n"); break;
+               case 2: 
+               case 3: printf("COM2 Drivers are disabled\n"); break;
+       }
+       switch((nicvga)&0x3)
+       {
+               case 0: printf("PHY is running\n"); break;
+               case 1: printf("PHY is in Power save mode in POS state\n"); break;
+               case 2: 
+               case 3: printf("PHY is in Power save mode\n"); break;
+       }
+       switch((nicvga>>2)&0x3)
+       {
+               case 0: printf("VGA is running\n"); break;
+               case 1: printf("VGA is in Power save mode in POS state\n"); break;
+               case 2: 
+               case 3: printf("VGA is in Power save mode\n"); break;
+       }
+       printf("PHY is %sreseted\n",((nicvga&0x10)==0x10)?"":"not ");
+       printf("VGA is %sreseted\n",((nicvga&0x20)==0x20)?"":"not ");
+       printf("Reserved Configuration is %d %d\n",(nicvga>>6)&0x1,(nicvga>>7)&0x1);
+       switch((scsirst)&0x3)
+       {
+               case 0: printf("SCSI Controller is running\n"); break;
+               case 1: printf("SCSI Controller is in Power save mode in POS state\n"); break;
+               case 2: 
+               case 3: printf("SCSI Controller is in Power save mode\n"); break;
+       }
+       printf("SCSI termination is %s\n",((scsirst&0x4)==0x4)?"disabled":"enabled");
+       printf("SCSI Controller is %sreseted\n",((scsirst&0x10)==0x10)?"":"not ");
+       printf("IDE disks are %sreseted\n",((scsirst&0x20)==0x20)?"":"not ");
+       printf("ISA Bus is %sreseted\n",((scsirst&0x40)==0x40)?"":"not ");
+       printf("Super IO is %sreseted\n",((scsirst&0x80)==0x80)?"":"not ");
+}
+
+void user_led0(unsigned char on)
+{
+       if(on==TRUE)
+               out8(PLD_LED_USER_REG,(in8(PLD_LED_USER_REG)|0x1));
+       else
+               out8(PLD_LED_USER_REG,(in8(PLD_LED_USER_REG)&0xfe));
+}
+
+void user_led1(unsigned char on)
+{
+       if(on==TRUE)
+               out8(PLD_LED_USER_REG,(in8(PLD_LED_USER_REG)|0x2));
+       else
+               out8(PLD_LED_USER_REG,(in8(PLD_LED_USER_REG)&0xfd));
+}
+
+void ide_set_reset(int idereset)
+{
+       /* if reset = 1 IDE reset will be asserted */
+       unsigned char resreg;
+       resreg=in8(PLD_SCSI_RST_REG);
+       if(idereset==1)
+               resreg|=0x20;
+       else
+               resreg&=0xdf;
+       out8(PLD_SCSI_RST_REG,resreg); 
+}
+
+
+/******************************************************
+ * Routines to display the Board information 
+ * to the screen (since the VGA will be initialized as last,
+ * we must resend the infos)
+ */
+
+void video_put_dev_string(block_dev_desc_t *dev_desc)
+{
+       char buf[80];
+       ldiv_t mb;
+       unsigned long lba512; /* number of blocks if 512bytes block size */
+
+       if(dev_desc->type!=DEV_TYPE_UNKNOWN) {
+               if(dev_desc->if_type==IF_TYPE_SCSI)
+                       sprintf(buf,"SCSI %d:  (%d:%d) ",dev_desc->dev,dev_desc->target,dev_desc->lun);
+               else
+                       sprintf(buf,"IDE %d:   ",dev_desc->dev);
+               video_puts(buf);
+               switch(dev_desc->type & 0x1F) {
+                       case DEV_TYPE_HARDDISK: video_puts("Hard Disk"); break;
+                       case DEV_TYPE_CDROM:            video_puts("CD ROM"); break;
+                       case DEV_TYPE_OPDISK:   video_puts("Optical Device"); break;
+                       case DEV_TYPE_TAPE:             video_puts("Tape"); break;
+                       default:                                                        video_puts("unknown"); break;
+               }
+               video_puts(" ");
+               video_puts(dev_desc->vendor);
+               video_puts(" ");
+               if(dev_desc->if_type!=IF_TYPE_IDE)
+                       video_puts(dev_desc->product);
+       
+               if((dev_desc->lba * dev_desc->blksz)>0L) {
+                       lba512=dev_desc->lba * (dev_desc->blksz/512);
+                       mb = ldiv(lba512, 2048); /* (1024 *1024 / 512 MB */
+                       /* round to 1 digit */
+                       mb.rem *= 10 * 512;
+                       mb.rem += 512 * 1024;
+                       mb.rem /= 1024 * 1024;
+                       sprintf (buf," %ld x %ld Bytes = %ld.%ld MB\n",dev_desc->lba,dev_desc->blksz,mb.quot, mb.rem);
+               }
+               else {
+                       sprintf (buf," Capacity: not available\n");
+               }
+               video_puts(buf);
+       }
+} 
+
+void video_write_board_info(void)
+{
+       extern char version_string[];
+  unsigned long pvr = get_pvr();
+  char buf[32],tmpbuf[80];
+  PPC405_SYS_INFO sys_info;
+  init_data_t *idata = (init_data_t *)(CFG_INIT_RAM_ADDR + CFG_INIT_DATA_OFFSET);
+  unsigned char *s = getenv("serial#");
+  unsigned char *e;
+  unsigned char bc;
+  block_dev_desc_t *dev_desc;
+       int i;
+       
+       /* first write PPCBOOT Info */
+       video_puts("\n");
+       video_puts(version_string);
+       video_puts("\n\n");
+       /* then CPU and board infos */
+  get_sys_info(&sys_info);
+  video_puts("CPU:     IBM PowerPC 405GP Rev. ");
+  switch (pvr) {
+    case PVR_405GP_RB: video_putc('B'); break;
+    case PVR_405GP_RC: video_putc('C'); break;
+    case PVR_405GP_RD: video_putc('D'); break;
+    default: video_puts("unknown"); break;
+  }
+  sprintf(tmpbuf," at %s MHz (PLB=%lu, OPB=%lu, EBC=%lu MHz)\n", strmhz(buf,idata->cpu_clk),
+         sys_info.freqPLB / 1000000,
+         sys_info.freqPLB / sys_info.pllOpbDiv / 1000000,
+         sys_info.freqPLB / sys_info.pllExtBusDiv / 1000000);
+       video_puts(tmpbuf);
+  if (mfdcr(strap) & PSR_PCI_ASYNC_EN)
+    video_puts("         PCI async ext clock used, ");
+  else {
+       sprintf(buf,"         PCI sync clock at %lu MHz, ", sys_info.freqPLB / sys_info.pllPciDiv / 1000000);
+    video_puts(buf);
+  }
+  if (mfdcr(strap) & PSR_PCI_ARBIT_EN)
+    video_puts("internal PCI arbiter enabled\n");
+  else
+    video_puts("external PCI arbiter enabled\n");
+  video_puts("         16 kB I-Cache 8 kB D-Cache\n");
+  /* now some board infos */
+  video_puts("Board:   ");
+  if (!s || strncmp(s, "PIP405", 6)) {
+       bc=video_set_attr(VGA_ATTR_CLR_RED | VGA_ATTR_ITN);
+               video_puts("### No HW ID - assuming PIP405");
+  }
+  else {
+       bc=video_set_attr(VGA_ATTR_CLR_GRN);
+       for (e=s; *e; ++e) {
+       if (*e == ' ')
+               break;
+    }
+    for ( ; s<e; ++s) {
+       if(*s=='_') {
+                               ++s;
+                               break;
+                       }
+                       video_putc (*s);
+               }
+               video_puts("  Serial No.: ");
+    for ( ; s<e; ++s) {
+                       video_putc (*s);
+               }
+  }
+       video_set_attr(bc);
+       bc=in8(CONFIG_PORT_ADDR);
+       sprintf(buf," Boot Config 0x%02X\n",bc);
+  video_puts(buf);
+       /* DRAM size    */
+  video_puts("DRAM:    ");
+       sprintf(buf,"%lu MBytes\n",bd_ptr->bi_memsize/0x100000);                
+  video_puts(buf);
+  /* flash size: */
+  video_puts("FLASH:   ");
+  if(switch_cs(0)==0) {
+       bc=video_set_attr(VGA_ATTR_CLR_GRN);
+               video_puts("(Flash boot)");
+               video_set_attr(bc);
+       }
+       else {
+       switch_cs(1); /* back to boot mode */
+               bc=video_set_attr(VGA_ATTR_CLR_RED | VGA_ATTR_ITN);
+               video_puts("(Multi Purpose Socket boot)");
+               video_set_attr(bc);
+       }
+       sprintf(buf," %lu MBytes\n",bd_ptr->bi_flashsize/0x100000);             
+  video_puts(buf);
+       /* revisions */
+  video_puts("Rev:     ");
+       sprintf(tmpbuf,"PCB Rev: %c PLD%d Rev %d PLD%d Rev %d\n\n",(in8(PLD_BOARD_CFG_REG)&0xf)+'A',
+                               in8(PLD_PART_REG)&0xf,in8(PLD_VERS_REG)&0xf,
+                               (in8(PLD_PART_REG)>>4)&0xf,(in8(PLD_VERS_REG)>>4)&0xf);         
+  video_puts(tmpbuf);
+       for(i=0;i<CFG_IDE_MAXDEVICE;i++) {
+               dev_desc=(block_dev_desc_t *)ide_get_dev(i);
+               video_put_dev_string(dev_desc);
+       }
+       video_puts("\n");
+       for(i=0;i<CFG_SCSI_MAX_DEVICE;i++) {
+               dev_desc=(block_dev_desc_t *)scsi_get_dev(i);
+               video_put_dev_string(dev_desc);
+       }
+       video_puts("\n");
+                       
+}
+
+
+
+
+
+
diff --git a/board/pip405/pip405.h b/board/pip405/pip405.h
new file mode 100644 (file)
index 0000000..ef65aa0
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * (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
+ *
+ */
+ /****************************************************************************
+ * Global routines used for PIP405
+ *****************************************************************************/
+int switch_cs(unsigned char boot);
+
+
+void print_pip405_info(void);
+
+void user_led0(unsigned char on);
+void user_led1(unsigned char on);
+
+#define PLD_BASE_ADDRESS               CFG_ISA_IO_BASE_ADDRESS + 0x800
+#define PLD_PART_REG                           PLD_BASE_ADDRESS + 0
+#define PLD_VERS_REG                           PLD_BASE_ADDRESS + 1
+#define PLD_BOARD_CFG_REG              PLD_BASE_ADDRESS + 2
+#define PLD_LED_USER_REG               PLD_BASE_ADDRESS + 3
+#define PLD_SYS_MAN_REG                        PLD_BASE_ADDRESS + 4
+#define PLD_FLASH_COM_REG              PLD_BASE_ADDRESS + 5
+#define PLD_CAN_REG                                    PLD_BASE_ADDRESS + 6
+#define PLD_SER_PWR_REG                        PLD_BASE_ADDRESS + 7
+#define PLD_COM_PWR_REG                        PLD_BASE_ADDRESS + 8
+#define PLD_NIC_VGA_REG                        PLD_BASE_ADDRESS + 9
+#define PLD_SCSI_RST_REG               PLD_BASE_ADDRESS + 0xA
+
+#define PIIX4_VENDOR_ID                        0x8086
+#define PIIX4_IDE_DEV_ID               0x7111
+
+
diff --git a/board/pip405/pip405_isa.c b/board/pip405/pip405_isa.c
new file mode 100644 (file)
index 0000000..4311617
--- /dev/null
@@ -0,0 +1,454 @@
+/*
+ * (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
+ *
+ *
+ * TODO: clean-up
+ */
+#include <ppcboot.h>
+#include <asm/processor.h>
+#include <devices.h>
+#include "pip405.h"
+#include "pip405_isa.h"
+#include "pci_piix4.h"
+#include "kbd.h"
+#include "video.h"
+
+
+#undef ISA_DEBUG
+
+#ifdef ISA_DEBUG
+#define        PRINTF(fmt,args...)     printf (fmt ,##args)
+#else
+#define PRINTF(fmt,args...)
+#endif
+
+#ifndef        TRUE
+#define TRUE            1
+#endif
+#ifndef FALSE
+#define FALSE           0
+#endif
+
+
+
+/* fdc (logical device 0) */
+const SIO_LOGDEV_TABLE sio_fdc[] = {
+       {0x60, 3},                      /* set IO to FDPort (3F0) */
+       {0x61, 0xF0},           /* set IO to FDPort (3F0) */
+       {0x70, 06},                     /* set IRQ 6 for FDPort */
+       {0x74, 02},                     /* set DMA 2 for FDPort */
+       {0xF0, 0x05},           /* set to PS2 type */
+       {0xF1, 0x00},     /* default value */
+       {0x30, 1},                      /* and activate the device */
+       {0xFF, 0}                               /* end of device table */
+};
+/* paralell port (logical device 3) */
+const SIO_LOGDEV_TABLE sio_pport[] = {
+       {0x60, 3},                      /* set IO to PPort (378) */
+       {0x61, 0x78},           /* set IO to PPort (378) */
+       {0x70, 07},                     /* set IRQ 7 for PPort */
+       {0x30, 1},                      /* and activate the device */
+       {0xFF, 0}                               /* end of device table */
+};
+/* uart 1 (logical device 4) */
+const SIO_LOGDEV_TABLE sio_com1[] = {
+       {0x60, 3},                      /* set IO to COM1 (3F8) */
+       {0x61, 0xF8},           /* set IO to COM1 (3F8) */
+       {0x70, 04},                     /* set IRQ 4 for COM1 */
+       {0x30, 1},                      /* and activate the device */
+       {0xFF, 0}                               /* end of device table */
+};
+/* uart 2 (logical device 5) */
+const SIO_LOGDEV_TABLE sio_com2[] = {
+       {0x60, 2},                      /* set IO to COM2 (2F8) */
+       {0x61, 0xF8},           /* set IO to COM2 (2F8) */
+       {0x70, 03},                     /* set IRQ 3 for COM2 */
+       {0x30, 1},                      /* and activate the device */
+       {0xFF, 0}                               /* end of device table */
+};
+
+/* keyboard controller (logical device 7) */
+const SIO_LOGDEV_TABLE sio_keyboard[] = {
+       {0x70, 1},                      /* set IRQ 1 for keyboard */
+       {0x72, 12},                     /* set IRQ 12 for mouse */
+       {0xF0, 0},                      /* disable Port92 (this is a PowerPC!!) */
+       {0x30, 1},                      /* and activate the device */
+       {0xFF, 0}                               /* end of device table */
+};
+
+/* SIO initialization table */
+const SIO_TABLE sio_table[] = {
+       {0, sio_fdc},                           /* init table for floppy disk controller */
+       {3, sio_pport},                 /* init table for paralell port */
+       {4, sio_com1},                  /* init table for COM1 */
+       {5, sio_com2},                  /* init table for COM2 */
+       {7, sio_keyboard},      /* init table for keyboard controller */
+       {0, NULL}                                               /* end of SIO table */
+};
+
+/*******************************************************************************
+* Config SuperIO FDC37C672
+********************************************************************************/
+unsigned char open_cfg_super_IO(int address)
+{
+       out8(CFG_ISA_IO_BASE_ADDRESS | address,0x55); /* open config */
+       out8(CFG_ISA_IO_BASE_ADDRESS | address,0x20); /* set address to DEV ID */
+       if(in8(CFG_ISA_IO_BASE_ADDRESS | address | 0x1)==0x40) /* ok Device ID is correct */
+               return TRUE;
+       else 
+               return FALSE;
+}
+
+void close_cfg_super_IO(int address)
+{
+       out8(CFG_ISA_IO_BASE_ADDRESS | address,0xAA); /* close config */
+}
+
+
+unsigned char read_cfg_super_IO(int address, unsigned char function, unsigned char regaddr)
+{
+       /* assuming config reg is open */
+       out8(CFG_ISA_IO_BASE_ADDRESS | address,0x7); /* points to the function reg */
+       out8(CFG_ISA_IO_BASE_ADDRESS | address | 1,function); /* set the function no */
+       out8(CFG_ISA_IO_BASE_ADDRESS | address,regaddr); /* sets the address in the function */
+       return in8(CFG_ISA_IO_BASE_ADDRESS | address | 1);      
+}
+
+void write_cfg_super_IO(int address, unsigned char function, unsigned char regaddr, unsigned char data)
+{
+       /* assuming config reg is open */
+       out8(CFG_ISA_IO_BASE_ADDRESS | address,0x7); /* points to the function reg */
+       out8(CFG_ISA_IO_BASE_ADDRESS | address | 1,function); /* set the function no */
+       out8(CFG_ISA_IO_BASE_ADDRESS | address,regaddr); /* sets the address in the function */
+       out8(CFG_ISA_IO_BASE_ADDRESS | address | 1,data); /* writes the data */
+}
+
+void isa_sio_loadtable(void)
+{
+       SIO_TABLE *t = (SIO_TABLE *)sio_table;
+       SIO_LOGDEV_TABLE *ldt;
+       
+       while (t->ldev_table != NULL) {
+               /* as long as their are logical device */
+               ldt = (SIO_LOGDEV_TABLE *)t->ldev_table;
+               
+               while (ldt->index != 0xFF) {
+                       /* as long as their are register to be programmed for this device, do it */
+                       write_cfg_super_IO(SIO_CFG_PORT, t->ldev, ldt->index, ldt->val);
+                       ldt++;  
+               } /* endwhile */
+               t++;
+       } /* endwhile */
+}
+
+
+void isa_sio_setup()
+{
+       if(open_cfg_super_IO(SIO_CFG_PORT)==TRUE)
+       {
+               
+               isa_sio_loadtable();
+               close_cfg_super_IO(0x3F0);      
+       }
+}
+
+
+
+/******************************************************************************
+ * IRQ Controller
+ * we use the Vector mode
+ */
+
+struct isa_irq_action {
+        interrupt_handler_t *handler;
+        void *arg;
+        int count;
+};
+
+static struct isa_irq_action isa_irqs[16];
+
+
+/*
+ * This contains the irq mask for both 8259A irq controllers,
+ */
+static unsigned int cached_irq_mask = 0xffff;
+
+#define cached_imr1    (unsigned char)cached_irq_mask
+#define cached_imr2    (unsigned char)(cached_irq_mask>>8)
+#define IMR_1          CFG_ISA_IO_BASE_ADDRESS + PIIX4_ISA_INT1_OCW1
+#define IMR_2          CFG_ISA_IO_BASE_ADDRESS + PIIX4_ISA_INT2_OCW1
+#define ICW1_1 CFG_ISA_IO_BASE_ADDRESS + PIIX4_ISA_INT1_ICW1
+#define ICW1_2 CFG_ISA_IO_BASE_ADDRESS + PIIX4_ISA_INT2_ICW1
+#define ICW2_1 CFG_ISA_IO_BASE_ADDRESS + PIIX4_ISA_INT1_ICW2
+#define ICW2_2 CFG_ISA_IO_BASE_ADDRESS + PIIX4_ISA_INT2_ICW2
+#define ICW3_1 ICW2_1
+#define ICW3_2 ICW2_2
+#define ICW4_1 ICW2_1
+#define ICW4_2 ICW2_2
+#define ISR_1          ICW1_1
+#define ISR_2          ICW1_2
+
+
+void disable_8259A_irq(unsigned int irq)
+{
+       unsigned int mask = 1 << irq;
+
+       cached_irq_mask |= mask;
+       if (irq & 8)
+               out8(IMR_2,cached_imr2);
+       else
+               out8(IMR_1,cached_imr1);
+}
+
+void enable_8259A_irq(unsigned int irq)
+{
+       unsigned int mask = ~(1 << irq);
+
+       cached_irq_mask &= mask;
+       if (irq & 8)
+               out8(IMR_2,cached_imr2);
+       else
+               out8(IMR_1,cached_imr1);
+}
+/*
+int i8259A_irq_pending(unsigned int irq)
+{
+       unsigned int mask = 1<<irq;
+       int ret;
+
+       if (irq < 8)
+               ret = inb(0x20) & mask;
+       else
+               ret = inb(0xA0) & (mask >> 8);
+       spin_unlock_irqrestore(&i8259A_lock, flags);
+
+       return ret;
+}
+*/
+
+/*
+ * This function assumes to be called rarely. Switching between
+ * 8259A registers is slow.
+ */
+int i8259A_irq_real(unsigned int irq)
+{
+       int value;
+       int irqmask = 1<<irq;
+
+       if (irq < 8) {
+               out8(ISR_1,0x0B);               /* ISR register */
+               value = in8(ISR_1) & irqmask;
+               out8(ISR_1,0x0A);               /* back to the IRR register */
+               return value;
+       }
+       out8(ISR_2,0x0B);               /* ISR register */
+       value = in8(ISR_2) & (irqmask >> 8);
+       out8(ISR_2,0x0A);               /* back to the IRR register */
+       return value;
+}
+
+/*
+ * Careful! The 8259A is a fragile beast, it pretty
+ * much _has_ to be done exactly like this (mask it
+ * first, _then_ send the EOI, and the order of EOI
+ * to the two 8259s is important!
+ */
+void mask_and_ack_8259A(unsigned int irq)
+{
+       unsigned int irqmask = 1 << irq;
+       unsigned int temp_irqmask = cached_irq_mask;
+       /*
+        * Lightweight spurious IRQ detection. We do not want
+        * to overdo spurious IRQ handling - it's usually a sign
+        * of hardware problems, so we only do the checks we can
+        * do without slowing down good hardware unnecesserily.
+        *
+        * Note that IRQ7 and IRQ15 (the two spurious IRQs
+        * usually resulting from the 8259A-1|2 PICs) occur
+        * even if the IRQ is masked in the 8259A. Thus we
+        * can check spurious 8259A IRQs without doing the
+        * quite slow i8259A_irq_real() call for every IRQ.
+        * This does not cover 100% of spurious interrupts,
+        * but should be enough to warn the user that there
+        * is something bad going on ...
+        */
+       if (temp_irqmask & irqmask)
+               goto spurious_8259A_irq;
+       temp_irqmask |= irqmask;
+
+handle_real_irq:
+       if (irq & 8) {
+               in8(IMR_2);             /* DUMMY - (do we need this?) */
+               out8(IMR_2,(unsigned char)(temp_irqmask>>8));
+               out8(ISR_2,0x60+(irq&7));/* 'Specific EOI' to slave */
+               out8(ISR_1,0x62);       /* 'Specific EOI' to master-IRQ2 */
+               out8(IMR_2,cached_imr2); /* turn it on again */
+       } else {
+               in8(IMR_1);             /* DUMMY - (do we need this?) */
+               out8(IMR_1,(unsigned char)temp_irqmask);
+               out8(ISR_1,0x60+irq);   /* 'Specific EOI' to master */
+               out8(IMR_1,cached_imr1); /* turn it on again */
+       }
+       
+       return;
+
+spurious_8259A_irq:
+       /*
+        * this is the slow path - should happen rarely.
+        */
+       if (i8259A_irq_real(irq))
+               /*
+                * oops, the IRQ _is_ in service according to the
+                * 8259A - not spurious, go handle it.
+                */
+               goto handle_real_irq;
+
+       {
+               static int spurious_irq_mask;
+               /*
+                * At this point we can be sure the IRQ is spurious,
+                * lets ACK and report it. [once per IRQ]
+                */
+               if (!(spurious_irq_mask & irqmask)) {
+                       PRINTF("spurious 8259A interrupt: IRQ%d.\n", irq);
+                       spurious_irq_mask |= irqmask;
+               }
+               /* irq_err_count++; */
+               /*
+                * Theoretically we do not have to handle this IRQ,
+                * but in Linux this does not cause problems and is
+                * simpler for us.
+                */
+               goto handle_real_irq;
+       }
+}
+
+void init_8259A(void)
+{
+       out8(IMR_1,0xff);       /* mask all of 8259A-1 */
+       out8(IMR_2,0xff);       /* mask all of 8259A-2 */
+
+       out8(ICW1_1,0x11);      /* ICW1: select 8259A-1 init */
+       out8(ICW2_1,0x20 + 0);  /* ICW2: 8259A-1 IR0-7 mapped to 0x20-0x27 */
+       out8(ICW3_1,0x04);      /* 8259A-1 (the master) has a slave on IR2 */
+       out8(ICW4_1,0x01);      /* master expects normal EOI */
+       out8(ICW1_2,0x11);      /* ICW2: select 8259A-2 init */
+       out8(ICW2_2,0x20 + 8);  /* ICW2: 8259A-2 IR0-7 mapped to 0x28-0x2f */
+       out8(ICW3_2,0x02);      /* 8259A-2 is a slave on master's IR2 */
+       out8(ICW4_2,0x01);      /* (slave's support for AEOI in flat mode
+                                   is to be investigated) */
+       udelay(10000);          /* wait for 8259A to initialize */
+       out8(IMR_1,cached_imr1);        /* restore master IRQ mask */
+       udelay(10000);          /* wait for 8259A to initialize */
+       out8(IMR_2,cached_imr2);        /* restore slave IRQ mask */
+}
+
+
+#define PCI_INT_ACK_ADDR 0xEED00000
+
+int handle_isa_int(void)
+{
+       unsigned long irqack;
+       unsigned char isr1,isr2,irq;
+       /* first we acknokledge the int via the PCI bus */
+       irqack=in32(PCI_INT_ACK_ADDR);
+       /* now we get the ISRs */
+       isr2=in8(ISR_2);
+       isr1=in8(ISR_1);
+       irq=(unsigned char)irqack;
+       if((irq==7)&&((isr1&0x80)==0)) {
+               PRINTF("IRQ7 detected but not in ISR\n");
+       }
+       else {
+               /* we should handle cascaded interrupts here also */
+               /* printf("ISA Irq %d\n",irq); */
+               isa_irqs[irq].count++;
+       if (isa_irqs[irq].handler != NULL)
+               (*isa_irqs[irq].handler)(isa_irqs[irq].arg);      /* call isr */
+       else
+       {
+       PRINTF ("bogus interrupt vector 0x%x\n", irq);
+       }
+       }
+       /* issue EOI instruction to clear the IRQ */
+       mask_and_ack_8259A(irq);
+       return 0;
+}
+
+
+
+/******************************************************************
+ * Install and free an ISA interrupt handler.
+ */
+
+void isa_irq_install_handler(int vec, interrupt_handler_t *handler, void *arg)
+{
+  if (isa_irqs[vec].handler != NULL) {
+   printf ("ISA Interrupt vector %d: handler 0x%x replacing 0x%x\n",
+           vec, (uint)handler, (uint)isa_irqs[vec].handler);
+  }
+  isa_irqs[vec].handler = handler;
+  isa_irqs[vec].arg     = arg;
+  enable_8259A_irq(vec);
+       PRINTF ("Install ISA IRQ %d ==> %p, @ %p mask=%04x\n", vec, handler, &isa_irqs[vec].handler,cached_irq_mask);
+
+}
+
+void isa_irq_free_handler(int vec)
+{
+       disable_8259A_irq(vec);
+  isa_irqs[vec].handler = NULL;
+  isa_irqs[vec].arg     = NULL;
+       printf ("Free ISA IRQ %d mask=%04x\n", vec, cached_irq_mask);
+
+}
+
+/****************************************************************************/
+
+
+
+
+void isa_init_irq_contr(void)
+{
+       int i;
+       /* disable all Interrupts */
+       /* first write icws controller 1 */
+       for(i=0;i<16;i++)
+       {
+               isa_irqs[i].handler=NULL;
+               isa_irqs[i].arg=NULL;
+               isa_irqs[i].count=0;
+       }
+       init_8259A();
+       out8(IMR_2,0xFF);                               
+}
+
+/***************************************************************************
+ * some helping routines
+ */
+
+int overwrite_console(void)
+{
+       return(in8(CONFIG_PORT_ADDR) & 0x1); /* return TRUE if console should be overwritten */
+}
+
diff --git a/board/pip405/pip405_isa.h b/board/pip405/pip405_isa.h
new file mode 100644 (file)
index 0000000..1b775fb
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * (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
+ */
+#ifndef _PIP405_ISA_H_
+#define _PIP405_ISA_H_
+/* Super IO */
+#define SIO_CFG_PORT   0x3F0   /* Config Port Address */
+
+
+
+/* table fore SIO initialization */
+typedef struct {
+       const uchar index;
+       const uchar val;
+} SIO_LOGDEV_TABLE;
+
+typedef struct {
+       const uchar ldev;
+       const SIO_LOGDEV_TABLE *ldev_table;
+} SIO_TABLE;
+
+
+
+
+unsigned char open_cfg_super_IO(int address);
+unsigned char read_cfg_super_IO(int address, unsigned char function, unsigned char regaddr);
+void write_cfg_super_IO(int address, unsigned char function, unsigned char regaddr, unsigned char data);
+void close_cfg_super_IO(int address);
+void isa_sio_setup(void);
+void isa_sio_setup(void);
+void isa_irq_install_handler(int vec, interrupt_handler_t *handler, void *arg);
+void isa_irq_free_handler(int vec);
+int handle_isa_int(void); 
+
+
+#endif
diff --git a/board/pip405/ppcboot.lds b/board/pip405/ppcboot.lds
new file mode 100644 (file)
index 0000000..01cdff5
--- /dev/null
@@ -0,0 +1,144 @@
+/*
+ * (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
+ */
+
+OUTPUT_ARCH(powerpc)
+SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
+/* Do we need any of these for elf?
+   __DYNAMIC = 0;    */
+SECTIONS
+{
+  .resetvec 0xFFFFFFFC :
+  {
+    *(.resetvec)
+  } = 0xffff
+
+  /* Read-only sections, merged into text segment: */
+  . = + SIZEOF_HEADERS;
+  .interp : { *(.interp) }
+  .hash          : { *(.hash)          }
+  .dynsym        : { *(.dynsym)                }
+  .dynstr        : { *(.dynstr)                }
+  .rel.text      : { *(.rel.text)              }
+  .rela.text     : { *(.rela.text)     }
+  .rel.data      : { *(.rel.data)              }
+  .rela.data     : { *(.rela.data)     }
+  .rel.rodata    : { *(.rel.rodata)    }
+  .rela.rodata   : { *(.rela.rodata)   }
+  .rel.got       : { *(.rel.got)               }
+  .rela.got      : { *(.rela.got)              }
+  .rel.ctors     : { *(.rel.ctors)     }
+  .rela.ctors    : { *(.rela.ctors)    }
+  .rel.dtors     : { *(.rel.dtors)     }
+  .rela.dtors    : { *(.rela.dtors)    }
+  .rel.bss       : { *(.rel.bss)               }
+  .rela.bss      : { *(.rela.bss)              }
+  .rel.plt       : { *(.rel.plt)               }
+  .rela.plt      : { *(.rela.plt)              }
+  .init          : { *(.init)  }
+  .plt : { *(.plt) }
+  .text      :
+  {
+    /* WARNING - the following is hand-optimized to fit within */
+    /* the sector layout of our flash chips!   XXX FIXME XXX   */
+
+    cpu/ppc4xx/start.o (.text)
+    board/pip405/init.o        (.text)
+    cpu/ppc4xx/kgdb.o  (.text)
+    cpu/ppc4xx/traps.o (.text)
+    cpu/ppc4xx/interrupts.o    (.text)
+    cpu/ppc4xx/serial.o        (.text)
+    cpu/ppc4xx/cpu_init.o      (.text)
+    cpu/ppc4xx/speed.o (.text)
+    cpu/ppc4xx/405gp_enet.o    (.text)
+    common/dlmalloc.o  (.text)
+    ppc/crc32.o                (.text)
+    ppc/extable.o      (.text)
+    ppc/zlib.o         (.text)
+
+/*    . = env_offset;*/
+/*    common/environment.o(.text)*/
+
+    *(.text)
+    *(.fixup)
+    *(.got1)
+  }
+  _etext = .;
+  PROVIDE (etext = .);
+  .rodata    :
+  {
+    *(.rodata)
+    *(.rodata1)
+  }
+  .fini      : { *(.fini)    } =0
+  .ctors     : { *(.ctors)   }
+  .dtors     : { *(.dtors)   }
+
+  /* Read-write section, merged into data segment: */
+  . = (. + 0x00FF) & 0xFFFFFF00;
+  _erotext = .;
+  PROVIDE (erotext = .);
+  .reloc   :
+  {
+    *(.got) 
+    _GOT2_TABLE_ = .;
+    *(.got2)
+    _FIXUP_TABLE_ = .;
+    *(.fixup)
+  }
+  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+  __fixup_entries = (. - _FIXUP_TABLE_)>>2;
+
+  .data    :
+  {
+    *(.data)
+    *(.data1)
+    *(.sdata)
+    *(.sdata2)
+    *(.dynamic)
+    CONSTRUCTORS
+  }
+  _edata  =  .;
+  PROVIDE (edata = .);
+
+  __start___ex_table = .;
+  __ex_table : { *(__ex_table) }
+  __stop___ex_table = .;
+
+  . = ALIGN(256);
+  __init_begin = .;
+  .text.init : { *(.text.init) }
+  .data.init : { *(.data.init) }
+  . = ALIGN(256);
+  __init_end = .;
+
+  __bss_start = .;
+  .bss       :
+  {
+   *(.sbss) *(.scommon)
+   *(.dynbss)
+   *(.bss)
+   *(COMMON)
+  }
+  _end = . ;
+  PROVIDE (end = .);
+}
diff --git a/board/pip405/ppcboot.lds.debug b/board/pip405/ppcboot.lds.debug
new file mode 100644 (file)
index 0000000..266238e
--- /dev/null
@@ -0,0 +1,131 @@
+/*
+ * (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
+ */
+
+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      :
+  {
+    /* WARNING - the following is hand-optimized to fit within */
+    /* the sector layout of our flash chips!   XXX FIXME XXX   */
+
+    mpc8xx/start.o     (.text)
+    common/dlmalloc.o  (.text)
+    ppc/vsprintf.o     (.text)
+    ppc/crc32.o                (.text)
+    ppc/extable.o      (.text)
+
+    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: */
+  . = (. + 0x0FFF) & 0xFFFFF000;
+  _erotext = .;
+  PROVIDE (erotext = .);
+  .reloc   :
+  {
+    *(.got) 
+    _GOT2_TABLE_ = .;
+    *(.got2)
+    _FIXUP_TABLE_ = .;
+    *(.fixup)
+  }
+  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+  __fixup_entries = (. - _FIXUP_TABLE_)>>2;
+
+  .data    :
+  {
+    *(.data)
+    *(.data1)
+    *(.sdata)
+    *(.sdata2)
+    *(.dynamic)
+    CONSTRUCTORS
+  }
+  _edata  =  .;
+  PROVIDE (edata = .);
+
+  __start___ex_table = .;
+  __ex_table : { *(__ex_table) }
+  __stop___ex_table = .;
+
+  . = ALIGN(4096);
+  __init_begin = .;
+  .text.init : { *(.text.init) }
+  .data.init : { *(.data.init) }
+  . = ALIGN(4096);
+  __init_end = .;
+
+  __bss_start = .;
+  .bss       :
+  {
+   *(.sbss) *(.scommon)
+   *(.dynbss)
+   *(.bss)
+   *(COMMON)
+  }
+  _end = . ;
+  PROVIDE (end = .);
+}
+
diff --git a/board/pip405/sym53c8xx.c b/board/pip405/sym53c8xx.c
new file mode 100644 (file)
index 0000000..6e2ed33
--- /dev/null
@@ -0,0 +1,751 @@
+/*
+ * (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.
+ */
+
+#include <ppcboot.h>
+#include <command.h> 
+#include <cmd_boot.h>
+#include "pci_pip405.h"
+#include <asm/processor.h>
+#include "sym53c8xx_defs.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 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);
+       scsi_mem_addr=addr;
+       scsi_chip_init();
+       scsi_bus_reset();
+       irq_install_handler(vec, (interrupt_handler_t *)handle_scsi_int, NULL);
+}
+
+
+/************************************************************************************
+ * 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;
+       t=scsi_read_byte(SCNTL1);
+       scsi_write_byte(SCNTL1,(t | CRST));
+       udelay(50);
+       scsi_write_byte(SCNTL1,t);
+       for(i=0;i<2000;i++)
+               udelay(1000); /* 2sec to give the devices time to spin up */
+       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((unsigned long)&script_cmd[0x04]); /* 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((unsigned long)&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((unsigned long)&pccb->msgout[0]);
+       script_msgout[i++]=swap_script(SCR_JUMP ^ IFTRUE (WHEN (SCR_COMMAND))); /* if Command phase */
+       script_msgout[i++]=swap_script((unsigned long)&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((unsigned long)&pccb->cmd[0]);
+       script_cmd[i++]=swap_script(SCR_JUMP ^ IFTRUE (WHEN (SCR_MSG_IN))); /* message in ? */
+       script_cmd[i++]=swap_script((unsigned long)&script_msgin[0]);
+       script_cmd[i++]=swap_script(SCR_JUMP ^ IFTRUE (IF (SCR_DATA_OUT))); /* data out ? */
+       script_cmd[i++]=swap_script((unsigned long)&script_data_out[0]);
+       script_cmd[i++]=swap_script(SCR_JUMP ^ IFTRUE (IF (SCR_DATA_IN))); /* data in ? */
+       script_cmd[i++]=swap_script((unsigned long)&script_data_in[0]);
+       script_cmd[i++]=swap_script(SCR_JUMP ^ IFTRUE (IF (SCR_STATUS)));  /* status ? */
+       script_cmd[i++]=swap_script((unsigned long)&script_status[0]);
+       script_cmd[i++]=swap_script(SCR_JUMP ^ IFTRUE (IF (SCR_COMMAND)));  /* command ? */
+       script_cmd[i++]=swap_script((unsigned long)&script_cmd[0]);
+       script_cmd[i++]=swap_script(SCR_JUMP ^ IFTRUE (IF (SCR_MSG_OUT)));  /* message out ? */
+       script_cmd[i++]=swap_script((unsigned long)&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((unsigned long)&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((unsigned long)pccb->pdata); /* pointer to buffer */
+       script_data_out[i++]=swap_script(SCR_JUMP ^ IFTRUE (WHEN (SCR_STATUS)));
+       script_data_out[i++]=swap_script((unsigned long)&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((unsigned long)pccb->pdata); /* pointer to buffer */
+       script_data_in[i++]=swap_script(SCR_JUMP ^ IFTRUE (WHEN (SCR_STATUS)));
+       script_data_in[i++]=swap_script((unsigned long)&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((unsigned long)&pccb->msgin[0]);
+       script_msgin[i++]=swap_script(SCR_JUMP ^ IFTRUE (DATA (M_COMPLETE)));
+       script_msgin[i++]=swap_script((unsigned long)&script_complete[0]);
+       script_msgin[i++]=swap_script(SCR_JUMP ^ IFTRUE (DATA (M_DISCONNECT)));
+       script_msgin[i++]=swap_script((unsigned long)&script_complete[0]);
+       script_msgin[i++]=swap_script(SCR_JUMP ^ IFTRUE (DATA (M_SAVE_DP)));
+       script_msgin[i++]=swap_script((unsigned long)&script_complete[0]);
+       script_msgin[i++]=swap_script(SCR_JUMP ^ IFTRUE (DATA (M_RESTORE_DP)));
+       script_msgin[i++]=swap_script((unsigned long)&script_complete[0]);
+       script_msgin[i++]=swap_script(SCR_JUMP ^ IFTRUE (DATA (M_EXTENDED)));
+       script_msgin[i++]=swap_script((unsigned long)&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((unsigned long)&pccb->msgin[1]);  
+       script_msg_ext[i++]=swap_script(SCR_JUMP ^ IFFALSE (IF (SCR_MSG_IN))); 
+       script_msg_ext[i++]=swap_script((unsigned long)&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((unsigned long)&pccb->msgin[2]);  
+       script_msg_ext[i++]=swap_script(SCR_JUMP ^ IFFALSE (IF (SCR_MSG_IN))); 
+       script_msg_ext[i++]=swap_script((unsigned long)&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((unsigned long)&pccb->msgin[3]);  
+       script_msg_ext[i++]=swap_script(SCR_JUMP ^ IFFALSE (IF (SCR_MSG_IN))); 
+       script_msg_ext[i++]=swap_script((unsigned long)&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((unsigned long)&pccb->msgin[4]);  
+       script_msg_ext[i++]=swap_script(SCR_JUMP ^ IFFALSE (IF (SCR_MSG_IN))); 
+       script_msg_ext[i++]=swap_script((unsigned long)&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((unsigned long)&pccb->msgin[5]);  
+       script_msg_ext[i++]=swap_script(SCR_JUMP ^ IFFALSE (IF (SCR_MSG_IN))); 
+       script_msg_ext[i++]=swap_script((unsigned long)&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((unsigned long)&pccb->msgin[6]);  
+       script_msg_ext[i++]=swap_script(SCR_JUMP ^ IFFALSE (IF (SCR_MSG_IN))); 
+       script_msg_ext[i++]=swap_script((unsigned long)&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((unsigned long)&pccb->msgin[7]);  
+       script_msg_ext[i++]=swap_script(SCR_JUMP ^ IFFALSE (IF (SCR_MSG_IN))); 
+       script_msg_ext[i++]=swap_script((unsigned long)&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((unsigned long)&pccb->status);
+       script_status[i++]=swap_script(SCR_JUMP ^ IFTRUE (WHEN (SCR_MSG_IN)));
+       script_status[i++]=swap_script((unsigned long)&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((unsigned long)&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; /* Interrupts which are enabled */
+       script_int_mask=0xff; /* enable all Ints */
+       scsi_int_enable();
+       scsi_write_dsp((unsigned long)&script_select[0]); /* start script */
+       /* now we have to wait for IRQs */
+retry: 
+       while(int_stat[0]==0);
+       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((unsigned long)&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((unsigned long)&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 */
+               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(DMODE,MAN);     
+#else
+       scsi_write_byte(DCNTL,IRQM);    
+       scsi_write_byte(DMODE,0x00);    
+#endif
+}
+#endif /* (CONFIG_COMMANDS & CFG_CMD_SCSI) */
+
+
diff --git a/board/pip405/sym53c8xx_defs.h b/board/pip405/sym53c8xx_defs.h
new file mode 100644 (file)
index 0000000..d1bc3cf
--- /dev/null
@@ -0,0 +1,582 @@
+/*
+ * (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/pip405/vga_table.h b/board/pip405/vga_table.h
new file mode 100644 (file)
index 0000000..d1cf5a6
--- /dev/null
@@ -0,0 +1,5115 @@
+/*
+ * (C) Copyright 2001
+ * Denis Peter, MPL AG, d.peter@mpl.ch.
+ *
+ * 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
+ *
+ * Note: Parts of these software are imported from 
+ *       - UBL, The Universal Talkware Boot Loader
+ *         Copyright (C) 2000 Universal Talkware Inc.
+ *       - Linux
+ *
+ * File: vga_table.c 
+ * 
+ * contains all tables (include fonts) for the vga controller.
+ *
+ **********************************************/
+#ifndef _VGA_TABLE_H
+#define _VGA_TABLE_H
+
+/* table for VGA Initialization  */
+typedef struct {
+       const unsigned char reg;
+       const unsigned char val;
+} VIDEO_CFG_TABLE;
+
+/* Attribute table */
+static VIDEO_CFG_TABLE attr[] = {
+       { 0x00, 0x00 }, /* black */
+       { 0x01, 0x01 }, /* blue */
+       { 0x02, 0x02 }, /* green */     
+       { 0x03, 0x03 }, /* cyan */
+       { 0x04, 0x04 }, /* red */
+       { 0x05, 0x05 }, /* magenta */
+       { 0x06, 0x14 }, /* brown */
+       { 0x07, 0x07 }, /* white */
+       { 0x08, 0x38 }, /* dark gray */
+       { 0x09, 0x39 }, /* light blue */
+       { 0x0A, 0x3A }, /* light green */
+       { 0x0B, 0x3B }, /* light Cyan */
+       { 0x0C, 0x3C }, /* light red */
+       { 0x0D, 0x3D }, /* light magenta */
+       { 0x0E, 0x3E }, /* yellow */
+       { 0x0F, 0x3F }, /* intense white */
+       { 0x10, 0x0C }, /* mode control */
+       { 0x11, 0x00 }, /* overscan color */
+       { 0x12, 0x0f }, /* color plane enable */
+       { 0x13, 0x08 }, /* horizontal Pel Panning */
+       { 0x14, 0x00 }, /* color select */
+       { 0xFF, 0xFF}           /* end of table */ 
+};
+
+/* Values for VGA 80 x 25 Text mode */
+static VIDEO_CFG_TABLE crtc[] = {
+       {0x00,0x5F},    /* horizontal total */
+       {0x01,0x4F},    /* horizontal displayed */
+       {0x02,0x50},    /* horizontal blank start */
+       {0x03,0x82},    /* horizontal blank end MIP520 BIOS*/
+       {0x04,0x55},    /* horizontal synch pos  MIP520 */
+       {0x05,0x9F},    /* horizontal synch width BIOS Source */
+       {0x06,0xBF},    /* vertical total BIOS MIP520*/
+       {0x07,0x1F},    /* overflow */
+       {0x08,0x00},    /* prescan  */
+       {0x09,0x4F},    /* maximum scanline */
+       {0x0A,0x0D},    /* cursor start */
+       {0x0B,0x0E},    /* cursor end */
+       {0x0C,0x00},    /* start address high byte */
+       {0x0D,0x00},    /* start address low byte */
+       {0x0E,0x07},    /* cursor location high byte */
+       {0x0F,0x80},    /* cursor location low byte */
+       {0x10,0x9C},    /* vertical synch start BIOS MIP520*/
+       {0x11,0x8E},    /* vertical synch end */
+       {0x12,0x8F},    /* vertical display enable end BIOS MIP520 */
+       {0x13,0x28},    /* offset */
+       {0x14,0x1F},    /* underline row */
+       {0x15,0x96},    /* verical blank start */
+       {0x16,0xB9},    /* verical blank end */
+       {0x17,0xA3},    /* crt Mode Control */
+       {0x18,0xFF},    /* line compare */
+       /* added for 69000 */
+       {0x22,0x20},    /* Memory Latch */
+       {0x30,0x00},    /* ext. total vertical register */
+       {0x31,0x00},    /* ext. vertical display end */
+       {0x32,0x00},    /* ext. vertical synch */
+       {0x33,0x00},    /* ext. vertical blanking start */
+       {0x38,0x00},    /* ext. total horizontal register */
+       {0x3C,0x00},    /* ext. horizontal blanking end */
+       {0x40,0x00},    /* ext. start address */
+       {0x41,0x00},    /* ext. offset */
+       {0x70,0x4F},    /* interlace control register */
+       {0x71,0x00},    /* NTSC/PAL Video Output Control */
+       {0x72,0x00},    /* NTSC/PAL horizontal serration 1 start */
+       {0x73,0x00},    /* NTSC/PAL horizontal serration 2 start */
+       {0x74,0x00},    /* NTSC/PAL horizontal pulse width */
+       {0x75,0x00},    /* NTSC/PAL filtering burst read length */
+       {0x76,0x00},    /* NTSC/PAL filtering burst read quantity */
+       {0x77,0x00},    /* NTSC/PAL Filtering Control */
+       {0x78,0x00},    /* NTSC/PAL Vertical reduction */
+       {0x79,0x00},    /* NTSC/PAL horizontal total fine adjust */
+       {0xFF,0xFF}             /* end of table */ 
+};
+
+static VIDEO_CFG_TABLE grmr[] = {
+       {0x00,0x00},    /* all planes are reset */
+       {0x01,0x00},    /* no special altering of plane */                
+       {0x02,0x00},    /* color compare */
+       {0x03,0x00},    /* data rotate */
+       {0x04,0x00},    /* read plane 0 */
+       {0x05,0x10},    /* Mode */
+       {0x06,0x0E},    /* misc */
+       {0x07,0x00},    /* Color */
+       {0x08,0xFF},    /* Bitmask */
+       {0xFF,0xFF}             /* end of table */ 
+};
+
+
+static VIDEO_CFG_TABLE seq[] = {
+       {0x00,0x03},    /* release the resets */
+       {0x01,0x00},    /* clocking mode */
+       {0x02,0x03},    /* enable plane 0,1 access */
+       {0x03,0x00},    /* character map */               
+       {0x04,0x02},    /* Memory mode */
+       {0x07,0x00},    /* Reset Counter */
+       {0xFF,0xFF}             /* end of table */ 
+};
+
+static VIDEO_CFG_TABLE xreg[] = {
+
+       { 0x0A, 0x00 }, /* Frame Buffer Mapping */
+       { 0x0B, 0x01 }, /* PCI Write Burst support */
+       { 0x0E, 0x00 }, /* Frame buffer Page select */
+       { 0x20, 0x00 }, /* BitBLT Configuration */
+       /*      { 0x40, 0x03 }, */ /* Memory Access Control */
+       { 0x40, 0x00 }, /* Memory Access Control */
+       { 0x60, 0x00 }, /* Video Pin Control */
+       { 0x61, 0x00 }, /* DPMS Synch control */
+       { 0x62, 0x00 }, /* GPIO Pin Control */
+       { 0x63, 0xBD }, /* GPIO Pin Data*/
+       { 0x67, 0x00 }, /* Pin Tri-State */
+       { 0x80, 0x00 }, /* Pixel Pipeline Config 0 register */
+       { 0x81, 0x00 }, /* Pixel Pipeline Config 1 register */
+       { 0x82, 0x00 }, /* Pixel Pipeline Config 2 register */
+       { 0xA0, 0x00 }, /* Cursor 1 Control Reg */
+       { 0xA1, 0x00 }, /* Cursor 1 Vertical Extension Reg */
+       { 0xA2, 0x00 }, /* Cursor 1 Base Address Low */
+       { 0xA3, 0x00 }, /* Cursor 1 Base Address High */
+       { 0xA4, 0x00 }, /* Cursor 1 X-Position Low */
+       { 0xA5, 0x00 }, /* Cursor 1 X-Position High */
+       { 0xA6, 0x00 }, /* Cursor 1 Y-Position Low */
+       { 0xA7, 0x00 }, /* Cursor 1 Y-Position High */
+       { 0xA8, 0x00 }, /* Cursor 2 Control Reg */
+       { 0xA9, 0x00 }, /* Cursor 2 Vertical Extension Reg */
+       { 0xAA, 0x00 }, /* Cursor 2 Base Address Low */
+       { 0xAB, 0x00 }, /* Cursor 2 Base Address High */
+       { 0xAC, 0x00 }, /* Cursor 2 X-Position Low */
+       { 0xAD, 0x00 }, /* Cursor 2 X-Position High */
+       { 0xAE, 0x00 }, /* Cursor 2 Y-Position Low */
+       { 0xAF, 0x00 }, /* Cursor 2 Y-Position High */
+       { 0xC0, 0x7D }, /* Dot Clock 0 VCO M-Divisor */
+       { 0xC1, 0x07 }, /* Dot Clock 0 VCO N-Divisor */
+       { 0xC3, 0x34 }, /* Dot Clock 0 Divisor select */
+       { 0xC4, 0x55 }, /* Dot Clock 1 VCO M-Divisor */
+       { 0xC5, 0x09 }, /* Dot Clock 1 VCO N-Divisor */
+       { 0xC7, 0x24 }, /* Dot Clock 1 Divisor select */
+       { 0xC8, 0x7D }, /* Dot Clock 2 VCO M-Divisor */
+       { 0xC9, 0x07 }, /* Dot Clock 2 VCO N-Divisor */
+       { 0xCB, 0x34 }, /* Dot Clock 2 Divisor select */
+       { 0xCC, 0x38 }, /* Memory Clock 0 VCO M-Divisor */
+       { 0xCD, 0x03 }, /* Memory Clock 0 VCO N-Divisor */
+       { 0xCE, 0x90 }, /* Memory Clock 0 Divisor select */
+       { 0xCF, 0x06 }, /* Clock Config */
+       { 0xD0, 0x0F }, /* Power Down */
+       { 0xD1, 0x01 }, /* Power Down BitBLT */
+       /*      { 0xD2, 0x0F }, */  /* 2KHz Counter Power Down  */
+       { 0xFF, 0xFF}                   /* end of table */ 
+};
+/* Clock Config:
+ * If Loop Divisor = 1 
+ *   Fvco = (Fref * M/N)
+ *      Fout = Fvco / Post Divisor
+ * Dot Clk0:
+ * ---------
+ * M  = (M Div + 2) = 127
+ * N  = (N Div + 2) = 9
+ * Post Divisor =     8
+ * Loop Divisor =     1
+ * Fref = 14.31818MHz => Fvco 202.045MHz => Dot Clock 0 = 25.25MHz
+ *
+ * Dot Clk1:
+ * ---------
+ * M  = (M Div + 2) = 57
+ * N  = (N Div + 2) = 11
+ * Post Divisor =     4
+ * Loop Divisor =     1
+ * Fref = 14.31818MHz => Fvco 113.24MHz => Dot Clock 1 = 28.31MHz
+ *
+ * Dot Clk2:
+ * ---------
+ * M  = (M Div + 2) = 127
+ * N  = (N Div + 2) = 9
+ * Post Divisor =     8
+ * Loop Divisor =     1
+ * Fref = 14.31818MHz => Fvco 202.045MHz => Dot Clock 2 = 25.25MHz
+ *
+ * Memory Clk:
+ * -----------
+ * M  = (M Div + 2) = 58
+ * N  = (N Div + 2) = 5
+ * Post Divisor =     2
+ * Fref = 14.31818MHz => Fvco 166MHz => Dot Clock 1 = 83MHz
+ *
+ */
+
+
+/* DAC datas */
+static unsigned char dac[][3] = {
+  {0x00, 0x00, 0x00}, /* Index  0 (00) */
+  {0x00, 0x00, 0x2A}, /* Index  1 (01) */
+  {0x00, 0x2A, 0x00}, /* Index  2 (02) */
+  {0x00, 0x2A, 0x2A}, /* Index  3 (03) */
+  {0x2A, 0x00, 0x00}, /* Index  4 (04) */
+  {0x2A, 0x00, 0x2A}, /* Index  5 (05) */
+  {0x2A, 0x2A, 0x00}, /* Index  6 (06) */
+  {0x2A, 0x2A, 0x2A}, /* Index  7 (07) */
+  {0x00, 0x00, 0x15}, /* Index  8 (08) */
+  {0x00, 0x00, 0x3F}, /* Index  9 (09) */
+  {0x00, 0x2A, 0x15}, /* Index 10 (0A) */
+  {0x00, 0x2A, 0x3F}, /* Index 11 (0B) */
+  {0x2A, 0x00, 0x15}, /* Index 12 (0C) */
+  {0x2A, 0x00, 0x3F}, /* Index 13 (0D) */
+  {0x2A, 0x2A, 0x15}, /* Index 14 (0E) */
+  {0x2A, 0x2A, 0x3F}, /* Index 15 (0F) */
+  {0x00, 0x15, 0x00}, /* Index 16 (10) */
+  {0x00, 0x15, 0x2A}, /* Index 17 (11) */
+  {0x00, 0x3F, 0x00}, /* Index 18 (12) */
+  {0x00, 0x3F, 0x2A}, /* Index 19 (13) */
+  {0x2A, 0x15, 0x00}, /* Index 20 (14) */
+  {0x2A, 0x15, 0x2A}, /* Index 21 (15) */
+  {0x2A, 0x3F, 0x00}, /* Index 22 (16) */
+  {0x2A, 0x3F, 0x2A}, /* Index 23 (17) */
+  {0x00, 0x15, 0x15}, /* Index 24 (18) */
+  {0x00, 0x15, 0x3F}, /* Index 25 (19) */
+  {0x00, 0x3F, 0x15}, /* Index 26 (1A) */
+  {0x00, 0x3F, 0x3F}, /* Index 27 (1B) */
+  {0x2A, 0x15, 0x15}, /* Index 28 (1C) */
+  {0x2A, 0x15, 0x3F}, /* Index 29 (1D) */
+  {0x2A, 0x3F, 0x15}, /* Index 30 (1E) */
+  {0x2A, 0x3F, 0x3F}, /* Index 31 (1F) */
+  {0x15, 0x00, 0x00}, /* Index 32 (20) */
+  {0x15, 0x00, 0x2A}, /* Index 33 (21) */
+  {0x15, 0x2A, 0x00}, /* Index 34 (22) */
+  {0x15, 0x2A, 0x2A}, /* Index 35 (23) */
+  {0x3F, 0x00, 0x00}, /* Index 36 (24) */
+  {0x3F, 0x00, 0x2A}, /* Index 37 (25) */
+  {0x3F, 0x2A, 0x00}, /* Index 38 (26) */
+  {0x3F, 0x2A, 0x2A}, /* Index 39 (27) */
+  {0x15, 0x00, 0x15}, /* Index 40 (28) */
+  {0x15, 0x00, 0x3F}, /* Index 41 (29) */
+  {0x15, 0x2A, 0x15}, /* Index 42 (2A) */
+  {0x15, 0x2A, 0x3F}, /* Index 43 (2B) */
+  {0x3F, 0x00, 0x15}, /* Index 44 (2C) */
+  {0x3F, 0x00, 0x3F}, /* Index 45 (2D) */
+  {0x3F, 0x2A, 0x15}, /* Index 46 (2E) */
+  {0x3F, 0x2A, 0x3F}, /* Index 47 (2F) */
+  {0x15, 0x15, 0x00}, /* Index 48 (30) */
+  {0x15, 0x15, 0x2A}, /* Index 49 (31) */
+  {0x15, 0x3F, 0x00}, /* Index 50 (32) */
+  {0x15, 0x3F, 0x2A}, /* Index 51 (33) */
+  {0x3F, 0x15, 0x00}, /* Index 52 (34) */
+  {0x3F, 0x15, 0x2A}, /* Index 53 (35) */
+  {0x3F, 0x3F, 0x00}, /* Index 54 (36) */
+  {0x3F, 0x3F, 0x2A}, /* Index 55 (37) */
+  {0x15, 0x15, 0x15}, /* Index 56 (38) */
+  {0x15, 0x15, 0x3F}, /* Index 57 (39) */
+  {0x15, 0x3F, 0x15}, /* Index 58 (3A) */
+  {0x15, 0x3F, 0x3F}, /* Index 59 (3B) */
+  {0x3F, 0x15, 0x15}, /* Index 60 (3C) */
+  {0x3F, 0x15, 0x3F}, /* Index 61 (3D) */
+  {0x3F, 0x3F, 0x15}, /* Index 62 (3E) */
+  {0x3F, 0x3F, 0x3F}, /* Index 63 (3F) */
+  {0x16, 0x1E, 0x17}, /* Index 64 (40) */
+  {0x27, 0x2F, 0x00}, /* Index 65 (41) */
+  {0x1E, 0x20, 0x18}, /* Index 66 (42) */
+  {0x30, 0x04, 0x06}, /* Index 67 (43) */
+  {0x08, 0x05, 0x12}, /* Index 68 (44) */
+  {0x30, 0x0A, 0x31}, /* Index 69 (45) */
+  {0x08, 0x16, 0x07}, /* Index 70 (46) */
+  {0x1B, 0x33, 0x21}, /* Index 71 (47) */
+  {0x02, 0x2C, 0x16}, /* Index 72 (48) */
+  {0x3D, 0x1C, 0x11}, /* Index 73 (49) */
+  {0x07, 0x22, 0x33}, /* Index 74 (4A) */
+  {0x1D, 0x2B, 0x0A}, /* Index 75 (4B) */
+  {0x1A, 0x15, 0x16}, /* Index 76 (4C) */
+  {0x15, 0x26, 0x24}, /* Index 77 (4D) */
+  {0x05, 0x2B, 0x1E}, /* Index 78 (4E) */
+  {0x11, 0x18, 0x01}, /* Index 79 (4F) */
+  {0x3A, 0x2C, 0x27}, /* Index 80 (50) */
+  {0x25, 0x23, 0x00}, /* Index 81 (51) */
+  {0x2A, 0x16, 0x2A}, /* Index 82 (52) */
+  {0x18, 0x19, 0x17}, /* Index 83 (53) */
+  {0x0B, 0x0F, 0x06}, /* Index 84 (54) */
+  {0x00, 0x34, 0x08}, /* Index 85 (55) */
+  {0x00, 0x19, 0x12}, /* Index 86 (56) */
+  {0x01, 0x06, 0x3B}, /* Index 87 (57) */
+  {0x29, 0x0E, 0x25}, /* Index 88 (58) */
+  {0x20, 0x10, 0x28}, /* Index 89 (59) */
+  {0x02, 0x37, 0x24}, /* Index 90 (5A) */
+  {0x08, 0x2A, 0x2E}, /* Index 91 (5B) */
+  {0x26, 0x2A, 0x22}, /* Index 92 (5C) */
+  {0x0C, 0x0C, 0x2A}, /* Index 93 (5D) */
+  {0x28, 0x07, 0x02}, /* Index 94 (5E) */
+  {0x34, 0x05, 0x2B}, /* Index 95 (5F) */
+  {0x0C, 0x31, 0x33}, /* Index 96 (60) */
+  {0x22, 0x08, 0x30}, /* Index 97 (61) */
+  {0x00, 0x25, 0x01}, /* Index 98 (62) */
+  {0x06, 0x15, 0x01}, /* Index 99 (63) */
+  {0x0D, 0x2A, 0x0A}, /* Index 100 (64) */
+  {0x08, 0x25, 0x16}, /* Index 101 (65) */
+  {0x2A, 0x0A, 0x01}, /* Index 102 (66) */
+  {0x08, 0x3B, 0x28}, /* Index 103 (67) */
+  {0x00, 0x09, 0x04}, /* Index 104 (68) */
+  {0x16, 0x0F, 0x05}, /* Index 105 (69) */
+  {0x02, 0x2F, 0x1D}, /* Index 106 (6A) */
+  {0x06, 0x3E, 0x02}, /* Index 107 (6B) */
+  {0x09, 0x30, 0x07}, /* Index 108 (6C) */
+  {0x34, 0x03, 0x06}, /* Index 109 (6D) */
+  {0x00, 0x15, 0x2A}, /* Index 110 (6E) */
+  {0x39, 0x23, 0x20}, /* Index 111 (6F) */
+  {0x2A, 0x32, 0x0C}, /* Index 112 (70) */
+  {0x09, 0x31, 0x26}, /* Index 113 (71) */
+  {0x27, 0x23, 0x28}, /* Index 114 (72) */
+  {0x20, 0x13, 0x0C}, /* Index 115 (73) */
+  {0x2C, 0x1E, 0x26}, /* Index 116 (74) */
+  {0x20, 0x2F, 0x05}, /* Index 117 (75) */
+  {0x22, 0x1B, 0x22}, /* Index 118 (76) */
+  {0x09, 0x1C, 0x06}, /* Index 119 (77) */
+  {0x16, 0x38, 0x0E}, /* Index 120 (78) */
+  {0x22, 0x16, 0x20}, /* Index 121 (79) */
+  {0x10, 0x17, 0x25}, /* Index 122 (7A) */
+  {0x04, 0x32, 0x22}, /* Index 123 (7B) */
+  {0x20, 0x00, 0x37}, /* Index 124 (7C) */
+  {0x21, 0x15, 0x1A}, /* Index 125 (7D) */
+  {0x01, 0x04, 0x20}, /* Index 126 (7E) */
+  {0x02, 0x0C, 0x1E}, /* Index 127 (7F) */
+  {0x15, 0x15, 0x29}, /* Index 128 (80) */
+  {0x24, 0x3B, 0x00}, /* Index 129 (81) */
+  {0x24, 0x28, 0x01}, /* Index 130 (82) */
+  {0x20, 0x19, 0x07}, /* Index 131 (83) */
+  {0x1A, 0x13, 0x02}, /* Index 132 (84) */
+  {0x04, 0x24, 0x1F}, /* Index 133 (85) */
+  {0x32, 0x30, 0x08}, /* Index 134 (86) */
+  {0x23, 0x12, 0x0B}, /* Index 135 (87) */
+  {0x21, 0x38, 0x00}, /* Index 136 (88) */
+  {0x04, 0x13, 0x09}, /* Index 137 (89) */
+  {0x06, 0x3E, 0x14}, /* Index 138 (8A) */
+  {0x23, 0x22, 0x2D}, /* Index 139 (8B) */
+  {0x3D, 0x35, 0x30}, /* Index 140 (8C) */
+  {0x24, 0x38, 0x05}, /* Index 141 (8D) */
+  {0x18, 0x01, 0x26}, /* Index 142 (8E) */
+  {0x27, 0x11, 0x38}, /* Index 143 (8F) */
+  {0x08, 0x1A, 0x08}, /* Index 144 (90) */
+  {0x00, 0x1A, 0x07}, /* Index 145 (91) */
+  {0x16, 0x0C, 0x30}, /* Index 146 (92) */
+  {0x1B, 0x0A, 0x0B}, /* Index 147 (93) */
+  {0x01, 0x0C, 0x09}, /* Index 148 (94) */
+  {0x00, 0x33, 0x03}, /* Index 149 (95) */
+  {0x13, 0x0A, 0x06}, /* Index 150 (96) */
+  {0x22, 0x19, 0x23}, /* Index 151 (97) */
+  {0x07, 0x30, 0x39}, /* Index 152 (98) */
+  {0x20, 0x07, 0x0D}, /* Index 153 (99) */
+  {0x39, 0x18, 0x20}, /* Index 154 (9A) */
+  {0x32, 0x31, 0x29}, /* Index 155 (9B) */
+  {0x28, 0x3F, 0x02}, /* Index 156 (9C) */
+  {0x02, 0x15, 0x3E}, /* Index 157 (9D) */
+  {0x27, 0x33, 0x0E}, /* Index 158 (9E) */
+  {0x39, 0x2E, 0x1D}, /* Index 159 (9F) */
+  {0x1E, 0x38, 0x10}, /* Index 160 (A0) */
+  {0x01, 0x33, 0x19}, /* Index 161 (A1) */
+  {0x2B, 0x20, 0x0B}, /* Index 162 (A2) */
+  {0x29, 0x0B, 0x23}, /* Index 163 (A3) */
+  {0x25, 0x04, 0x19}, /* Index 164 (A4) */
+  {0x34, 0x36, 0x08}, /* Index 165 (A5) */
+  {0x17, 0x1D, 0x01}, /* Index 166 (A6) */
+  {0x0A, 0x29, 0x10}, /* Index 167 (A7) */
+  {0x14, 0x1C, 0x2B}, /* Index 168 (A8) */
+  {0x02, 0x2C, 0x13}, /* Index 169 (A9) */
+  {0x14, 0x16, 0x3A}, /* Index 170 (AA) */
+  {0x2B, 0x22, 0x28}, /* Index 171 (AB) */
+  {0x2E, 0x0A, 0x22}, /* Index 172 (AC) */
+  {0x00, 0x20, 0x28}, /* Index 173 (AD) */
+  {0x08, 0x22, 0x2D}, /* Index 174 (AE) */
+  {0x2C, 0x17, 0x1D}, /* Index 175 (AF) */
+  {0x02, 0x0D, 0x20}, /* Index 176 (B0) */
+  {0x00, 0x18, 0x2C}, /* Index 177 (B1) */
+  {0x19, 0x19, 0x3C}, /* Index 178 (B2) */
+  {0x20, 0x32, 0x10}, /* Index 179 (B3) */
+  {0x38, 0x1C, 0x21}, /* Index 180 (B4) */
+  {0x36, 0x10, 0x00}, /* Index 181 (B5) */
+  {0x20, 0x08, 0x19}, /* Index 182 (B6) */
+  {0x09, 0x12, 0x01}, /* Index 183 (B7) */
+  {0x1D, 0x39, 0x03}, /* Index 184 (B8) */
+  {0x20, 0x28, 0x11}, /* Index 185 (B9) */
+  {0x35, 0x17, 0x01}, /* Index 186 (BA) */
+  {0x0C, 0x02, 0x08}, /* Index 187 (BB) */
+  {0x39, 0x0D, 0x10}, /* Index 188 (BC) */
+  {0x38, 0x21, 0x16}, /* Index 189 (BD) */
+  {0x29, 0x3E, 0x14}, /* Index 190 (BE) */
+  {0x0A, 0x1C, 0x28}, /* Index 191 (BF) */
+  {0x2F, 0x03, 0x08}, /* Index 192 (C0) */
+  {0x02, 0x18, 0x39}, /* Index 193 (C1) */
+  {0x0F, 0x31, 0x1E}, /* Index 194 (C2) */
+  {0x24, 0x0C, 0x03}, /* Index 195 (C3) */
+  {0x04, 0x1A, 0x04}, /* Index 196 (C4) */
+  {0x30, 0x33, 0x04}, /* Index 197 (C5) */
+  {0x2C, 0x18, 0x36}, /* Index 198 (C6) */
+  {0x18, 0x2F, 0x09}, /* Index 199 (C7) */
+  {0x03, 0x04, 0x03}, /* Index 200 (C8) */
+  {0x22, 0x05, 0x10}, /* Index 201 (C9) */
+  {0x03, 0x24, 0x0A}, /* Index 202 (CA) */
+  {0x00, 0x1E, 0x1A}, /* Index 203 (CB) */
+  {0x00, 0x0A, 0x11}, /* Index 204 (CC) */
+  {0x0E, 0x1F, 0x09}, /* Index 205 (CD) */
+  {0x1B, 0x3A, 0x3B}, /* Index 206 (CE) */
+  {0x22, 0x39, 0x36}, /* Index 207 (CF) */
+  {0x22, 0x10, 0x23}, /* Index 208 (D0) */
+  {0x31, 0x14, 0x2B}, /* Index 209 (D1) */
+  {0x0C, 0x33, 0x35}, /* Index 210 (D2) */
+  {0x27, 0x3E, 0x10}, /* Index 211 (D3) */
+  {0x10, 0x04, 0x30}, /* Index 212 (D4) */
+  {0x05, 0x21, 0x0A}, /* Index 213 (D5) */
+  {0x09, 0x11, 0x24}, /* Index 214 (D6) */
+  {0x02, 0x2B, 0x00}, /* Index 215 (D7) */
+  {0x02, 0x05, 0x15}, /* Index 216 (D8) */
+  {0x11, 0x32, 0x1A}, /* Index 217 (D9) */
+  {0x2E, 0x1B, 0x08}, /* Index 218 (DA) */
+  {0x0D, 0x2F, 0x11}, /* Index 219 (DB) */
+  {0x03, 0x30, 0x28}, /* Index 220 (DC) */
+  {0x15, 0x38, 0x0A}, /* Index 221 (DD) */
+  {0x07, 0x00, 0x00}, /* Index 222 (DE) */
+  {0x1D, 0x1C, 0x20}, /* Index 223 (DF) */
+  {0x35, 0x11, 0x35}, /* Index 224 (E0) */
+  {0x24, 0x29, 0x03}, /* Index 225 (E1) */
+  {0x22, 0x37, 0x39}, /* Index 226 (E2) */
+  {0x11, 0x1B, 0x10}, /* Index 227 (E3) */
+  {0x2D, 0x18, 0x00}, /* Index 228 (E4) */
+  {0x20, 0x2F, 0x10}, /* Index 229 (E5) */
+  {0x21, 0x26, 0x32}, /* Index 230 (E6) */
+  {0x24, 0x10, 0x3D}, /* Index 231 (E7) */
+  {0x27, 0x0E, 0x03}, /* Index 232 (E8) */
+  {0x31, 0x1F, 0x11}, /* Index 233 (E9) */
+  {0x16, 0x0D, 0x02}, /* Index 234 (EA) */
+  {0x24, 0x12, 0x16}, /* Index 235 (EB) */
+  {0x0F, 0x27, 0x18}, /* Index 236 (EC) */
+  {0x10, 0x0E, 0x20}, /* Index 237 (ED) */
+  {0x12, 0x0C, 0x0D}, /* Index 238 (EE) */
+  {0x14, 0x38, 0x0B}, /* Index 239 (EF) */
+  {0x23, 0x0C, 0x09}, /* Index 240 (F0) */
+  {0x13, 0x21, 0x0E}, /* Index 241 (F1) */
+  {0x2C, 0x05, 0x2C}, /* Index 242 (F2) */
+  {0x08, 0x29, 0x01}, /* Index 243 (F3) */
+  {0x36, 0x0A, 0x13}, /* Index 244 (F4) */
+  {0x08, 0x2D, 0x26}, /* Index 245 (F5) */
+  {0x23, 0x30, 0x3E}, /* Index 246 (F6) */
+  {0x33, 0x00, 0x04}, /* Index 247 (F7) */
+  {0x25, 0x1E, 0x3A}, /* Index 248 (F8) */
+  {0x11, 0x2C, 0x26}, /* Index 249 (F9) */
+  {0x20, 0x32, 0x27}, /* Index 250 (FA) */
+  {0x23, 0x21, 0x13}, /* Index 251 (FB) */
+  {0x22, 0x23, 0x1F}, /* Index 252 (FC) */
+  {0x31, 0x08, 0x0A}, /* Index 253 (FD) */
+  {0x00, 0x01, 0x09}, /* Index 254 (FE) */
+  {0x17, 0x07, 0x38} /* Index 255 (FF) */
+};
+
+
+/***********************************************
+ * 8x16 Font 
+ * 
+ * copied from file 
+ * drivers/video/font_8x16.c (LINUX)
+ **********************************************/
+/**********************************************/
+/*                                            */
+/*       Font file generated by cpi2fnt       */
+/*                                            */
+/**********************************************/
+
+#define FONTDATAMAX 4096
+
+unsigned char fontdata_8x16[FONTDATAMAX] = {
+
+       /* 0 0x00 '^@' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 1 0x01 '^A' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x7e, /* 01111110 */
+       0x81, /* 10000001 */
+       0xa5, /* 10100101 */
+       0x81, /* 10000001 */
+       0x81, /* 10000001 */
+       0xbd, /* 10111101 */
+       0x99, /* 10011001 */
+       0x81, /* 10000001 */
+       0x81, /* 10000001 */
+       0x7e, /* 01111110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 2 0x02 '^B' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x7e, /* 01111110 */
+       0xff, /* 11111111 */
+       0xdb, /* 11011011 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xc3, /* 11000011 */
+       0xe7, /* 11100111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0x7e, /* 01111110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 3 0x03 '^C' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x6c, /* 01101100 */
+       0xfe, /* 11111110 */
+       0xfe, /* 11111110 */
+       0xfe, /* 11111110 */
+       0xfe, /* 11111110 */
+       0x7c, /* 01111100 */
+       0x38, /* 00111000 */
+       0x10, /* 00010000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 4 0x04 '^D' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x10, /* 00010000 */
+       0x38, /* 00111000 */
+       0x7c, /* 01111100 */
+       0xfe, /* 11111110 */
+       0x7c, /* 01111100 */
+       0x38, /* 00111000 */
+       0x10, /* 00010000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 5 0x05 '^E' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x18, /* 00011000 */
+       0x3c, /* 00111100 */
+       0x3c, /* 00111100 */
+       0xe7, /* 11100111 */
+       0xe7, /* 11100111 */
+       0xe7, /* 11100111 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x3c, /* 00111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 6 0x06 '^F' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x18, /* 00011000 */
+       0x3c, /* 00111100 */
+       0x7e, /* 01111110 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0x7e, /* 01111110 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x3c, /* 00111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 7 0x07 '^G' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x18, /* 00011000 */
+       0x3c, /* 00111100 */
+       0x3c, /* 00111100 */
+       0x18, /* 00011000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 8 0x08 '^H' */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xe7, /* 11100111 */
+       0xc3, /* 11000011 */
+       0xc3, /* 11000011 */
+       0xe7, /* 11100111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+
+       /* 9 0x09 '^I' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x3c, /* 00111100 */
+       0x66, /* 01100110 */
+       0x42, /* 01000010 */
+       0x42, /* 01000010 */
+       0x66, /* 01100110 */
+       0x3c, /* 00111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 10 0x0a '^J' */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xc3, /* 11000011 */
+       0x99, /* 10011001 */
+       0xbd, /* 10111101 */
+       0xbd, /* 10111101 */
+       0x99, /* 10011001 */
+       0xc3, /* 11000011 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+
+       /* 11 0x0b '^K' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x1e, /* 00011110 */
+       0x0e, /* 00001110 */
+       0x1a, /* 00011010 */
+       0x32, /* 00110010 */
+       0x78, /* 01111000 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0x78, /* 01111000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 12 0x0c '^L' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x3c, /* 00111100 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x3c, /* 00111100 */
+       0x18, /* 00011000 */
+       0x7e, /* 01111110 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 13 0x0d '^M' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x3f, /* 00111111 */
+       0x33, /* 00110011 */
+       0x3f, /* 00111111 */
+       0x30, /* 00110000 */
+       0x30, /* 00110000 */
+       0x30, /* 00110000 */
+       0x30, /* 00110000 */
+       0x70, /* 01110000 */
+       0xf0, /* 11110000 */
+       0xe0, /* 11100000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 14 0x0e '^N' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x7f, /* 01111111 */
+       0x63, /* 01100011 */
+       0x7f, /* 01111111 */
+       0x63, /* 01100011 */
+       0x63, /* 01100011 */
+       0x63, /* 01100011 */
+       0x63, /* 01100011 */
+       0x67, /* 01100111 */
+       0xe7, /* 11100111 */
+       0xe6, /* 11100110 */
+       0xc0, /* 11000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 15 0x0f '^O' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0xdb, /* 11011011 */
+       0x3c, /* 00111100 */
+       0xe7, /* 11100111 */
+       0x3c, /* 00111100 */
+       0xdb, /* 11011011 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 16 0x10 '^P' */
+       0x00, /* 00000000 */
+       0x80, /* 10000000 */
+       0xc0, /* 11000000 */
+       0xe0, /* 11100000 */
+       0xf0, /* 11110000 */
+       0xf8, /* 11111000 */
+       0xfe, /* 11111110 */
+       0xf8, /* 11111000 */
+       0xf0, /* 11110000 */
+       0xe0, /* 11100000 */
+       0xc0, /* 11000000 */
+       0x80, /* 10000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 17 0x11 '^Q' */
+       0x00, /* 00000000 */
+       0x02, /* 00000010 */
+       0x06, /* 00000110 */
+       0x0e, /* 00001110 */
+       0x1e, /* 00011110 */
+       0x3e, /* 00111110 */
+       0xfe, /* 11111110 */
+       0x3e, /* 00111110 */
+       0x1e, /* 00011110 */
+       0x0e, /* 00001110 */
+       0x06, /* 00000110 */
+       0x02, /* 00000010 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 18 0x12 '^R' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x18, /* 00011000 */
+       0x3c, /* 00111100 */
+       0x7e, /* 01111110 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x7e, /* 01111110 */
+       0x3c, /* 00111100 */
+       0x18, /* 00011000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 19 0x13 '^S' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x00, /* 00000000 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 20 0x14 '^T' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x7f, /* 01111111 */
+       0xdb, /* 11011011 */
+       0xdb, /* 11011011 */
+       0xdb, /* 11011011 */
+       0x7b, /* 01111011 */
+       0x1b, /* 00011011 */
+       0x1b, /* 00011011 */
+       0x1b, /* 00011011 */
+       0x1b, /* 00011011 */
+       0x1b, /* 00011011 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 21 0x15 '^U' */
+       0x00, /* 00000000 */
+       0x7c, /* 01111100 */
+       0xc6, /* 11000110 */
+       0x60, /* 01100000 */
+       0x38, /* 00111000 */
+       0x6c, /* 01101100 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0x6c, /* 01101100 */
+       0x38, /* 00111000 */
+       0x0c, /* 00001100 */
+       0xc6, /* 11000110 */
+       0x7c, /* 01111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 22 0x16 '^V' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xfe, /* 11111110 */
+       0xfe, /* 11111110 */
+       0xfe, /* 11111110 */
+       0xfe, /* 11111110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 23 0x17 '^W' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x18, /* 00011000 */
+       0x3c, /* 00111100 */
+       0x7e, /* 01111110 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x7e, /* 01111110 */
+       0x3c, /* 00111100 */
+       0x18, /* 00011000 */
+       0x7e, /* 01111110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 24 0x18 '^X' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x18, /* 00011000 */
+       0x3c, /* 00111100 */
+       0x7e, /* 01111110 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 25 0x19 '^Y' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x7e, /* 01111110 */
+       0x3c, /* 00111100 */
+       0x18, /* 00011000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 26 0x1a '^Z' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x18, /* 00011000 */
+       0x0c, /* 00001100 */
+       0xfe, /* 11111110 */
+       0x0c, /* 00001100 */
+       0x18, /* 00011000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 27 0x1b '^[' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x30, /* 00110000 */
+       0x60, /* 01100000 */
+       0xfe, /* 11111110 */
+       0x60, /* 01100000 */
+       0x30, /* 00110000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 28 0x1c '^\' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xc0, /* 11000000 */
+       0xc0, /* 11000000 */
+       0xc0, /* 11000000 */
+       0xfe, /* 11111110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 29 0x1d '^]' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x28, /* 00101000 */
+       0x6c, /* 01101100 */
+       0xfe, /* 11111110 */
+       0x6c, /* 01101100 */
+       0x28, /* 00101000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 30 0x1e '^^' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x10, /* 00010000 */
+       0x38, /* 00111000 */
+       0x38, /* 00111000 */
+       0x7c, /* 01111100 */
+       0x7c, /* 01111100 */
+       0xfe, /* 11111110 */
+       0xfe, /* 11111110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 31 0x1f '^_' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xfe, /* 11111110 */
+       0xfe, /* 11111110 */
+       0x7c, /* 01111100 */
+       0x7c, /* 01111100 */
+       0x38, /* 00111000 */
+       0x38, /* 00111000 */
+       0x10, /* 00010000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 32 0x20 ' ' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 33 0x21 '!' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x18, /* 00011000 */
+       0x3c, /* 00111100 */
+       0x3c, /* 00111100 */
+       0x3c, /* 00111100 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x00, /* 00000000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 34 0x22 '"' */
+       0x00, /* 00000000 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x24, /* 00100100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 35 0x23 '#' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x6c, /* 01101100 */
+       0x6c, /* 01101100 */
+       0xfe, /* 11111110 */
+       0x6c, /* 01101100 */
+       0x6c, /* 01101100 */
+       0x6c, /* 01101100 */
+       0xfe, /* 11111110 */
+       0x6c, /* 01101100 */
+       0x6c, /* 01101100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 36 0x24 '$' */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x7c, /* 01111100 */
+       0xc6, /* 11000110 */
+       0xc2, /* 11000010 */
+       0xc0, /* 11000000 */
+       0x7c, /* 01111100 */
+       0x06, /* 00000110 */
+       0x06, /* 00000110 */
+       0x86, /* 10000110 */
+       0xc6, /* 11000110 */
+       0x7c, /* 01111100 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 37 0x25 '%' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xc2, /* 11000010 */
+       0xc6, /* 11000110 */
+       0x0c, /* 00001100 */
+       0x18, /* 00011000 */
+       0x30, /* 00110000 */
+       0x60, /* 01100000 */
+       0xc6, /* 11000110 */
+       0x86, /* 10000110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 38 0x26 '&' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x38, /* 00111000 */
+       0x6c, /* 01101100 */
+       0x6c, /* 01101100 */
+       0x38, /* 00111000 */
+       0x76, /* 01110110 */
+       0xdc, /* 11011100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0x76, /* 01110110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 39 0x27 ''' */
+       0x00, /* 00000000 */
+       0x30, /* 00110000 */
+       0x30, /* 00110000 */
+       0x30, /* 00110000 */
+       0x60, /* 01100000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 40 0x28 '(' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x0c, /* 00001100 */
+       0x18, /* 00011000 */
+       0x30, /* 00110000 */
+       0x30, /* 00110000 */
+       0x30, /* 00110000 */
+       0x30, /* 00110000 */
+       0x30, /* 00110000 */
+       0x30, /* 00110000 */
+       0x18, /* 00011000 */
+       0x0c, /* 00001100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 41 0x29 ')' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x30, /* 00110000 */
+       0x18, /* 00011000 */
+       0x0c, /* 00001100 */
+       0x0c, /* 00001100 */
+       0x0c, /* 00001100 */
+       0x0c, /* 00001100 */
+       0x0c, /* 00001100 */
+       0x0c, /* 00001100 */
+       0x18, /* 00011000 */
+       0x30, /* 00110000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 42 0x2a '*' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x66, /* 01100110 */
+       0x3c, /* 00111100 */
+       0xff, /* 11111111 */
+       0x3c, /* 00111100 */
+       0x66, /* 01100110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 43 0x2b '+' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x7e, /* 01111110 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 44 0x2c ',' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x30, /* 00110000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 45 0x2d '-' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xfe, /* 11111110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 46 0x2e '.' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 47 0x2f '/' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x02, /* 00000010 */
+       0x06, /* 00000110 */
+       0x0c, /* 00001100 */
+       0x18, /* 00011000 */
+       0x30, /* 00110000 */
+       0x60, /* 01100000 */
+       0xc0, /* 11000000 */
+       0x80, /* 10000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 48 0x30 '0' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x38, /* 00111000 */
+       0x6c, /* 01101100 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xd6, /* 11010110 */
+       0xd6, /* 11010110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0x6c, /* 01101100 */
+       0x38, /* 00111000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 49 0x31 '1' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x18, /* 00011000 */
+       0x38, /* 00111000 */
+       0x78, /* 01111000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x7e, /* 01111110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 50 0x32 '2' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x7c, /* 01111100 */
+       0xc6, /* 11000110 */
+       0x06, /* 00000110 */
+       0x0c, /* 00001100 */
+       0x18, /* 00011000 */
+       0x30, /* 00110000 */
+       0x60, /* 01100000 */
+       0xc0, /* 11000000 */
+       0xc6, /* 11000110 */
+       0xfe, /* 11111110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 51 0x33 '3' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x7c, /* 01111100 */
+       0xc6, /* 11000110 */
+       0x06, /* 00000110 */
+       0x06, /* 00000110 */
+       0x3c, /* 00111100 */
+       0x06, /* 00000110 */
+       0x06, /* 00000110 */
+       0x06, /* 00000110 */
+       0xc6, /* 11000110 */
+       0x7c, /* 01111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 52 0x34 '4' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x0c, /* 00001100 */
+       0x1c, /* 00011100 */
+       0x3c, /* 00111100 */
+       0x6c, /* 01101100 */
+       0xcc, /* 11001100 */
+       0xfe, /* 11111110 */
+       0x0c, /* 00001100 */
+       0x0c, /* 00001100 */
+       0x0c, /* 00001100 */
+       0x1e, /* 00011110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 53 0x35 '5' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xfe, /* 11111110 */
+       0xc0, /* 11000000 */
+       0xc0, /* 11000000 */
+       0xc0, /* 11000000 */
+       0xfc, /* 11111100 */
+       0x06, /* 00000110 */
+       0x06, /* 00000110 */
+       0x06, /* 00000110 */
+       0xc6, /* 11000110 */
+       0x7c, /* 01111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 54 0x36 '6' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x38, /* 00111000 */
+       0x60, /* 01100000 */
+       0xc0, /* 11000000 */
+       0xc0, /* 11000000 */
+       0xfc, /* 11111100 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0x7c, /* 01111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 55 0x37 '7' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xfe, /* 11111110 */
+       0xc6, /* 11000110 */
+       0x06, /* 00000110 */
+       0x06, /* 00000110 */
+       0x0c, /* 00001100 */
+       0x18, /* 00011000 */
+       0x30, /* 00110000 */
+       0x30, /* 00110000 */
+       0x30, /* 00110000 */
+       0x30, /* 00110000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 56 0x38 '8' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x7c, /* 01111100 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0x7c, /* 01111100 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0x7c, /* 01111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 57 0x39 '9' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x7c, /* 01111100 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0x7e, /* 01111110 */
+       0x06, /* 00000110 */
+       0x06, /* 00000110 */
+       0x06, /* 00000110 */
+       0x0c, /* 00001100 */
+       0x78, /* 01111000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 58 0x3a ':' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 59 0x3b ';' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x30, /* 00110000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 60 0x3c '<' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x06, /* 00000110 */
+       0x0c, /* 00001100 */
+       0x18, /* 00011000 */
+       0x30, /* 00110000 */
+       0x60, /* 01100000 */
+       0x30, /* 00110000 */
+       0x18, /* 00011000 */
+       0x0c, /* 00001100 */
+       0x06, /* 00000110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 61 0x3d '=' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x7e, /* 01111110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x7e, /* 01111110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 62 0x3e '>' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x60, /* 01100000 */
+       0x30, /* 00110000 */
+       0x18, /* 00011000 */
+       0x0c, /* 00001100 */
+       0x06, /* 00000110 */
+       0x0c, /* 00001100 */
+       0x18, /* 00011000 */
+       0x30, /* 00110000 */
+       0x60, /* 01100000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 63 0x3f '?' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x7c, /* 01111100 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0x0c, /* 00001100 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x00, /* 00000000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 64 0x40 '@' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x7c, /* 01111100 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xde, /* 11011110 */
+       0xde, /* 11011110 */
+       0xde, /* 11011110 */
+       0xdc, /* 11011100 */
+       0xc0, /* 11000000 */
+       0x7c, /* 01111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 65 0x41 'A' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x10, /* 00010000 */
+       0x38, /* 00111000 */
+       0x6c, /* 01101100 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xfe, /* 11111110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 66 0x42 'B' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xfc, /* 11111100 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x7c, /* 01111100 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0xfc, /* 11111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 67 0x43 'C' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x3c, /* 00111100 */
+       0x66, /* 01100110 */
+       0xc2, /* 11000010 */
+       0xc0, /* 11000000 */
+       0xc0, /* 11000000 */
+       0xc0, /* 11000000 */
+       0xc0, /* 11000000 */
+       0xc2, /* 11000010 */
+       0x66, /* 01100110 */
+       0x3c, /* 00111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 68 0x44 'D' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xf8, /* 11111000 */
+       0x6c, /* 01101100 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x6c, /* 01101100 */
+       0xf8, /* 11111000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 69 0x45 'E' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xfe, /* 11111110 */
+       0x66, /* 01100110 */
+       0x62, /* 01100010 */
+       0x68, /* 01101000 */
+       0x78, /* 01111000 */
+       0x68, /* 01101000 */
+       0x60, /* 01100000 */
+       0x62, /* 01100010 */
+       0x66, /* 01100110 */
+       0xfe, /* 11111110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 70 0x46 'F' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xfe, /* 11111110 */
+       0x66, /* 01100110 */
+       0x62, /* 01100010 */
+       0x68, /* 01101000 */
+       0x78, /* 01111000 */
+       0x68, /* 01101000 */
+       0x60, /* 01100000 */
+       0x60, /* 01100000 */
+       0x60, /* 01100000 */
+       0xf0, /* 11110000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 71 0x47 'G' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x3c, /* 00111100 */
+       0x66, /* 01100110 */
+       0xc2, /* 11000010 */
+       0xc0, /* 11000000 */
+       0xc0, /* 11000000 */
+       0xde, /* 11011110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0x66, /* 01100110 */
+       0x3a, /* 00111010 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 72 0x48 'H' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xfe, /* 11111110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 73 0x49 'I' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x3c, /* 00111100 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x3c, /* 00111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 74 0x4a 'J' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x1e, /* 00011110 */
+       0x0c, /* 00001100 */
+       0x0c, /* 00001100 */
+       0x0c, /* 00001100 */
+       0x0c, /* 00001100 */
+       0x0c, /* 00001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0x78, /* 01111000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 75 0x4b 'K' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xe6, /* 11100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x6c, /* 01101100 */
+       0x78, /* 01111000 */
+       0x78, /* 01111000 */
+       0x6c, /* 01101100 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0xe6, /* 11100110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 76 0x4c 'L' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xf0, /* 11110000 */
+       0x60, /* 01100000 */
+       0x60, /* 01100000 */
+       0x60, /* 01100000 */
+       0x60, /* 01100000 */
+       0x60, /* 01100000 */
+       0x60, /* 01100000 */
+       0x62, /* 01100010 */
+       0x66, /* 01100110 */
+       0xfe, /* 11111110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 77 0x4d 'M' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xc6, /* 11000110 */
+       0xee, /* 11101110 */
+       0xfe, /* 11111110 */
+       0xfe, /* 11111110 */
+       0xd6, /* 11010110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 78 0x4e 'N' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xc6, /* 11000110 */
+       0xe6, /* 11100110 */
+       0xf6, /* 11110110 */
+       0xfe, /* 11111110 */
+       0xde, /* 11011110 */
+       0xce, /* 11001110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 79 0x4f 'O' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x7c, /* 01111100 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0x7c, /* 01111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 80 0x50 'P' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xfc, /* 11111100 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x7c, /* 01111100 */
+       0x60, /* 01100000 */
+       0x60, /* 01100000 */
+       0x60, /* 01100000 */
+       0x60, /* 01100000 */
+       0xf0, /* 11110000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 81 0x51 'Q' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x7c, /* 01111100 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xd6, /* 11010110 */
+       0xde, /* 11011110 */
+       0x7c, /* 01111100 */
+       0x0c, /* 00001100 */
+       0x0e, /* 00001110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 82 0x52 'R' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xfc, /* 11111100 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x7c, /* 01111100 */
+       0x6c, /* 01101100 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0xe6, /* 11100110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 83 0x53 'S' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x7c, /* 01111100 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0x60, /* 01100000 */
+       0x38, /* 00111000 */
+       0x0c, /* 00001100 */
+       0x06, /* 00000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0x7c, /* 01111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 84 0x54 'T' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x7e, /* 01111110 */
+       0x7e, /* 01111110 */
+       0x5a, /* 01011010 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x3c, /* 00111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 85 0x55 'U' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0x7c, /* 01111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 86 0x56 'V' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0x6c, /* 01101100 */
+       0x38, /* 00111000 */
+       0x10, /* 00010000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 87 0x57 'W' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xd6, /* 11010110 */
+       0xd6, /* 11010110 */
+       0xd6, /* 11010110 */
+       0xfe, /* 11111110 */
+       0xee, /* 11101110 */
+       0x6c, /* 01101100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 88 0x58 'X' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0x6c, /* 01101100 */
+       0x7c, /* 01111100 */
+       0x38, /* 00111000 */
+       0x38, /* 00111000 */
+       0x7c, /* 01111100 */
+       0x6c, /* 01101100 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 89 0x59 'Y' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x3c, /* 00111100 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x3c, /* 00111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 90 0x5a 'Z' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xfe, /* 11111110 */
+       0xc6, /* 11000110 */
+       0x86, /* 10000110 */
+       0x0c, /* 00001100 */
+       0x18, /* 00011000 */
+       0x30, /* 00110000 */
+       0x60, /* 01100000 */
+       0xc2, /* 11000010 */
+       0xc6, /* 11000110 */
+       0xfe, /* 11111110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 91 0x5b '[' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x3c, /* 00111100 */
+       0x30, /* 00110000 */
+       0x30, /* 00110000 */
+       0x30, /* 00110000 */
+       0x30, /* 00110000 */
+       0x30, /* 00110000 */
+       0x30, /* 00110000 */
+       0x30, /* 00110000 */
+       0x30, /* 00110000 */
+       0x3c, /* 00111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 92 0x5c '\' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x80, /* 10000000 */
+       0xc0, /* 11000000 */
+       0xe0, /* 11100000 */
+       0x70, /* 01110000 */
+       0x38, /* 00111000 */
+       0x1c, /* 00011100 */
+       0x0e, /* 00001110 */
+       0x06, /* 00000110 */
+       0x02, /* 00000010 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 93 0x5d ']' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x3c, /* 00111100 */
+       0x0c, /* 00001100 */
+       0x0c, /* 00001100 */
+       0x0c, /* 00001100 */
+       0x0c, /* 00001100 */
+       0x0c, /* 00001100 */
+       0x0c, /* 00001100 */
+       0x0c, /* 00001100 */
+       0x0c, /* 00001100 */
+       0x3c, /* 00111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 94 0x5e '^' */
+       0x10, /* 00010000 */
+       0x38, /* 00111000 */
+       0x6c, /* 01101100 */
+       0xc6, /* 11000110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 95 0x5f '_' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xff, /* 11111111 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 96 0x60 '`' */
+       0x00, /* 00000000 */
+       0x30, /* 00110000 */
+       0x18, /* 00011000 */
+       0x0c, /* 00001100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 97 0x61 'a' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x78, /* 01111000 */
+       0x0c, /* 00001100 */
+       0x7c, /* 01111100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0x76, /* 01110110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 98 0x62 'b' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xe0, /* 11100000 */
+       0x60, /* 01100000 */
+       0x60, /* 01100000 */
+       0x78, /* 01111000 */
+       0x6c, /* 01101100 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x7c, /* 01111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 99 0x63 'c' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x7c, /* 01111100 */
+       0xc6, /* 11000110 */
+       0xc0, /* 11000000 */
+       0xc0, /* 11000000 */
+       0xc0, /* 11000000 */
+       0xc6, /* 11000110 */
+       0x7c, /* 01111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 100 0x64 'd' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x1c, /* 00011100 */
+       0x0c, /* 00001100 */
+       0x0c, /* 00001100 */
+       0x3c, /* 00111100 */
+       0x6c, /* 01101100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0x76, /* 01110110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 101 0x65 'e' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x7c, /* 01111100 */
+       0xc6, /* 11000110 */
+       0xfe, /* 11111110 */
+       0xc0, /* 11000000 */
+       0xc0, /* 11000000 */
+       0xc6, /* 11000110 */
+       0x7c, /* 01111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 102 0x66 'f' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x1c, /* 00011100 */
+       0x36, /* 00110110 */
+       0x32, /* 00110010 */
+       0x30, /* 00110000 */
+       0x78, /* 01111000 */
+       0x30, /* 00110000 */
+       0x30, /* 00110000 */
+       0x30, /* 00110000 */
+       0x30, /* 00110000 */
+       0x78, /* 01111000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 103 0x67 'g' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x76, /* 01110110 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0x7c, /* 01111100 */
+       0x0c, /* 00001100 */
+       0xcc, /* 11001100 */
+       0x78, /* 01111000 */
+       0x00, /* 00000000 */
+
+       /* 104 0x68 'h' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xe0, /* 11100000 */
+       0x60, /* 01100000 */
+       0x60, /* 01100000 */
+       0x6c, /* 01101100 */
+       0x76, /* 01110110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0xe6, /* 11100110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 105 0x69 'i' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x00, /* 00000000 */
+       0x38, /* 00111000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x3c, /* 00111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 106 0x6a 'j' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x06, /* 00000110 */
+       0x06, /* 00000110 */
+       0x00, /* 00000000 */
+       0x0e, /* 00001110 */
+       0x06, /* 00000110 */
+       0x06, /* 00000110 */
+       0x06, /* 00000110 */
+       0x06, /* 00000110 */
+       0x06, /* 00000110 */
+       0x06, /* 00000110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x3c, /* 00111100 */
+       0x00, /* 00000000 */
+
+       /* 107 0x6b 'k' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xe0, /* 11100000 */
+       0x60, /* 01100000 */
+       0x60, /* 01100000 */
+       0x66, /* 01100110 */
+       0x6c, /* 01101100 */
+       0x78, /* 01111000 */
+       0x78, /* 01111000 */
+       0x6c, /* 01101100 */
+       0x66, /* 01100110 */
+       0xe6, /* 11100110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 108 0x6c 'l' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x38, /* 00111000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x3c, /* 00111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 109 0x6d 'm' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xec, /* 11101100 */
+       0xfe, /* 11111110 */
+       0xd6, /* 11010110 */
+       0xd6, /* 11010110 */
+       0xd6, /* 11010110 */
+       0xd6, /* 11010110 */
+       0xc6, /* 11000110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 110 0x6e 'n' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xdc, /* 11011100 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 111 0x6f 'o' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x7c, /* 01111100 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0x7c, /* 01111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 112 0x70 'p' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xdc, /* 11011100 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x7c, /* 01111100 */
+       0x60, /* 01100000 */
+       0x60, /* 01100000 */
+       0xf0, /* 11110000 */
+       0x00, /* 00000000 */
+
+       /* 113 0x71 'q' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x76, /* 01110110 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0x7c, /* 01111100 */
+       0x0c, /* 00001100 */
+       0x0c, /* 00001100 */
+       0x1e, /* 00011110 */
+       0x00, /* 00000000 */
+
+       /* 114 0x72 'r' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xdc, /* 11011100 */
+       0x76, /* 01110110 */
+       0x66, /* 01100110 */
+       0x60, /* 01100000 */
+       0x60, /* 01100000 */
+       0x60, /* 01100000 */
+       0xf0, /* 11110000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 115 0x73 's' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x7c, /* 01111100 */
+       0xc6, /* 11000110 */
+       0x60, /* 01100000 */
+       0x38, /* 00111000 */
+       0x0c, /* 00001100 */
+       0xc6, /* 11000110 */
+       0x7c, /* 01111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 116 0x74 't' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x10, /* 00010000 */
+       0x30, /* 00110000 */
+       0x30, /* 00110000 */
+       0xfc, /* 11111100 */
+       0x30, /* 00110000 */
+       0x30, /* 00110000 */
+       0x30, /* 00110000 */
+       0x30, /* 00110000 */
+       0x36, /* 00110110 */
+       0x1c, /* 00011100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 117 0x75 'u' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0x76, /* 01110110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 118 0x76 'v' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0x6c, /* 01101100 */
+       0x38, /* 00111000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 119 0x77 'w' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xd6, /* 11010110 */
+       0xd6, /* 11010110 */
+       0xd6, /* 11010110 */
+       0xfe, /* 11111110 */
+       0x6c, /* 01101100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 120 0x78 'x' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xc6, /* 11000110 */
+       0x6c, /* 01101100 */
+       0x38, /* 00111000 */
+       0x38, /* 00111000 */
+       0x38, /* 00111000 */
+       0x6c, /* 01101100 */
+       0xc6, /* 11000110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 121 0x79 'y' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0x7e, /* 01111110 */
+       0x06, /* 00000110 */
+       0x0c, /* 00001100 */
+       0xf8, /* 11111000 */
+       0x00, /* 00000000 */
+
+       /* 122 0x7a 'z' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xfe, /* 11111110 */
+       0xcc, /* 11001100 */
+       0x18, /* 00011000 */
+       0x30, /* 00110000 */
+       0x60, /* 01100000 */
+       0xc6, /* 11000110 */
+       0xfe, /* 11111110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 123 0x7b '{' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x0e, /* 00001110 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x70, /* 01110000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x0e, /* 00001110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 124 0x7c '|' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 125 0x7d '}' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x70, /* 01110000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x0e, /* 00001110 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x70, /* 01110000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 126 0x7e '~' */
+       0x00, /* 00000000 */
+       0x76, /* 01110110 */
+       0xdc, /* 11011100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 127 0x7f '' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x10, /* 00010000 */
+       0x38, /* 00111000 */
+       0x6c, /* 01101100 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xfe, /* 11111110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 128 0x80 '' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x3c, /* 00111100 */
+       0x66, /* 01100110 */
+       0xc2, /* 11000010 */
+       0xc0, /* 11000000 */
+       0xc0, /* 11000000 */
+       0xc0, /* 11000000 */
+       0xc0, /* 11000000 */
+       0xc2, /* 11000010 */
+       0x66, /* 01100110 */
+       0x3c, /* 00111100 */
+       0x18, /* 00011000 */
+       0x70, /* 01110000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 129 0x81 '' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xcc, /* 11001100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0x76, /* 01110110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 130 0x82 '' */
+       0x00, /* 00000000 */
+       0x0c, /* 00001100 */
+       0x18, /* 00011000 */
+       0x30, /* 00110000 */
+       0x00, /* 00000000 */
+       0x7c, /* 01111100 */
+       0xc6, /* 11000110 */
+       0xfe, /* 11111110 */
+       0xc0, /* 11000000 */
+       0xc0, /* 11000000 */
+       0xc6, /* 11000110 */
+       0x7c, /* 01111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 131 0x83 '' */
+       0x00, /* 00000000 */
+       0x10, /* 00010000 */
+       0x38, /* 00111000 */
+       0x6c, /* 01101100 */
+       0x00, /* 00000000 */
+       0x78, /* 01111000 */
+       0x0c, /* 00001100 */
+       0x7c, /* 01111100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0x76, /* 01110110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 132 0x84 '' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xcc, /* 11001100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x78, /* 01111000 */
+       0x0c, /* 00001100 */
+       0x7c, /* 01111100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0x76, /* 01110110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 133 0x85 '' */
+       0x00, /* 00000000 */
+       0x60, /* 01100000 */
+       0x30, /* 00110000 */
+       0x18, /* 00011000 */
+       0x00, /* 00000000 */
+       0x78, /* 01111000 */
+       0x0c, /* 00001100 */
+       0x7c, /* 01111100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0x76, /* 01110110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 134 0x86 '' */
+       0x00, /* 00000000 */
+       0x38, /* 00111000 */
+       0x6c, /* 01101100 */
+       0x38, /* 00111000 */
+       0x00, /* 00000000 */
+       0x78, /* 01111000 */
+       0x0c, /* 00001100 */
+       0x7c, /* 01111100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0x76, /* 01110110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 135 0x87 '' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x7c, /* 01111100 */
+       0xc6, /* 11000110 */
+       0xc0, /* 11000000 */
+       0xc0, /* 11000000 */
+       0xc0, /* 11000000 */
+       0xc6, /* 11000110 */
+       0x7c, /* 01111100 */
+       0x18, /* 00011000 */
+       0x70, /* 01110000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 136 0x88 '' */
+       0x00, /* 00000000 */
+       0x10, /* 00010000 */
+       0x38, /* 00111000 */
+       0x6c, /* 01101100 */
+       0x00, /* 00000000 */
+       0x7c, /* 01111100 */
+       0xc6, /* 11000110 */
+       0xfe, /* 11111110 */
+       0xc0, /* 11000000 */
+       0xc0, /* 11000000 */
+       0xc6, /* 11000110 */
+       0x7c, /* 01111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 137 0x89 '' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xc6, /* 11000110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x7c, /* 01111100 */
+       0xc6, /* 11000110 */
+       0xfe, /* 11111110 */
+       0xc0, /* 11000000 */
+       0xc0, /* 11000000 */
+       0xc6, /* 11000110 */
+       0x7c, /* 01111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 138 0x8a '' */
+       0x00, /* 00000000 */
+       0x60, /* 01100000 */
+       0x30, /* 00110000 */
+       0x18, /* 00011000 */
+       0x00, /* 00000000 */
+       0x7c, /* 01111100 */
+       0xc6, /* 11000110 */
+       0xfe, /* 11111110 */
+       0xc0, /* 11000000 */
+       0xc0, /* 11000000 */
+       0xc6, /* 11000110 */
+       0x7c, /* 01111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 139 0x8b '' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x66, /* 01100110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x38, /* 00111000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x3c, /* 00111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 140 0x8c '' */
+       0x00, /* 00000000 */
+       0x18, /* 00011000 */
+       0x3c, /* 00111100 */
+       0x66, /* 01100110 */
+       0x00, /* 00000000 */
+       0x38, /* 00111000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x3c, /* 00111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 141 0x8d '' */
+       0x00, /* 00000000 */
+       0x60, /* 01100000 */
+       0x30, /* 00110000 */
+       0x18, /* 00011000 */
+       0x00, /* 00000000 */
+       0x38, /* 00111000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x3c, /* 00111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 142 0x8e '' */
+       0x00, /* 00000000 */
+       0xc6, /* 11000110 */
+       0x00, /* 00000000 */
+       0x10, /* 00010000 */
+       0x38, /* 00111000 */
+       0x6c, /* 01101100 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xfe, /* 11111110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 143 0x8f '' */
+       0x38, /* 00111000 */
+       0x6c, /* 01101100 */
+       0x38, /* 00111000 */
+       0x10, /* 00010000 */
+       0x38, /* 00111000 */
+       0x6c, /* 01101100 */
+       0xc6, /* 11000110 */
+       0xfe, /* 11111110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 144 0x90 '' */
+       0x0c, /* 00001100 */
+       0x18, /* 00011000 */
+       0x00, /* 00000000 */
+       0xfe, /* 11111110 */
+       0x66, /* 01100110 */
+       0x62, /* 01100010 */
+       0x68, /* 01101000 */
+       0x78, /* 01111000 */
+       0x68, /* 01101000 */
+       0x62, /* 01100010 */
+       0x66, /* 01100110 */
+       0xfe, /* 11111110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 145 0x91 '' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xec, /* 11101100 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x7e, /* 01111110 */
+       0xd8, /* 11011000 */
+       0xd8, /* 11011000 */
+       0x6e, /* 01101110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 146 0x92 '' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x3e, /* 00111110 */
+       0x6c, /* 01101100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xfe, /* 11111110 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xce, /* 11001110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 147 0x93 '' */
+       0x00, /* 00000000 */
+       0x10, /* 00010000 */
+       0x38, /* 00111000 */
+       0x6c, /* 01101100 */
+       0x00, /* 00000000 */
+       0x7c, /* 01111100 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0x7c, /* 01111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 148 0x94 '' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xc6, /* 11000110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x7c, /* 01111100 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0x7c, /* 01111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 149 0x95 '' */
+       0x00, /* 00000000 */
+       0x60, /* 01100000 */
+       0x30, /* 00110000 */
+       0x18, /* 00011000 */
+       0x00, /* 00000000 */
+       0x7c, /* 01111100 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0x7c, /* 01111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 150 0x96 '' */
+       0x00, /* 00000000 */
+       0x30, /* 00110000 */
+       0x78, /* 01111000 */
+       0xcc, /* 11001100 */
+       0x00, /* 00000000 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0x76, /* 01110110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 151 0x97 '' */
+       0x00, /* 00000000 */
+       0x60, /* 01100000 */
+       0x30, /* 00110000 */
+       0x18, /* 00011000 */
+       0x00, /* 00000000 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0x76, /* 01110110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 152 0x98 '' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xc6, /* 11000110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0x7e, /* 01111110 */
+       0x06, /* 00000110 */
+       0x0c, /* 00001100 */
+       0x78, /* 01111000 */
+       0x00, /* 00000000 */
+
+       /* 153 0x99 '' */
+       0x00, /* 00000000 */
+       0xc6, /* 11000110 */
+       0x00, /* 00000000 */
+       0x7c, /* 01111100 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0x7c, /* 01111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 154 0x9a '' */
+       0x00, /* 00000000 */
+       0xc6, /* 11000110 */
+       0x00, /* 00000000 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0x7c, /* 01111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 155 0x9b '' */
+       0x00, /* 00000000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x7c, /* 01111100 */
+       0xc6, /* 11000110 */
+       0xc0, /* 11000000 */
+       0xc0, /* 11000000 */
+       0xc0, /* 11000000 */
+       0xc6, /* 11000110 */
+       0x7c, /* 01111100 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 156 0x9c '' */
+       0x00, /* 00000000 */
+       0x38, /* 00111000 */
+       0x6c, /* 01101100 */
+       0x64, /* 01100100 */
+       0x60, /* 01100000 */
+       0xf0, /* 11110000 */
+       0x60, /* 01100000 */
+       0x60, /* 01100000 */
+       0x60, /* 01100000 */
+       0x60, /* 01100000 */
+       0xe6, /* 11100110 */
+       0xfc, /* 11111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 157 0x9d '' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x3c, /* 00111100 */
+       0x18, /* 00011000 */
+       0x7e, /* 01111110 */
+       0x18, /* 00011000 */
+       0x7e, /* 01111110 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 158 0x9e '' */
+       0x00, /* 00000000 */
+       0xf8, /* 11111000 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xf8, /* 11111000 */
+       0xc4, /* 11000100 */
+       0xcc, /* 11001100 */
+       0xde, /* 11011110 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xc6, /* 11000110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 159 0x9f '' */
+       0x00, /* 00000000 */
+       0x0e, /* 00001110 */
+       0x1b, /* 00011011 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x7e, /* 01111110 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0xd8, /* 11011000 */
+       0x70, /* 01110000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 160 0xa0 ' ' */
+       0x00, /* 00000000 */
+       0x18, /* 00011000 */
+       0x30, /* 00110000 */
+       0x60, /* 01100000 */
+       0x00, /* 00000000 */
+       0x78, /* 01111000 */
+       0x0c, /* 00001100 */
+       0x7c, /* 01111100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0x76, /* 01110110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 161 0xa1 '¡' */
+       0x00, /* 00000000 */
+       0x0c, /* 00001100 */
+       0x18, /* 00011000 */
+       0x30, /* 00110000 */
+       0x00, /* 00000000 */
+       0x38, /* 00111000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x3c, /* 00111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 162 0xa2 '¢' */
+       0x00, /* 00000000 */
+       0x18, /* 00011000 */
+       0x30, /* 00110000 */
+       0x60, /* 01100000 */
+       0x00, /* 00000000 */
+       0x7c, /* 01111100 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0x7c, /* 01111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 163 0xa3 '£' */
+       0x00, /* 00000000 */
+       0x18, /* 00011000 */
+       0x30, /* 00110000 */
+       0x60, /* 01100000 */
+       0x00, /* 00000000 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0x76, /* 01110110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 164 0xa4 '¤' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x76, /* 01110110 */
+       0xdc, /* 11011100 */
+       0x00, /* 00000000 */
+       0xdc, /* 11011100 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 165 0xa5 '¥' */
+       0x76, /* 01110110 */
+       0xdc, /* 11011100 */
+       0x00, /* 00000000 */
+       0xc6, /* 11000110 */
+       0xe6, /* 11100110 */
+       0xf6, /* 11110110 */
+       0xfe, /* 11111110 */
+       0xde, /* 11011110 */
+       0xce, /* 11001110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 166 0xa6 '¦' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x3c, /* 00111100 */
+       0x6c, /* 01101100 */
+       0x6c, /* 01101100 */
+       0x3e, /* 00111110 */
+       0x00, /* 00000000 */
+       0x7e, /* 01111110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 167 0xa7 '§' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x38, /* 00111000 */
+       0x6c, /* 01101100 */
+       0x6c, /* 01101100 */
+       0x38, /* 00111000 */
+       0x00, /* 00000000 */
+       0x7c, /* 01111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 168 0xa8 '¨' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x30, /* 00110000 */
+       0x30, /* 00110000 */
+       0x00, /* 00000000 */
+       0x30, /* 00110000 */
+       0x30, /* 00110000 */
+       0x60, /* 01100000 */
+       0xc0, /* 11000000 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0x7c, /* 01111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 169 0xa9 '©' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xfe, /* 11111110 */
+       0xc0, /* 11000000 */
+       0xc0, /* 11000000 */
+       0xc0, /* 11000000 */
+       0xc0, /* 11000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 170 0xaa 'ª' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xfe, /* 11111110 */
+       0x06, /* 00000110 */
+       0x06, /* 00000110 */
+       0x06, /* 00000110 */
+       0x06, /* 00000110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 171 0xab '«' */
+       0x00, /* 00000000 */
+       0x60, /* 01100000 */
+       0xe0, /* 11100000 */
+       0x62, /* 01100010 */
+       0x66, /* 01100110 */
+       0x6c, /* 01101100 */
+       0x18, /* 00011000 */
+       0x30, /* 00110000 */
+       0x60, /* 01100000 */
+       0xdc, /* 11011100 */
+       0x86, /* 10000110 */
+       0x0c, /* 00001100 */
+       0x18, /* 00011000 */
+       0x3e, /* 00111110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 172 0xac '¬' */
+       0x00, /* 00000000 */
+       0x60, /* 01100000 */
+       0xe0, /* 11100000 */
+       0x62, /* 01100010 */
+       0x66, /* 01100110 */
+       0x6c, /* 01101100 */
+       0x18, /* 00011000 */
+       0x30, /* 00110000 */
+       0x66, /* 01100110 */
+       0xce, /* 11001110 */
+       0x9a, /* 10011010 */
+       0x3f, /* 00111111 */
+       0x06, /* 00000110 */
+       0x06, /* 00000110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 173 0xad '­' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x00, /* 00000000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x3c, /* 00111100 */
+       0x3c, /* 00111100 */
+       0x3c, /* 00111100 */
+       0x18, /* 00011000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 174 0xae '®' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x36, /* 00110110 */
+       0x6c, /* 01101100 */
+       0xd8, /* 11011000 */
+       0x6c, /* 01101100 */
+       0x36, /* 00110110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 175 0xaf '¯' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xd8, /* 11011000 */
+       0x6c, /* 01101100 */
+       0x36, /* 00110110 */
+       0x6c, /* 01101100 */
+       0xd8, /* 11011000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 176 0xb0 '°' */
+       0x11, /* 00010001 */
+       0x44, /* 01000100 */
+       0x11, /* 00010001 */
+       0x44, /* 01000100 */
+       0x11, /* 00010001 */
+       0x44, /* 01000100 */
+       0x11, /* 00010001 */
+       0x44, /* 01000100 */
+       0x11, /* 00010001 */
+       0x44, /* 01000100 */
+       0x11, /* 00010001 */
+       0x44, /* 01000100 */
+       0x11, /* 00010001 */
+       0x44, /* 01000100 */
+       0x11, /* 00010001 */
+       0x44, /* 01000100 */
+
+       /* 177 0xb1 '±' */
+       0x55, /* 01010101 */
+       0xaa, /* 10101010 */
+       0x55, /* 01010101 */
+       0xaa, /* 10101010 */
+       0x55, /* 01010101 */
+       0xaa, /* 10101010 */
+       0x55, /* 01010101 */
+       0xaa, /* 10101010 */
+       0x55, /* 01010101 */
+       0xaa, /* 10101010 */
+       0x55, /* 01010101 */
+       0xaa, /* 10101010 */
+       0x55, /* 01010101 */
+       0xaa, /* 10101010 */
+       0x55, /* 01010101 */
+       0xaa, /* 10101010 */
+
+       /* 178 0xb2 '²' */
+       0xdd, /* 11011101 */
+       0x77, /* 01110111 */
+       0xdd, /* 11011101 */
+       0x77, /* 01110111 */
+       0xdd, /* 11011101 */
+       0x77, /* 01110111 */
+       0xdd, /* 11011101 */
+       0x77, /* 01110111 */
+       0xdd, /* 11011101 */
+       0x77, /* 01110111 */
+       0xdd, /* 11011101 */
+       0x77, /* 01110111 */
+       0xdd, /* 11011101 */
+       0x77, /* 01110111 */
+       0xdd, /* 11011101 */
+       0x77, /* 01110111 */
+
+       /* 179 0xb3 '³' */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+
+       /* 180 0xb4 '´' */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0xf8, /* 11111000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+
+       /* 181 0xb5 'µ' */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0xf8, /* 11111000 */
+       0x18, /* 00011000 */
+       0xf8, /* 11111000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+
+       /* 182 0xb6 '¶' */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0xf6, /* 11110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+
+       /* 183 0xb7 '·' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xfe, /* 11111110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+
+       /* 184 0xb8 '¸' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xf8, /* 11111000 */
+       0x18, /* 00011000 */
+       0xf8, /* 11111000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+
+       /* 185 0xb9 '¹' */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0xf6, /* 11110110 */
+       0x06, /* 00000110 */
+       0xf6, /* 11110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+
+       /* 186 0xba 'º' */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+
+       /* 187 0xbb '»' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xfe, /* 11111110 */
+       0x06, /* 00000110 */
+       0xf6, /* 11110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+
+       /* 188 0xbc '¼' */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0xf6, /* 11110110 */
+       0x06, /* 00000110 */
+       0xfe, /* 11111110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 189 0xbd '½' */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0xfe, /* 11111110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 190 0xbe '¾' */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0xf8, /* 11111000 */
+       0x18, /* 00011000 */
+       0xf8, /* 11111000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 191 0xbf '¿' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xf8, /* 11111000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+
+       /* 192 0xc0 'À' */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x1f, /* 00011111 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 193 0xc1 'Á' */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0xff, /* 11111111 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 194 0xc2 'Â' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xff, /* 11111111 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+
+       /* 195 0xc3 'Ã' */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x1f, /* 00011111 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+
+       /* 196 0xc4 'Ä' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xff, /* 11111111 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 197 0xc5 'Å' */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0xff, /* 11111111 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+
+       /* 198 0xc6 'Æ' */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x1f, /* 00011111 */
+       0x18, /* 00011000 */
+       0x1f, /* 00011111 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+
+       /* 199 0xc7 'Ç' */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x37, /* 00110111 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+
+       /* 200 0xc8 'È' */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x37, /* 00110111 */
+       0x30, /* 00110000 */
+       0x3f, /* 00111111 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 201 0xc9 'É' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x3f, /* 00111111 */
+       0x30, /* 00110000 */
+       0x37, /* 00110111 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+
+       /* 202 0xca 'Ê' */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0xf7, /* 11110111 */
+       0x00, /* 00000000 */
+       0xff, /* 11111111 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 203 0xcb 'Ë' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xff, /* 11111111 */
+       0x00, /* 00000000 */
+       0xf7, /* 11110111 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+
+       /* 204 0xcc 'Ì' */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x37, /* 00110111 */
+       0x30, /* 00110000 */
+       0x37, /* 00110111 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+
+       /* 205 0xcd 'Í' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xff, /* 11111111 */
+       0x00, /* 00000000 */
+       0xff, /* 11111111 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 206 0xce 'Î' */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0xf7, /* 11110111 */
+       0x00, /* 00000000 */
+       0xf7, /* 11110111 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+
+       /* 207 0xcf 'Ï' */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0xff, /* 11111111 */
+       0x00, /* 00000000 */
+       0xff, /* 11111111 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 208 0xd0 'Ð' */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0xff, /* 11111111 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 209 0xd1 'Ñ' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xff, /* 11111111 */
+       0x00, /* 00000000 */
+       0xff, /* 11111111 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+
+       /* 210 0xd2 'Ò' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xff, /* 11111111 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+
+       /* 211 0xd3 'Ó' */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x3f, /* 00111111 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 212 0xd4 'Ô' */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x1f, /* 00011111 */
+       0x18, /* 00011000 */
+       0x1f, /* 00011111 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 213 0xd5 'Õ' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x1f, /* 00011111 */
+       0x18, /* 00011000 */
+       0x1f, /* 00011111 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+
+       /* 214 0xd6 'Ö' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x3f, /* 00111111 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+
+       /* 215 0xd7 '×' */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0xff, /* 11111111 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+
+       /* 216 0xd8 'Ø' */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0xff, /* 11111111 */
+       0x18, /* 00011000 */
+       0xff, /* 11111111 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+
+       /* 217 0xd9 'Ù' */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0xf8, /* 11111000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 218 0xda 'Ú' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x1f, /* 00011111 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+
+       /* 219 0xdb 'Û' */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+
+       /* 220 0xdc 'Ü' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+
+       /* 221 0xdd 'Ý' */
+       0xf0, /* 11110000 */
+       0xf0, /* 11110000 */
+       0xf0, /* 11110000 */
+       0xf0, /* 11110000 */
+       0xf0, /* 11110000 */
+       0xf0, /* 11110000 */
+       0xf0, /* 11110000 */
+       0xf0, /* 11110000 */
+       0xf0, /* 11110000 */
+       0xf0, /* 11110000 */
+       0xf0, /* 11110000 */
+       0xf0, /* 11110000 */
+       0xf0, /* 11110000 */
+       0xf0, /* 11110000 */
+       0xf0, /* 11110000 */
+       0xf0, /* 11110000 */
+
+       /* 222 0xde 'Þ' */
+       0x0f, /* 00001111 */
+       0x0f, /* 00001111 */
+       0x0f, /* 00001111 */
+       0x0f, /* 00001111 */
+       0x0f, /* 00001111 */
+       0x0f, /* 00001111 */
+       0x0f, /* 00001111 */
+       0x0f, /* 00001111 */
+       0x0f, /* 00001111 */
+       0x0f, /* 00001111 */
+       0x0f, /* 00001111 */
+       0x0f, /* 00001111 */
+       0x0f, /* 00001111 */
+       0x0f, /* 00001111 */
+       0x0f, /* 00001111 */
+       0x0f, /* 00001111 */
+
+       /* 223 0xdf 'ß' */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 224 0xe0 'à' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x76, /* 01110110 */
+       0xdc, /* 11011100 */
+       0xd8, /* 11011000 */
+       0xd8, /* 11011000 */
+       0xd8, /* 11011000 */
+       0xdc, /* 11011100 */
+       0x76, /* 01110110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 225 0xe1 'á' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x78, /* 01111000 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xd8, /* 11011000 */
+       0xcc, /* 11001100 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xcc, /* 11001100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 226 0xe2 'â' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xfe, /* 11111110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc0, /* 11000000 */
+       0xc0, /* 11000000 */
+       0xc0, /* 11000000 */
+       0xc0, /* 11000000 */
+       0xc0, /* 11000000 */
+       0xc0, /* 11000000 */
+       0xc0, /* 11000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 227 0xe3 'ã' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xfe, /* 11111110 */
+       0x6c, /* 01101100 */
+       0x6c, /* 01101100 */
+       0x6c, /* 01101100 */
+       0x6c, /* 01101100 */
+       0x6c, /* 01101100 */
+       0x6c, /* 01101100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 228 0xe4 'ä' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xfe, /* 11111110 */
+       0xc6, /* 11000110 */
+       0x60, /* 01100000 */
+       0x30, /* 00110000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x30, /* 00110000 */
+       0x60, /* 01100000 */
+       0xc6, /* 11000110 */
+       0xfe, /* 11111110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 229 0xe5 'å' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x7e, /* 01111110 */
+       0xd8, /* 11011000 */
+       0xd8, /* 11011000 */
+       0xd8, /* 11011000 */
+       0xd8, /* 11011000 */
+       0xd8, /* 11011000 */
+       0x70, /* 01110000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 230 0xe6 'æ' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x7c, /* 01111100 */
+       0x60, /* 01100000 */
+       0x60, /* 01100000 */
+       0xc0, /* 11000000 */
+       0x00, /* 00000000 */
+
+       /* 231 0xe7 'ç' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x76, /* 01110110 */
+       0xdc, /* 11011100 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 232 0xe8 'è' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x7e, /* 01111110 */
+       0x18, /* 00011000 */
+       0x3c, /* 00111100 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x3c, /* 00111100 */
+       0x18, /* 00011000 */
+       0x7e, /* 01111110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 233 0xe9 'é' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x38, /* 00111000 */
+       0x6c, /* 01101100 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xfe, /* 11111110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0x6c, /* 01101100 */
+       0x38, /* 00111000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 234 0xea 'ê' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x38, /* 00111000 */
+       0x6c, /* 01101100 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0x6c, /* 01101100 */
+       0x6c, /* 01101100 */
+       0x6c, /* 01101100 */
+       0x6c, /* 01101100 */
+       0xee, /* 11101110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 235 0xeb 'ë' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x1e, /* 00011110 */
+       0x30, /* 00110000 */
+       0x18, /* 00011000 */
+       0x0c, /* 00001100 */
+       0x3e, /* 00111110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x3c, /* 00111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 236 0xec 'ì' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x7e, /* 01111110 */
+       0xdb, /* 11011011 */
+       0xdb, /* 11011011 */
+       0xdb, /* 11011011 */
+       0x7e, /* 01111110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 237 0xed 'í' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x03, /* 00000011 */
+       0x06, /* 00000110 */
+       0x7e, /* 01111110 */
+       0xdb, /* 11011011 */
+       0xdb, /* 11011011 */
+       0xf3, /* 11110011 */
+       0x7e, /* 01111110 */
+       0x60, /* 01100000 */
+       0xc0, /* 11000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 238 0xee 'î' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x1c, /* 00011100 */
+       0x30, /* 00110000 */
+       0x60, /* 01100000 */
+       0x60, /* 01100000 */
+       0x7c, /* 01111100 */
+       0x60, /* 01100000 */
+       0x60, /* 01100000 */
+       0x60, /* 01100000 */
+       0x30, /* 00110000 */
+       0x1c, /* 00011100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 239 0xef 'ï' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x7c, /* 01111100 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 240 0xf0 'ð' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xfe, /* 11111110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xfe, /* 11111110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xfe, /* 11111110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 241 0xf1 'ñ' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x7e, /* 01111110 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x7e, /* 01111110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 242 0xf2 'ò' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x30, /* 00110000 */
+       0x18, /* 00011000 */
+       0x0c, /* 00001100 */
+       0x06, /* 00000110 */
+       0x0c, /* 00001100 */
+       0x18, /* 00011000 */
+       0x30, /* 00110000 */
+       0x00, /* 00000000 */
+       0x7e, /* 01111110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 243 0xf3 'ó' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x0c, /* 00001100 */
+       0x18, /* 00011000 */
+       0x30, /* 00110000 */
+       0x60, /* 01100000 */
+       0x30, /* 00110000 */
+       0x18, /* 00011000 */
+       0x0c, /* 00001100 */
+       0x00, /* 00000000 */
+       0x7e, /* 01111110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 244 0xf4 'ô' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x0e, /* 00001110 */
+       0x1b, /* 00011011 */
+       0x1b, /* 00011011 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+
+       /* 245 0xf5 'õ' */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0xd8, /* 11011000 */
+       0xd8, /* 11011000 */
+       0xd8, /* 11011000 */
+       0x70, /* 01110000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 246 0xf6 'ö' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x18, /* 00011000 */
+       0x00, /* 00000000 */
+       0x7e, /* 01111110 */
+       0x00, /* 00000000 */
+       0x18, /* 00011000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 247 0xf7 '÷' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x76, /* 01110110 */
+       0xdc, /* 11011100 */
+       0x00, /* 00000000 */
+       0x76, /* 01110110 */
+       0xdc, /* 11011100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 248 0xf8 'ø' */
+       0x00, /* 00000000 */
+       0x38, /* 00111000 */
+       0x6c, /* 01101100 */
+       0x6c, /* 01101100 */
+       0x38, /* 00111000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 249 0xf9 'ù' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 250 0xfa 'ú' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x18, /* 00011000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 251 0xfb 'û' */
+       0x00, /* 00000000 */
+       0x0f, /* 00001111 */
+       0x0c, /* 00001100 */
+       0x0c, /* 00001100 */
+       0x0c, /* 00001100 */
+       0x0c, /* 00001100 */
+       0x0c, /* 00001100 */
+       0xec, /* 11101100 */
+       0x6c, /* 01101100 */
+       0x6c, /* 01101100 */
+       0x3c, /* 00111100 */
+       0x1c, /* 00011100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 252 0xfc 'ü' */
+       0x00, /* 00000000 */
+       0x6c, /* 01101100 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 253 0xfd 'ý' */
+       0x00, /* 00000000 */
+       0x3c, /* 00111100 */
+       0x66, /* 01100110 */
+       0x0c, /* 00001100 */
+       0x18, /* 00011000 */
+       0x32, /* 00110010 */
+       0x7e, /* 01111110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 254 0xfe 'þ' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x7e, /* 01111110 */
+       0x7e, /* 01111110 */
+       0x7e, /* 01111110 */
+       0x7e, /* 01111110 */
+       0x7e, /* 01111110 */
+       0x7e, /* 01111110 */
+       0x7e, /* 01111110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 255 0xff 'ÿ' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+};
+
+#endif /* #ifndef _VGA_TABLE_H */
diff --git a/board/pip405/video.c b/board/pip405/video.c
new file mode 100644 (file)
index 0000000..199e235
--- /dev/null
@@ -0,0 +1,741 @@
+/*
+ * (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
+ *
+ * Note: Parts of these software are imported from 
+ *       - UBL, The Universal Talkware Boot Loader
+ *         Copyright (C) 2000 Universal Talkware Inc.
+ *       - Linux
+ *
+ * 
+ */
+
+#include <ppcboot.h>
+#include <command.h>
+#include <asm/processor.h>
+#include <devices.h>
+#include "video.h"
+#ifdef CONFIG_PPC405
+#include <405gp_pci.h>
+#endif
+#include "vga_table.h"
+
+#ifdef CONFIG_VIDEO_CT69000
+#define VIDEO_VEND_ID 0x102C
+#define VIDEO_DEV_ID  0x00C0
+#else
+#error  CONFIG_VIDEO_CT69000 must be defined
+#endif
+
+/* 
+ * Routine for resent board info to video
+ * resides in pip405.c
+ */
+extern void video_write_board_info(void); 
+
+#undef VGA_DEBUG
+
+#ifdef VGA_DEBUG
+#define        PRINTF(fmt,args...)     printf (fmt ,##args)
+#else
+#define PRINTF(fmt,args...)
+#endif
+
+#define VGA_MAXROWS    25
+#define VGA_MAXCOLS 80
+
+#define CRTC_CURSH     14 /* cursor high pos */
+#define CRTC_CURSL     15 /* cursor low pos */
+
+/* description of the hardware layout */
+
+#define ATTRI_INDEX            CFG_ISA_IO_BASE_ADDRESS | 0x3c0                         /* Index and Data write port of the attribute Registers */
+#define ATTRI_DATA             CFG_ISA_IO_BASE_ADDRESS | 0x3c1                         /* Data port of the attribute Registers */
+#define STATUS_REG0            CFG_ISA_IO_BASE_ADDRESS | 0x3c2                         /* Status Register 0 (read only) */
+#define MSR_REG_W                      CFG_ISA_IO_BASE_ADDRESS | 0x3c2                         /* Misc. Output Register (write only) */
+#define SEQ_INDEX                      CFG_ISA_IO_BASE_ADDRESS | 0x3c4                         /* Index port of the Sequencer Controller */
+#define SEQ_DATA                       CFG_ISA_IO_BASE_ADDRESS | 0x3c5                         /* Data port of the Sequencer Controller */
+#define COL_PAL_MASK   CFG_ISA_IO_BASE_ADDRESS | 0x3c6                         /* Color Palette Mask */
+#define COL_PAL_STAT   CFG_ISA_IO_BASE_ADDRESS | 0x3c7                         /* Color Palette Status (read only) */
+#define COL_PAL_IND_R  CFG_ISA_IO_BASE_ADDRESS | 0x3c7                         /* Color Palette Read Mode Index (write only) */
+#define COL_PAL_IND_W  CFG_ISA_IO_BASE_ADDRESS | 0x3c8                         /* Color Palette Write Mode Index */
+#define COL_PAL_DATA   CFG_ISA_IO_BASE_ADDRESS | 0x3c9                         /* Color Palette Data Port */
+#define FCR_REG_R                      CFG_ISA_IO_BASE_ADDRESS | 0x3ca                         /* Feature Control Register (read only) */
+#define MSR_REG_R                      CFG_ISA_IO_BASE_ADDRESS | 0x3cc                         /* Misc. Output Register (read only) */
+#define GR_INDEX                       CFG_ISA_IO_BASE_ADDRESS | 0x3ce                         /* Index port of the Graphic Controller Registers */
+#define GR_DATA                                CFG_ISA_IO_BASE_ADDRESS | 0x3cf                         /* Data port of the Graphic Controller Registers */
+#define FP_INDEX                       CFG_ISA_IO_BASE_ADDRESS | 0x3d0                         /* Index port of the Flat panel Registers */
+#define FP_DATA                                CFG_ISA_IO_BASE_ADDRESS | 0x3d1                         /* Data port of the Flat panel Registers */
+#define MR_INDEX                       CFG_ISA_IO_BASE_ADDRESS | 0x3d2                         /* Index Port of the Multimedia Extension */                            
+#define MR_DATA                                CFG_ISA_IO_BASE_ADDRESS | 0x3d3                         /* Data Port of the Multimedia Extension */
+#define CRT_INDEX                      CFG_ISA_IO_BASE_ADDRESS | 0x3d4                         /* Index port of the CRT Controller */
+#define CRT_DATA                       CFG_ISA_IO_BASE_ADDRESS | 0x3d5                         /* Data port of the CRT Controller */
+#define XREG_INDEX             CFG_ISA_IO_BASE_ADDRESS | 0x3d6                         /* Extended Register index */
+#define XREG_DATA                      CFG_ISA_IO_BASE_ADDRESS | 0x3d7                         /* Extended Register data */
+#define STATUS_REG1            CFG_ISA_IO_BASE_ADDRESS | 0x3da                         /* Input Status Register 1 (read only) */
+#define FCR_REG_W                      CFG_ISA_IO_BASE_ADDRESS | 0x3da                         /* Feature Control Register (write only) */
+
+
+static unsigned char * video_fb;               /* Frame buffer */
+
+/* current hardware state */
+
+static int     video_row;
+static int     video_col;
+static unsigned char video_attr;
+
+static unsigned long font_base_addr;
+/**********************************************************************
+ * some forward declerations...
+ */
+int video_init(int busdevfunc);
+void vga_set_attrib(void);
+void vga_set_crt(void);
+void vga_set_dac(void);
+void vga_set_gr(void);
+void vga_set_seq(void);
+void vga_set_xreg(void);
+void vga_write_sr(unsigned char reg,unsigned char val);
+void vga_write_gr(unsigned char reg,unsigned char val);
+void vga_write_cr(unsigned char reg,unsigned char val);
+void vga_set_font(void);
+
+/***************************************************************************
+ * Init VGA Device
+ */
+
+int drv_video_init(void)
+{
+       int error, devices = 1 ;
+  device_t vgadev ;
+       int     busdevfunc;
+
+       busdevfunc=PCI_Find_Device(VIDEO_VEND_ID,VIDEO_DEV_ID); /* get PCI Device ID */
+       if(busdevfunc==-1) {
+               printf("Error VGA Controller (%04X,%04X) not found\n",VIDEO_VEND_ID,VIDEO_DEV_ID);
+               return -1;
+       }
+       video_init(busdevfunc);
+       video_write_board_info();
+  memset (&vgadev, 0, sizeof(vgadev));
+
+  strcpy(vgadev.name, "vga");
+  vgadev.flags =  DEV_FLAGS_OUTPUT | DEV_FLAGS_SYSTEM;
+  vgadev.putc = video_putc;
+  vgadev.puts = video_puts;
+  vgadev.getc = NULL;
+  vgadev.tstc = NULL;
+
+  error = device_register (&vgadev);
+               
+  return (error == 0) ? devices : error ;
+}
+
+
+/***********************************************************
+ * VGA Initializing
+ */
+
+int video_init(int busdevfunc)
+{
+  font_base_addr = PCI_Read_CFG_Reg(busdevfunc, PCI_CFG_BASE_ADDRESS_0, 4);
+
+  video_fb = (char*)font_base_addr; /* we look into the big linaer memory area */
+
+  /* set the extended Registers */
+       vga_set_xreg();
+
+       /* set IO Addresses to 0x3Dx (color mode ) */
+       out8(MSR_REG_W,0x01);
+
+  /* Feature Control Register:
+     Bits 7-4 Reserved = 0
+     Bit  3   Vertical Sync select = 1 = Enabled
+     Bits 2-0 Reserved = 010 = as read from memory.
+  */
+  out8(FCR_REG_W,0x02);
+
+
+  /* Miscelaneous output Register:
+     Bits 7-6 (num lines) = 01 = VGA 400 lines,
+     Bit  5   (Odd/Even Page) =  1 = Sleect high page of memory,
+     Bit  4   reserved = 0,
+     Bits 3-2 (Clocl Select) = 01 = 28.322Mhz
+     Bit  1 = Display Ram Enable = 1 = Enable processor access.
+     Bit  0 = Io Address Select = 1 = Color Graphics Enulation.
+  */
+  out8(MSR_REG_W,0x67);
+  /* set the palette */
+  vga_set_dac();
+  /* set the attributes (before we bring up the engine
+     then we dont have to wait for refresh).
+  */
+  vga_set_attrib();
+
+  /* set the crontroller register. */
+  vga_set_crt();
+
+       vga_write_sr(0x00,0x01); /* synchronous reset */
+       vga_write_sr(0x01,0x00); /* clocking mode */
+       vga_write_sr(0x02,0x03); /* write to map 0, 1 */
+       vga_write_sr(0x03,0x00); /* select character map 0 */
+       vga_write_sr(0x04,0x03); /* even-odd addressing */
+       vga_write_sr(0x00,0x03); /* clear synchronous reset */
+
+  vga_set_seq(); /* Set the extended sr's. */
+
+  vga_set_gr(); /* Set the graphic registers. */
+
+  /* load the font */
+  vga_set_font();
+
+  /* initialize the rol/col counts and the text attribute. */
+  video_row=0;
+  video_col=0;
+  video_attr = VGA_ATTR_CLR_WHT;
+
+  /* Clear the video ram */
+  video_clear();
+
+  return 1;
+}
+
+void vga_set_font(void)
+{
+       int i,j;
+       char *fontmap;
+       fontmap = (char *)font_base_addr;
+       
+       vga_write_sr(0x00,0x01); /* synchronous reset */
+       vga_write_sr(0x04,0x06); /* sequential addressing */
+       vga_write_sr(0x02,0x04); /* write to map 2 */
+       vga_write_sr(0x00,0x03); /* clear synchronous reset */
+
+       vga_write_gr(0x04,0x02); /* select map 2 */
+       vga_write_gr(0x05,0x00); /* disable odd-even addressing */
+       vga_write_gr(0x06,0x00); /* map start at 0xa0000 */
+       
+       for(i=0;i<0x100;i++) {
+               for(j=0;j<0x10;j++) {
+                       *((char *)fontmap+i*32+j)=(char)fontdata_8x16[i*16+j];
+               }
+       }
+       vga_write_sr(0x00,0x01); /* synchronous reset */
+       vga_write_sr(0x02,0x03); /* write to map 0 and 1 */
+       vga_write_sr(0x04,0x03); /* odd-even addressing */
+       vga_write_sr(0x03,0x00); /* Character map 0 & 1 */
+       vga_write_sr(0x00,0x03); /* clear synchronous reset */
+
+       vga_write_gr(0x04,0x00); /* select map 0 for CPU */
+       vga_write_gr(0x05,0x10); /* enable odd-even addressing */
+       vga_write_gr(0x06,0x0E); /* map start at 0xb8000 */
+}
+
+
+/* since we are BIG endian, swap attributes and char */
+unsigned short vga_swap_short(unsigned short val)
+{
+       unsigned short swapped;
+       swapped = ((val & 0xff)<<8) | ((val & 0xff00)>>8);
+       return swapped;
+}
+
+/****************************************************
+ * Routines usable Outside world
+ */
+/* scolls the text up row rows */
+void video_scroll(int row)
+{
+  unsigned short clear = ((unsigned short)video_attr << 8) | (' ');
+  unsigned short* addr16 = &((unsigned short *)video_fb)[(VGA_MAXROWS-row)*VGA_MAXCOLS];
+  int i;
+
+       clear=vga_swap_short(clear);
+  memcpy(video_fb, video_fb+row*(VGA_MAXCOLS*2), (VGA_MAXROWS-row)*(VGA_MAXCOLS*2));
+  for (i = 0 ; i < row * VGA_MAXCOLS ; i++)
+    addr16[i] = clear;
+  video_row-=row;
+  video_col=0;
+}
+
+
+unsigned long video_cursor(int col, int row)
+{
+   unsigned short off = row * VGA_MAXCOLS + col ;
+   unsigned long saved = (video_col << 16) | (video_row & 0xFFFF);
+   video_col = col;
+   video_row = row;
+   
+   vga_write_cr(CRTC_CURSH,(unsigned char)((off & 0xff00)>>8)); /* Cursor pos. high */
+   vga_write_cr(CRTC_CURSL,(unsigned char)(off & 0xff));          /* Cursor pos. low */
+   return saved;
+}
+
+void video_set_lxy(unsigned long lxy)
+{
+  int col = (lxy >> 16) & 0xFFFF;
+  int row = lxy & 0xFFFF;
+  video_cursor(col,row);
+}
+
+unsigned long video_get_lxy(void)
+{
+   return (video_col << 16) | (video_row & 0xFFFF);
+}
+
+void video_clear(void)
+{
+  int i;
+  unsigned short clear = ((unsigned short)video_attr << 8) | (' ');
+  unsigned short * addr16 = (unsigned short * )video_fb;
+       clear=vga_swap_short(clear);
+  video_row = video_col = 0;
+  for (i = 0 ; i < 2000 ; i++) {
+    addr16[i] = clear;
+  }
+}
+
+void video_copy(unsigned short *buffer)
+{
+  int i;
+  unsigned short * addr16 = (unsigned short * )video_fb;
+  for (i = 0 ; i < 2000 ; i++) {
+    buffer[i] = addr16[i];
+  }
+}
+
+void video_write(unsigned short *buffer)
+{
+  int i;
+  unsigned short * addr16 = (unsigned short *)video_fb;
+  for (i = 0 ; i < 2000 ; i++) {
+    addr16[i] = buffer[i];
+  }
+}
+
+void video_putc(char ch)
+{
+   char* addr;
+   
+   switch (ch) {
+    case '\n':
+      video_col=0;
+      video_row++;
+      break;
+    case '\r':
+      video_col=0;
+      break;
+    case '\t':
+      video_col += 8 - video_col % 8;
+      break;
+    case '\a':
+/*      beep(); */
+      break;
+    case '\b':
+      if(video_col)
+                               video_col--;
+      else 
+                               return;
+      break;
+    default:
+      addr = video_fb + 2 * video_row * 80 + 2 * video_col;
+      
+      *((char *)addr+1) = (char) video_attr;
+      *((char *)addr) = (char) ch;
+      video_col++;
+      if (video_col > (VGA_MAXCOLS-1)) {
+                               video_row++;
+                               video_col=0;
+      }
+   }
+
+   /* If we're on the bottom of the secreen, wrap one row */
+   if (video_row > (VGA_MAXROWS-1))
+     video_scroll(1);
+    video_cursor(video_col, video_row);
+}
+
+
+unsigned char video_set_attr(unsigned char attr) 
+{
+  unsigned char saved_attr = video_attr;
+  video_attr = attr;
+  return saved_attr;
+}
+
+unsigned char video_set_attr_xy(unsigned char attr, int x, int y) 
+{
+  unsigned char *addr = video_fb + (x * 80 + y) * 2 + 1;
+  unsigned char saved_attr = *addr;
+  *addr = attr;
+  return saved_attr;
+}
+
+/* put char at xy */
+void video_putc_xy(char ch, int x, int y) 
+{
+  video_col = x;
+  video_row = y;
+  video_putc(ch);
+}
+
+/* put char at xy relative to the position */
+void video_putc_rxy(char ch, int x, int y) 
+{
+  video_col += x;
+  video_row += y;
+  video_putc(ch);
+}
+
+/* put char with attribute at xy */
+void video_putc_axy(char ch, char attr, int x, int y) 
+{
+  unsigned char saved_attr = video_set_attr(attr);
+  video_col = x;
+  video_row = y;
+  video_putc(ch);
+  video_set_attr(saved_attr);
+}
+
+void video_puts(const char *s)
+{
+   while(*s) {
+      video_putc(*s);
+      s++;
+   }
+}
+
+void video_puts_a(const char *s, char attr) 
+{
+  unsigned char saved_attr = video_set_attr(attr);
+  video_puts(s);
+  video_set_attr(saved_attr);
+}
+
+void video_puts_xy(const char *s, int x, int y) 
+{
+  video_cursor(x,y);
+  video_puts(s);
+}
+
+void video_puts_axy(const char *s, char attr, int x, int y) 
+{
+  unsigned char saved_attr = video_set_attr(attr);
+  video_puts_xy(s, x, y);
+  video_set_attr(saved_attr);
+}
+
+void video_wipe_ca_area(unsigned char ch, char attr, int x, int y, int w, int h) 
+{
+  int r, c;
+  /* better to do this as word writes */ 
+  unsigned short * addr16 = (unsigned short  *)video_fb + (y * 80 + x);
+  unsigned short charattr = (unsigned short)ch << 8 | attr;
+       charattr=vga_swap_short(charattr);
+  for (r = 0 ; r < h ; r++, addr16 += 80) {
+    for (c = 0 ; c < w ; c++) {
+      addr16[c] = charattr;
+    }
+  }
+}
+
+void video_wipe_a_area(unsigned char attr, int x, int y, int w, int h) 
+{
+  int r, c;
+  /* better to do this as word writes */ 
+  unsigned short * addr16 = (unsigned short *)video_fb + (y * 80 + x);
+  for (r = 0 ; r < h ; r++, addr16 += 80) {
+    for (c = 0 ; c < w ; c++) {
+      ((char*)addr16)[c*2+1] = attr;
+    }
+  }
+}
+
+void video_wipe_c_area(unsigned char ch, int x, int y, int w, int h) 
+{
+  int r, c;
+  /* better to do this as word writes */ 
+  unsigned short * addr16 = (unsigned short  *)video_fb + (y * 80 + x);
+  for (r = 0 ; r < h ; r++, addr16 += 80) {
+    for (c = 0 ; c < w ; c++) {
+      ((char*)addr16)[c*2] = ch;
+    }
+  }
+}
+
+
+/*
+tl t tr
+l    l
+bl b br
+*/
+typedef struct {
+  unsigned char tl; /* top left corner */
+  unsigned char t;  /* top edge */
+  unsigned char tr; /* top right corner */
+  unsigned char l;  /* left edge */
+  unsigned char r;  /* right edge */
+  unsigned char bl; /* bottom left corner */
+  unsigned char b;  /* bottom edge */
+  unsigned char br; /* bottom right corner */
+} box_chars_t;
+
+box_chars_t sbox_chars = {
+  0xDA, 0xC4, 0xBF,
+  0xB3,       0xB3,
+  0xC0, 0xC4, 0xD9
+};
+
+box_chars_t dbox_chars = {
+  0xC9, 0xCD, 0xBB,
+  0xBA,       0xBA,
+  0xC8, 0xCD, 0xBC
+};
+
+static char cmap[] = "0123456789ABCDEF";
+void video_putchex(char c) 
+{
+  video_putc(cmap[(c >> 4 ) & 0xF]);
+  video_putc(cmap[c & 0xF]);
+}
+
+void video_putchexl(char c) 
+{
+  video_putc(cmap[c & 0xF]);
+}
+
+void video_putchexh(char c) 
+{
+  video_putc(cmap[(c >> 4) & 0xF]);
+}
+
+#define VGA_CELL_CA(a,c) (((unsigned short)c<<8)|a) /* for BIG endians */
+
+void video_gbox_area(box_chars_t *box_chars_p, int x, int y, int w, int h) 
+{
+  int r, c;
+  /* better to do this as word writes */ 
+  unsigned short* addr16 = (unsigned short *)video_fb + (y * VGA_MAXCOLS + x);
+  for (r = 0 ; r < h ; r++, addr16 += VGA_MAXCOLS) {
+    if (r == 0) {
+      addr16[0]   = VGA_CELL_CA(video_attr, box_chars_p->tl);
+      addr16[w-1] = VGA_CELL_CA(video_attr, box_chars_p->tr);
+      for (c = 1 ; c < w - 1 ; c++)
+                               addr16[c] = VGA_CELL_CA(video_attr, box_chars_p->t);
+    } else if (r == h - 1) {
+      addr16[0] = VGA_CELL_CA(video_attr, box_chars_p->bl);
+      addr16[w-1] = VGA_CELL_CA(video_attr, box_chars_p->br);
+      for (c = 1 ; c < w - 1 ; c++)
+                               addr16[c] = VGA_CELL_CA(video_attr, box_chars_p->b);
+    } else {
+      addr16[0] = VGA_CELL_CA(video_attr, box_chars_p->l);
+      addr16[w-1] = VGA_CELL_CA(video_attr, box_chars_p->r);
+    }
+  }
+}
+
+/* Writes a box on the screen */
+void video_box_area(int x, int y, int w, int h) {
+  video_gbox_area(&sbox_chars, x, y, w, h);
+}
+/*writes a box with double lines on the screen */
+void video_dbox_area(int x, int y, int w, int h) {
+  video_gbox_area(&dbox_chars, x, y, w, h);
+}
+
+/* routines to set the VGA registers */
+
+/* set attributes */
+void vga_set_attrib(void)
+{
+       int i;
+       unsigned char status;
+       
+       status=in8(STATUS_REG1);
+       i=0;
+       
+       while(attr[i].reg!=0xFF) {
+               out8(ATTRI_INDEX,attr[i].reg);
+               out8(ATTRI_INDEX,attr[i].val); /* Attribute uses index for index and data */
+               i++;
+       }
+       out8(ATTRI_INDEX,0x20); /* unblank the screen */
+}
+
+/* set CRT Controller Registers */
+void vga_set_crt(void)
+{
+       int i;
+       i=0;
+       while(crtc[i].reg!=0xFF) {
+               out8(CRT_INDEX,crtc[i].reg);
+               out8(CRT_DATA,crtc[i].val); 
+               i++;
+       }
+}
+/* Set Palette Registers (DAC) */
+void vga_set_dac(void)
+{
+       int i;
+       for(i=0;i<256;i++) {
+               out8(COL_PAL_IND_W,(unsigned char)i);
+               out8(COL_PAL_DATA,dac[i][0]); /* red */
+               out8(COL_PAL_DATA,dac[i][1]); /* green */
+               out8(COL_PAL_DATA,dac[i][2]); /* blue */
+       }
+       out8(COL_PAL_MASK,0xff); /* set mask */
+}
+/* set Graphic Controller Register */
+void vga_set_gr(void)
+{
+       int i;
+       i=0;
+       while(grmr[i].reg!=0xFF) {
+               out8(GR_INDEX,grmr[i].reg);
+               out8(GR_DATA,grmr[i].val); 
+               i++;
+       }
+}
+
+/* Set Sequencer Registers */
+void vga_set_seq(void)
+{
+       int i;
+       i=0;
+       while(seq[i].reg!=0xFF) {
+               out8(SEQ_INDEX,seq[i].reg);
+               out8(SEQ_DATA,seq[i].val); 
+               i++;
+       }
+}
+
+
+/* Set Extension Registers */
+void vga_set_xreg(void)
+{
+       int i;
+       i=0;
+       while(xreg[i].reg!=0xFF) {
+               out8(XREG_INDEX,xreg[i].reg);
+               out8(XREG_DATA,xreg[i].val); 
+               i++;
+       }
+}
+
+/************************************************************
+ * some helping routines
+ */
+void vga_write_sr(unsigned char reg,unsigned char val)
+{
+       out8(SEQ_INDEX,reg);
+       out8(SEQ_DATA,val); 
+}
+
+void vga_write_gr(unsigned char reg,unsigned char val)
+{
+       out8(GR_INDEX,reg);
+       out8(GR_DATA,val); 
+}
+
+void vga_write_cr(unsigned char reg,unsigned char val)
+{
+       out8(CRT_INDEX,reg);
+       out8(CRT_DATA,val); 
+}
+
+
+#if 0
+void video_dump_reg(void)
+{
+       /* first dump attributes */
+       int i;
+       unsigned char status;
+
+       
+       printf("Extended Regs:\n");     
+       i=0;
+       while(xreg[i].reg!=0xFF) {
+               out8(XREG_INDEX,xreg[i].reg);
+               status=in8(XREG_DATA);
+               printf("XR%02X is %02X, should be %02X\n",xreg[i].reg,status,xreg[i].val);
+               i++;
+       }
+       printf("Sequencer Regs:\n");    
+       i=0;
+       while(seq[i].reg!=0xFF) {
+               out8(SEQ_INDEX,seq[i].reg);
+               status=in8(SEQ_DATA);
+               printf("SR%02X is %02X, should be %02X\n",seq[i].reg,status,seq[i].val);
+               i++;
+       }
+       printf("Graphic Regs:\n");      
+       i=0;
+       while(grmr[i].reg!=0xFF) {
+               out8(GR_INDEX,grmr[i].reg);
+               status=in8(GR_DATA);
+               printf("GR%02X is %02X, should be %02X\n",grmr[i].reg,status,grmr[i].val);
+               i++;
+       }
+       printf("CRT Regs:\n");  
+       i=0;
+       while(crtc[i].reg!=0xFF) {
+               out8(CRT_INDEX,crtc[i].reg);
+               status=in8(CRT_DATA);
+               printf("CR%02X is %02X, should be %02X\n",crtc[i].reg,status,crtc[i].val);
+               i++;
+       }
+       printf("Attributes:\n");        
+       status=in8(STATUS_REG1);
+       i=0;
+       while(attr[i].reg!=0xFF) {
+               out8(ATTRI_INDEX,attr[i].reg);
+               status=in8(ATTRI_DATA);
+               out8(ATTRI_INDEX,attr[i].val); /* Attribute uses index for index and data */
+               printf("AR%02X is %02X, should be %02X\n",attr[i].reg,status,attr[i].val);
+               i++;
+       }
+}
+#endif
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/board/pip405/video.h b/board/pip405/video.h
new file mode 100644 (file)
index 0000000..3c6f513
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * (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
+ *
+ */
+#ifndef _VIDEO_H
+#define _VIDEO_H
+
+int video_init(int busdevfunc);
+void video_clear(void);
+void video_putc(char ch);
+void video_puts(const char *s);
+void video_puts_a(const char *s, char attr); 
+unsigned char video_set_attr(unsigned char attr);
+
+void video_box_area(int x, int y, int w, int h);
+void video_dbox_area(int x, int y, int w, int h);
+void video_wipe_c_area(unsigned char ch, int x, int y, int w, int h);
+
+void video_wipe_a_area(unsigned char attr, int x, int y, int w, int h); 
+void video_wipe_ca_area(unsigned char ch, char attr, int x, int y, int w, int h); 
+void video_puts_axy(const char *s, char attr, int x, int y); 
+void video_putc_rxy(char ch, int x, int y); 
+void video_putc_xy(char ch, int x, int y); 
+unsigned char video_set_attr_xy(unsigned char attr, int x, int y); 
+void video_copy(unsigned short *buffer);
+void video_write(unsigned short *buffer);
+
+#define VGA_ATTR_CLR_RED       0x4
+#define VGA_ATTR_CLR_GRN       0x2
+#define VGA_ATTR_CLR_BLU       0x1
+#define VGA_ATTR_CLR_YEL       (VGA_ATTR_CLR_RED | VGA_ATTR_CLR_GRN)
+#define VGA_ATTR_CLR_CYN       (VGA_ATTR_CLR_GRN | VGA_ATTR_CLR_BLU)
+#define VGA_ATTR_CLR_MAG       (VGA_ATTR_CLR_BLU | VGA_ATTR_CLR_RED)
+#define VGA_ATTR_CLR_BLK       0
+#define VGA_ATTR_CLR_WHT       (VGA_ATTR_CLR_RED | VGA_ATTR_CLR_GRN | VGA_ATTR_CLR_BLU)
+
+#define VGA_ATTR_BNK                   0x80
+#define VGA_ATTR_ITN                   0x08
+
+#define VGA_ATTR_BG_MSK  0x70
+#define VGA_ATTR_FG_MSK  0x07
+
+#define VGA_ATTR_BG_GET(v) (((v) & VGA_ATTR_BG_MSK)>>4)
+#define VGA_ATTR_BG_SET(v, c) (((c) & VGA_ATTR_FG_MSK)<<4) | (v & ~VGA_ATTR_BG_MSK))
+
+#define VGA_ATTR_FG_GET(v) ((v) & VGA_ATTR_FG_MSK)
+#define VGA_ATTR_FG_SET(v, c) ((c) & VGA_ATTR_FG_MSK) | (v & ~VGA_ATTR_FG_MSK))
+
+#define VGA_ATTR_FG_BG_SET(v, b, f) (VGA_ATTR_BG_SET(v, b) | VGA_ATTR_FG_SET(v, cf))
+
+#define VGA_ATTR_INVERT(A) ((((A)&0x7)<<4)|(((A)&0x70)>>4) |((A)&0x88))
+
+#endif
index e8f80158a9a04cb86deec063973bf00a2b041326..814fa2480e6ad26cbdfac055b82e88199c9447d9 100644 (file)
@@ -33,6 +33,7 @@ COBJS = board.o main.o command.o \
          cmd_console.o cmd_date.o cmd_eeprom.o \
          cmd_flash.o cmd_ide.o cmd_mem.o cmd_net.o \
          cmd_nvedit.o cmd_pcmcia.o cmd_reginfo.o \
+         cmd_fdc.o cmd_scsi.o \
          cmd_bedbug.o bedbug.o s_record.o dlmalloc.o \
          kgdb.o console.o lists.o devices.o flash.o cmd_i2c.o cmd_immap.o
 
index 25b44c0a0abd0f352ec716b2f6b5f14dd73a2fa7..c47ae26cf630f996f4c89da8671750e76db8054e 100644 (file)
@@ -31,6 +31,9 @@
 #if (CONFIG_COMMANDS & CFG_CMD_IDE)
 #include <ide.h>
 #endif
+#if (CONFIG_COMMANDS & CFG_CMD_SCSI)
+#include <scsi.h>
+#endif
 #if (CONFIG_COMMANDS & CFG_CMD_KGDB)
 #include <kgdb.h>
 #endif
@@ -156,6 +159,7 @@ board_init_f (ulong bootflag)
     defined(CONFIG_AR405)     || \
     defined(CONFIG_CANBT)     || \
     defined(CONFIG_WALNUT405) || \
+    defined(CONFIG_PIP405)    || \
     defined(CONFIG_CPCIISER4) || \
     defined(CONFIG_ADCIOP)    || \
     defined(CONFIG_LWMON)     || \
@@ -259,6 +263,7 @@ board_init_f (ulong bootflag)
      * First reserve memory for monitor code at end of DRAM.
      */
     len = get_endaddr() - CFG_MONITOR_BASE;
+    
     if (len > CFG_MONITOR_LEN) {
        printf ("*** PPCBoot size %ld > reserved memory (%d)\n",
                len, CFG_MONITOR_LEN);
@@ -400,7 +405,11 @@ board_init_f (ulong bootflag)
 
     bd->bi_procfreq    = idata->cpu_clk; /* Processor Speed, In Hz */
     bd->bi_plb_busfreq = bd->bi_busfreq;
+#ifdef CONFIG_PPC405 
+    bd->bi_pci_busfreq = get_PCI_freq();
+#else
     bd->bi_pci_busfreq = bd->bi_busfreq;
+#endif
 #endif
 
     /* Function pointers must be added after code relocation */
@@ -545,11 +554,12 @@ void    board_init_r  (bd_t *bd, ulong dest_addr)
     /* relocate environment function pointers etc. */
     env_relocate (reloc_off);
 
-#if defined(CONFIG_COGENT)  || \
-    defined(CONFIG_HYMOD)   || \
-    defined(CONFIG_CPCI405) || \
-    defined(CONFIG_PCU_E)   || \
-    defined(CONFIG_EVB64260)
+#if defined(CONFIG_COGENT)     || \
+    defined(CONFIG_CPCI405)    || \
+    defined(CONFIG_EVB64260)   || \
+    defined(CONFIG_HYMOD)      || \
+    defined(CONFIG_LWMON)      || \
+    defined(CONFIG_PCU_E)
     /* miscellaneous platform dependent initialisations */
     misc_init_r(bd);
 #endif
@@ -565,8 +575,8 @@ void    board_init_r  (bd_t *bd, ulong dest_addr)
     defined(CONFIG_IVML24)     || \
     defined(CONFIG_IP860)      || \
     defined(CONFIG_LWMON)      || \
-    defined(CONFIG_RPXSUPER)   || \
-    defined(CONFIG_PCU_E)      )
+    defined(CONFIG_PCU_E)      || \
+    defined(CONFIG_RPXSUPER)   )
 # ifdef DEBUG
     puts ("  Reset Ethernet PHY\n");
 # endif
@@ -631,6 +641,10 @@ void    board_init_r  (bd_t *bd, ulong dest_addr)
     ide_init(bd);
 #endif /* CFG_CMD_IDE */
 
+#if (CONFIG_COMMANDS & CFG_CMD_SCSI)
+       scsi_init();
+#endif
+
 #if (CONFIG_COMMANDS & CFG_CMD_BEDBUG)
     bedbug_init();
 #endif
index e7ae5488515deab074b59bf25786cc0b5c471a8e..6f70f1e39a638b455035f95f0d6e6e5e5fe16efe 100644 (file)
@@ -59,6 +59,11 @@ void do_bdinfo (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
        print_num ("immr_base",     bd->bi_immr_base    );
 #endif
        print_num ("bootflags",     bd->bi_bootflags    );
+#if defined(CONFIG_PPC405)
+       print_str ("procfreq",      strmhz(buf, bd->bi_procfreq));
+       print_str ("plb_busfreq",           strmhz(buf, bd->bi_plb_busfreq));
+       print_str ("pci_busfreq",           strmhz(buf, bd->bi_pci_busfreq));
+#else
 #if defined(CFG_CLKS_IN_HZ)
        print_str ("intfreq",       strmhz(buf, bd->bi_intfreq));
        print_str ("busfreq",       strmhz(buf, bd->bi_busfreq));
@@ -66,6 +71,7 @@ void do_bdinfo (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
        print_str ("intfreq",       strmhz(buf, bd->bi_intfreq*1000000L));
        print_str ("busfreq",       strmhz(buf, bd->bi_busfreq*1000000L));
 #endif /* CFG_CLKS_IN_HZ */
+#endif /* CONFIG_PPC405) */
        printf ("  ethaddr     =");
        for (i=0; i<6; ++i) {
                printf ("%c%02X", i ? ':' : ' ', bd->bi_enetaddr[i]);
index f38f6f5b8e55b8aa0a196be3bf55790d845fc626..51aa4c93259de1386c947e11b093885c91eac7b3 100644 (file)
@@ -674,6 +674,7 @@ print_type (image_header_t *hdr)
        case IH_OS_INVALID:     os = "Invalid OS";              break;
        case IH_OS_NETBSD:      os = "NetBSD";                  break;
        case IH_OS_LINUX:       os = "Linux";                   break;
+       case IH_OS_PPCBOOT:     os = "PPCBoot";                 break;
        default:                os = "Unknown OS";              break;
        }
 
@@ -699,6 +700,7 @@ print_type (image_header_t *hdr)
        case IH_TYPE_KERNEL:    type = "Kernel Image";          break;
        case IH_TYPE_RAMDISK:   type = "RAMDisk Image";         break;
        case IH_TYPE_MULTI:     type = "Multi-File Image";      break;
+       case IH_TYPE_FIRMWARE:  type = "Firmware";                      break;
        default:                type = "Unknown Image";         break;
        }
 
index 6c4fe6059f21ea000c4ab05af87f98f9d9accdbf..84ac1a22340e130f28d1a6314da5a35c26645139 100644 (file)
@@ -65,6 +65,7 @@ void do_date (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
                        (tm.tm_wday<0 || tm.tm_wday>6) ?
                                "unknown " : weekdays[tm.tm_wday],
                        tm.tm_hour, tm.tm_min, tm.tm_sec);
+                       
                return;
        default:
                printf ("Usage:\n%s\n", cmdtp->usage);
diff --git a/common/cmd_fdc.c b/common/cmd_fdc.c
new file mode 100644 (file)
index 0000000..e854885
--- /dev/null
@@ -0,0 +1,731 @@
+/*
+ * (C) Copyright 2001
+ * Denis Peter, MPL AG, 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
+ *
+ */
+/*
+ * Floppy Disk support
+ */
+
+#include <ppcboot.h>
+#include <config.h>
+#include <command.h>
+#include <image.h>
+
+
+#undef FDC_DEBUG
+
+#ifdef FDC_DEBUG
+#define        PRINTF(fmt,args...)     printf (fmt ,##args)
+#else
+#define PRINTF(fmt,args...)
+#endif
+
+#ifndef        TRUE
+#define TRUE            1
+#endif
+#ifndef FALSE
+#define FALSE           0
+#endif
+
+
+#if (CONFIG_COMMANDS & CFG_CMD_DATE)
+#include <rtc.h>
+#endif
+
+#if (CONFIG_COMMANDS & CFG_CMD_FDC)
+
+
+typedef struct {
+       int                                             flags;          /* connected drives ect */
+       unsigned long blnr;                     /* Logical block nr */
+       uchar                                   drive;          /* drive no */
+       uchar                                   cmdlen;         /* cmd length */
+       uchar                                   cmd[16];        /* cmd desc */
+       uchar                                   dma;                    /* if > 0 dma enabled */
+       uchar                                   result[11];/* status information */
+       uchar                                   resultlen; /* lenght of result */
+} FDC_COMMAND_STRUCT;
+/* flags: only the lower 8bit used:
+ * bit 0 if set drive 0 is present
+ * bit 1 if set drive 1 is present
+ * bit 2 if set drive 2 is present
+ * bit 3 if set drive 3 is present
+ * bit 4 if set disk in drive 0 is inserted
+ * bit 5 if set disk in drive 1 is inserted
+ * bit 6 if set disk in drive 2 is inserted
+ * bit 7 if set disk in drive 4 is inserted
+ */
+
+/* cmd indexes */
+#define COMMAND                0  
+#define DRIVE                  1  
+#define CONFIG0                        1  
+#define SPEC_HUTSRT    1
+#define TRACK                  2
+#define CONFIG1                        2
+#define SPEC_HLT               2
+#define HEAD                           3
+#define CONFIG2                        3
+#define SECTOR                         4
+#define SECTOR_SIZE    5
+#define LAST_TRACK     6
+#define GAP                                    7
+#define DTL                                    8
+/* result indexes */
+#define STATUS_0                                               0
+#define STATUS_PCN                                     1
+#define STATUS_1                                               1
+#define STATUS_2                                               2
+#define STATUS_TRACK                           3
+#define STATUS_HEAD                                    4
+#define STATUS_SECT                                    5
+#define STATUS_SECT_SIZE               6
+
+
+/* Register addresses */
+#define FDC_BASE       0x3F0
+#define FDC_SRA                FDC_BASE + 0    /* Status Register A */
+#define FDC_SRB                FDC_BASE + 1    /* Status Register B */
+#define FDC_DOR                FDC_BASE + 2    /* Digital Output Register */
+#define FDC_TDR                FDC_BASE + 3    /* Tape Drive Register */
+#define FDC_DSR                FDC_BASE + 4    /* Data rate Register */
+#define FDC_MSR                FDC_BASE + 4    /* Main Status Register */
+#define FDC_FIFO       FDC_BASE + 5    /* FIFO */
+#define FDC_DIR                FDC_BASE + 6    /* Digital Input Register */  
+#define FDC_CCR                FDC_BASE + 7    /* Configuration Control */
+/* Commands */
+#define FDC_CMD_SENSE_INT              0x08
+#define FDC_CMD_CONFIGURE              0x13
+#define FDC_CMD_SPECIFY                                0x03
+#define FDC_CMD_RECALIBRATE    0x07
+#define FDC_CMD_READ                                   0x06
+#define FDC_CMD_READ_TRACK             0x02
+#define FDC_CMD_READ_ID                                0x0A
+#define FDC_CMD_DUMP_REG                       0x0E
+#define FDC_CMD_SEEK                                   0x0F
+
+#define FDC_CMD_SENSE_INT_LEN          0x01
+#define FDC_CMD_CONFIGURE_LEN          0x04
+#define FDC_CMD_SPECIFY_LEN                            0x03
+#define FDC_CMD_RECALIBRATE_LEN        0x02
+#define FDC_CMD_READ_LEN                                       0x09
+#define FDC_CMD_READ_TRACK_LEN         0x09
+#define FDC_CMD_READ_ID_LEN                            0x02
+#define FDC_CMD_DUMP_REG_LEN                   0x01
+#define FDC_CMD_SEEK_LEN                                       0x03
+
+#define FDC_FIFO_THR                   0x0C
+#define FDC_FIFO_DIS                   0x00
+#define FDC_IMPLIED_SEEK       0x01
+#define FDC_POLL_DIS                   0x00
+#define FDC_PRE_TRK                            0x00
+#define FDC_CONFIGURE                  FDC_FIFO_THR | (FDC_POLL_DIS<<4) | (FDC_FIFO_DIS<<5) | (FDC_IMPLIED_SEEK << 6)
+#define FDC_MFM_MODE                   0x01 /* MFM enable */
+#define FDC_SKIP_MODE                  0x00 /* skip enable */
+
+#define FDC_TIME_OUT 100000 /* time out */ 
+#define        FDC_RW_RETRIES          3 /* read write retries */
+#define FDC_CAL_RETRIES                3 /* calibration and seek retries */
+
+
+/* Disk structure */
+typedef struct  {
+       unsigned int size;                      /* nr of sectors total */
+       unsigned int sect;                      /* sectors per track */
+       unsigned int head;                      /* nr of heads */
+       unsigned int track;                     /* nr of tracks */
+       unsigned int stretch;           /* !=0 means double track steps */
+       unsigned char   gap;                    /* gap1 size */
+       unsigned char   rate;                   /* data rate. |= 0x40 for perpendicular */
+       unsigned char   spec1;          /* stepping rate, head unload time */
+       unsigned char   fmt_gap;        /* gap2 size */
+       unsigned char hlt;                      /* head load time */
+       unsigned char sect_code; /* Sector Size code */
+       const char      * name;                 /* used only for predefined formats */
+} FD_GEO_STRUCT;
+
+
+/* supported Floppy types (currently only one) */
+const static FD_GEO_STRUCT floppy_type[2] = {
+       { 2880,18,2,80,0,0x1B,0x00,0xCF,0x6C,16,2,"H1440" },    /*  7 1.44MB 3.5"   */
+       {    0, 0,0, 0,0,0x00,0x00,0x00,0x00, 0,0,NULL    },    /*  end of table    */
+};
+
+static FDC_COMMAND_STRUCT cmd; /* global command struct */
+
+/* Supporting Functions */
+/* reads a Register of the FDC */
+unsigned char read_fdc_reg(unsigned int addr)
+{
+       volatile unsigned char *val = (volatile unsigned char *)(CFG_ISA_IO_BASE_ADDRESS | addr);
+       return val[0];
+}
+
+/* writes a Register of the FDC */
+void write_fdc_reg(unsigned int addr, unsigned char val)
+{
+               volatile unsigned char *tmp = (volatile unsigned char *)(CFG_ISA_IO_BASE_ADDRESS | addr);
+               tmp[0]=val;
+}
+
+/* waits for an interrupt (polling) */
+int wait_for_fdc_int(void)
+{
+       unsigned long timeout;
+       timeout = FDC_TIME_OUT;
+       while((read_fdc_reg(FDC_SRA)&0x80)==0) {
+               timeout--;
+               udelay(10);
+               if(timeout==0) /* timeout occured */
+                       return FALSE; 
+       }
+       return TRUE;
+}
+
+
+/* reads a byte from the FIFO of the FDC and checks direction and RQM bit
+   of the MSR. returns -1 if timeout, or byte if ok */ 
+int read_fdc_byte(void)
+{
+       unsigned long timeout;
+       timeout = FDC_TIME_OUT;
+       while((read_fdc_reg(FDC_MSR)&0xC0)!=0xC0) { 
+               /* direction out and ready */
+               udelay(10);
+               timeout--;
+               if(timeout==0) /* timeout occured */
+                       return -1; 
+       }
+       return read_fdc_reg(FDC_FIFO);
+}
+
+/* if the direction of the FIFO is wrong, this routine is used to 
+   empty the FIFO. Should _not_ be used */
+int fdc_need_more_output(void)
+{
+       unsigned char c;
+       while((read_fdc_reg(FDC_MSR)&0xC0)==0xC0)       {
+                       c=(unsigned char)read_fdc_byte();
+                       printf("Error: more output: %x\n",c);
+       }
+       return TRUE;
+}              
+
+
+/* writes a byte to the FIFO of the FDC and checks direction and RQM bit
+   of the MSR */ 
+int write_fdc_byte(unsigned char val)
+{
+       unsigned long timeout;
+       timeout = FDC_TIME_OUT;
+       while((read_fdc_reg(FDC_MSR)&0xC0)!=0x80) {
+               /* direction in and ready for byte */
+               timeout--;
+               udelay(10);
+               fdc_need_more_output();
+               if(timeout==0) /* timeout occured */
+                       return FALSE; 
+       }
+       write_fdc_reg(FDC_FIFO,val);
+       return TRUE;
+}
+
+/* sets up all FDC commands and issues it to the FDC. If
+   the command causes direct results (no Execution Phase)
+   the result is be read as well. */
+
+int fdc_issue_cmd(FDC_COMMAND_STRUCT *pCMD,FD_GEO_STRUCT *pFG)
+{
+       int i;
+       unsigned long head,track,sect,timeout;
+       track = pCMD->blnr / (pFG->sect * pFG->head); /* track nr */ 
+       sect =  pCMD->blnr % (pFG->sect * pFG->head); /* remaining blocks */
+       head = sect / pFG->sect; /* head nr */
+       sect =  sect % pFG->sect; /* remaining blocks */
+       sect++; /* sectors are 1 based */
+       PRINTF("Track %ld, Head %ld, Sector %ld, Drive %d (blnr %ld)\n",track,head,sect,pCMD->drive,pCMD->blnr);
+       if(head|=0) { /* max heads = 2 */
+               pCMD->cmd[DRIVE]=pCMD->drive | 0x04; /* head 1 */
+               pCMD->cmd[HEAD]=(unsigned char) head; /* head register */
+       }
+       else {
+               pCMD->cmd[DRIVE]=pCMD->drive; /* head 0 */
+               pCMD->cmd[HEAD]=(unsigned char) head; /* head register */
+       }
+       pCMD->cmd[TRACK]=(unsigned char) track; /* track */
+       switch (pCMD->cmd[COMMAND]) {
+               case FDC_CMD_READ:
+                       pCMD->cmd[SECTOR]=(unsigned char) sect; /* sector */
+                       pCMD->cmd[SECTOR_SIZE]=pFG->sect_code; /* sector size code */
+                       pCMD->cmd[LAST_TRACK]=pFG->sect; /* End of track */
+                       pCMD->cmd[GAP]=pFG->gap; /* gap */
+                       pCMD->cmd[DTL]=0xFF; /* DTL */
+                       pCMD->cmdlen=FDC_CMD_READ_LEN;
+                       pCMD->cmd[COMMAND]|=(FDC_MFM_MODE<<6); /* set MFM bit */
+                       pCMD->cmd[COMMAND]|=(FDC_SKIP_MODE<<5); /* set Skip bit */
+                       pCMD->resultlen=0;  /* result only after execution */
+                       break;
+               case FDC_CMD_SEEK:
+                       pCMD->cmdlen=FDC_CMD_SEEK_LEN;
+                       pCMD->resultlen=0;  /* no result */ 
+                       break;
+               case FDC_CMD_CONFIGURE:
+                       pCMD->cmd[CONFIG0]=0;
+                       pCMD->cmd[CONFIG1]=FDC_CONFIGURE; /* FIFO Threshold, Poll, Enable FIFO */
+                       pCMD->cmd[CONFIG2]=FDC_PRE_TRK;         /* Precompensation Track */
+                       pCMD->cmdlen=FDC_CMD_CONFIGURE_LEN;
+                       pCMD->resultlen=0;  /* no result */
+                       break;
+               case FDC_CMD_SPECIFY:
+                       pCMD->cmd[SPEC_HUTSRT]=pFG->spec1;
+                       pCMD->cmd[SPEC_HLT]=(pFG->hlt)<<1; /* head load time */
+                       if(pCMD->dma==0)
+                               pCMD->cmd[SPEC_HLT]|=0x1; /* no dma */
+                       pCMD->cmdlen=FDC_CMD_SPECIFY_LEN;
+                       pCMD->resultlen=0;  /* no result */
+                       break;
+               case FDC_CMD_DUMP_REG:
+                       pCMD->cmdlen=FDC_CMD_DUMP_REG_LEN;
+                       pCMD->resultlen=10;  /* 10 byte result */
+                       break;
+               case FDC_CMD_READ_ID:
+                       pCMD->cmd[COMMAND]|=(FDC_MFM_MODE<<6); /* set MFM bit */
+                       pCMD->cmdlen=FDC_CMD_READ_ID_LEN;
+                       pCMD->resultlen=7;  /* 7 byte result */
+                       break;
+               case FDC_CMD_RECALIBRATE:
+                       pCMD->cmd[DRIVE]&=0x03; /* don't set the head bit */
+                       pCMD->cmdlen=FDC_CMD_RECALIBRATE_LEN;
+                       pCMD->resultlen=0;  /* no result */
+                       break;
+                       break;
+               case FDC_CMD_SENSE_INT:
+                       pCMD->cmdlen=FDC_CMD_SENSE_INT_LEN;
+                       pCMD->resultlen=2;
+                       break;
+       }
+       for(i=0;i<pCMD->cmdlen;i++) {
+               /* PRINTF("write cmd%d = 0x%02X\n",i,pCMD->cmd[i]); */
+               if(write_fdc_byte(pCMD->cmd[i])==FALSE) {
+                       PRINTF("Error: timeout while issue cmd%d\n",i);
+                       return FALSE;
+               }
+       }
+       timeout=FDC_TIME_OUT;   
+       for(i=0;i<pCMD->resultlen;i++) {
+               while((read_fdc_reg(FDC_MSR)&0xC0)!=0xC0) {
+                       timeout--;
+                       if(timeout==0) {
+                               PRINTF(" timeout while reading result%d MSR=0x%02X\n",i,read_fdc_reg(FDC_MSR));
+                               return FALSE;
+                       }
+               }               
+               pCMD->result[i]=(unsigned char)read_fdc_byte();
+       }       
+       return TRUE;
+}
+
+/* selects the drive assigned in the cmd structur and
+   switches on the Motor */                            
+void select_fdc_drive(FDC_COMMAND_STRUCT *pCMD)
+{
+       unsigned char val;
+       
+       val=(1<<(4+pCMD->drive))|pCMD->drive|0xC; /* set reset, dma gate and motor bits */
+       if((read_fdc_reg(FDC_DOR)&val)!=val) {
+               write_fdc_reg(FDC_DOR,val);
+               for(val=0;val<255;val++)
+                       udelay(500); /* wait some time to start motor */
+       }
+}
+
+/* switches off the Motor of the specified drive */                            
+void stop_fdc_drive(FDC_COMMAND_STRUCT *pCMD)
+{
+       unsigned char val;
+       
+       val=(1<<(4+pCMD->drive))|pCMD->drive; /* sets motor bits */
+       write_fdc_reg(FDC_DOR,(read_fdc_reg(FDC_DOR)&~val));
+}
+
+/* issues a recalibrate command, waits for interrupt and 
+ * issues a sense_interrupt */
+int fdc_recalibrate(FDC_COMMAND_STRUCT *pCMD,FD_GEO_STRUCT *pFG)
+{
+       pCMD->cmd[COMMAND]=FDC_CMD_RECALIBRATE;
+       if(fdc_issue_cmd(pCMD,pFG)==FALSE)
+               return FALSE;
+       while(wait_for_fdc_int()!=TRUE);
+       pCMD->cmd[COMMAND]=FDC_CMD_SENSE_INT;
+       return(fdc_issue_cmd(pCMD,pFG));
+}
+
+/* issues a recalibrate command, waits for interrupt and 
+ * issues a sense_interrupt */
+int fdc_seek(FDC_COMMAND_STRUCT *pCMD,FD_GEO_STRUCT *pFG)
+{
+       pCMD->cmd[COMMAND]=FDC_CMD_SEEK;
+       if(fdc_issue_cmd(pCMD,pFG)==FALSE)
+               return FALSE;
+       while(wait_for_fdc_int()!=TRUE);
+       pCMD->cmd[COMMAND]=FDC_CMD_SENSE_INT;
+       return(fdc_issue_cmd(pCMD,pFG));
+}
+
+
+/* terminates current command, by not servicing the FIFO
+ * waits for interrupt and fills in the result bytes */
+int fdc_terminate(FDC_COMMAND_STRUCT *pCMD)
+{
+       int i;
+       for(i=0;i<100;i++)
+               udelay(500); /* wait 500usec for fifo overrun */
+       while((read_fdc_reg(FDC_SRA)&0x80)==0x00); /* wait as long as no int has occured */
+       for(i=0;i<7;i++) {
+               pCMD->result[i]=(unsigned char)read_fdc_byte();
+       }
+       return TRUE;
+}
+
+/* reads data from FDC, seek commands are issued automatic */
+int fdc_read_data(unsigned char *buffer, unsigned long blocks,FDC_COMMAND_STRUCT *pCMD, FD_GEO_STRUCT *pFG)
+{
+  /* first seek to start address */
+       unsigned long len,lastblk,readblk,i,timeout,ii,offset; 
+       unsigned char pcn,c,retriesrw,retriescal;
+       unsigned char *bufferw; /* working buffer */
+       int sect_size;
+       int flags;
+       
+       flags=disable_interrupts(); /* switch off all Interrupts */
+       select_fdc_drive(pCMD); /* switch on drive */
+       sect_size=0x080<<pFG->sect_code;
+       retriesrw=0;
+       retriescal=0;
+       offset=0;
+       if(fdc_seek(pCMD,pFG)==FALSE) {
+               stop_fdc_drive(pCMD);
+               enable_interrupts();
+               return FALSE;
+       }
+       if((pCMD->result[STATUS_0]&0x20)!=0x20) {
+               printf("Seek error Status: %02X\n",pCMD->result[STATUS_0]);
+               stop_fdc_drive(pCMD);
+               enable_interrupts();
+               return FALSE;
+       }
+       pcn=pCMD->result[STATUS_PCN]; /* current track */
+       /* now determine the next seek point */
+       lastblk=pCMD->blnr + blocks;
+       /*      readblk=(pFG->head*pFG->sect)-(pCMD->blnr%(pFG->head*pFG->sect)); */
+       readblk=pFG->sect-(pCMD->blnr%pFG->sect);
+       PRINTF("1st nr of block possible read %ld start %ld\n",readblk,pCMD->blnr);
+       if(readblk>blocks) /* is end within 1st track */
+               readblk=blocks; /* yes, correct it */
+       PRINTF("we read %ld blocks start %ld\n",readblk,pCMD->blnr);
+       bufferw=&buffer[0]; /* setup working buffer */
+       do {
+retryrw:
+               len=sect_size * readblk;
+               pCMD->cmd[COMMAND]=FDC_CMD_READ;
+               if(fdc_issue_cmd(pCMD,pFG)==FALSE) {
+                       stop_fdc_drive(pCMD);
+                       enable_interrupts();
+                       return FALSE;
+               }
+               for (i=0;i<len;i++) {
+                       timeout=FDC_TIME_OUT;
+                       do {
+                               c=read_fdc_reg(FDC_MSR);
+                               if((c&0xC0)==0xC0) {
+                                       bufferw[i]=read_fdc_reg(FDC_FIFO);
+                                       break;
+                               }
+                               if((c&0xC0)==0x80) { /* output */
+                                       PRINTF("Transfer error transfered: at %ld, MSR=%02X\n",i,c);
+                                       if(i>6) {
+                                               for(ii=0;ii<7;ii++) {
+                                                       pCMD->result[ii]=bufferw[(i-7+ii)];
+                                               } /* for */
+                                       }
+                                       if(retriesrw++>FDC_RW_RETRIES) {
+                                               if (retriescal++>FDC_CAL_RETRIES) {
+                                                       stop_fdc_drive(pCMD);
+                                                       enable_interrupts();
+                                                       return FALSE;
+                                               }
+                                               else {
+                                                       PRINTF(" trying to recalibrate Try %d\n",retriescal);
+                                                       if(fdc_recalibrate(pCMD,pFG)==FALSE) {
+                                                               stop_fdc_drive(pCMD);
+                                                               enable_interrupts();
+                                                               return FALSE;
+                                                       }
+                                                       retriesrw=0;
+                                                       goto retrycal;
+                                               } /* else >FDC_CAL_RETRIES */
+                                       }
+                                       else {
+                                               PRINTF("Read retry %d\n",retriesrw);
+                                               goto retryrw;
+                                       } /* else >FDC_RW_RETRIES */
+                               }/* if output */
+                               timeout--;
+                       }while(TRUE);
+               } /* for len */
+               /* the last sector of a track or all data has been read,
+                * we need to get the results */
+               fdc_terminate(pCMD);
+               offset+=(sect_size*readblk); /* set up buffer pointer */
+               bufferw=&buffer[offset];
+               pCMD->blnr+=readblk; /* update current block nr */
+               blocks-=readblk; /* update blocks */
+               if(blocks==0)
+                       break; /* we are finish */
+               /* setup new read blocks */
+               /*      readblk=pFG->head*pFG->sect; */
+               readblk=pFG->sect;
+               if(readblk>blocks)
+                       readblk=blocks;
+retrycal:
+               /* a seek is necessary */
+               if(fdc_seek(pCMD,pFG)==FALSE) {
+                       stop_fdc_drive(pCMD);
+                       enable_interrupts();
+                       return FALSE;
+               }
+               if((pCMD->result[STATUS_0]&0x20)!=0x20) {
+                       PRINTF("Seek error Status: %02X\n",pCMD->result[STATUS_0]);
+                       stop_fdc_drive(pCMD);
+                       return FALSE;
+               }
+               pcn=pCMD->result[STATUS_PCN]; /* current track */
+       }while(TRUE); /* start over */
+       stop_fdc_drive(pCMD); /* switch off drive */
+       enable_interrupts();
+       return TRUE;
+}
+
+/* Scan all drives and check if drive is present and disk is inserted */
+int fdc_check_drive(FDC_COMMAND_STRUCT *pCMD, FD_GEO_STRUCT *pFG)
+{
+       int i,drives,state;
+  /* OK procedure of data book is satisfied. 
+        * trying to get some information over the drives */
+       state=0; /* no drives, no disks */
+       for(drives=0;drives<4;drives++) {
+               pCMD->drive=drives;
+               select_fdc_drive(pCMD);
+               pCMD->blnr=0; /* set to the 1st block */
+               if(fdc_recalibrate(pCMD,pFG)==FALSE)
+                       break;
+               if((pCMD->result[STATUS_0]&0x10)==0x10)
+                       break;
+               /* ok drive connected check for disk */
+               state|=(1<<drives);
+               pCMD->blnr=pFG->size; /* set to the last block */
+               if(fdc_seek(pCMD,pFG)==FALSE)
+                       break;
+               pCMD->blnr=0; /* set to the 1st block */
+               if(fdc_recalibrate(pCMD,pFG)==FALSE)
+                       break;
+               pCMD->cmd[COMMAND]=FDC_CMD_READ_ID;
+               if(fdc_issue_cmd(pCMD,pFG)==FALSE)
+                       break;
+               state|=(0x10<<drives);
+       }
+       stop_fdc_drive(pCMD);
+       for(i=0;i<4;i++) {
+               PRINTF("Floppy Drive %d %sconnected %sDisk inserted %s\n",i,
+                       ((state&(1<<i))==(1<<i)) ? "":"not ",
+                       ((state&(0x10<<i))==(0x10<<i)) ? "":"no ",
+                       ((state&(0x10<<i))==(0x10<<i)) ? pFG->name : "");
+       }
+       pCMD->flags=state;
+       return TRUE;
+}
+
+
+/**************************************************************************
+* int fdc_setup
+* setup the fdc according the datasheet
+* assuming in PS2 Mode
+*/
+int fdc_setup(FDC_COMMAND_STRUCT *pCMD,        FD_GEO_STRUCT *pFG)
+{
+
+       int i;
+       /* first, we reset the FDC via the DOR */
+       write_fdc_reg(FDC_DOR,0x00);
+       for(i=0; i<255; i++) /* then we wait some time */
+               udelay(500);
+       /* then, we clear the reset in the DOR */
+       pCMD->drive=0;
+       select_fdc_drive(pCMD);
+       /* initialize the CCR */
+       write_fdc_reg(FDC_CCR,pFG->rate);
+       /* then initialize the DSR */
+       write_fdc_reg(FDC_DSR,pFG->rate);
+       if(wait_for_fdc_int()==FALSE) {
+                       PRINTF("Time Out after writing CCR\n");
+                       return FALSE;   
+       }
+       /* now issue sense Interrupt and status command
+        * assuming only one drive present (drive 0) */
+       pCMD->dma=0; /* we don't use any dma at all */
+       for(i=0;i<4;i++) {
+               /* issue sense interrupt for all 4 possible drives */
+               pCMD->cmd[COMMAND]=FDC_CMD_SENSE_INT;
+               if(fdc_issue_cmd(pCMD,pFG)==FALSE) {
+                       PRINTF("Sense Interrupt for drive %d failed\n",i);
+               }
+       }
+       /* assuming drive 0 for rest of configuration
+        * issue the configure command */
+       pCMD->drive=0;
+       select_fdc_drive(pCMD);
+       pCMD->cmd[COMMAND]=FDC_CMD_CONFIGURE;
+       if(fdc_issue_cmd(pCMD,pFG)==FALSE) {
+               PRINTF(" configure timeout\n");
+               stop_fdc_drive(pCMD);
+               return FALSE;
+       }
+       /* issue specify command */
+       pCMD->cmd[COMMAND]=FDC_CMD_SPECIFY;
+       if(fdc_issue_cmd(pCMD,pFG)==FALSE) {
+               PRINTF(" specify timeout\n");
+               stop_fdc_drive(pCMD);
+               return FALSE;
+       
+       }
+       /* then, we clear the reset in the DOR */
+       /* fdc_check_drive(pCMD,pFG);   */
+       /*      write_fdc_reg(FDC_DOR,0x04); */
+       return TRUE;
+}
+
+/****************************************************************************
+ * main routine do_fdcboot
+ */
+void do_fdcboot(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
+{
+       FD_GEO_STRUCT *pFG = (FD_GEO_STRUCT *)floppy_type;
+       FDC_COMMAND_STRUCT *pCMD = &cmd;
+       unsigned long addr,imsize;
+       image_header_t *hdr;  /* used for fdc boot */
+       unsigned char boot_drive; 
+       int i,nrofblk;
+       char *ep;
+       
+       switch (argc) {
+       case 1:
+               addr = CFG_LOAD_ADDR;
+               boot_drive=0; /* default boot from drive 0 */
+               break;
+       case 2:
+               addr = simple_strtoul(argv[1], NULL, 16);
+               boot_drive=0; /* default boot from drive 0 */
+               break;
+       case 3:
+               addr = simple_strtoul(argv[1], NULL, 16);
+               boot_drive=simple_strtoul(argv[2], NULL, 10);
+               break;
+       default:
+               printf ("Usage:\n%s\n", cmdtp->usage);
+               return;
+       }
+       /* setup FDC and scan for drives  */
+       if(fdc_setup(pCMD,pFG)==FALSE) {
+               printf("\n** Error in setup FDC **\n");
+               return;
+       }
+       if(fdc_check_drive(pCMD,pFG)==FALSE) {
+               printf("\n** Error in check_drives **\n");
+               return;
+       }
+       if((pCMD->flags&(1<<boot_drive))==0) { 
+               /* drive not available */
+               printf("\n** Drive %d not availabe **\n",boot_drive);
+               return;
+       }
+       if((pCMD->flags&(0x10<<boot_drive))==0) {
+               /* no disk inserted */
+               printf("\n** No disk inserted in drive %d **\n",boot_drive);
+               return;
+       }
+       /* ok, we have a valid source */
+       pCMD->drive=boot_drive;
+       /* read first block */
+       pCMD->blnr=0;
+       if(fdc_read_data((unsigned char *)addr,1,pCMD,pFG)==FALSE) {
+               printf("\nRead error:");
+               for(i=0;i<7;i++)
+                       printf("result%d: 0x%02X\n",i,pCMD->result[i]);
+               return;
+       }
+       hdr = (image_header_t *)addr;
+       if (hdr->ih_magic  != IH_MAGIC) {
+               printf ("Bad Magic Number\n");
+               return;
+       }
+       print_image_hdr(hdr);
+       
+       imsize= hdr->ih_size+sizeof(image_header_t);
+       nrofblk=imsize/512;
+       if((imsize%512)>0)
+               nrofblk++;
+       printf("Loading %ld Bytes (%d blocks) at 0x%08lx..\n",imsize,nrofblk,addr);
+       pCMD->blnr=0;
+       if(fdc_read_data((unsigned char *)addr,nrofblk,pCMD,pFG)==FALSE) {
+               /* read image block */
+               printf("\nRead error:");
+               for(i=0;i<7;i++)
+                       printf("result%d: 0x%02X\n",i,pCMD->result[i]);   
+               return;
+       }
+       printf("OK %ld Bytes loaded.\n",imsize);
+       /* Loading ok, update default load address */
+
+       load_addr = addr;
+       if(hdr->ih_type  == IH_TYPE_KERNEL) {
+               /* Check if we should attempt an auto-start */
+               if (((ep = getenv("autostart")) != NULL) && (strcmp(ep,"yes") == 0)) {
+                       char *local_args[2];
+                       extern void do_bootm (cmd_tbl_t *, bd_t *, int, int, char *[]);
+       
+                       local_args[0] = argv[0];
+                       local_args[1] = NULL;
+       
+                       printf ("Automatic boot of image at addr 0x%08lX ...\n", addr);
+
+                       do_bootm (cmdtp, bd, 0, 1, local_args);
+               }
+       }
+}      
+       
+       
+       
+#endif /* CONFIG_COMMANDS & CFG_CMD_FDC */
+
+
index 78260666aeb00bbc63daa0ea6185f3c833075f04..c9b273f76efd2cc3f5e3bed2fadcb75e94a2b3f0 100644 (file)
@@ -53,6 +53,7 @@ do_i2c (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
     
 
 #if !defined(CONFIG_CPCI405) && !defined(CONFIG_AR405) && \
+               !defined(CONFIG_PIP405) && \
     !defined (CONFIG_WALNUT405) && !defined (CONFIG_ERIC)
 
     i2c_state_t state;
@@ -70,6 +71,7 @@ do_i2c (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
        if (strncmp (argv[1], "res", 3) == 0) {
            printf ("I2C reset 50kHz ... ");
 #if defined(CONFIG_CPCI405) || defined(CONFIG_AR405) || \
+               defined(CONFIG_PIP405) || \
     defined (CONFIG_WALNUT405) || defined (CONFIG_ERIC)
            i2c_init ();
 #else
@@ -88,6 +90,7 @@ do_i2c (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
            else
                printf ("I2C reset %dkHz ... ", speed/1000);
 #if defined(CONFIG_CPCI405) || defined(CONFIG_AR405) || \
+               defined(CONFIG_PIP405) || \
     defined (CONFIG_WALNUT405) || defined (CONFIG_ERIC)
            i2c_init ();
 #else
@@ -115,6 +118,7 @@ do_i2c (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
                        , i2c_addr, (ulong)data_addr, size);
 
 #if defined(CONFIG_CPCI405) || defined(CONFIG_AR405) || \
+               defined(CONFIG_PIP405) || \
     defined (CONFIG_WALNUT405) || defined (CONFIG_ERIC)
 
 #else
@@ -123,6 +127,7 @@ do_i2c (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
 
 
 #if defined(CONFIG_CPCI405) || defined(CONFIG_AR405) || \
+               defined(CONFIG_PIP405) || \
     defined (CONFIG_WALNUT405) || defined (CONFIG_ERIC)
 
                rc = i2c_receive (i2c_addr, size, data_addr);
@@ -140,6 +145,7 @@ do_i2c (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
                }
 
 #if defined(CONFIG_CPCI405) || defined(CONFIG_AR405) || \
+               defined(CONFIG_PIP405) || \
     defined (CONFIG_WALNUT405) || defined (CONFIG_ERIC)
 
 #else
@@ -164,6 +170,7 @@ do_i2c (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
 
 
 #if defined(CONFIG_CPCI405) || defined(CONFIG_AR405) || \
+               defined(CONFIG_PIP405) || \
     defined (CONFIG_WALNUT405) || defined (CONFIG_ERIC)
 
 #else
@@ -171,6 +178,7 @@ do_i2c (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
 #endif
 
 #if defined(CONFIG_CPCI405) || defined(CONFIG_AR405) || \
+               defined(CONFIG_PIP405) || \
     defined (CONFIG_WALNUT405) || defined (CONFIG_ERIC)
 
                rc = i2c_send (i2c_addr, size, data_addr);
@@ -185,6 +193,7 @@ do_i2c (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
                }
 
 #if defined(CONFIG_CPCI405) || defined(CONFIG_AR405) || \
+               defined(CONFIG_PIP405) || \
     defined (CONFIG_WALNUT405) || defined (CONFIG_ERIC)
 
 #else
@@ -214,6 +223,7 @@ do_i2c (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
                        i2c_addr, sec_addr, (ulong)data_addr, size);
 
 #if defined(CONFIG_CPCI405) || defined(CONFIG_AR405) || \
+               defined(CONFIG_PIP405) || \
     defined (CONFIG_WALNUT405) || defined (CONFIG_ERIC)
 
 #else
@@ -221,6 +231,7 @@ do_i2c (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
 #endif
 
 #if defined(CONFIG_CPCI405) || defined(CONFIG_AR405) || \
+               defined(CONFIG_PIP405) || \
     defined (CONFIG_WALNUT405) || defined (CONFIG_ERIC)
 
                rc = i2c_receive (i2c_addr, size, data_addr);
@@ -237,6 +248,7 @@ do_i2c (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
                }
 
 #if defined(CONFIG_CPCI405) || defined(CONFIG_AR405) || \
+               defined(CONFIG_PIP405) || \
     defined (CONFIG_WALNUT405) || defined (CONFIG_ERIC)
 
 #else
@@ -263,6 +275,7 @@ do_i2c (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
                        i2c_addr, sec_addr, (ulong)data_addr, size);
 
 #if defined(CONFIG_CPCI405) || defined(CONFIG_AR405) || \
+               defined(CONFIG_PIP405) || \
     defined (CONFIG_WALNUT405) || defined (CONFIG_ERIC)
 
 #else
@@ -270,6 +283,7 @@ do_i2c (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
 #endif
 
 #if defined(CONFIG_CPCI405) || defined(CONFIG_AR405) || \
+               defined(CONFIG_PIP405) || \
     defined (CONFIG_WALNUT405) || defined (CONFIG_ERIC)
 
                rc = i2c_send (i2c_addr, size, data_addr);
@@ -285,6 +299,7 @@ do_i2c (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
                }
 
 #if defined(CONFIG_CPCI405) || defined(CONFIG_AR405) || \
+               defined(CONFIG_PIP405) || \
     defined (CONFIG_WALNUT405) || defined (CONFIG_ERIC)
 
 #else
index 8265010ef22ed6881a375db77cefac3dea5a66fe..6f64a1b6b68f3127b61a6ed38a2b0cd58e16787e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * (C) Copyright 2000
+ * (C) Copyright 2000, 2001
  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  *
  * See file CREDITS for list of people who contributed to this
 # include <status_led.h>
 #endif
 
-/* stdlib.h causes some compatibility problems; should fixe these! -- wd */
-#ifndef __ldiv_t_defined
-typedef struct {
-       long int quot;          /* Quotient     */
-       long int rem;           /* Remainder    */
-} ldiv_t;
-extern ldiv_t ldiv (long int __numer, long int __denom);
-# define __ldiv_t_defined      1
-#endif
 
 #undef IDE_DEBUG
 
@@ -115,15 +106,9 @@ static ulong bus_offset[CFG_IDE_MAXBUS] = {
 
 #define        ATA_CURR_BASE(dev)      (CFG_ATA_BASE_ADDR+bus_offset[IDE_BUS(dev)])
 
-typedef struct ide_dev_id {
-       ulong   size;
-       uchar   model[40];
-       uchar   serial_no[20];
-} ide_dev_id_t;
-
 static int         ide_bus_ok[CFG_IDE_MAXBUS];
-static ide_dev_id_t ide_device[CFG_IDE_MAXDEVICE];
 
+static  block_dev_desc_t ide_dev_desc[CFG_IDE_MAXDEVICE];
 /* ------------------------------------------------------------------------- */
 
 #ifdef CONFIG_IDE_LED
@@ -138,16 +123,31 @@ static void  ide_reset (void);
 #define ide_reset()    /* dummy */
 #endif
 
-static void  ide_ident (int device);
-static void  ide_print (int device);
+static void  ide_ident (block_dev_desc_t *dev_desc);
 static uchar ide_wait  (int dev, ulong t);
 
+#ifdef CONFIG_PIP405
+#define IDE_TIME_OUT 2000 /* 2 sec timeout */
+#else
+#define IDE_TIME_OUT 500 /* 500ms timeout */
+#endif
+
+#define ATAPI_TIME_OUT 7000 /* 7 sec timeout (5 sec seems to work...) */
+
+
 static void __inline__ outb(int dev, int port, unsigned char val);
 static unsigned char __inline__ inb(int dev, int port);
 static void input_swap_data(int dev, ulong *sect_buf, int words);
 static void input_data(int dev, ulong *sect_buf, int words);
 static void output_data(int dev, ulong *sect_buf, int words);
-static void trim_trail (unsigned char *str, unsigned int len);
+static void ident_cpy (unsigned char *dest, unsigned char *src, unsigned int len);
+
+
+#ifdef CONFIG_ATAPI
+static void    atapi_inquiry(block_dev_desc_t *dev_desc);
+ulong atapi_read (int device, ulong blknr, ulong blkcnt, ulong *buffer);
+#endif
+
 
 #ifdef CONFIG_IDE_PCMCIA
 static void set_pcmcia_timing (int pmode);
@@ -180,8 +180,10 @@ void do_ide (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
                putc ('\n');
 
                for (i=0; i<CFG_IDE_MAXDEVICE; ++i) {
+                       if(ide_dev_desc[i].type==DEV_TYPE_UNKNOWN)
+                               continue; /* list only known devices */
                        printf ("IDE device %d: ", i);
-                       ide_print (i);
+                       dev_print(&ide_dev_desc[i]);
                }
                return;
 
@@ -191,17 +193,17 @@ void do_ide (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
                        return;
                }
                printf ("\nIDE device %d: ", curr_device);
-               ide_print (curr_device);
+               dev_print(&ide_dev_desc[curr_device]);
                return;
        } else if (strncmp(argv[1],"part",4) == 0) {
                int dev, ok;
 
                for (ok=0, dev=0; dev<CFG_IDE_MAXDEVICE; ++dev) {
-                       if (ide_device[dev].size) {
+                       if (ide_dev_desc[dev].part_type!=PART_TYPE_UNKNOWN) {
                                ++ok;
                                if (dev)
                                        putc ('\n');
-                               print_part (dev);
+                               print_part(&ide_dev_desc[dev]);
                        }
                }
                if (!ok)
@@ -219,10 +221,10 @@ void do_ide (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
                        puts ("unknown device\n");
                        return;
                }
+               dev_print(&ide_dev_desc[dev]);
+               /*ide_print (dev);*/
 
-               ide_print (dev);
-
-               if (ide_device[dev].size == 0) {
+               if (ide_dev_desc[dev].type == DEV_TYPE_UNKNOWN) {
                        return;
                }
 
@@ -234,8 +236,8 @@ void do_ide (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
        } else if (strncmp(argv[1],"part",4) == 0) {
                int dev = (int)simple_strtoul(argv[2], NULL, 10);
 
-               if (ide_device[dev].size) {
-                       print_part (dev);
+               if (ide_dev_desc[dev].part_type!=PART_TYPE_UNKNOWN) {
+                               print_part(&ide_dev_desc[dev]);
                } else {
                        printf ("\nIDE device %d not available\n", dev);
                }
@@ -270,7 +272,8 @@ void do_ide (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
                printf ("\nIDE read: device %d block # %ld, count %ld ... ",
                        curr_device, blk, cnt);
 
-               n = ide_read (curr_device, blk, cnt, (ulong *)addr);
+               n = ide_dev_desc[curr_device].block_read (curr_device, blk, cnt, (ulong *)addr);
+/*             n = ide_read (curr_device, blk, cnt, (ulong *)addr); */
 
                printf ("%ld blocks read: %s\n",
                        n, (n==cnt) ? "OK" : "ERROR");
@@ -335,7 +338,7 @@ void do_diskboot (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
 
        dev = simple_strtoul(boot_device, &ep, 16);
 
-       if (ide_device[dev].size == 0) {
+       if (ide_dev_desc[dev].type==DEV_TYPE_UNKNOWN) {
                printf ("\n** Device %d not available\n", dev);
                return;
        }
@@ -347,11 +350,9 @@ void do_diskboot (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
                }
                part = simple_strtoul(++ep, NULL, 16);
        }
-
-       if (get_partition_info (dev, part, &info)) {
+       if (get_partition_info (&ide_dev_desc[dev], part, &info)) {
                return;
        }
-
        if (strncmp(info.type, BOOT_PART_TYPE, sizeof(info.type)) != 0) {
                printf ("\n** Invalid partition type \"%.32s\""
                        " (expect \"" BOOT_PART_TYPE "\")\n",
@@ -366,7 +367,7 @@ void do_diskboot (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
        PRINTF ("First Block: %ld,  # of blocks: %ld, Block Size: %ld\n",
                info.start, info.size, info.blksz);
 
-       if (ide_read (dev, info.start, 1, (ulong *)addr) != 1) {
+       if (ide_dev_desc[dev].block_read (dev, info.start, 1, (ulong *)addr) != 1) {
                printf ("** Read error on %d:%d\n", dev, part);
                return;
        }
@@ -382,10 +383,11 @@ void do_diskboot (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
                cnt /= info.blksz;
                cnt -= 1;
        } else {
-               cnt = info.size - 1;
+               printf("\n** Bad Magic Number **\n");
+               return;
        }
 
-       if (ide_read (dev, info.start+1, cnt,
+       if (ide_dev_desc[dev].block_read (dev, info.start+1, cnt,
                      (ulong *)(addr+info.blksz)) != cnt) {
                printf ("** Read error on %d:%d\n", dev, part);
                return;
@@ -460,7 +462,7 @@ void ide_init (bd_t *bd)
         * Light LED's to show
         */
        ide_led ((LED_IDE1 | LED_IDE2), 1);             /* LED's on     */
-       ide_reset ();
+       ide_reset (); /* ATAPI Drives seems to need a proper IDE Reset */
 
 #ifdef CONFIG_IDE_PCMCIA
        /* PCMCIA / IDE initialization for common mem space */
@@ -515,10 +517,12 @@ void ide_init (bd_t *bd)
 
                if (c & (ATA_STAT_BUSY | ATA_STAT_FAULT)) {
                        printf ("Status 0x%02x ", c);
-               } else if ((c & ATA_STAT_READY) == 0) {
+#ifndef CONFIG_ATAPI /* ATAPI Devices do not set DRDY */
+               } else  if ((c & ATA_STAT_READY) == 0) {
                        puts ("not available  ");
+#endif
                } else {
-                       puts ("OK  ");
+                       puts ("OK ");
                        ide_bus_ok[bus] = 1;
                }
 #if defined(CONFIG_WATCHDOG)
@@ -534,19 +538,24 @@ void ide_init (bd_t *bd)
 #ifdef CONFIG_IDE_LED
                int led = (IDE_BUS(i) == 0) ? LED_IDE1 : LED_IDE2;
 #endif
-
+               ide_dev_desc[i].if_type=IF_TYPE_IDE;
+               ide_dev_desc[i].dev=i;
+               ide_dev_desc[i].part_type=PART_TYPE_UNKNOWN;
+               ide_dev_desc[i].blksz=0;
+               ide_dev_desc[i].lba=0;
+               ide_dev_desc[i].block_read=ide_read;
                if (!ide_bus_ok[IDE_BUS(i)])
                        continue;
                ide_led (led, 1);               /* LED on       */
-               ide_ident (i);
+               ide_ident(&ide_dev_desc[i]);
                ide_led (led, 0);               /* LED off      */
-               ide_print (i);
-
-               init_part (i);                  /* initialize partition type */
-
-               /* make first available device current */
-               if ((ide_device[i].size > 0) && (curr_device < 0)) {
-                       curr_device = i;
+               dev_print(&ide_dev_desc[i]);
+/*             ide_print (i); */
+/*             if((ide_device[i].size > 0) && (ide_dev_desc[i].if_type==IF_TYPE_IDE)) */
+               if((ide_dev_desc[i].lba > 0) && (ide_dev_desc[i].blksz > 0)) {
+                       init_part (&ide_dev_desc[i]);                   /* initialize partition type */
+                       if(curr_device < 0) 
+                               curr_device = i;
                }
        }
 #if defined(CONFIG_WATCHDOG)
@@ -556,6 +565,12 @@ void ide_init (bd_t *bd)
 
 /* ------------------------------------------------------------------------- */
 
+block_dev_desc_t * ide_get_dev(int dev)
+{
+       return((block_dev_desc_t *)&ide_dev_desc[dev]);
+}
+
+
 #ifdef CONFIG_IDE_PCMCIA
 
 static void
@@ -722,44 +737,68 @@ input_data(int dev, ulong *sect_buf, int words)
 
 /* -------------------------------------------------------------------------
  */
-static void ide_ident (int device)
+static void ide_ident (block_dev_desc_t *dev_desc)
 {
        ulong iobuf[ATA_SECTORWORDS];
        unsigned char c;
        hd_driveid_t *iop = (hd_driveid_t *)iobuf;
-       ide_dev_id_t *idp = &(ide_device[device]);
+
 #if 0
        int mode, cycle_time;
 #endif
-
+       int device;
+       device=dev_desc->dev;
        printf ("    Device %d: ", device);
 
        ide_led (DEVICE_LED(device), 1);        /* LED on       */
        /* Select device
         */
        outb (device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device));
+       dev_desc->if_type=IF_TYPE_IDE;          
+#ifdef CONFIG_ATAPI
+       /* check signature */
+       if((inb(device,ATA_SECT_CNT)==0x01) &&
+                (inb(device,ATA_SECT_NUM)==0x01) &&
+                (inb(device,ATA_CYL_LOW)==0x14) &&
+                (inb(device,ATA_CYL_HIGH)==0xEB)) {
+               /* ATAPI Signature found */
+               dev_desc->if_type=IF_TYPE_ATAPI;                
+               /* Start Ident Command
+                */
+               outb (device, ATA_COMMAND, ATAPI_CMD_IDENT);
+               /* Wait for completion ATAPI devices need more time to become ready
+                */
+               c = ide_wait (device, ATAPI_TIME_OUT);
+       }
+       else 
+#endif
+       {
+               /* Start Ident Command
+                */
+               outb (device, ATA_COMMAND, ATA_CMD_IDENT);
 
-       /* Start Ident Command
-        */
-       outb (device, ATA_COMMAND, ATA_CMD_IDENT);
-
-       /* Wait for completion
-        */
-       c = ide_wait (device, 100);
-
+               /* Wait for completion
+                */
+               c = ide_wait (device, IDE_TIME_OUT);
+       }
        ide_led (DEVICE_LED(device), 0);        /* LED off      */
 
        if (((c & ATA_STAT_READY) == 0) ||
            ((c & (ATA_STAT_FAULT|ATA_STAT_ERR)) != 0) ) {
-               idp->size = 0;
-               idp->model[0] = idp->serial_no[0] = '\0';
+               dev_desc->type=DEV_TYPE_UNKNOWN;
                return;
        }
 
        input_swap_data (device, iobuf, ATA_SECTORWORDS);
+       
+       ident_cpy (dev_desc->revision, iop->fw_rev, sizeof(dev_desc->revision));
+       ident_cpy (dev_desc->vendor, iop->model, sizeof(dev_desc->vendor));
+       ident_cpy (dev_desc->product, iop->serial_no, sizeof(dev_desc->product));
 
-       trim_trail (iop->model,     sizeof(iop->model));
-       trim_trail (iop->serial_no, sizeof(iop->serial_no));
+       if((iop->config & 0x0080)==0x0080)
+               dev_desc->removable = 1;
+       else
+               dev_desc->removable = 0;
 
 #if 0
        /*
@@ -789,43 +828,21 @@ static void ide_ident (int device)
 printf ("PIO mode to use: PIO %d\n", mode);
 #endif
 
+#ifdef CONFIG_ATAPI
+       if(dev_desc->if_type==IF_TYPE_ATAPI) {
+               atapi_inquiry(dev_desc);
+               return;
+       }                
+#endif
        /* swap shorts */
-       idp->size = (iop->lba_capacity << 16) | (iop->lba_capacity >> 16);
-
-       strncpy (idp->model,     iop->model,     sizeof(idp->model));
-       strncpy (idp->serial_no, iop->serial_no, sizeof(idp->serial_no));
+       dev_desc->lba = (iop->lba_capacity << 16) | (iop->lba_capacity >> 16);
+       /* assuming HD */
+       dev_desc->type=DEV_TYPE_HARDDISK;
+       dev_desc->blksz=ATA_BLOCKSIZE;
+       dev_desc->lun=0; /* just to fill something in... */
+       
 }
 
-/* ------------------------------------------------------------------------- */
-
-static void ide_print (int device)
-{
-       ldiv_t mb, gb;
-       ide_dev_id_t *idp = &(ide_device[device]);
-       char *mod, *ser;
-
-       if (idp->size == 0) {
-               puts ("not available\n");
-               return;
-       }
-
-       mb = ldiv(idp->size, ((1024 * 1024) / 512)); /* MB */
-       /* round to 1 digit */
-       mb.rem *= 10 * 512;
-       mb.rem += 512 * 1024;
-       mb.rem /= 1024 * 1024;
-
-       gb = ldiv(10 * mb.quot + mb.rem, 10240);
-       gb.rem += 512;
-       gb.rem /= 1024;
-
-       mod = idp->model;       while (*mod && (*mod==' ')) ++mod;
-       ser = idp->serial_no;   while (*ser && (*ser==' ')) ++ser;
-
-       printf ("Model: %s  Serial #: %s  ", mod, ser);
-       printf ("Capacity: %ld.%ld MB = %ld.%ld GB\n",
-               mb.quot, mb.rem, gb.quot, gb.rem);
-}
 
 /* ------------------------------------------------------------------------- */
 
@@ -834,6 +851,7 @@ ulong ide_read (int device, ulong blknr, ulong blkcnt, ulong *buffer)
        ulong n = 0;
        unsigned char c;
 
+       PRINTF("ide_read dev %d start %lX, blocks %lX buffer at %lX\n",device,blknr,blkcnt,(ulong)buffer);
        ide_led (DEVICE_LED(device), 1);        /* LED on       */
 
        /* Select device
@@ -842,7 +860,7 @@ ulong ide_read (int device, ulong blknr, ulong blkcnt, ulong *buffer)
 
        while (blkcnt-- > 0) {
 
-               c = ide_wait (device, 500);
+               c = ide_wait (device, IDE_TIME_OUT);
 
                if (c & ATA_STAT_BUSY) {
                        printf ("IDE read: device %d not ready\n", device);
@@ -860,7 +878,7 @@ ulong ide_read (int device, ulong blknr, ulong blkcnt, ulong *buffer)
 
                udelay (50);
 
-               c = ide_wait (device, 500);     /* can't take over 500 ms */
+               c = ide_wait (device, IDE_TIME_OUT);    /* can't take over 500 ms */
 
                if ((c&(ATA_STAT_DRQ|ATA_STAT_BUSY|ATA_STAT_ERR)) != ATA_STAT_DRQ) {
                        printf ("Error (no IRQ) dev %d blk %ld: status 0x%02x\n",
@@ -896,7 +914,7 @@ ulong ide_write (int device, ulong blknr, ulong blkcnt, ulong *buffer)
 
        while (blkcnt-- > 0) {
 
-               c = ide_wait (device, 500);
+               c = ide_wait (device, IDE_TIME_OUT);
 
                if (c & ATA_STAT_BUSY) {
                        printf ("IDE read: device %d not ready\n", device);
@@ -914,7 +932,7 @@ ulong ide_write (int device, ulong blknr, ulong blkcnt, ulong *buffer)
 
                udelay (50);
 
-               c = ide_wait (device, 500);     /* can't take over 500 ms */
+               c = ide_wait (device, IDE_TIME_OUT);    /* can't take over 500 ms */
 
                if ((c&(ATA_STAT_DRQ|ATA_STAT_BUSY|ATA_STAT_ERR)) != ATA_STAT_DRQ) {
                        printf ("Error (no IRQ) dev %d blk %ld: status 0x%02x\n",
@@ -935,18 +953,28 @@ WR_OUT:
 
 /* ------------------------------------------------------------------------- */
 
-/* Trim trailing blanks, and NUL-terminate string
+/* copy src to dest, skipping leading and trailing blanks and null terminate the string
  */
-static void trim_trail (unsigned char *str, unsigned int len)
+static void ident_cpy (unsigned char *dest, unsigned char *src, unsigned int len)
 {
-       unsigned char *p = str + len - 1;
+       int start,end;
 
-       while (len-- > 0) {
-               *p-- = '\0';
-               if (*p != ' ') {
-                       return;
-               }
+       start=0;
+       while(start<len) {
+               if(src[start]!=' ')
+                       break;
+               start++;
+       }
+       end=len-1;
+       while(end>start) {
+               if(src[end]!=' ')
+                       break;
+               end--;
        }
+       for( ; start<=end; start++) {
+               *dest++=src[start];
+       }
+       *dest='\0';
 }
 
 /* ------------------------------------------------------------------------- */
@@ -972,19 +1000,23 @@ static uchar ide_wait (int dev, ulong t)
 /* ------------------------------------------------------------------------- */
 
 #ifdef CONFIG_IDE_RESET
+#ifdef CONFIG_IDE_RESET_ROUTINE
+extern void ide_set_reset(int idereset);
+#endif
 
 static void ide_reset (void)
 {
        int i;
+#if defined(CFG_PC_IDE_RESET) 
        volatile immap_t *immr = (immap_t *)CFG_IMMR;
-
+#endif
        curr_device = -1;
        for (i=0; i<CFG_IDE_MAXBUS; ++i)
                ide_bus_ok[i] = 0;
        for (i=0; i<CFG_IDE_MAXDEVICE; ++i)
-               ide_device[i].size = 0;
+               ide_dev_desc[i].type = DEV_TYPE_UNKNOWN;
 
-#if defined(CFG_PC_IDE_RESET)
+#if defined(CFG_PC_IDE_RESET) 
        /* Configure PC for IDE Reset Pin
         */
        immr->im_ioport.iop_pcdat &= ~(CFG_PC_IDE_RESET);       /* Set reset bit */
@@ -998,7 +1030,14 @@ static void ide_reset (void)
        /* de-assert RESET signal of IDE */
        immr->im_ioport.iop_pcdat |=   CFG_PC_IDE_RESET;
 #else
+#ifdef CONFIG_IDE_RESET_ROUTINE
+       ide_set_reset(1); /* assert reset */
+       udelay (20000);
+       /* de-assert RESET signal of IDE */
+       ide_set_reset(0); 
+#else
 #error IDE reset pin not configured
+#endif  /* CONFIG_IDE_RESET_ROUTINE */
 #endif /* CFG_PC_IDE_RESET */
 
 #if defined(CONFIG_WATCHDOG)
@@ -1076,4 +1115,247 @@ static void ide_led (uchar led, uchar status)
 
 /* ------------------------------------------------------------------------- */
 
+#ifdef CONFIG_ATAPI
+/****************************************************************************
+ * ATAPI Support
+ */
+
+
+
+#undef ATAPI_DEBUG
+
+#ifdef ATAPI_DEBUG
+#define        AT_PRINTF(fmt,args...)  printf (fmt ,##args)
+#else
+#define AT_PRINTF(fmt,args...)
+#endif
+
+/*
+ * issue an atapi command
+ */
+unsigned char atapi_issue(int device,unsigned char* ccb,int ccblen, unsigned char * buffer,int buflen)
+{
+       unsigned char c,err;
+       int n;
+       ide_led (DEVICE_LED(device), 1);        /* LED on       */
+
+       /* Select device
+        */
+       outb (device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device));
+       c = ide_wait (device, ATAPI_TIME_OUT);
+
+       if (c & ATA_STAT_BUSY) {
+               printf ("ATAPI_ISSUE: device %d not ready\n", device);
+               err=0xff;
+               goto AI_OUT;
+       }
+       outb (device, ATA_ERROR_REG, 0); /* no DMA, no overlaped */
+       outb (device, ATA_CYL_LOW, (unsigned char)(buflen & 0xff));
+       outb (device, ATA_CYL_HIGH, (unsigned char)((buflen<<8) & 0xff));
+       outb (device, ATA_DEV_HD,   ATA_LBA             | ATA_DEVICE(device));  
+
+       outb (device, ATA_COMMAND,  ATAPI_CMD_PACKET);
+       udelay (50);
+       c = ide_wait (device, ATAPI_TIME_OUT);  /* can't take over 500 ms */
+
+       if ((c&(ATA_STAT_DRQ|ATA_STAT_BUSY|ATA_STAT_ERR)) != ATA_STAT_DRQ) { /* DRQ must be 1, BSY 0 */
+               printf ("ATTAPI_ISSUE: Error (no IRQ) before sending ccb dev %d  status 0x%02x\n",device,c);
+               err=0xff;
+               goto AI_OUT;
+       }
+       output_data (device, (unsigned long *)ccb,ccblen/2); /* write command block */
+       /*while((inb(device,ATA_STATUS) & ATA_STAT_BUSY)==0) */
+       udelay (50); /* device must set bsy */
+       /*c = inb (device, ATA_STATUS);*/       /* clear IRQ */
+       c = ide_wait (device, ATAPI_TIME_OUT); /* wait until BSY=0, DRQ=1 */
+       if ((c&(ATA_STAT_DRQ|ATA_STAT_BUSY|ATA_STAT_ERR)) != ATA_STAT_DRQ) {
+               if((c&ATA_STAT_ERR) == ATA_STAT_ERR) {
+                       err=(inb(device,ATA_ERROR_REG)); 
+                       AT_PRINTF("atapi_issue returned sense key %X\n",err);
+               }
+               else {
+                       /* maybe no data command ? */
+                       if(buflen==0)
+                               err=0;
+                       else {
+                               printf ("ATTAPI_ISSUE: (no IRQ) after sending ccb (%x)  status 0x%02x\n", ccb[0],c);
+                               err=0xff;
+                       }
+               }
+               goto AI_OUT;
+       }
+       n=inb(device, ATA_CYL_HIGH);
+       n<<=8;
+       n+=inb(device, ATA_CYL_LOW);
+       AT_PRINTF("ATAPI_ISSUE: %d Bytes to transfer\n",n);
+       /* ok now decide if it is an in or output */
+       if((inb(device, ATA_SECT_CNT)&0x02)==0) {
+               AT_PRINTF("Write to device\n");
+               output_data(device,(unsigned long *)buffer,n>>2);
+       }
+       else {
+               AT_PRINTF("Read from device @ %p words %d\n",buffer,n>>2);
+               input_data(device,(unsigned long *)buffer,n>>2);
+       }
+       c = inb (device, ATA_STATUS);   /* clear IRQ */
+       if((c & ATA_STAT_ERR) == ATA_STAT_ERR) {
+               err=(inb(device,ATA_ERROR_REG) >> 8) &0x0f; 
+               AT_PRINTF("atapi_issue returned sense key %X\n",err);
+       }
+       else
+               err = 0;
+AI_OUT: 
+       ide_led (DEVICE_LED(device), 0);        /* LED off      */
+       return(err);
+}
+
+/*
+ * sending the command to atapi_issue. If an status other than good returns, an request_sense 
+ * will be issued
+ */
+unsigned char atapi_issue_autoreq(int device,unsigned char* ccb,int ccblen, unsigned char * buffer,int buflen)
+{
+       unsigned char sense_data[16],sense_ccb[12];
+       unsigned char res;
+       int i,retrycnt;
+       
+       retrycnt=0;
+retry:
+       res= atapi_issue(device,ccb,ccblen,buffer,buflen);
+       if(res==0)
+               return (0); /* Ok */
+       if(res==0xff)
+               return (0xff); /* error */
+       AT_PRINTF("(auto_req)atapi_issue returned sense key %X\n",res);
+       for(i=0;i<12;i++)
+               sense_ccb[i]=0; /* initialize it to zero */
+       sense_ccb[0]=ATAPI_CMD_REQ_SENSE; 
+       sense_ccb[4]=16; /* allocation Legnth */
+       res=atapi_issue(device,sense_ccb,12,sense_data,14);
+       AT_PRINTF("ATAPI_CMD_REQ_SENSE returned %x\n",res);
+       AT_PRINTF(" Sense page: %02X key %02X ASC %02X ASCQ %02X\n",sense_data[0],sense_data[2]&0xf,sense_data[12],sense_data[13]);
+       if(((sense_data[2]&0xf)==0) && (sense_data[12]==0) && (sense_data[13]==0))
+               return(0); /* ok device ready */
+       if(((sense_data[2]&0xf)==0x02) && (sense_data[12]==0x04) && (sense_data[13]!=0x01)) {
+               printf("Error\n");
+               return (0xff);
+       }
+       if(((sense_data[2]&0xf)==0x02) && (sense_data[12]==0x3A)) {
+               AT_PRINTF("Media not present\n");
+               return (0xff);
+       }
+       if((sense_data[2]&0xf)==0x06) {
+               AT_PRINTF("Unit attention...retry\n");
+               if(retrycnt++<4)
+                       goto retry;
+               return (0xff);
+       }
+       printf("unknown sense_key\n");
+       return(0xff);
+}
+       
+
+
+static void    atapi_inquiry(block_dev_desc_t * dev_desc)
+{
+       unsigned char ccb[12]; /* Command descriptor block */
+       unsigned char iobuf[64]; /* temp buf */
+       unsigned char c;
+       int i,device;
+
+       device=dev_desc->dev;
+       dev_desc->type=DEV_TYPE_UNKNOWN; /* not yet valid */
+       dev_desc->block_read=atapi_read;
+       for(i=0;i<12;i++)
+               ccb[i]=0; /* initialize it to zero */
+       ccb[0]=ATAPI_CMD_INQUIRY; 
+       ccb[4]=40; /* allocation Legnth */
+       c=atapi_issue_autoreq(device,ccb,12,(unsigned char *)iobuf,40);
+       AT_PRINTF("ATAPI_CMD_INQUIRY returned %x\n",c);
+       if(c!=0)
+               return;
+       /* copy device ident strings */
+       ident_cpy(dev_desc->vendor,&iobuf[8],8);
+       ident_cpy(dev_desc->product,&iobuf[16],16);
+       ident_cpy(dev_desc->revision,&iobuf[32],5);
+       dev_desc->lun=0;
+       dev_desc->lba=0;
+       dev_desc->blksz=0;
+       dev_desc->type=iobuf[0] & 0x1f;
+       if((iobuf[1]&0x80)==0x80)
+               dev_desc->removable = 1;
+       else
+               dev_desc->removable = 0;
+       for(i=0;i<12;i++)
+               ccb[i]=0; /* initialize it to zero */
+       ccb[0]=ATAPI_CMD_START_STOP; 
+       ccb[4]=0x01; /* start */ 
+       c=atapi_issue_autoreq(device,ccb,12,(unsigned char *)iobuf,0);
+       AT_PRINTF("ATAPI_CMD_START_STOP returned %x\n",c);
+       if(c!=0)
+               return;
+       for(i=0;i<12;i++)
+               ccb[i]=0; /* initialize it to zero */
+       ccb[0]=ATAPI_CMD_READ_CAP; 
+       c=atapi_issue_autoreq(device,ccb,12,(unsigned char *)iobuf,8);
+       AT_PRINTF("ATAPI_CMD_READ_CAP returned %x\n",c);
+       if(c!=0)
+               return;
+       AT_PRINTF("Read Cap: LBA %02X%02X%02X%02X blksize %02X%02X%02X%02X\n",iobuf[0],iobuf[1],iobuf[2],iobuf[3],
+               iobuf[4],iobuf[5],iobuf[6],iobuf[7]);
+       dev_desc->lba=((unsigned long)iobuf[0]<<24)+((unsigned long)iobuf[1]<<16)+((unsigned long)iobuf[2]<<8)+((unsigned long)iobuf[3]);
+       dev_desc->blksz=((unsigned long)iobuf[4]<<24)+((unsigned long)iobuf[5]<<16)+((unsigned long)iobuf[6]<<8)+((unsigned long)iobuf[7]);
+       return;
+}
+
+
+/* 
+ * atapi_read:
+ * we transfer only one block per command, since the multiple DRQ per command is not yet implemented
+ */
+#define ATAPI_READ_MAX_BYTES 2048 /* we read max 32kbytes */
+#define ATAPI_READ_BLOCK_SIZE 2048     /* assuming CD part */
+#define ATAPI_READ_MAX_BLOCK ATAPI_READ_MAX_BYTES/ATAPI_READ_BLOCK_SIZE        /* max blocks */
+
+ulong atapi_read (int device, ulong blknr, ulong blkcnt, ulong *buffer)
+{
+       ulong n = 0;
+       unsigned char ccb[12]; /* Command descriptor block */
+       ulong cnt;
+       
+       AT_PRINTF("atapi_read dev %d start %lX, blocks %lX buffer at %lX\n",device,blknr,blkcnt,(ulong)buffer);
+       do {
+               if(blkcnt>ATAPI_READ_MAX_BLOCK) {
+                       cnt=ATAPI_READ_MAX_BLOCK;
+               }
+               else {
+                       cnt=blkcnt;
+               }
+               ccb[0]=ATAPI_CMD_READ_12; 
+               ccb[1]=0; /* reserved */
+               ccb[2]=(unsigned char) (blknr>>24) & 0xff; /* MSB Block */
+               ccb[3]=(unsigned char) (blknr>>16) & 0xff; /*  */
+               ccb[4]=(unsigned char) (blknr>>8) & 0xff; 
+               ccb[5]=(unsigned char) blknr & 0xff; /* LSB Block */
+               ccb[6]=(unsigned char) (cnt>>24) & 0xff; /* MSB Block count */
+               ccb[7]=(unsigned char) (cnt>>16) & 0xff;
+               ccb[8]=(unsigned char) (cnt>>8) & 0xff; 
+               ccb[9]=(unsigned char) cnt & 0xff; /* LSB Block */
+               ccb[10]=0; /* reserved */
+               ccb[11]=0; /* reserved */
+               if(atapi_issue_autoreq(device,ccb,12,(unsigned char *)buffer,cnt*ATAPI_READ_BLOCK_SIZE)==0xff)
+                       return(n);
+               n+=cnt;
+               blkcnt-=cnt;
+               blknr+=cnt;
+               buffer+=cnt*(ATAPI_READ_BLOCK_SIZE/4); /* ulong blocksize in ulong */
+       } while(blkcnt>0);
+       return(n);
+}
+
+/* ------------------------------------------------------------------------- */
+
+
+#endif /* CONFIG_ATAPI */
+
 #endif /* CONFIG_COMMANDS & CFG_CMD_IDE */
diff --git a/common/cmd_scsi.c b/common/cmd_scsi.c
new file mode 100644 (file)
index 0000000..1c2fe19
--- /dev/null
@@ -0,0 +1,585 @@
+/*
+ * (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
+ *
+ *
+ *
+ */
+
+/* 
+ * SCSI support.
+ */
+
+#include <ppcboot.h>
+#include <command.h> 
+#include <cmd_boot.h>
+#include <asm/processor.h>
+#include <scsi.h>
+#include <image.h>
+#include <cmd_disk.h>
+#ifdef CONFIG_PPC405
+#include <405gp_pci.h>
+#endif
+
+
+
+
+#undef SCSI_DEBUG
+
+#ifdef SCSI_DEBUG
+#define        PRINTF(fmt,args...)     printf (fmt ,##args)
+#else
+#define PRINTF(fmt,args...)
+#endif
+
+#if (CONFIG_COMMANDS & CFG_CMD_SCSI)
+
+#ifdef CONFIG_SCSI_SYM53C8XX
+#define SCSI_VEND_ID   0x1000
+#define SCSI_DEV_ID            0x0001
+#else
+#error CONFIG_SCSI_SYM53C8XX must be defined
+#endif
+
+
+static ccb tempccb;    /* temporary scsi command buffer */
+
+static unsigned char tempbuff[512]; /* temporary data buffer */
+
+static int scsi_max_devs; /* number of highest available scsi device */
+
+static int scsi_curr_dev; /* current device */
+
+static block_dev_desc_t scsi_dev_desc[CFG_SCSI_MAX_DEVICE];
+
+/********************************************************************************
+ *  forward declerations of some Setup Routines
+ */
+void scsi_setup_test_unit_ready(ccb * pccb);
+void scsi_setup_read_capacity(ccb * pccb);
+void scsi_setup_read6(ccb * pccb, unsigned long start, unsigned short blocks);
+void scsi_setup_read_ext(ccb * pccb, unsigned long start, unsigned short blocks);
+void scsi_setup_inquiry(ccb * pccb);
+void scsi_ident_cpy (unsigned char *dest, unsigned char *src, unsigned int len);
+
+
+ulong scsi_read(int device, ulong blknr, ulong blkcnt, ulong *buffer);
+
+
+/*********************************************************************************
+ * (re)-scan the scsi bus and reports scsi device info
+ * to the user if mode = 1
+ */
+void scsi_scan(int mode)
+{
+       unsigned char i,perq,modi,lun;
+       unsigned long capacity,blksz;
+       ccb* pccb=(ccb *)&tempccb;
+
+       if(mode==1) {
+               printf("  SCSI: scanning bus for devices...\n");
+       }
+       for(i=0;i<CFG_SCSI_MAX_DEVICE;i++) {
+               scsi_dev_desc[i].target=0xff;
+               scsi_dev_desc[i].lun=0xff;
+               scsi_dev_desc[i].lba=0;
+               scsi_dev_desc[i].blksz=0;
+               scsi_dev_desc[i].type=DEV_TYPE_UNKNOWN;
+               scsi_dev_desc[i].vendor[0]=0;
+               scsi_dev_desc[i].product[0]=0;
+               scsi_dev_desc[i].revision[0]=0;
+               scsi_dev_desc[i].removable=FALSE;
+               scsi_dev_desc[i].if_type=IF_TYPE_SCSI;
+               scsi_dev_desc[i].dev=i;
+               scsi_dev_desc[i].part_type=PART_TYPE_UNKNOWN;
+               scsi_dev_desc[i].block_read=scsi_read;
+       }
+       scsi_max_devs=0;
+       for(i=0;i<CFG_SCSI_MAX_SCSI_ID;i++) {
+               pccb->target=i;
+               for(lun=0;lun<CFG_SCSI_MAX_LUN;lun++) {
+                       pccb->lun=lun;
+                       pccb->pdata=(unsigned char *)&tempbuff;
+                       pccb->datalen=512;
+                       scsi_setup_inquiry(pccb);
+                       if(scsi_exec(pccb)!=TRUE) {
+                               if(pccb->contr_stat==SCSI_SEL_TIME_OUT) {
+                                       PRINTF("Selection timeout ID %d\n",pccb->target);
+                                       continue; /* selection timeout => assuming no device present */
+                               }
+                               scsi_print_error(pccb);
+                               continue;
+                       }
+                       perq=tempbuff[0];
+                       modi=tempbuff[1];
+                       if((perq & 0x1f)==0x1f) {
+                               continue; /* skip unknown devices */
+                       }
+                       if((modi&0x80)==0x80) /* drive is removable */
+                               scsi_dev_desc[scsi_max_devs].removable=TRUE;
+                       /* get info for this device */
+                       scsi_ident_cpy(&scsi_dev_desc[scsi_max_devs].vendor[0],&tempbuff[8],8);
+                       scsi_ident_cpy(&scsi_dev_desc[scsi_max_devs].product[0],&tempbuff[16],16);
+                       scsi_ident_cpy(&scsi_dev_desc[scsi_max_devs].revision[0],&tempbuff[32],4);
+                       scsi_dev_desc[scsi_max_devs].target=pccb->target;
+                       scsi_dev_desc[scsi_max_devs].lun=pccb->lun;
+                       
+                       pccb->datalen=0;
+                       scsi_setup_test_unit_ready(pccb);
+                       if(scsi_exec(pccb)!=TRUE) {
+                               if(scsi_dev_desc[scsi_max_devs].removable==TRUE) {
+                                       scsi_dev_desc[scsi_max_devs].type=perq;
+                                       goto removable;
+                               }                       
+                               scsi_print_error(pccb);
+                               continue;
+                       }
+                       pccb->datalen=8;
+                       scsi_setup_read_capacity(pccb);
+                       if(scsi_exec(pccb)!=TRUE) {
+                               scsi_print_error(pccb);
+                               continue;
+                       }
+                       capacity=((unsigned long)tempbuff[0]<<24)|((unsigned long)tempbuff[1]<<16)|
+                                       ((unsigned long)tempbuff[2]<<8)|((unsigned long)tempbuff[3]);
+                       blksz=((unsigned long)tempbuff[4]<<24)|((unsigned long)tempbuff[5]<<16)|
+                               ((unsigned long)tempbuff[6]<<8)|((unsigned long)tempbuff[7]);
+                       scsi_dev_desc[scsi_max_devs].lba=capacity;
+                       scsi_dev_desc[scsi_max_devs].blksz=blksz;
+                       scsi_dev_desc[scsi_max_devs].type=perq;
+                       init_part(&scsi_dev_desc[scsi_max_devs]);
+removable:
+                       if(mode==1) {
+                               printf ("    Device %d: ", scsi_max_devs);
+                               dev_print(&scsi_dev_desc[scsi_max_devs]);
+                       } /* if mode */
+                       scsi_max_devs++;
+               } /* next LUN */ 
+       }
+       if(scsi_max_devs>0)
+               scsi_curr_dev=0;
+       else
+               scsi_curr_dev=-1;
+}                              
+                               
+
+
+void scsi_init(void)
+{
+       int busdevfunc;
+       
+       busdevfunc=PCI_Find_Device(SCSI_VEND_ID,SCSI_DEV_ID); /* get PCI Device ID */
+       if(busdevfunc==-1) {
+               printf("Error SCSI Controller (%04X,%04X) not found\n",SCSI_VEND_ID,SCSI_DEV_ID);
+               return;
+       }
+       scsi_low_level_init(busdevfunc);
+       scsi_scan(1);
+}
+
+block_dev_desc_t * scsi_get_dev(int dev)
+{
+       return((block_dev_desc_t *)&scsi_dev_desc[dev]);
+}
+
+
+
+/******************************************************************************
+ * scsi boot command intepreter. Derived from diskboot
+ */
+void do_scsiboot (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
+{
+       char *boot_device = NULL;
+       char *ep;
+       int dev, part;
+       ulong cnt;
+       ulong addr;
+       disk_partition_t info;
+       image_header_t *hdr;
+
+       switch (argc) {
+       case 1:
+               addr = CFG_LOAD_ADDR;
+               boot_device = getenv ("bootdevice");
+               break;
+       case 2:
+               addr = simple_strtoul(argv[1], NULL, 16);
+               boot_device = getenv ("bootdevice");
+               break;
+       case 3:
+               addr = simple_strtoul(argv[1], NULL, 16);
+               boot_device = argv[2];
+               break;
+       default:
+               printf ("Usage:\n%s\n", cmdtp->usage);
+               return;
+       }
+
+       if (!boot_device) {
+               puts ("\n** No boot device **\n");
+               return;
+       }
+
+       dev = simple_strtoul(boot_device, &ep, 16);
+       printf("booting from dev %d\n",dev);
+       if (scsi_dev_desc[dev].type == DEV_TYPE_UNKNOWN) {
+               printf ("\n** Device %d not available\n", dev);
+               return;
+       }
+
+       if (*ep) {
+               if (*ep != ':') {
+                       puts ("\n** Invalid boot device, use `dev[:part]' **\n");
+                       return;
+               }
+               part = simple_strtoul(++ep, NULL, 16);
+       }
+       if (get_partition_info (&scsi_dev_desc[dev], part, &info)) {
+               printf("error reading partinfo\n");
+               return;
+       }
+       if (strncmp(info.type, BOOT_PART_TYPE, sizeof(info.type)) != 0) {
+               printf ("\n** Invalid partition type \"%.32s\""
+                       " (expect \"" BOOT_PART_TYPE "\")\n",
+                       info.type);
+               return;
+       }
+
+       printf ("\nLoading from SCSI device %d, partition %d: "
+               "Name: %.32s  Type: %.32s\n",
+               dev, part, info.name, info.type);
+
+       PRINTF ("First Block: %ld,  # of blocks: %ld, Block Size: %ld\n",
+               info.start, info.size, info.blksz);
+
+       if (scsi_read (dev, info.start, 1, (ulong *)addr) != 1) {
+               printf ("** Read error on %d:%d\n", dev, part);
+               return;
+       }
+
+       hdr = (image_header_t *)addr;
+
+       if (hdr->ih_magic == IH_MAGIC) {
+
+               print_image_hdr (hdr);
+               cnt = (hdr->ih_size + sizeof(image_header_t));
+               cnt += info.blksz - 1;
+               cnt /= info.blksz;
+               cnt -= 1;
+       } else {
+               cnt = info.size - 1;
+       }
+
+       if (scsi_read (dev, info.start+1, cnt,
+                     (ulong *)(addr+info.blksz)) != cnt) {
+               printf ("** Read error on %d:%d\n", dev, part);
+               return;
+       }
+       /* Loading ok, update default load address */
+       load_addr = addr;
+       /* Check if we should attempt an auto-start */
+       if (((ep = getenv("autostart")) != NULL) && (strcmp(ep,"yes") == 0)) {
+               char *local_args[2];
+               extern void do_bootm (cmd_tbl_t *, bd_t *, int, int, char *[]);
+               local_args[0] = argv[0];
+               local_args[1] = NULL;
+               printf ("Automatic boot of image at addr 0x%08lX ...\n", addr);
+               do_bootm (cmdtp, bd, 0, 1, local_args);
+       }
+}
+
+/*********************************************************************************
+ * scsi command intepreter
+ */
+void do_scsi (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
+{
+       switch (argc) {
+    case 0:
+    case 1:    printf ("Usage:\n%s\n", cmdtp->usage);  return;
+    case 2:
+                       if (strncmp(argv[1],"res",3) == 0) {
+                               printf("\nReset SCSI\n");
+                               scsi_bus_reset();
+                               scsi_scan(1);
+                               return;
+                       } 
+                       if (strncmp(argv[1],"inf",3) == 0) {
+                               int i;
+                               for (i=0; i<CFG_SCSI_MAX_DEVICE; ++i) {
+                                       if(scsi_dev_desc[i].type==DEV_TYPE_UNKNOWN)
+                                               continue; /* list only known devices */
+                                       printf ("SCSI dev. %d:  ", i);
+                                       dev_print(&scsi_dev_desc[i]); 
+                               }
+                               return;
+                       }
+                       if (strncmp(argv[1],"dev",3) == 0) {
+                               if ((scsi_curr_dev < 0) || (scsi_curr_dev >= CFG_SCSI_MAX_DEVICE)) {
+                                       printf("\nno SCSI devices available\n");
+                                       return;
+                               }
+                               printf ("\n    Device %d: ", scsi_curr_dev);
+                               dev_print(&scsi_dev_desc[scsi_curr_dev]);
+                               return;
+                       }  
+                       if (strncmp(argv[1],"scan",4) == 0) {
+                               scsi_scan(1);
+                               return;
+                       }  
+                       if (strncmp(argv[1],"part",4) == 0) {
+                               int dev, ok;
+                               for (ok=0, dev=0; dev<CFG_SCSI_MAX_DEVICE; ++dev) {
+                                       if (scsi_dev_desc[dev].type!=DEV_TYPE_UNKNOWN) {
+                                               ok++;
+                                               if (dev)
+                                                       printf("\n");
+                                               PRINTF("print_part of %x\n",dev);
+                                                       print_part(&scsi_dev_desc[dev]);
+                                       }
+                               }
+                               if (!ok)
+                                       printf("\nno SCSI devices available\n");
+                               return;
+                       }
+                       printf ("Usage:\n%s\n", cmdtp->usage);
+                       return;
+       case 3:
+                       if (strncmp(argv[1],"dev",3) == 0) {
+                               int dev = (int)simple_strtoul(argv[2], NULL, 10);
+                               printf ("\nSCSI device %d: ", dev);
+                               if (dev >= CFG_SCSI_MAX_DEVICE) {
+                                       printf("unknown device\n");
+                                       return;
+                               }
+                               printf ("\n    Device %d: ", dev);
+                               dev_print(&scsi_dev_desc[dev]);
+                               if(scsi_dev_desc[dev].type == DEV_TYPE_UNKNOWN) {
+                                       return;
+                               }
+                               scsi_curr_dev = dev;
+                               printf("... is now current device\n");
+                               return;
+                       }
+                       if (strncmp(argv[1],"part",4) == 0) {
+                               int dev = (int)simple_strtoul(argv[2], NULL, 10);
+                               if(scsi_dev_desc[dev].type != DEV_TYPE_UNKNOWN) {
+                                       print_part(&scsi_dev_desc[dev]);
+                               } 
+                               else {
+                                       printf ("\nSCSI device %d not available\n", dev);
+                               }
+                               return;
+                       }
+                       printf ("Usage:\n%s\n", cmdtp->usage);
+                       return;
+    default:
+                       /* at least 4 args */
+                       if (strcmp(argv[1],"read") == 0) {
+                               ulong addr = simple_strtoul(argv[2], NULL, 16);
+                               ulong blk  = simple_strtoul(argv[3], NULL, 16);
+                               ulong cnt  = simple_strtoul(argv[4], NULL, 16);
+                               ulong n;
+                               printf ("\nSCSI read: device %d block # %ld, count %ld ... ",
+                                               scsi_curr_dev, blk, cnt);
+                               n = scsi_read(scsi_curr_dev, blk, cnt, (ulong *)addr);
+                               printf ("%ld blocks read: %s\n",n,(n==cnt) ? "OK" : "ERROR");
+                               return;
+                       } 
+       } /* switch */
+       printf ("Usage:\n%s\n", cmdtp->usage);
+}
+
+/****************************************************************************************
+ * scsi_read
+ */
+#define SCSI_MAX_READ_BLK 0xFFFF /* almost the maximum amount of the scsi_ext command.. */
+
+ulong scsi_read(int device, ulong blknr, ulong blkcnt, ulong *buffer)
+{
+       ulong start,blks, buf_addr;
+       unsigned short smallblks;
+       ccb* pccb=(ccb *)&tempccb;
+       device&=0xff;
+       /* Setup  device
+        */
+       pccb->target=scsi_dev_desc[device].target;
+       pccb->lun=scsi_dev_desc[device].lun;
+       buf_addr=(unsigned long)buffer;
+       start=blknr;
+       blks=blkcnt;
+       PRINTF("\nscsi_read: dev %d startblk %lx, blccnt %lx buffer %lx\n",device,start,blks,(unsigned long)buffer);
+       do {
+               pccb->pdata=(unsigned char *)buf_addr;
+               if(blks>SCSI_MAX_READ_BLK) {
+                       pccb->datalen=scsi_dev_desc[device].blksz * SCSI_MAX_READ_BLK;
+                       smallblks=SCSI_MAX_READ_BLK;
+                       scsi_setup_read_ext(pccb,start,smallblks);
+                       start+=SCSI_MAX_READ_BLK;
+                       blks-=SCSI_MAX_READ_BLK;
+               }
+               else {
+                       pccb->datalen=scsi_dev_desc[device].blksz * blks;
+                       smallblks=(unsigned short) blks;
+                       scsi_setup_read_ext(pccb,start,smallblks);
+                       start+=blks;
+                       blks=0;
+               }
+               PRINTF("scsi_read_ext: startblk %lx, blccnt %x buffer %lx\n",start,smallblks,buf_addr);
+               if(scsi_exec(pccb)!=TRUE) {
+                       scsi_print_error(pccb);
+                       blkcnt-=blks;
+                       break;
+               }
+               buf_addr+=pccb->datalen;
+       } while(blks!=0);
+       PRINTF("scsi_read_ext: end startblk %lx, blccnt %x buffer %lx\n",start,smallblks,buf_addr);
+       return(blkcnt);
+}
+
+/* copy src to dest, skipping leading and trailing blanks 
+ * and null terminate the string
+ */
+void scsi_ident_cpy (unsigned char *dest, unsigned char *src, unsigned int len)
+{
+       int start,end;
+
+       start=0;
+       while(start<len) {
+               if(src[start]!=' ')
+                       break;
+               start++;
+       }
+       end=len-1;
+       while(end>start) {
+               if(src[end]!=' ')
+                       break;
+               end--;
+       }
+       for( ; start<=end; start++) {
+               *dest++=src[start];
+       }
+       *dest='\0';
+}
+
+
+
+/* Trim trailing blanks, and NUL-terminate string
+ */
+void scsi_trim_trail (unsigned char *str, unsigned int len)
+{
+       unsigned char *p = str + len - 1;
+
+       while (len-- > 0) {
+               *p-- = '\0';
+               if (*p != ' ') {
+                       return;
+               }
+       }
+}
+
+
+/************************************************************************************
+ * Some setup (fill-in) routines
+ */
+void scsi_setup_test_unit_ready(ccb * pccb)
+{
+       pccb->cmd[0]=SCSI_TST_U_RDY;
+       pccb->cmd[1]=pccb->lun<<5;
+       pccb->cmd[2]=0;
+       pccb->cmd[3]=0;
+       pccb->cmd[4]=0;
+       pccb->cmd[5]=0;
+       pccb->cmdlen=6;
+       pccb->msgout[0]=SCSI_IDENTIFY; /* NOT USED */
+}
+
+void scsi_setup_read_capacity(ccb * pccb)
+{
+       pccb->cmd[0]=SCSI_RD_CAPAC;
+       pccb->cmd[1]=pccb->lun<<5;
+       pccb->cmd[2]=0;
+       pccb->cmd[3]=0;
+       pccb->cmd[4]=0;
+       pccb->cmd[5]=0;
+       pccb->cmd[6]=0;
+       pccb->cmd[7]=0;
+       pccb->cmd[8]=0;
+       pccb->cmd[9]=0;
+       pccb->cmdlen=10;
+       pccb->msgout[0]=SCSI_IDENTIFY; /* NOT USED */
+
+}
+
+void scsi_setup_read_ext(ccb * pccb, unsigned long start, unsigned short blocks)
+{
+       pccb->cmd[0]=SCSI_READ10;
+       pccb->cmd[1]=pccb->lun<<5;
+       pccb->cmd[2]=((unsigned char) (start>>24))&0xff;
+       pccb->cmd[3]=((unsigned char) (start>>16))&0xff;
+       pccb->cmd[4]=((unsigned char) (start>>8))&0xff;
+       pccb->cmd[5]=((unsigned char) (start))&0xff;
+       pccb->cmd[6]=0;
+       pccb->cmd[7]=((unsigned char) (blocks>>8))&0xff;
+       pccb->cmd[8]=(unsigned char) blocks & 0xff;
+       pccb->cmd[6]=0;
+       pccb->cmdlen=10;
+       pccb->msgout[0]=SCSI_IDENTIFY; /* NOT USED */
+       PRINTF("scsi_setup_read_ext: cmd: %02X %02X startblk %02X%02X%02X%02X blccnt %02X%02X\n",
+               pccb->cmd[0],pccb->cmd[1],
+               pccb->cmd[2],pccb->cmd[3],pccb->cmd[4],pccb->cmd[5],
+               pccb->cmd[7],pccb->cmd[8]);
+}
+
+void scsi_setup_read6(ccb * pccb, unsigned long start, unsigned short blocks)
+{
+       pccb->cmd[0]=SCSI_READ6;
+       pccb->cmd[1]=pccb->lun<<5 | (((unsigned char)(start>>16))&0x1f);
+       pccb->cmd[2]=((unsigned char) (start>>8))&0xff;
+       pccb->cmd[3]=((unsigned char) (start))&0xff;
+       pccb->cmd[4]=(unsigned char) blocks & 0xff;
+       pccb->cmd[5]=0;
+       pccb->cmdlen=6;
+       pccb->msgout[0]=SCSI_IDENTIFY; /* NOT USED */
+       PRINTF("scsi_setup_read6: cmd: %02X %02X startblk %02X%02X blccnt %02X\n",
+               pccb->cmd[0],pccb->cmd[1],
+               pccb->cmd[2],pccb->cmd[3],pccb->cmd[4]);
+}
+
+
+void scsi_setup_inquiry(ccb * pccb)
+{
+       pccb->cmd[0]=SCSI_INQUIRY;
+       pccb->cmd[1]=pccb->lun<<5;
+       pccb->cmd[2]=0;
+       pccb->cmd[3]=0;
+       if(pccb->datalen>255)
+               pccb->cmd[4]=255;
+       else
+               pccb->cmd[4]=(unsigned char)pccb->datalen;
+       pccb->cmd[5]=0;
+       pccb->cmdlen=6;
+       pccb->msgout[0]=SCSI_IDENTIFY; /* NOT USED */
+}
+
+#endif /* #if (CONFIG_COMMANDS & CFG_CMD_SCSI) */
+
+
index 544768641bce37405ad4c65569ff422d0c834b7e..ec6c46f41f0d190fda415b67338fbdb5058d0073 100644 (file)
 #include <cmd_rtc.h>
 
 #include <cmd_bsp.h>           /* board special functions */
+#include <cmd_fdc.h>    /* Floppy support */
+#include <cmd_scsi.h>
 
 #ifdef CONFIG_HYMOD
 #include <board/hymod/cmd_fpga.h>
 #endif
 
+
 #include <cmd_bedbug.h>
 
 /*
@@ -200,6 +203,8 @@ cmd_tbl_t cmd_tbl[] = {
        CMD_TBL_RARPB
        CMD_TBL_DHCP
        CMD_TBL_DISK
+       CMD_TBL_SCSIBOOT
+       CMD_TBL_FDC
        CMD_TBL_BOOTD
        CMD_TBL_LOADS
        CMD_TBL_LOADB
@@ -225,6 +230,7 @@ cmd_tbl_t cmd_tbl[] = {
        CMD_TBL_IRQINFO
        CMD_TBL_CONINFO
        CMD_TBL_IDE
+       CMD_TBL_SCSI
        CMD_TBL_PINIT
        CMD_TBL_I2C
        CMD_TBL_EEPROM
@@ -263,7 +269,6 @@ cmd_tbl_t cmd_tbl[] = {
        CMD_TBL_VERS
        CMD_TBL_HELP
        CMD_TBL_QUES
-
         CMD_TBL_DIS
         CMD_TBL_ASM
         CMD_TBL_BREAK
@@ -272,7 +277,6 @@ cmd_tbl_t cmd_tbl[] = {
         CMD_TBL_STEP
         CMD_TBL_NEXT
         CMD_TBL_RDUMP
-        
        /* the following entry terminates this table */
        MK_CMD_TBL_ENTRY( NULL, 0, 0, 0, NULL, NULL, NULL )
 };
index 748d33c2e2adddd882c8ed7e166d37bbe253851a..e41627077209c0bb855f86bdd98dd4410974313c 100644 (file)
 #include <malloc.h>
 #include <console.h>
 
+#ifdef CFG_CONSOLE_IS_IN_ENV
+/* 
+ * if overwrite_console returns 1, the stdin, stderr and stdout
+ * are switched to the serial port, else the settings in the 
+ * environment are used
+ */
+#ifdef CFG_CONSOLE_OVERWRITE_ROUTINE
+extern int overwrite_console(void);
+#else
+int overwrite_console(void) 
+{
+       return (0);
+}
+#endif
+
+#endif /* CFG_CONSOLE_IS_IN_ENV */
+
 static int console_setfile(int file, device_t  *dev)
 {
     int error = 0;
@@ -38,19 +55,19 @@ static int console_setfile(int file, device_t  *dev)
     case stdin:
     case stdout:
     case stderr:
-       // Start new device
+       /* Start new device */
        if (dev->start)
        {
            error = dev->start() ;
-           // If it's not started dont use it
+           /* If it's not started dont use it */
            if (error < 0)
                break;
        }
 
-       // Assign the new device (leaving the existing one started)
+       /* Assign the new device (leaving the existing one started) */
        stdio_devices[file] = dev ;
 
-       // Update monitor functions (to use the console stuff by other applications)
+       /* Update monitor functions (to use the console stuff by other applications) */
        switch (file){
            case stdin:
                bd_ptr->bi_mon_fnc->getc = dev->getc ;
@@ -64,13 +81,13 @@ static int console_setfile(int file, device_t  *dev)
        }
        break;
 
-    default:   // Invalid file ID
+    default:   /* Invalid file ID */
        error = -1 ;
     }
     return error ;
 }
 
-//** PPCBOOT INITIAL CONSOLE-NOT COMPATIBLE FUNCTIONS *************************
+/** PPCBOOT INITIAL CONSOLE-NOT COMPATIBLE FUNCTIONS *************************/
 
 void serial_printf(const char *fmt, ...)
 {
@@ -131,21 +148,21 @@ void fprintf(int file, const char *fmt, ...)
        i = vsprintf(printbuffer, fmt, args);
        va_end(args);
 
-       // Send to desired file
+       /* Send to desired file */
         fputs(file, printbuffer);
 }
 
-//** PPCBOOT INITIAL CONSOLE-COMPATIBLE FUNCTION *****************************
+/** PPCBOOT INITIAL CONSOLE-COMPATIBLE FUNCTION *****************************/
 
 int    getc(void)
 {
     init_data_t *idata = (init_data_t *)(CFG_INIT_RAM_ADDR + CFG_INIT_DATA_OFFSET);
 
     if (idata->relocated)
-           // Get from the standard input
+           /* Get from the standard input */
            return fgetc (stdin);
 
-    // Send directly to the handler
+    /* Send directly to the handler */
     return serial_getc();
 }
 
@@ -154,10 +171,10 @@ int       tstc(void)
     init_data_t *idata = (init_data_t *)(CFG_INIT_RAM_ADDR + CFG_INIT_DATA_OFFSET);
 
     if (idata->relocated)
-           // Test the standard input
+           /* Test the standard input */
            return ftstc (stdin);
 
-    // Send directly to the handler
+    /* Send directly to the handler */
     return serial_tstc();
 }
 
@@ -166,10 +183,10 @@ void      putc(const char c)
     init_data_t *idata = (init_data_t *)(CFG_INIT_RAM_ADDR + CFG_INIT_DATA_OFFSET);
 
     if (idata->relocated)
-       // Send to the standard output
+       /* Send to the standard output */
        fputc (stdout, c);
     else
-       // Send directly to the handler
+       /* Send directly to the handler */
        serial_putc(c);
 }
 
@@ -178,10 +195,10 @@ void      puts(const char *s)
     init_data_t *idata = (init_data_t *)(CFG_INIT_RAM_ADDR + CFG_INIT_DATA_OFFSET);
 
     if (idata->relocated)
-       // Send to the standard output
+       /* Send to the standard output */
        fputs (stdout, s);
     else
-       // Send directly to the handler
+       /* Send directly to the handler */
        serial_puts(s);
 }
 
@@ -199,11 +216,11 @@ void printf(const char *fmt, ...)
        i = vsprintf(printbuffer, fmt, args);
        va_end(args);
 
-       // Print the string
+       /* Print the string */
        puts (printbuffer);
 }
 
-// test if ctrl-c was pressed.
+/* test if ctrl-c was pressed */
 static int ctrlc_disabled = 0;         /* see disable_ctrl() */
 static int ctrlc_was_pressed = 0;
 int
@@ -248,13 +265,13 @@ clear_ctrlc(void)
        ctrlc_was_pressed = 0;
 }
 
-//** PPCBOOT INIT FUNCTIONS *************************************************
+/** PPCBOOT INIT FUNCTIONS *************************************************/
 
 int console_assign (int file, char *devname)
 {
     int                        flag , i;
 
-    // Check for valid file
+    /* Check for valid file */
     switch(file){
     case stdin:
        flag = DEV_FLAGS_INPUT ;
@@ -267,7 +284,7 @@ int console_assign (int file, char *devname)
        return -1 ;
     }
 
-    // Check for valid device name
+    /* Check for valid device name */
 
     for(i=1; i<=ListNumItems(devlist); i++)
     {
@@ -285,12 +302,12 @@ int console_assign (int file, char *devname)
     return -1 ;
 }
 
-// Called before relocation - use serial functions
+/* Called before relocation - use serial functions */
 void   console_init_f (void)
 {
     init_data_t *idata = (init_data_t *)(CFG_INIT_RAM_ADDR + CFG_INIT_DATA_OFFSET);
 
-    idata->relocated           = 0 ;           // Use these pointers before relocation
+    idata->relocated           = 0 ;           /* Use these pointers before relocation */
     idata->bi_mon_fnc.getc     = serial_getc;
     idata->bi_mon_fnc.tstc     = serial_tstc;
     idata->bi_mon_fnc.putc     = serial_putc;
@@ -298,17 +315,106 @@ void     console_init_f (void)
     idata->bi_mon_fnc.printf   = serial_printf;
 }
 
-// Called after the relocation - use desierd console functions
+#ifdef CFG_CONSOLE_IS_IN_ENV
+/* search a device */
+device_t *search_device(int flags, char * name)
+{
+       int i,items;
+       device_t        *dev = NULL;
+       items = ListNumItems(devlist);
+       if(name==NULL)
+               return dev;
+        for (i=1; i<=items; i++) {
+               dev = ListGetPtrToItem(devlist, i) ;
+               if ((dev->flags & flags) && (strcmp(name,dev->name)==0)) {
+                       break;
+               }
+       }
+       return dev;
+}
+#endif /* CFG_CONSOLE_IS_IN_ENV */
+
+#ifdef CFG_CONSOLE_IS_IN_ENV 
+/* Called after the relocation - use desierd console functions */
 void   console_init_r (ulong reloc_offset)
 {
-    init_data_t *idata = (init_data_t *)(CFG_INIT_RAM_ADDR + CFG_INIT_DATA_OFFSET);
-    device_t   *inputdev = NULL, *outputdev = NULL ;
-    int i, items = ListNumItems(devlist) ;
+       init_data_t *idata = (init_data_t *)(CFG_INIT_RAM_ADDR + CFG_INIT_DATA_OFFSET);
+       device_t        *inputdev = NULL, *outputdev = NULL, *errdev = NULL;
+       /* sdtin stdout and stderr are in environment */
+       /* scan for it */
+       char *stdinname = getenv("stdin");
+       char *stdoutname = getenv("stdout");
+       char *stderrname = getenv("stderr");
+
+       /* Global pointer to monitor structure (updated by the console stuff) */
+       bd_ptr->bi_mon_fnc = &idata->bi_mon_fnc ;
+       
+       if(overwrite_console()==0) { /* if not overwritten by config switch */
+       inputdev=search_device(DEV_FLAGS_INPUT,stdinname);
+       outputdev=search_device(DEV_FLAGS_OUTPUT,stdoutname);
+       errdev=search_device(DEV_FLAGS_OUTPUT,stderrname);
+       }
+       /* if the devices are overwritten or not found, use default device */
+       if(inputdev==NULL)
+       inputdev=search_device(DEV_FLAGS_INPUT,"serial");
+       if(outputdev==NULL)
+       outputdev=search_device(DEV_FLAGS_OUTPUT,"serial");
+       if(errdev==NULL)
+       errdev=search_device(DEV_FLAGS_OUTPUT,"serial");
+  /* Initializes output console first */
+  if (outputdev != NULL) 
+               console_setfile(stdout, outputdev);
+  if (errdev != NULL) 
+               console_setfile(stderr, errdev);
+  if (inputdev != NULL) 
+               console_setfile(stdin, inputdev);
+       
+       /* Print informations */
+       printf("  In:    ");
+       if (stdio_devices[stdin] == NULL)
+               printf("No input devices available!\n");
+       else
+               printf("%s\n", stdio_devices[stdin]->name);
+
+       printf("  Out:   ");
+       if (stdio_devices[stdout] == NULL)
+               printf("No output devices available!\n");
+       else
+               printf("%s\n", stdio_devices[stdout]->name);
+
+       printf("  Err:   ");
+       if (stdio_devices[stderr] == NULL)
+               printf("No error devices available!\n");
+       else
+               printf("%s\n", stdio_devices[stderr]->name);
+
+#ifdef CFG_CONSOLE_ENV_OVERWRITE
+   /* set the environment variables (will overwrite previous env settings) */
+       for (i=0; i<3; i++)
+               setenv(stdio_names[i], stdio_devices[i]->name);
+#endif /*  CFG_CONSOLE_ENV_OVERWRITE */
+       /* If nothing usable installed, use only the initial console */
+       if ((stdio_devices[stdin] == NULL) && (stdio_devices[stdout] == NULL))
+               return ;
+
+       /* Set the relocation flag */
+       idata->relocated = reloc_offset;
+}
 
-    // Global pointer to monitor structure (updated by the console stuff)
-    bd_ptr->bi_mon_fnc = &idata->bi_mon_fnc ;
 
-    // Scan devices looking for input and output devices
+#else /* CFG_CONSOLE_IS_IN_ENV */
+/* Called after the relocation - use desierd console functions */
+void   console_init_r (ulong reloc_offset)
+{
+       init_data_t *idata = (init_data_t *)(CFG_INIT_RAM_ADDR + CFG_INIT_DATA_OFFSET);
+       device_t        *inputdev = NULL, *outputdev = NULL ;
+       int i, items = ListNumItems(devlist) ;
+       
+       /* Global pointer to monitor structure (updated by the console stuff) */
+       bd_ptr->bi_mon_fnc = &idata->bi_mon_fnc ;
+       
+
+    /* Scan devices looking for input and output devices */
     for (i=1; (i<=items) && ((inputdev == NULL) || (outputdev == NULL)); i++)
     {
        device_t        *dev = ListGetPtrToItem(devlist, i) ;
@@ -320,18 +426,18 @@ void      console_init_r (ulong reloc_offset)
            outputdev = dev ;
     }
 
-    // Initializes output console first
+    /* Initializes output console first */
     if (outputdev != NULL)
     {
        console_setfile(stdout, outputdev);
        console_setfile(stderr, outputdev);
     }
 
-    // Initializes input console
+    /* Initializes input console */
     if (inputdev != NULL)
        console_setfile(stdin, inputdev);
 
-    // Print informations
+    /* Print informations */
     printf("  In:    ");
     if (stdio_devices[stdin] == NULL)
        printf("No input devices available!\n");
@@ -350,14 +456,17 @@ void      console_init_r (ulong reloc_offset)
     else
        printf("%s\n", stdio_devices[stderr]->name);
 
-    // Setting environment variables
+    /* Setting environment variables */
     for (i=0; i<3; i++)
        setenv(stdio_names[i], stdio_devices[i]->name);
 
-    // If nothing usable installed, use only the initial console
+    /* If nothing usable installed, use only the initial console */
     if ((stdio_devices[stdin] == NULL) && (stdio_devices[stdout] == NULL))
        return ;
 
-    // Set the relocation flag
+    /* Set the relocation flag */
     idata->relocated = reloc_offset;
 }
+
+#endif /* CFG_CONSOLE_IS_IN_ENV */
+
index f782596cf6483b88abc42f51b087ff2239a7d6f5..7f4a1ff7b8fbe44cf5e7103e4f758447de29ba4b 100644 (file)
@@ -37,7 +37,9 @@ extern int drv_video_init(void);
 #ifdef CONFIG_WL_4PPM_KEYBOARD
 extern int drv_wlkbd_init(void);
 #endif
-
+#ifdef CONFIG_ISA_KEYBOARD
+extern int drv_isa_kbd_init(void);
+#endif
 // **************************************************************************
 // * SYSTEM DRIVERS
 // **************************************************************************
@@ -71,6 +73,7 @@ int device_register (device_t *dev)
     return 0 ;
 }
 
+
 int devices_init (ulong relocation_offset)
 {
     int i;
@@ -95,6 +98,9 @@ int devices_init (ulong relocation_offset)
 #endif
 #ifdef CONFIG_WL_4PPM_KEYBOARD
     drv_wlkbd_init();
+#endif
+#ifdef CONFIG_ISA_KEYBOARD
+    drv_isa_kbd_init();
 #endif
     drv_system_init();
 
index fe33a8f7d9875e0b8df02e819f9fe41b987ac7dc..301b8b196e6d2bc5d0c436ccaf59b7f5315b8148 100644 (file)
@@ -31,6 +31,7 @@ static int parse_line (char *, char *[]);
 #if (CONFIG_BOOTDELAY >= 0)
 static int abortboot(int);
 #endif
+#undef DEBUG_PARSER
 
 char        console_buffer[CFG_CBSIZE];                /* console I/O buffer   */
 
@@ -178,7 +179,7 @@ static __inline__ int abortboot(int bootdelay)
        return abort;
 }
 # endif        /* CONFIG_AUTOBOOT_KEYED */
-#endif /* CONFIG_BOOTDELAY >= 0 */
+#endif /* CONFIG_BOOTDELAY >= 0  */
 
 /****************************************************************************/
 
@@ -191,7 +192,7 @@ void main_loop(bd_t *bd)
 
 #if (CONFIG_BOOTDELAY >= 0)
        char *s = getenv ("bootdelay");
-       int bootdelay = s ? (int)simple_strtoul(s, NULL, 10) : 0;
+       int bootdelay = s ? (int)simple_strtol(s, NULL, 10) : 0;
 
 #if 0
        printf ("### main_loop entered:\n\n");
index 224e2def2a7d3ff3a67cf45b30f54e63c1f2976a..c267bff53cf2a07cfc365ecadcf2bcc6070cf671 100644 (file)
 #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
@@ -74,7 +78,9 @@
        .long   0x27051956              /* PPCBOOT Magic Number         */
        .globl  version_string
 version_string:
-       .ascii PPCBOOT_VERSION, " (", __DATE__, " - ", __TIME__, ")\0"
+       .ascii PPCBOOT_VERSION
+       .ascii " (", __DATE__, " - ", __TIME__, ")"
+       .ascii CONFIG_IDENT_STRING, "\0"
 
 #if 0
 /* this is used in the led on/off routines */
index fca61d829ba21ae5b130d3186c5ab447119c2af8..672659ce7c3f6a8698b35e330f18834be991292a 100644 (file)
 #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
@@ -83,7 +87,9 @@
        .long   0x27051956              /* PPCBOOT Magic Number                 */
        .globl  version_string
 version_string:
-       .ascii PPCBOOT_VERSION, " (", __DATE__, " - ", __TIME__, ")\0"
+       .ascii PPCBOOT_VERSION
+       .ascii " (", __DATE__, " - ", __TIME__, ")"
+       .ascii CONFIG_IDENT_STRING, "\0"
 
        . = EXC_OFF_SYS_RESET
        .globl  _start
index 6189474c387974986f8b1b08a02bc77627554391..fcd0110405c531588f599b66a36d3b63c3d5cac8 100644 (file)
 #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
@@ -79,7 +83,9 @@
        .data
        .globl  version_string
 version_string:
-       .ascii PPCBOOT_VERSION, " (", __DATE__, " - ", __TIME__, ")\0"
+       .ascii PPCBOOT_VERSION
+       .ascii " (", __DATE__, " - ", __TIME__, ")"
+       .ascii CONFIG_IDENT_STRING, "\0"
 
 /*
  *  Hard Reset Configuration Word (HRCW) table
index 5abd1b90cd4f3c9b327b3d79a79b396078a963c0..db470eddb907e909f88369186a3bfde2d290cde3 100644 (file)
 #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
@@ -84,7 +88,9 @@
        .long   0x27051956              /* PPCBOOT Magic Number                 */
        .globl  version_string
 version_string:
-       .ascii PPCBOOT_VERSION, " (", __DATE__, " - ", __TIME__, ")\0"
+       .ascii PPCBOOT_VERSION
+       .ascii " (", __DATE__, " - ", __TIME__, ")"
+       .ascii CONFIG_IDENT_STRING, "\0"
 
        . = EXC_OFF_SYS_RESET
        .globl  _start
index fbe4b581dd78817081d2e07e1531da64813a0d49..cc2953d7339da17884e4fd4b6bd68e6cec20169c 100644 (file)
@@ -57,6 +57,7 @@
 #include <405gp_pci.h>
 #include <asm/processor.h>
 
+#ifndef CONFIG_PIP405
 
 void pciinfo(int bus_no);
 
@@ -903,3 +904,4 @@ pciBheaderPrint(PCI_HEADER_BRIDGE * pB)
 #endif /* CONFIG_PCI */
 
 #endif /* CONFIG_PPC405GP */
+#endif /* CONFIG_PIP405 */
index 2f05cee2c57d7c33ff516161923a099b1f47cd63..481a3bc8eefb3083529d0939dc6f8ac86ce0acb0 100644 (file)
@@ -270,29 +270,91 @@ int i2c_send(unsigned char address,
 
 void i2c_read (uchar *addr, int alen, uchar *buffer, int len)
 {
-       if (alen != 2) {
+
+       if ((alen != 2) && (alen != 3)) {
                printf ("I2C read: addr len %d not supported\n", alen);
                return;
        }
-       i2c_send (addr[0] << 1, 1, addr+1);
+
+       i2c_send (addr[0] << 1, alen-1, addr+1);
        i2c_receive ((addr[0] << 1) | 0x01, len, buffer);
 }
 
+#ifndef CFG_EEPROM_PAGE_WRITE_ENABLE
+
 void i2c_write (uchar *addr, int alen, uchar *buffer, int len)
 {
-       uchar xbuf[2];
+       uchar xbuf[3];
+       unsigned short paddr;
+
+       if (alen == 2) {
+               /* write with ack polling */
+               while (len-- > 0) {
+                       xbuf[0] = addr[1]++; /* increase write offset */
+                       xbuf[1] = *buffer++;
+                       /* single write + ack polling */
+                       while (i2c_send (addr[0] << 1, 2, xbuf) != 0) {
+                               udelay(100);
+                       }
+               }
+               return;
+       }
 
-       if (alen != 2) {
-               printf ("I2C write: addr len %d not supported\n", alen);
+       paddr=(addr[1]<<8)+addr[2];
+
+       if (alen == 3) {
+               /* write with ack polling */
+               while (len-- > 0) {
+                       xbuf[0] = (uchar)(paddr>>8);    /* High addr */
+                       xbuf[1] = (uchar)(paddr&0xff);  /* Low  addr */
+                       paddr++;
+                       xbuf[2] = *buffer++;
+                       /* single write + ack polling */
+                       while (i2c_send (addr[0] << 1, 3, xbuf) != 0) {
+                               udelay(100);
+                       }
+               }
                return;
        }
 
-       /* write with ack polling */
-       /* XXX this should be improved to allow page write mode XXX - wd */
-       while (len-- > 0) {
-          xbuf[0] = addr[1]++; /* increase write offset */
-          xbuf[1] = *buffer++;
-          while (i2c_send (addr[0] << 1, 2, xbuf) != 0) /* single write + ack polling */
-            udelay(100);
+       printf ("I2C write: addr len %d not supported\n", alen);
+}
+
+#else /* CFG_EEPROM_PAGE_WRITE_ENABLE */
+
+void i2c_write (uchar *addr, int alen, uchar *buffer, int len)
+{
+       /* buffer for one page + addresses */
+       uchar wbuffer[(1<<CFG_EEPROM_PAGE_WRITE_BITS)+2];
+
+       int i;
+
+       if (alen == 2) {
+               /* fill in address first */
+               wbuffer[0] = addr[1]; 
+               for (i=1; i < len+1; i++) {
+                       wbuffer[i] = *buffer++; /* copy data */
+               }
+               /* write page + ack polling */
+               while (i2c_send (addr[0] << 1, len+1, wbuffer) != 0) {
+                       udelay(100);
+               }
+               return;
        }
+       if (alen == 3) {
+               /* fill in the address first */
+               wbuffer[0] = addr[1]; 
+               wbuffer[1] = addr[2]; 
+               for (i=2; i < len+2; i++) {
+                       wbuffer[i] = *buffer++; /* copy data */
+               }
+               /* write page + ack polling */
+               while (i2c_send (addr[0] << 1, len+2, wbuffer) != 0) {
+                       udelay(100);
+               }
+               return;
+       }
+       printf ("I2C write: addr len %d not supported\n", alen);
 }
+#endif /* CFG_EEPROM_PAGE_WRITE_ENABLE */
+
index 6e2cdd08cdfba7fd0c420565ba93347bfa027cef..bb2874fe0f43f28e6f02e2b2abfcfb130d7c63e9 100644 (file)
@@ -253,4 +253,20 @@ ulong get_OPB_freq (void)
   return val;
 }
 
-/* ------------------------------------------------------------------------- */
+#ifdef CONFIG_PPC405
+
+/********************************************
+ * get_PCI_freq
+ * return PCI bus freq in Hz
+*********************************************/
+ulong get_PCI_freq (void)
+{
+  ulong val;
+  PPC405_SYS_INFO sys_info;
+
+  get_sys_info(&sys_info);
+  val = sys_info.freqPLB/sys_info.pllPciDiv;
+  return val;
+}
+#endif
+/*---------------------------------------------------------------------- */
index 80e8fe261d23ef5f5eeb0eac153f781b71519dd2..8fa6cf6ea50b3a9a2c1229a8c8dc18d6e9a50658 100644 (file)
 #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
        .long   0x27051956              /* PPCBOOT Magic Number                 */
        .globl  version_string
 version_string:
-       .ascii PPCBOOT_VERSION, " (", __DATE__, " - ", __TIME__, ")\0"
+       .ascii PPCBOOT_VERSION
+       .ascii " (", __DATE__, " - ", __TIME__, ")"
+       .ascii CONFIG_IDENT_STRING, "\0"
 
        . = EXC_OFF_SYS_RESET
        .globl  _start
@@ -274,10 +280,10 @@ boot_warm:
         //-----------------------------------------------------------------------
         bl      sdram_init
 
-        addis   r1,r0,CFG_INIT_RAM_ADDR@h
+             addis   r1,r0,CFG_INIT_RAM_ADDR@h
                ori     r1,r1,CFG_INIT_SP_OFFSET           /* set up the stack in SDRAM */
 
-       GET_GOT                 /* initialize GOT access                        */
+        GET_GOT                        /* initialize GOT access                        */
 
        bl      board_init_f    /* run first part of init code (from Flash)     */
 
index 449449e419429ee9ef07f24d7c68b2e9fd2da4a3..7b80174f5b370915678ccc99744f1a21af4c9dbe 100644 (file)
@@ -27,7 +27,7 @@ include $(TOPDIR)/config.mk
 
 LIB    = libdisk.a
 
-OBJS   = part.o part_mac.o part_dos.o
+OBJS   = part.o part_mac.o part_dos.o part_iso.o
 
 all:   $(LIB)
 
index a0bbab359b04673d5bbd3cf69802da6b4adedefe..e6d6e9a75c0d4347240193dabf1b6c69353df937 100644 (file)
 #include <ide.h>
 #include <cmd_disk.h>
 
-#if (CONFIG_COMMANDS & CFG_CMD_IDE)
+#undef PART_DEBUG
 
-#if defined(CONFIG_MAC_PARTITION) || defined(CONFIG_DOS_PARTITION)
+#ifdef PART_DEBUG
+#define        PRINTF(fmt,args...)     printf (fmt ,##args)
+#else
+#define PRINTF(fmt,args...)
+#endif
+
+#if (CONFIG_COMMANDS & CFG_CMD_IDE) || (CONFIG_COMMANDS & CFG_CMD_SCSI)  
+
+/* stdlib.h causes some compatibility problems; should fixe these! -- wd */
+#ifndef __ldiv_t_defined
+typedef struct {
+       long int quot;          /* Quotient     */
+       long int rem;           /* Remainder    */
+} ldiv_t;
+extern ldiv_t ldiv (long int __numer, long int __denom);
+# define __ldiv_t_defined      1
+#endif
+
+
+/* ------------------------------------------------------------------------- */
+/*
+ * reports device info to the user 
+ */
+void dev_print(block_dev_desc_t *dev_desc)
+{
+       ldiv_t mb, gb;
+       ulong lba512; /* number of blocks if 512bytes block size */
+       if (dev_desc->type==DEV_TYPE_UNKNOWN) {
+               printf("not available\n");
+               return;
+       }
+       if(dev_desc->if_type==IF_TYPE_SCSI) 
+               printf ("(%d:%d) ", dev_desc->target,dev_desc->lun);
+       if(dev_desc->if_type==IF_TYPE_IDE) 
+               printf ("Model: %s Firm: %s Ser#: %s\n", dev_desc->vendor,dev_desc->revision,dev_desc->product);
+       else
+               printf ("Vendor: %s Prod.: %s Rev: %s\n", dev_desc->vendor,dev_desc->product,dev_desc->revision);
+       printf("              Type: ");
+       if(dev_desc->removable)
+               printf ("Removable ");
+       switch(dev_desc->type & 0x1F) {
+               case DEV_TYPE_HARDDISK: printf("Hard Disk"); break;
+               case DEV_TYPE_CDROM:            printf("CD ROM"); break;
+               case DEV_TYPE_OPDISK:   printf("Optical Device"); break;
+               case DEV_TYPE_TAPE:             printf("Tape"); break;
+               default:                                                        printf("# %02X #",dev_desc->type & 0x1F); break;
+       } 
+       printf("\n");
+       if((dev_desc->lba * dev_desc->blksz)>0L) {
+               lba512=(dev_desc->lba * (dev_desc->blksz/512));
+               mb = ldiv(lba512, 2048); /* (1024 *1024 / 512 MB */
+               /* round to 1 digit */
+               mb.rem *= 10 * 512;
+               mb.rem += 512 * 1024;
+               mb.rem /= 1024 * 1024;
+               gb = ldiv(10 * mb.quot + mb.rem, 10240);
+               gb.rem += 512;
+               gb.rem /= 1024;
+               printf ("              Capacity: %ld.%ld MB = %ld.%ld GB (%ld x %ld)\n",mb.quot, mb.rem, gb.quot, gb.rem,dev_desc->lba,dev_desc->blksz);
+       }
+       else {
+               printf ("              Capacity: not available\n");
+       }
+}
 
-#define        PART_TYPE_UNKNOWN       0x00
-#define PART_TYPE_MAC          0x01
-#define PART_TYPE_DOS          0x02
 
-static char part_type [CFG_IDE_MAXDEVICE] = { PART_TYPE_UNKNOWN, };
 
-void init_part (int dev)
+#if defined(CONFIG_MAC_PARTITION) || defined(CONFIG_DOS_PARTITION) || defined(CONFIG_ISO_PARTITION)
+
+void init_part (block_dev_desc_t * dev_desc)
 {
+#ifdef CONFIG_ISO_PARTITION
+       if (test_part_iso(dev_desc) == 0) {
+               dev_desc->part_type = PART_TYPE_ISO;
+               return;
+       }
+#endif
+
 #ifdef CONFIG_MAC_PARTITION
-       if (test_part_mac(dev) == 0) {
-               part_type [dev] = PART_TYPE_MAC;
+       if (test_part_mac(dev_desc) == 0) {
+               dev_desc->part_type = PART_TYPE_MAC;
                return;
        }
 #endif
 
 #ifdef CONFIG_DOS_PARTITION
-       if (test_part_dos(dev) == 0) {
-               part_type [dev] = PART_TYPE_DOS;
+       if (test_part_dos(dev_desc) == 0) {
+               dev_desc->part_type = PART_TYPE_DOS;
                return;
        }
 #endif
 }
 
-int get_partition_info (int dev, int part, disk_partition_t *info)
+
+int get_partition_info (block_dev_desc_t * dev_desc, int part, disk_partition_t *info)
 {
-       switch (part_type[dev]) {
+               switch(dev_desc->part_type) {
 #ifdef CONFIG_MAC_PARTITION
        case PART_TYPE_MAC:
-               if (get_partition_info_mac(dev,part,info) == 0) {
-#ifdef DEBUG
-                       printf ("## Valid MAC partition found ##\n");
-#endif
+               if (get_partition_info_mac(dev_desc,part,info) == 0) {
+                       PRINTF ("## Valid MAC partition found ##\n");
                        return (0);
                }
                break;
@@ -69,10 +136,17 @@ int get_partition_info (int dev, int part, disk_partition_t *info)
 
 #ifdef CONFIG_DOS_PARTITION
        case PART_TYPE_DOS:
-               if (get_partition_info_dos(dev,part,info) == 0) {
-#ifdef DEBUG
-                       printf ("## Valid DOS partition found ##\n");
+               if (get_partition_info_dos(dev_desc,part,info) == 0) {
+                       PRINTF ("## Valid DOS partition found ##\n");
+                       return (0);
+               }
+               break;
 #endif
+
+#ifdef CONFIG_ISO_PARTITION
+       case PART_TYPE_ISO:
+               if (get_partition_info_iso(dev_desc,part,info) == 0) {
+                       PRINTF ("## Valid ISO boot partition found ##\n");
                        return (0);
                }
                break;
@@ -83,39 +157,52 @@ int get_partition_info (int dev, int part, disk_partition_t *info)
        return (-1);
 }
 
-static void print_part_header (const char *type, int dev)
+static void print_part_header (const char *type, block_dev_desc_t * dev_desc)
 {
-       printf ("\nPartition Map for IDE device %d  --   Partition Type: %s\n\n",
-               dev, type);
+       printf ("\nPartition Map for ");
+       switch(dev_desc->if_type) {
+               case IF_TYPE_IDE:       printf("IDE"); break;
+               case IF_TYPE_SCSI:      printf("SCSI"); break;
+               case IF_TYPE_ATAPI:     printf("ATAPI"); break;
+               default:                                                printf("UNKNOWN"); break;
+       }
+       printf(" device %d  --   Partition Type: %s\n\n",
+                       dev_desc->dev, type);
 }
 
-void print_part (int dev)
+void print_part (block_dev_desc_t * dev_desc)
 {
-       switch (part_type[dev]) {
+
+               switch(dev_desc->part_type) {
 #ifdef CONFIG_MAC_PARTITION
        case PART_TYPE_MAC:
-#ifdef DEBUG
-               printf ("## Testing for valid MAC partition ##\n");
-#endif
-               print_part_header ("MAC", dev);
-               print_part_mac (dev);
+               PRINTF ("## Testing for valid MAC partition ##\n");
+               print_part_header ("MAC", dev_desc);
+               print_part_mac (dev_desc);
                return;
 #endif
 #ifdef CONFIG_DOS_PARTITION
        case PART_TYPE_DOS:
-#ifdef DEBUG
-               printf ("## Testing for valid DOS partition ##\n");
+               PRINTF ("## Testing for valid DOS partition ##\n");
+               print_part_header ("DOS", dev_desc);
+               print_part_dos (dev_desc);
+               return;
 #endif
-               print_part_header ("DOS", dev);
-               print_part_dos (dev);
+
+#ifdef CONFIG_ISO_PARTITION
+       case PART_TYPE_ISO:
+               PRINTF ("## Testing for valid ISO Boot partition ##\n");
+               print_part_header ("ISO", dev_desc);
+               print_part_iso (dev_desc);
                return;
 #endif
        }
        printf ("## Unknown partition table\n");
 }
 
-#else  /* neither MAC nor DOS partition configured */
-# error neither CONFIG_MAC_PARTITION nor CONFIG_DOS_PARTITION configured!
+
+#else  /* neither MAC nor DOS nor ISO partition configured */
+# error neither CONFIG_MAC_PARTITION nor CONFIG_DOS_PARTITION nor CONFIG_ISO_PARTITION configured!
 #endif
 
-#endif /* (CONFIG_COMMANDS & CFG_CMD_IDE) */
+#endif /* (CONFIG_COMMANDS & CFG_CMD_IDE) || CONFIG_COMMANDS & CFG_CMD_SCSI) */
index 3949e6af4dcb4e02ad584c766c3224b1b616e724..ff62614ddcddf6d625ea11d559f6bc3d5cd6f757 100644 (file)
@@ -36,7 +36,7 @@
 #include <cmd_disk.h>
 #include "part_dos.h"
 
-#if (CONFIG_COMMANDS & CFG_CMD_IDE) && defined(CONFIG_DOS_PARTITION)
+#if ((CONFIG_COMMANDS & CFG_CMD_IDE) || (CONFIG_COMMANDS & CFG_CMD_SCSI)) && defined(CONFIG_DOS_PARTITION)
 
 /* Convert char[4] in little endian format to the host format integer
  */
@@ -66,11 +66,13 @@ static void print_one_part (dos_partition_t *p, int ext_part_sector, int part_nu
                (is_extended (p->sys_ind) ? " Extd" : ""));
 }
 
-int test_part_dos (int dev)
+
+
+int test_part_dos (block_dev_desc_t *dev_desc)
 {
        unsigned char buffer[DEFAULT_SECTOR_SIZE];
 
-       if ((ide_read (dev, 0, 1, (ulong *) buffer) != 1) ||
+       if ((dev_desc->block_read(dev_desc->dev, 0, 1, (ulong *) buffer) != 1) ||
            (buffer[DOS_PART_MAGIC_OFFSET + 0] != 0x55) ||
            (buffer[DOS_PART_MAGIC_OFFSET + 1] != 0xaa) ) {
                return (-1);
@@ -78,19 +80,18 @@ int test_part_dos (int dev)
        return (0);
 }
 
-
 /*  Print a partition that is relative to its Extended partition table
  */
-static void print_partition_extended (int dev, int ext_part_sector, int relative,
+static void print_partition_extended (block_dev_desc_t *dev_desc, int ext_part_sector, int relative,
                                                           int part_num)
 {
        unsigned char buffer[DEFAULT_SECTOR_SIZE];
        dos_partition_t *pt;
        int i;
 
-       if (ide_read (dev, ext_part_sector, 1, (ulong *) buffer) != 1) {
+       if (dev_desc->block_read(dev_desc->dev, ext_part_sector, 1, (ulong *) buffer) != 1) {
                printf ("** Can't read partition table on %d:%d **\n",
-                       dev, ext_part_sector);
+                       dev_desc->dev, ext_part_sector);
                return;
        }
        if (buffer[DOS_PART_MAGIC_OFFSET] != 0x55 ||
@@ -127,7 +128,7 @@ static void print_partition_extended (int dev, int ext_part_sector, int relative
                if (is_extended (pt->sys_ind)) {
                        int lba_start = le32_to_int (pt->start4) + relative;
 
-                       print_partition_extended (dev, lba_start,
+                       print_partition_extended (dev_desc, lba_start,
                                                  ext_part_sector == 0  ? lba_start
                                                                        : relative,
                                                  part_num);
@@ -140,7 +141,7 @@ static void print_partition_extended (int dev, int ext_part_sector, int relative
 
 /*  Print a partition that is relative to its Extended partition table
  */
-static int get_partition_info_extended (int dev, int ext_part_sector,
+static int get_partition_info_extended (block_dev_desc_t *dev_desc, int ext_part_sector,
                                 int relative, int part_num,
                                 int which_part, disk_partition_t *info)
 {
@@ -148,9 +149,9 @@ static int get_partition_info_extended (int dev, int ext_part_sector,
        dos_partition_t *pt;
        int i;
 
-       if (ide_read (dev, ext_part_sector, 1, (ulong *) buffer) != 1) {
+       if (dev_desc->block_read (dev_desc->dev, ext_part_sector, 1, (ulong *) buffer) != 1) {
                printf ("** Can't read partition table on %d:%d **\n",
-                       dev, ext_part_sector);
+                       dev_desc->dev, ext_part_sector);
                return -1;
        }
        if (buffer[DOS_PART_MAGIC_OFFSET] != 0x55 ||
@@ -172,8 +173,18 @@ static int get_partition_info_extended (int dev, int ext_part_sector,
                        info->blksz = 512;
                        info->start = ext_part_sector + le32_to_int (pt->start4);
                        info->size  = le32_to_int (pt->size4);
-                       sprintf (info->name, "hd%c%d\n", 'a' + dev, part_num);
-                       // sprintf(info->type, "%d, pt->sys_ind);
+                       switch(dev_desc->if_type) {
+                               case IF_TYPE_IDE:
+                                       sprintf (info->name, "hd%c%d\n", 'a' + dev_desc->dev, part_num);
+                                       break;
+                               case IF_TYPE_SCSI:
+                                       sprintf (info->name, "sd%c%d\n", 'a' + dev_desc->dev, part_num);
+                                       break;
+                               default:
+                                       sprintf (info->name, "xx%c%d\n", 'a' + dev_desc->dev, part_num);
+                                       break;
+                       }
+                       /* sprintf(info->type, "%d, pt->sys_ind); */
                        sprintf (info->type, "PPCBoot");
                        return 0;
                }
@@ -191,7 +202,7 @@ static int get_partition_info_extended (int dev, int ext_part_sector,
                if (is_extended (pt->sys_ind)) {
                        int lba_start = le32_to_int (pt->start4) + relative;
 
-                       return get_partition_info_extended (dev, lba_start,
+                       return get_partition_info_extended (dev_desc, lba_start,
                                 ext_part_sector == 0 ? lba_start : relative,
                                 part_num, which_part, info);
                }
@@ -199,15 +210,17 @@ static int get_partition_info_extended (int dev, int ext_part_sector,
        return -1;
 }
 
-void print_part_dos (int dev)
+void print_part_dos (block_dev_desc_t *dev_desc)
 {
        printf ("Partition     Start Sector     Num Sectors     Type\n");
-       print_partition_extended (dev, 0, 0, 1);
+       print_partition_extended (dev_desc, 0, 0, 1);
 }
 
-int get_partition_info_dos (int dev, int part, disk_partition_t * info)
+int get_partition_info_dos (block_dev_desc_t *dev_desc, int part, disk_partition_t * info)
 {
-       return get_partition_info_extended (dev, 0, 0, 1, part, info);
+       return get_partition_info_extended (dev_desc, 0, 0, 1, part, info);
 }
 
+
+
 #endif /* (CONFIG_COMMANDS & CFG_CMD_IDE) && CONFIG_DOS_PARTITION */
diff --git a/disk/part_iso.c b/disk/part_iso.c
new file mode 100644 (file)
index 0000000..b1369a7
--- /dev/null
@@ -0,0 +1,241 @@
+/*
+ * (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
+ */
+
+#include <ppcboot.h>
+#include <command.h>
+#include <cmd_disk.h>
+#include "part_iso.h"
+
+#if ((CONFIG_COMMANDS & CFG_CMD_IDE) || (CONFIG_COMMANDS & CFG_CMD_SCSI)) && defined(CONFIG_ISO_PARTITION)
+
+#undef ISO_PART_DEBUG
+
+#ifdef ISO_PART_DEBUG
+#define        PRINTF(fmt,args...)     printf (fmt ,##args)
+#else
+#define PRINTF(fmt,args...)
+#endif
+
+#define CD_SECTSIZE 2048
+
+static unsigned char tmpbuf[CD_SECTSIZE];
+/* Convert char[4] in little endian format to the host format integer
+ */
+static inline unsigned long le32_to_int(unsigned char *le32)
+{
+    return ((le32[3] << 24) +
+           (le32[2] << 16) +
+           (le32[1] << 8) +
+            le32[0]
+          );
+}
+
+/* only boot records will be listed as valid partitions */ 
+int get_partition_info_iso_verb(block_dev_desc_t * dev_desc, int part_num, disk_partition_t * info, int verb)
+{
+       int i,offset,entry_num;
+       unsigned short *chksumbuf;
+       unsigned short chksum;
+       unsigned long newblkaddr,blkaddr,lastsect,bootaddr;
+       iso_boot_rec_t *pbr = (iso_boot_rec_t   *)tmpbuf; /* boot record */
+       iso_pri_rec_t *ppr = (iso_pri_rec_t     *)tmpbuf;       /* primary desc */
+       iso_val_entry_t *pve = (iso_val_entry_t *)tmpbuf;
+       iso_init_def_entry_t *pide;     
+       iso_header_entry_t *phe;        
+
+       /* the first sector (sector 0x10) must be a primary volume desc */
+       blkaddr=PVD_OFFSET;
+       if (dev_desc->block_read (dev_desc->dev, PVD_OFFSET, 1, (ulong *) tmpbuf) != 1)
+       return (-1);
+       if(ppr->desctype!=0x01) {
+               if(verb)
+                       printf(" first descriptor is NOT a primary desc\n");
+               return (-1);
+       }
+       if(strncmp(ppr->stand_ident,"CD001",5)!=0) {
+               if(verb)
+                       printf("ISO Ident: %s wrong\n",ppr->stand_ident);
+               return (-1);
+       }
+       lastsect= ((ppr->firstsek_LEpathtab1_LE & 0xff)<<24) +
+                                               ((ppr->firstsek_LEpathtab1_LE & 0xff00)<<8) +
+                                               ((ppr->firstsek_LEpathtab1_LE & 0xff0000)>>8) +
+                                               ((ppr->firstsek_LEpathtab1_LE & 0xff000000)>>24);
+       info->blksz=ppr->secsize_BE; /* assuming same block size for all entries */
+       PRINTF(" Lastsect:%08lx\n",lastsect);
+       for(i=blkaddr;i<lastsect;i++) {
+               if (dev_desc->block_read (dev_desc->dev, i, 1, (ulong *) tmpbuf) != 1)
+               return (-1);
+               if(ppr->desctype==0x00)
+                       break; /* boot entry found */
+               if(ppr->desctype==0xff) {
+                       if(verb)
+                               printf(" No valid boot catalog found\n");
+                       return (-1);
+               }
+       }
+       /* boot entry found */
+       if(strncmp(pbr->ident_str,"EL TORITO SPECIFICATION",23)!=0) {
+               if(verb)
+                       printf("Ident: %s wrong\n",pbr->ident_str);
+               return (-1);
+       }
+       bootaddr=le32_to_int(pbr->pointer);
+       PRINTF(" Boot Entry at: %08lX\n",bootaddr);
+       if (dev_desc->block_read (dev_desc->dev, bootaddr, 1, (ulong *) tmpbuf) != 1)
+               return (-1);
+       chksum=0;
+       chksumbuf = (unsigned short *)tmpbuf;
+       for(i=0;i<0x10;i++)
+               chksum+=((chksumbuf[i] &0xff)<<8)+((chksumbuf[i] &0xff00)>>8);
+       if(chksum!=0) {
+               if(verb)
+                       printf(" checksum Error in booting catalog validation entry\n");
+               return (-1);
+       }
+       if((pve->key[0]!=0x55)||(pve->key[1]!=0xAA)) {
+               if(verb)
+                       printf(" key 0x55 0xAA error\n");
+               return(-1);
+       }
+       /* the validation entry seems to be ok, now search the "partition" */
+       entry_num=0;
+       offset=0x20;
+       if(part_num==0) { /* the default partition */                   
+               #if 0
+               if(pve->platform!=0x01) {
+                       if(verb)
+                               printf(" default entry is no PowerPC partition\n");
+                       return(-1);
+               }
+               #endif
+               sprintf(info->name,"%.32s",pve->manu_str); 
+               sprintf (info->type, "PPCBoot");
+               pide=(iso_init_def_entry_t *)&tmpbuf[offset];
+               goto found;
+       }
+       /* partition is not the default partition */
+       offset+=0x20;
+       while(1) {
+               phe=(iso_header_entry_t *)&tmpbuf[offset];
+               if((phe->header_id & 0xfe)!=0x90) { /* no valid header ID */
+                       if(verb)
+                               printf(" part %d not found\n",part_num);
+                       return(-1);
+               }
+               if((entry_num+(phe->numentry[1]<<8)+phe->numentry[0])>=part_num) { /* partition lies in this header */
+                       #if 0
+                       if(phe->platform!=0x01) {
+                               if(verb)
+                                       printf(" part %d is no PowerPC partition\n",part_num);
+                               return(-1);
+                       }
+                       #endif
+                       sprintf(info->type,"%.32s",phe->id_str);
+                       entry_num++;
+                       offset+=0x20;
+                       while(entry_num!=part_num) {
+                               offset+=0x20;
+                               while(tmpbuf[offset]==0x44)
+                                       offset+=0x20; /* skip extension records */
+                               entry_num++;
+                       }
+                       /* part entry should be here */
+                       pide=(iso_init_def_entry_t *)&tmpbuf[offset];
+                       goto found;
+               }
+               else { /* search next header */
+                       if((phe->header_id)==0x91) { /* last header ID */
+                               if(verb)
+                                       printf(" part %d not found\n",part_num);
+                               return(-1);
+                       }
+                       entry_num+=((phe->numentry[1]<<8)+phe->numentry[0]); /* count partitions */
+                       offset+=0x20;
+                       while((tmpbuf[offset]=0x44) || /* skip extension records */
+                                               (tmpbuf[offset]=0x88) || /* skip boot entries */
+                                               (tmpbuf[offset]=0x00)) {         /* skip no boot entries */
+                               offset+=0x20;
+                               if(offset>=CD_SECTSIZE) { /* to prevent overflow */
+                                       if(verb)
+                                               printf(" part %d not found\n",part_num);
+                                       return(-1);
+                               }
+                       } /* while skipping all unused records */
+               } /* else */
+       } /* while(TRUE) */
+found:                         
+       if(pide->boot_ind!=0x88) {
+               if(verb)
+                       printf(" part %d is not bootable\n",part_num);
+               return (-1);
+       }
+       switch(pide->boot_media) {
+               case 0x00:      info->size=2880>>2; break; /* dummy (No Emulation) */
+               case 0x01:      info->size=2400>>2; break; /* 1.2MByte Floppy */
+               case 0x02:      info->size=2880>>2; break; /* 1.44MByte Floppy */
+               case 0x03:      info->size=5760>>2; break; /* 2.88MByte Floppy */
+               case 0x04:      info->size=2880>>2; break; /* dummy (HD Emulation) */
+               default:                info->size=0; break;
+       }
+       newblkaddr=le32_to_int(pide->rel_block_addr);
+       info->start=newblkaddr;
+       if(verb)
+               printf(" part %d found @ %lx size %lx\n",part_num,newblkaddr,info->size);
+       return 0;
+}              
+
+int get_partition_info_iso(block_dev_desc_t * dev_desc, int part_num, disk_partition_t * info)
+{
+       return(get_partition_info_iso_verb(dev_desc, part_num, info, 0));
+}
+
+                                               
+                                                                                               
+void print_part_iso(block_dev_desc_t * dev_desc)
+{
+       disk_partition_t info;
+       int i;
+       if(get_partition_info_iso_verb(dev_desc,0,&info,0)==-1) {
+               printf("** No boot partition found on device %d **\n",dev_desc->dev);
+               return;
+       }
+       printf("Part   Start     Sect x Size Type\n"); 
+       i=0;
+       do {
+               printf(" %2d %8ld %8ld %6ld %.32s\n",i,info.start,info.size,info.blksz,info.type);
+               i++;
+       }while(get_partition_info_iso_verb(dev_desc,i,&info,0)!=-1);
+}
+
+int test_part_iso (block_dev_desc_t *dev_desc)
+{
+       disk_partition_t info;
+
+       return(get_partition_info_iso_verb(dev_desc,0,&info,0));
+}
+
+#endif /* ((CONFIG_COMMANDS & CFG_CMD_IDE) || (CONFIG_COMMANDS & CFG_CMD_SCSI)) && defined(CONFIG_ISO_PARTITION) */
+
+
diff --git a/disk/part_iso.h b/disk/part_iso.h
new file mode 100644 (file)
index 0000000..2c733a3
--- /dev/null
@@ -0,0 +1,171 @@
+/*
+ * (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
+ */
+#ifndef _PART_CD_H
+#define _PART_CD_H
+
+#define BRVD   0x11
+#define PVD_OFFSET 0x10
+
+
+typedef struct iso_boot_rec {
+       unsigned char desctype;                 /* type of Volume descriptor: 0 = boot record, 1 = primary, 2 = Supplement, 3 = volume part 0xff trminator */
+       unsigned char stand_ident[5]; /* "CD001" */
+       unsigned char vers;                                     /* Version */
+       char                                    ident_str[0x20]; /* Ident String "EL TORITO SPECIFICATION" */
+       unsigned char unused[0x20];             /* unused */
+       unsigned char pointer[4];               /* absolute pointer to Boot Catalog */
+} iso_boot_rec_t;
+       
+
+typedef struct iso_pri_rec {  
+       unsigned char desctype;                 /* type of Volume descriptor: 0 = boot record, 1 = primary, 2 = Supplement, 3 = volume part 0xff trminator */
+       unsigned char stand_ident[5]; /* "CD001" */
+       unsigned char vers;                                     /* Version */
+       unsigned char unused;
+       char                                    sysid[32];              /* system Identifier */
+       char                                    volid[32];              /* volume Identifier */
+       unsigned char zeros1[8];                /* unused */
+       unsigned long volsiz_LE;                /* volume size Little Endian */
+       unsigned long volsiz_BE;                /* volume size Big Endian */
+       unsigned char zeros2[32];               /* unused */
+       unsigned short setsize_LE;      /* volume set size LE */
+       unsigned short setsize_BE;      /* volume set size BE */
+       unsigned short seqnum_LE;               /* volume sequence number LE */
+       unsigned short seqnum_BE;               /* volume sequence number BE */
+       unsigned short secsize_LE;      /* sector size LE */
+       unsigned short secsize_BE;      /* sector size BE */
+       unsigned long pathtablen_LE;/* Path Table size LE */
+       unsigned long pathtablen_BE;/* Path Table size BE */
+       unsigned long firstsek_LEpathtab1_LE; /* location of first occurrence of little endian type path table */
+       unsigned long firstsek_LEpathtab2_LE; /* location of optional occurrence of little endian type path table */
+       unsigned long firstsek_BEpathtab1_BE; /* location of first occurrence of big endian type path table */
+       unsigned long firstsek_BEpathtab2_BE; /* location of optional occurrence of big endian type path table */
+       unsigned char rootdir[34];      /* directory record for root dir */
+       char                                    volsetid[128];/* Volume set identifier */
+       char                                    pubid[128];             /* Publisher identifier */
+       char                                    dataprepid[128]; /* data preparer identifier */
+       char                                    appid[128];             /* application identifier */
+       char                                    copyr[37];              /* copyright string */
+       char                                    abstractfileid[37]; /* abstract file identifier */
+       char                                    bibliofileid[37]; /* bibliographic file identifier */
+       unsigned char creationdate[17]; /* creation date */
+       unsigned char modify[17];               /* modification date */
+       unsigned char expire[17];               /* expiring date */
+       unsigned char effective[17];/* effective date */
+       unsigned char filestruc_ver;    /* file structur version */
+} iso_pri_rec_t;   
+
+typedef struct iso_sup_rec {  
+       unsigned char desctype;                 /* type of Volume descriptor: 0 = boot record, 1 = primary, 2 = Supplement, 3 = volume part 0xff trminator */
+       unsigned char stand_ident[5]; /* "CD001" */
+       unsigned char vers;                                     /* Version */
+       unsigned char volumeflags;      /* if bit 0 = 0 => all escape sequences are according ISO 2375 */
+       char                                    sysid[32];              /* system Identifier */
+       char                                    volid[32];              /* volume Identifier */
+       unsigned char zeros1[8];                /* unused */
+       unsigned long volsiz_LE;                /* volume size Little Endian */
+       unsigned long volsiz_BE;                /* volume size Big Endian */
+       unsigned char escapeseq[32];/* Escape sequences */
+       unsigned short setsize_LE;      /* volume set size LE */
+       unsigned short setsize_BE;      /* volume set size BE */
+       unsigned short seqnum_LE;               /* volume sequence number LE */
+       unsigned short seqnum_BE;               /* volume sequence number BE */
+       unsigned short secsize_LE;      /* sector size LE */
+       unsigned short secsize_BE;      /* sector size BE */
+       unsigned long pathtablen_LE;/* Path Table size LE */
+       unsigned long pathtablen_BE;/* Path Table size BE */
+       unsigned long firstsek_LEpathtab1_LE; /* location of first occurrence of little endian type path table */
+       unsigned long firstsek_LEpathtab2_LE; /* location of optional occurrence of little endian type path table */
+       unsigned long firstsek_BEpathtab1_BE; /* location of first occurrence of big endian type path table */
+       unsigned long firstsek_BEpathtab2_BE; /* location of optional occurrence of big endian type path table */
+       unsigned char rootdir[34];      /* directory record for root dir */
+       char                                    volsetid[128];/* Volume set identifier */
+       char                                    pubid[128];             /* Publisher identifier */
+       char                                    dataprepid[128]; /* data preparer identifier */
+       char                                    appid[128];             /* application identifier */
+       char                                    copyr[37];              /* copyright string */
+       char                                    abstractfileid[37]; /* abstract file identifier */
+       char                                    bibliofileid[37]; /* bibliographic file identifier */
+       unsigned char creationdate[17]; /* creation date */
+       unsigned char modify[17];               /* modification date */
+       unsigned char expire[17];               /* expiring date */
+       unsigned char effective[17];/* effective date */
+       unsigned char filestruc_ver;    /* file structur version */
+}iso_sup_rec_t;
+
+typedef struct iso_part_rec {  
+       unsigned char desctype;                 /* type of Volume descriptor: 0 = boot record, 1 = primary, 2 = Supplement, 3 = volume part 0xff trminator */
+       unsigned char stand_ident[5]; /* "CD001" */
+       unsigned char vers;                                     /* Version */
+       unsigned char unused;
+       char                                    sysid[32];               /* system Identifier */
+       char                                    volid[32];              /* volume partition Identifier */
+       unsigned long partloc_LE;               /* volume partition location LE */
+       unsigned long partloc_BE;               /* volume partition location BE */
+       unsigned long partsiz_LE;               /* volume partition size LE */
+       unsigned long partsiz_BE;               /* volume partition size BE */
+}iso_part_rec_t;
+
+
+
+
+typedef struct iso_val_entry {
+       unsigned char   header_id;              /* Header ID must be 0x01 */
+       unsigned char   platform;                       /* Platform: 0=x86, 1=PowerPC, 2=MAC */
+       unsigned char res[2];                           /* reserved */
+       char                                    manu_str[0x18]; /* Ident String of manufacturer/developer */
+       unsigned char chk_sum[2];       /* Check sum (all words must be zero)  */
+       unsigned char key[2];                           /* key[0]=55, key[1]=0xAA */
+} iso_val_entry_t;
+
+typedef struct iso_header_entry {
+       unsigned char   header_id;              /* Header ID must be 0x90 or 0x91 */
+       unsigned char   platform;                       /* Platform: 0=x86, 1=PowerPC, 2=MAC */
+       unsigned char numentry[2];      /* number of entries */
+       char                                    id_str[0x1C]; /* Ident String of sectionr */
+} iso_header_entry_t;
+
+
+typedef struct iso_init_def_entry {
+       unsigned char   boot_ind;                       /* Boot indicator 0x88=bootable 0=not bootable */
+       unsigned char   boot_media;             /* boot Media Type: 0=no Emulation, 1=1.2MB floppy, 2=1.44MB floppy, 3=2.88MB floppy 4=hd (0x80) */
+       unsigned char ld_seg[2];                /* Load segment (flat model=addr/10) */
+       unsigned char systype;                  /* System Type copy of byte5 of part table */
+       unsigned char res;                                      /* reserved */
+       unsigned char sec_cnt[2];               /* sector count in VIRTUAL Blocks (0x200) */
+       unsigned char rel_block_addr[4];        /* relative Block address */
+} iso_init_def_entry_t;
+
+
+void print_partition_cd(int dev);
+
+
+
+
+
+
+
+
+#endif /* _PART_CD_H */
+
+
index 3ecbb972845281a46ce363b37a927d62da4aa09c..97831055f358bb35dc73cb77c6992ef5e08dcdb2 100644 (file)
@@ -35,7 +35,7 @@
 #include <cmd_disk.h>
 #include "part_mac.h"
 
-#if (CONFIG_COMMANDS & CFG_CMD_IDE) && defined(CONFIG_MAC_PARTITION)
+#if ((CONFIG_COMMANDS & CFG_CMD_IDE) || (CONFIG_COMMANDS & CFG_CMD_SCSI)) && defined(CONFIG_MAC_PARTITION)
 
 /* stdlib.h causes some compatibility problems; should fixe these! -- wd */
 #ifndef __ldiv_t_defined
@@ -48,26 +48,26 @@ extern ldiv_t ldiv (long int __numer, long int __denom);
 #endif
 
 
-static int part_mac_read_ddb (int dev, mac_driver_desc_t *ddb_p);
-static int part_mac_read_pdb (int dev, int part, mac_partition_t *pdb_p);
+static int part_mac_read_ddb (block_dev_desc_t *dev_desc, mac_driver_desc_t *ddb_p);
+static int part_mac_read_pdb (block_dev_desc_t *dev_desc, int part, mac_partition_t *pdb_p);
 
 /*
  * Test for a valid MAC partition
  */
-int test_part_mac (int dev)
+int test_part_mac (block_dev_desc_t *dev_desc)
 {
        mac_driver_desc_t       ddesc;
        mac_partition_t         mpart;
        ulong i, n;
 
-       if (part_mac_read_ddb (dev, &ddesc)) {
+       if (part_mac_read_ddb (dev_desc, &ddesc)) {
                /* error reading Driver Desriptor Block, or no valid Signature */
                return (-1);
        }
 
        n = 1;  /* assuming at least one partition */
        for (i=1; i<=n; ++i) {
-               if ((ide_read (dev, i, 1, (ulong *)&mpart) != 1) ||
+               if ((dev_desc->block_read(dev_desc->dev, i, 1, (ulong *)&mpart) != 1) ||
                    (mpart.signature != MAC_PARTITION_MAGIC) ) {
                        return (-1);
                }
@@ -78,14 +78,14 @@ int test_part_mac (int dev)
 }
 
 
-void print_part_mac (int dev)
+void print_part_mac (block_dev_desc_t *dev_desc)
 {
        ulong i, n;
        mac_driver_desc_t       ddesc;
        mac_partition_t         mpart;
        ldiv_t mb, gb;
 
-       if (part_mac_read_ddb (dev, &ddesc)) {
+       if (part_mac_read_ddb (dev_desc, &ddesc)) {
                /* error reading Driver Desriptor Block, or no valid Signature */
                return;
        }
@@ -120,16 +120,16 @@ void print_part_mac (int dev)
                char c;
 
                printf ("%4ld: ", i);
-               if (ide_read (dev, i, 1, (ulong *)&mpart) != 1) {
+               if (dev_desc->block_read (dev_desc->dev, i, 1, (ulong *)&mpart) != 1) {
                        printf ("** Can't read Partition Map on %d:%ld **\n",
-                               dev, i);
+                               dev_desc->dev, i);
                        return;
                }
 
                if (mpart.signature != MAC_PARTITION_MAGIC) {
                        printf ("** Bad Signature on %d:%ld - "
                                "expected 0x%04x, got 0x%04x\n",
-                               dev, i, MAC_PARTITION_MAGIC, mpart.signature);
+                               dev_desc->dev, i, MAC_PARTITION_MAGIC, mpart.signature);
                        return;
                }
 
@@ -164,9 +164,9 @@ void print_part_mac (int dev)
 /*
  * Read Device Descriptor Block
  */
-static int part_mac_read_ddb (int dev, mac_driver_desc_t *ddb_p)
+static int part_mac_read_ddb (block_dev_desc_t *dev_desc, mac_driver_desc_t *ddb_p)
 {
-       if (ide_read (dev, 0, 1, (ulong *)ddb_p) != 1) {
+       if (dev_desc->block_read(dev_desc->dev, 0, 1, (ulong *)ddb_p) != 1) {
                printf ("** Can't read Driver Desriptor Block **\n");
                return (-1);
        }
@@ -184,7 +184,7 @@ static int part_mac_read_ddb (int dev, mac_driver_desc_t *ddb_p)
 /*
  * Read Partition Descriptor Block
  */
-static int part_mac_read_pdb (int dev, int part, mac_partition_t *pdb_p)
+static int part_mac_read_pdb (block_dev_desc_t *dev_desc, int part, mac_partition_t *pdb_p)
 {
        int n = 1;
 
@@ -194,16 +194,16 @@ static int part_mac_read_pdb (int dev, int part, mac_partition_t *pdb_p)
                  * partition 1 first since this is the only way to
                  * know how many partitions we have.
                 */
-               if (ide_read (dev, n, 1, (ulong *)pdb_p) != 1) {
+               if (dev_desc->block_read (dev_desc->dev, n, 1, (ulong *)pdb_p) != 1) {
                        printf ("** Can't read Partition Map on %d:%d **\n",
-                               dev, n);
+                               dev_desc->dev, n);
                        return (-1);
                }
 
                if (pdb_p->signature != MAC_PARTITION_MAGIC) {
                        printf ("** Bad Signature on %d:%d: "
                                "expected 0x%04x, got 0x%04x\n",
-                               dev, n, MAC_PARTITION_MAGIC, pdb_p->signature);
+                               dev_desc->dev, n, MAC_PARTITION_MAGIC, pdb_p->signature);
                        return (-1);
                }
 
@@ -212,9 +212,9 @@ static int part_mac_read_pdb (int dev, int part, mac_partition_t *pdb_p)
 
                if ((part < 1) || (part > pdb_p->map_count)) {
                        printf ("** Invalid partition %d:%d [%d:1...%d:%d only]\n",
-                               dev, part,
-                               dev,
-                               dev, pdb_p->map_count);
+                               dev_desc->dev, part,
+                               dev_desc->dev,
+                               dev_desc->dev, pdb_p->map_count);
                        return (-1);
                }
 
@@ -225,18 +225,18 @@ static int part_mac_read_pdb (int dev, int part, mac_partition_t *pdb_p)
        /* NOTREACHED */
 }
 
-int get_partition_info_mac (int dev, int part, disk_partition_t *info)
+int get_partition_info_mac (block_dev_desc_t *dev_desc, int part, disk_partition_t *info)
 {
        mac_driver_desc_t       ddesc;
        mac_partition_t         mpart;
 
-       if (part_mac_read_ddb (dev, &ddesc)) {
+       if (part_mac_read_ddb (dev_desc, &ddesc)) {
                return (-1);
        }
 
        info->blksz = ddesc.blk_size;
 
-       if (part_mac_read_pdb (dev, part, &mpart)) {
+       if (part_mac_read_pdb (dev_desc, part, &mpart)) {
                return (-1);
        }
 
diff --git a/doc/README.PIP405 b/doc/README.PIP405
new file mode 100644 (file)
index 0000000..1ffc056
--- /dev/null
@@ -0,0 +1,382 @@
+PPCBoot Changes due to PIP405 Port:
+===================================
+
+Changed files:
+==============
+- MAKEALL                       added PIP405
+- makefile                      added PIP405
+- common/Makefile               added Floppy disk and SCSI support
+- common/board.c                added PIP405, SCSI support, get_PCI_freq()
+- common/bootm.c                added IH_OS_PPCBOOT, IH_TYPE_FIRMWARE
+- common/cmd_i2c.c              added "defined(CONFIG_PIP405)"
+- common/cmd_ide.c              changed div. functions to work with block device
+                                description
+                                added ATAPI support
+- common/command.c              added SCSI and Floppy support
+- common/console.c              replaced // with /* comments
+                                added console settings from environment
+- common/devices.c              added ISA keyboard init
+- common/main.c                 corrected the read of bootdelay
+- cpu/ppc4xx/405gp_pci.c        excluded file from PIP405
+- cpu/ppc4xx/i2c.c              added 16bit read write I2C support
+                                added page write
+- cpu/ppc4xx/speed.c            added get_PCI_freq
+- cpu/ppc4xx/start.S            added CONFIG_IDENT_STRING
+- disk/Makefile                 added part_iso for CD support
+- disk/part.c                   changed to work with block device description
+                                added ISO CD support
+                                added dev_print (was ide_print in cmd_ide.c)
+- disk/part_dos.c               changed to work with block device description
+- disk/part_mac.c               changed to work with block device description
+- include/ata.h                 added ATAPI commands
+- include/cmd_bsp.h             added PIP405 commands definitions
+- include/cmd_condefs.h         added Floppy and SCSI support
+- include/cmd_disk.h            changed to work with block device description
+- include/config_LANTEC.h       excluded CFG_CMD_FDC and CFG_CMD_SCSI from
+                                CONFIG_CMD_FULL
+- include/config_hymod.h        excluded CFG_CMD_FDC and CFG_CMD_SCSI from
+                                CONFIG_CMD_FULL
+- include/flash.h               added INTEL_ID_28F320C3T  0x88C488C4
+- include/i2c.h                 added "defined(CONFIG_PIP405)"
+- include/image.h               added IH_OS_PPCBOOT, IH_TYPE_FIRMWARE
+- include/ppcboot.h             moved partitions functions definitions to part.h
+                                added "defined(CONFIG_PIP405)"
+                                added get_PCI_freq() definition
+- rtc/Makefile                  added MC146818 RTC support
+- tools/mkimage.c               added IH_OS_PPCBOOT, IH_TYPE_FIRMWARE
+
+Added files:
+============
+- board/pip405                  directory for PIP405
+- board/pip405/cmd_pip405.c     board specific commands
+- board/pip405/config.mk        config make
+- board/pip405/flash.c          flash support
+- board/pip405/init.s           start-up
+- board/pip405/kbd.c            keyboard support
+- board/pip405/kbd.h            keyboard support
+- board/pip405/Makefile         Makefile
+- board/pip405/pci_piix4.h      southbridge definitions
+- board/pip405/pci_pip405.c     PCI support for PIP405
+- board/pip405/pci_pip405.h     PCI support for PIP405
+- board/pip405/pip405.c         PIP405 board init
+- board/pip405/pip405.h         PIP405 board init
+- board/pip405/pip405_isa.c     ISA support
+- board/pip405/pip405_isa.h     ISA support
+- board/pip405/ppcboot.lds      Linker description
+- board/pip405/ppcboot.lds.debugLinker description debug
+- board/pip405/sym53c8xx.c      SYM53C810A support
+- board/pip405/sym53c8xx_defs.h SYM53C810A definitions
+- board/pip405/vga_table.h      definitions of tables for VGA
+- board/pip405/video.c          CT69000 support
+- board/pip405/video.h          CT69000 support
+- common/cmd_fdc.c              Floppy disk support
+- common/cmd_scsi.c             SCSI support
+- disk/part_iso.c               ISO CD ROM support
+- disk/part_iso.h               ISO CD ROM support
+- include/cmd_fdc.h             command forFloppy disk support
+- include/cmd_scsi.h            command for SCSI support
+- include/part.h                partitions functions definitions
+                                (was part of ppcboot.h)
+- include/scsi.h                SCSI support
+- rtc/mc146818.c                MC146818 RTC support
+
+
+New Config Switches:
+====================
+For detailed description, refer to the corresponding paragraph in the
+section "Changes".
+
+New Commands:
+-------------
+CFG_CMD_SCSI    SCSI Support
+CFG_CMF_FDC     Floppy disk support
+
+IDE additions:
+--------------
+CONFIG_IDE_RESET_ROUTINE        defines that instead of a reset Pin,
+                                the routine ide_set_reset(int idereset) is used.
+ATAPI support (experimental)
+----------------------------
+CONFIG_ATAPI   enables ATAPI Support
+
+SCSI support (experimental) only SYM53C8xx supported
+----------------------------------------------------
+CONFIG_SCSI_SYM53C8XX           type of SCSI controller
+CFG_SCSI_MAX_LUN       8       number of supported LUNs
+CFG_SCSI_MAX_SCSI_ID   7       maximum SCSI ID (0..6)
+CFG_SCSI_MAX_DEVICE    CFG_SCSI_MAX_SCSI_ID * CFG_SCSI_MAX_LUN
+                                maximum of Target devices (multiple LUN support
+                                for boot)
+
+ISO (CD-Boot) partition support (Experimental)
+----------------------------------------------
+CONFIG_ISO_PARTITION            CD-boot support
+
+RTC
+----
+CONFIG_RTC_MC146818             MC146818 RTC support
+
+Keyboard:
+---------
+CONFIG_ISA_KEYBOARD             Standard (PC-Style) Keyboard support
+
+Video:
+------
+CONFIG_VIDEO_CT69000            Enable Chips & Technologies 69000 Video chip
+                                CONFIG_VIDEO must be defined also
+
+External peripheral base address:
+---------------------------------
+CFG_ISA_IO_BASE_ADDRESS         address of all ISA-bus related parts
+                                _must_ be defined for ISA-bus parts
+
+Identify:
+---------
+CONFIG_IDENT_STRING             added to the PPCBOOT_VERSION String
+
+
+I2C stuff:
+----------
+CFG_EEPROM_PAGE_WRITE_ENABLE    enables page write of the I2C EEPROM
+                                CFG_EEPROM_PAGE_WRITE_BITS _must_ be
+                                defined.
+
+
+Environment / Console:
+----------------------
+CFG_CONSOLE_IS_IN_ENV           if defined, stdin, stdout and stderr used from
+                                the values stored in the evironment.
+CFG_CONSOLE_OVERWRITE_ROUTINE   if defined, console_overwrite() decides if the
+                                values stored in the environment or the standard
+                                serial in/out put should be assigned to the console.
+CFG_CONSOLE_ENV_OVERWRITE       if defined, the start-up console switching
+                                are stored in the environment.
+
+PIP405 specific:
+----------------
+CONFIG_PORT_ADDR                address used to read boot configuration
+MULTI_PURPOSE_SOCKET_ADDR       address of the multi purpose socked
+SDRAM_EEPROM_WRITE_ADDRESS      addresses of the serial presence detect
+SDRAM_EEPROM_READ_ADDRESS       EEPROM on the SDRAM module.
+
+
+Changes:
+========
+
+Added Devices:
+==============
+
+Floppy support:
+---------------
+Support of a standard floppy disk controller at address CFG_ISA_IO_BASE_ADDRESS
++ 0x3F0. Enabled with define CFG_CMD_FDC. Reads a unformated floppy disk with a
+image header (see: mkimage). No interrupts and no DMA are used for this.
+Added files:
+- common/cmd_fdc.c
+- include/cmd_fdc.h
+
+SCSI support:
+-------------
+Support for Symbios SYM53C810A chip. Implemented as follows:
+- without disconnect
+- only asynchrounous
+- multiple LUN support (caution, needs a lot of RAM. define CFG_SCSI_MAX_LUN 1 to
+  save RAM)
+- multiple SCSI ID support
+- no write support
+- analyses the MAC, DOS and ISO pratition similar to the IDE support
+- allows booting from SCSI devices similar to the IDE support.
+The device numbers are not assigned like they are within the IDE support. The first
+device found will get the number 0, the next 1 etc. If all SCSI IDs (0..6) and all
+LUNs (8) are enabled, 56 boot devices are possible. This uses a lot of RAM since the
+device descriptors are not yet dynamically allocated. 56 boot devices are overkill
+anyway. Please refer to the section "Todo" chapter "block device support enhancement".
+The SYM53C810A uses 1 Interrupt and must be able of mastering the PCI bus.
+Added files:
+- common/cmd_scsi.c
+- common/board.c
+- include/cmd_scsi.h
+- include/scsi.h
+- board/pip405/sym53c8xx.c
+- board/pip405/sym53c8xx_defs.h
+
+ATAPI support (IDE changes):
+----------------------------
+Added ATAPI support (with CONFIG_ATAPI) in the file cmd_ide.c.
+To support a hardreset, when the IDE reset pin is not connected to the
+CFG_PC_IDE_RESET pin, the switch CONFIG_IDE_RESET_ROUTINE has been added. When
+this switch is enabled the routine void ide_set_reset(int idereset) must be
+within the board specific files.
+Only read from ATAPI devices are supported.
+Found out that the function trim_trail cuts off the last character if the whole
+string is filled. Added function cpy_ident instead, which trims also leading
+spaces and copies the string in the buffer.
+Changed files:
+- common/cmd_ide.c
+- include/ata.h
+
+ISO partition support:
+----------------------
+Added CD boot support for El-Torito bootable ISO CDs. The bootfile image must contain
+the ppcboot image header. Since CDs do not have "partitions", the boot partition is 0.
+The bootcatalog feature has not been tested so far. CD Boot is supported for ATAPI
+("diskboot") and SCSI ("scsiboot") devices.
+Added files:
+- disk/iso_part.c
+- disk/iso_part.h
+
+Block device changes:
+---------------------
+To allow the use of dos_part.c, mac_part.c and iso_part.c, the parameter
+block_dev_desc will be used when accessing the functions in these files. The block
+device descriptor (block_dev_desc) contains a pointer to the read routine of the
+device, which will be used to read blocks from the device.
+Renamed function ide_print to dev_print and moved it to the file disk/part.c to use
+it for IDE ATAPI and SCSI devices.
+Please refer to the section "Todo" chapter "block device support enhancement".
+Added files:
+- include/part.h
+changed files:
+- disk/dos_part.c
+- disk/dos_part.h
+- disk/mac_part.c
+- disk/mac_part.h
+- disk/part.c
+- common/cmd_ide.c
+- include/ppcboot.h
+
+
+MC146818 RTC support:
+---------------------
+Added support for MC146818 RTC with defining CONFIG_RTC_MC146818. The ISA bus IO
+base address must be defined with CFG_ISA_IO_BASE_ADDRESS.
+Added files:
+- rtc/mc146818.c
+
+Standard ISA bus Keyboard support:
+----------------------------------
+Added support for the standard PC kyeboard controller. For the PIP405 the superIO
+controller must be set up previously. The keyboard uses the standard ISA IRQ, so
+the ISA PIC must also be set up.
+Added files:
+- board/pip405/kbd.c
+- board/pip405/kbd.h
+- board/pip405/pip405_isa.c
+- board/pip405/pip405_isa.h
+
+Chips and Technologie 69000 VGA controller support:
+---------------------------------------------------
+Added support for the CT69000 VGA controller.
+Added files:
+- board/pip405/video.c
+- board/pip405/video.h
+- board/pip405/vga_table.h
+
+
+Changed Items:
+==============
+
+Identify:
+---------
+Added the config variable CONFIG_IDENT_STRING which will be added to the
+"PPCBOOT_VERSION __TIME__ DATE___ " String, to allows to identify intermidiate
+and custom versions.
+Changed files:
+- cpu/ppc4xx/start.s
+
+Firmware Image:
+---------------
+Added IH_OS_PPCBOOT and IH_TYPE_FIRMWARE to the image definitions to allows the
+PPCBoot update with prior CRC check.
+Changed files:
+- include/image.h
+- tools/mkimage.c
+- common/cmd_bootm.c
+
+Correct PCI Frequency for PPC405:
+---------------------------------
+Added function (in cpu/ppc4xx/speed.c) to get the PCI frequency for PPC405 CPU.
+The PCI Frequency will now be set correct in the board description in common/board.c.
+(was set to the busfreq before).
+Changed files:
+- cpu/ppc4xx/speed.c
+- common/board.c
+
+I2C Stuff:
+----------
+Added defined(CONFIG_PIP405) at several points in common/cmd_i2c.c.
+Added 16bit read/write support for I2C (PPC405), and page write to
+I2C EEPROM if defined CFG_EEPROM_PAGE_WRITE_ENABLE.
+Changed files:
+- cpu/ppc4xx/i2c.c
+- common/cmd_i2c.c
+
+Environment / Console:
+----------------------
+Although in README.console described, the PPCBoot has not assinged the values
+found in the environment to the console. Corrected this behavior, but only if
+CFG_CONSOLE_IS_IN_ENV is defined.
+If CFG_CONSOLE_OVERWRITE_ROUTINE is defined, console_overwrite() decides if the
+values stored in the environment or the standard serial in/output should be
+assigned to the console. This is useful if the environment values are not correct.
+If CFG_CONSOLE_ENV_OVERWRITE is defined the devices assigned to the console at
+start-up time will be written to the environment. This means that if the
+environment values are overwritten by the overwrite_console() routine, they will be
+stored in the environment.
+Changed files:
+- common/console.c
+
+Correct bootdelay intepretation:
+--------------------------------
+Changed bootdelay read from the environment from simple_strtoul (unsigned) to
+simple_strtol (signed), to be able to get a bootdelay of -1.
+Changed files:
+- common/main.c
+
+Todo:
+=====
+
+Block device support enhancement:
+---------------------------------
+Consider to unify the block device handling. Instead of using diskboot for IDE,
+scsiboot for SCSI and fdcboot for floppy disks, it would make sense to use only
+one command ("devboot" ???) with a parameter of the desired device ("hda1", "sda1",
+"fd0" ???) to boot from. The other ide commands can be handled in the same way
+("dev hda read.." instead of "ide read.." or "dev sda read.." instead of
+"scsi read..."). Todo this, a common way of assign a block device to its name
+(first found ide device = hda, second found hdb etc., or hda is device 0 on bus 0,
+hdb is device 1 on bus 0 etc.) as well as the names (hdx for ide, sdx for scsi, fx for
+floppy ???) must be defined.
+Maybe there are better ideas to do this.
+
+Console assingment:
+-------------------
+Consider to initialize and assign the console stdin, stdout and stderr as soon as
+possible to see the boot messages also on an other console than serial.
+
+
+Todo for PIP405:
+================
+
+LCD support for VGA:
+--------------------
+Add LCD support for the CT69000
+
+Default environment:
+--------------------
+Consider to write a default environment to the OTP part of the EEPROM and use it
+if the normal environment is not valid. Useful for serial# and ethaddr values.
+
+Watchdog:
+---------
+Implement Watchdog.
+
+Files clean-up:
+---------------
+Following files needs to be cleaned up:
+- cmd_pip405.c
+- flash.c
+- pci_pip405.c
+- pip405.c
+- pip405_isa.c
+Consider to split up the files in their functions.
index d6cded8bdbadc2704275551b179dd324863f5916..1c7c83b145fe9f221f64602f8db2d1b5730299a0 100644 (file)
 #define ATA_CMD_IDENT  0xEC    /* Identify Device              */
 #define ATA_CMD_SETF   0xEF    /* Set Features                 */
 
+/*
+ * ATAPI Commands
+ */
+#define ATAPI_CMD_IDENT 0xA1 /* Identify AT Atachment Packed Interface Device */
+#define ATAPI_CMD_PACKET 0xA0 /* Packed Command */
+
+
+#define ATAPI_CMD_INQUIRY 0x12
+#define ATAPI_CMD_REQ_SENSE 0x03
+#define ATAPI_CMD_READ_CAP 0x25
+#define ATAPI_CMD_START_STOP 0x1B
+#define ATAPI_CMD_READ_12 0xA8
+
 
 #define ATA_GET_ERR()  inb(ATA_STATUS)
 #define ATA_GET_STAT() inb(ATA_STATUS)
index 483a301a16c63b6c3ac4b510099f64efb16d0cfd..b9719a21ab80b8310d07bf7d1429990697304417 100644 (file)
@@ -61,6 +61,24 @@ void do_puma (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]);
 #endif /* CONFIG_PCU_E */
 /* ----------------------------------------------------------------------------*/
 
+/* ----- PIP405 -----------------------------------------------------------------
+ */
+#if defined(CONFIG_PIP405)
+
+#define        CMD_TBL_BSP MK_CMD_TBL_ENTRY(                           \
+       "pip405",       4,      6,      1,      do_pip405,                      \
+       "pip405  - PIP405 specific Cmds\n",                                     \
+       "flash mem [SrcAddr] - updates PPCBOOT with image in memory\n"                                  \
+       "pip405 flash floppy [SrcAddr] - updates PPCBOOT with image from floppy\n"                                      \
+       "pip405 flash mps - updates PPCBOOT with image from MPS\n"                                      \
+),
+
+void do_pip405 (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]);
+
+#endif /* CONFIG_PIP405 */
+/* ----------------------------------------------------------------------------*/
+
+
 #else
 
 #define CMD_TBL_BSP
index d5fd950d05c9f7e5883e9b3881d4ae6ba8c115fb..118b3ba46b3054e60ad343f5687ac3c569ae1082 100644 (file)
@@ -57,6 +57,8 @@
 #define        CFG_CMD_DATE    0x00800000      /* support for RTC, date/time...*/
 #define CFG_CMD_DHCP   0x01000000      /* DHCP Support                 */
 #define CFG_CMD_BEDBUG  0x02000000      /* Include BedBug Debugger      */
+#define        CFG_CMD_FDC     0x04000000      /* Floppy Disk Support  */
+#define        CFG_CMD_SCSI    0x08000000      /* SCSI Support */
 #define        CFG_CMD_BSP     0x80000000      /* Board SPecific functions     */
 
 #define CFG_CMD_ALL    0xFFFFFFFF      /* ALL commands                 */
@@ -76,6 +78,8 @@
                        CFG_CMD_I2C     | \
                        CFG_CMD_REGINFO | \
                        CFG_CMD_IMMAP   | \
+                       CFG_CMD_FDC     | \
+                       CFG_CMD_SCSI    | \
                        CFG_CMD_DATE    | \
                        CFG_CMD_BEDBUG  | \
                        CFG_CMD_BSP     )
index 5b9818f4508aa6a075c9b83d483f7919f48c2950..93dc974d4840c25a449ae1bd648c84f2c650689e 100644 (file)
@@ -35,6 +35,8 @@
  */
 #define BOOT_PART_TYPE "PPCBoot"
 
+#if 0
+
 typedef        struct disk_partition {
        ulong   start;          /* # of first block in partition        */
        ulong   size;           /* number of blocks in partition        */
@@ -43,12 +45,13 @@ typedef     struct disk_partition {
        uchar   type[32];       /* string type description              */
 } disk_partition_t;
 
-int get_partition_info     (int dev, int part, disk_partition_t *info);
+int get_partition_info     (block_dev_desc_t * dev_desc, int part, disk_partition_t *info);
 #ifdef CONFIG_MAC_PARTITION
-int get_partition_info_mac (int dev, int part, disk_partition_t *info);
+int get_partition_info_mac (block_dev_desc_t * dev_desc, int part, disk_partition_t *info);
 #endif
 #ifdef CONFIG_DOS_PARTITION
-int get_partition_info_dos (int dev, int part, disk_partition_t *info);
+int get_partition_info_dos (block_dev_desc_t * dev_desc, int part, disk_partition_t *info);
 #endif
+#endif /* 0 */
 
 #endif /* _CMD_DISK_H */
diff --git a/include/cmd_fdc.h b/include/cmd_fdc.h
new file mode 100644 (file)
index 0000000..0c241c5
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * (C) Copyright 2001
+ * Denis Peter, MPL AG, 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
+ */
+
+/*
+ * Floppy support
+ */
+#ifndef        _CMD_FDC_H
+#define        _CMD_FDC_H
+
+#include <ppcboot.h>
+#include <command.h>
+
+
+#if (CONFIG_COMMANDS & CFG_CMD_FDC)
+
+#define CMD_TBL_FDC    MK_CMD_TBL_ENTRY(                                       \
+       "fdcboot", 4,   3,      1,      do_fdcboot,                             \
+       "fdcboot - boot from floppy device\n",                                  \
+       "loadAddr drive\n"                                                      \
+),
+void do_fdcboot (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]);
+
+#else
+#define CMD_TBL_FDC
+#endif
+
+#endif /* _CMD_FDC_H */
index eca0e354489a19a56bd6bc73d02baf189c95a9a5..fe20dcacf860795bc5452e66790a32866504734a 100644 (file)
@@ -47,7 +47,7 @@
 
 #define CMD_TBL_DISK   MK_CMD_TBL_ENTRY(                                       \
        "diskboot", 4,  3,      1,      do_diskboot,                            \
-       "diskboot- boot from IDE device",                                       \
+       "diskboot- boot from IDE device\n",                                     \
        "loadAddr dev:part\n"                                                   \
 ),
 
diff --git a/include/cmd_scsi.h b/include/cmd_scsi.h
new file mode 100644 (file)
index 0000000..a73ca01
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * (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
+ *
+ */
+#ifndef        _CMD_SCSI_H
+#define        _CMD_SCSI_H
+
+#include <ppcboot.h>
+#include <command.h>
+
+
+#if (CONFIG_COMMANDS & CFG_CMD_SCSI)
+
+#define        CMD_TBL_SCSI    MK_CMD_TBL_ENTRY(                                       \
+       "scsi", 4,      5,      1,      do_scsi,                                        \
+       "scsi    - SCSI sub-system\n",                                          \
+       "reset - reset SCSI controller\n"                                       \
+       "scsi info  - show available SCSI devices\n"                            \
+       "scsi scan  - (re-)scan SCSI bus\n"                             \
+       "scsi device [dev] - show or set current device\n"                      \
+       "scsi part [dev] - print partition table of one or all SCSI devices\n"  \
+       "scsi read addr blk# cnt - read `cnt' blocks starting at block `blk#'\n"        \
+       "     to memory address `addr'\n"                                       \
+),
+
+
+#define        CMD_TBL_SCSIBOOT        MK_CMD_TBL_ENTRY(                                       \
+       "scsiboot",     5,      3,      1,      do_scsiboot,                                    \
+       "scsiboot- boot from SCSI device\n",                                            \
+       "loadAddr dev:part\n"                   \
+),
+
+void do_scsi (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]);
+void do_scsiboot (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]);
+
+
+#else
+#define CMD_TBL_SCSI
+#define CMD_TBL_SCSIBOOT
+#endif
+
+#endif /* _CMD_SCSI_H */
+
index 0922b360fa66bffc1416284b27640238138450f8..16d4ce66b1d0dd5974a5279df48db7676f58ef23 100644 (file)
 #if 1
 #define CONFIG_COMMANDS  (CFG_CMD_ALL & ~(CFG_CMD_KGDB | CFG_CMD_IDE \
                                          | CFG_CMD_PCMCIA | CFG_CMD_PCI \
+                                         | CFG_CMD_SCSI   | CFG_CMD_FDC \
                                          | CFG_CMD_EEPROM | CFG_CMD_DATE))
 #else
 #define CONFIG_COMMANDS CONFIG_CMD_DFL
index 90e5229c5b50745dd03dfb3e7464f4c2999fbd1e..d1af62783c59746f057ac16e3ca5627912134176 100644 (file)
@@ -87,6 +87,8 @@
                                             & ~CFG_CMD_PCI     \
                                             & ~CFG_CMD_EEPROM  \
                                             & ~CFG_CMD_I2C     \
+                                            & ~CFG_CMD_FDC     \
+                                            & ~CFG_CMD_SCSI    \
                                             & ~CFG_CMD_IRQ     \
                                             & ~CFG_CMD_BEDBUG  )
 
diff --git a/include/config_PIP405.h b/include/config_PIP405.h
new file mode 100644 (file)
index 0000000..8311018
--- /dev/null
@@ -0,0 +1,308 @@
+/*
+ * (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
+ */
+
+/*
+ * board/config.h - configuration options, board specific
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/***********************************************************
+ * High Level Configuration Options
+ * (easy to change)
+ ***********************************************************/
+#define CONFIG_PPC405GP        1       /* This is a PPC405 CPU         */
+#define CONFIG_PPC405          1       /* ...member of PPC405 family   */
+#define CONFIG_PIP405          1       /* ...on a PIP405 board */
+/***********************************************************
+ * Clock
+ ***********************************************************/
+#define CONFIG_SYS_CLK_FREQ  33000000 /* external frequency to pll   */
+
+/***********************************************************
+ * Command definitions
+ ***********************************************************/
+#define CONFIG_COMMANDS                \
+       (CONFIG_CMD_DFL | CFG_CMD_PCI | CFG_CMD_IRQ | \
+        CFG_CMD_DATE | CFG_CMD_IDE | CFG_CMD_BSP | \
+        CFG_CMD_FDC | CFG_CMD_SCSI )
+
+/* this must be included AFTER the definition of CONFIG_COMMANDS  (if any) */
+#include <cmd_confdefs.h>
+
+
+/**************************************************************
+ * I2C Stuff:
+ * the PIP405 is equiped with an Atmel 24C128/256 EEPROM at address
+ * 0x53. 
+ * Caution: on the same bus is the SPD (Serial Presens Detect
+ * EEPROM of the SDRAM
+ * The Atmel EEPROM uses 16Bit addressing.
+ ***************************************************************/ 
+#define CONFIG_I2C_X
+#define CFG_I2C_EEPROM_ADDR                    0x53
+#define CFG_ENV_IS_IN_EEPROM    1       /* use EEPROM for environment vars */
+#define CFG_ENV_OFFSET          0x000   /* environment starts at the beginning of the EEPROM */
+#define CFG_ENV_SIZE            0x200   /* 512 bytes may be used for env vars */
+/* The Atmel 24C128/256 has 64 byte page write mode using last 6 bits of the address   */
+#define CFG_EEPROM_PAGE_WRITE_BITS 6   
+#define CFG_EEPROM_PAGE_WRITE_ENABLE /* enable Page write */   
+/***************************************************************
+ * Definitions for Serial Presence Detect EEPROM address
+ * (to get SDRAM settings)
+ ***************************************************************/
+#define SDRAM_EEPROM_WRITE_ADDRESS 0xA0
+#define SDRAM_EEPROM_READ_ADDRESS  0xA1
+
+/**************************************************************
+ * Environment definitions
+ **************************************************************/
+#define CONFIG_BAUDRATE                9600    /* STD Baudrate */
+#define CONFIG_BOOTDELAY       -1                      /* no autoboot */
+
+#define CONFIG_BOOTCOMMAND     "diskboot 200000 0:1; bootm" /* autoboot command                */
+#define CONFIG_BOOTARGS                "console=ttyS0,9600 root=/dev/hda5" /* boot arguments */
+
+#define CONFIG_IPADDR                  10.0.0.100
+#define CONFIG_SERVERIP                10.0.0.1
+
+/***************************************************************
+ * defines if the console is stored in the environment
+ ***************************************************************/ 
+#define CFG_CONSOLE_IS_IN_ENV  /* stdin, stdout and stderr are in evironment */                                
+/***************************************************************
+ * defines if an overwrite_console function exists
+ *************************************************************/
+#define CFG_CONSOLE_OVERWRITE_ROUTINE
+
+/***************************************************************
+ * defines if the overwrite_console should be stored in the
+ * environment
+ **************************************************************/
+#undef CFG_CONSOLE_ENV_OVERWRITE
+
+/**************************************************************
+ * loads config
+ *************************************************************/
+#define CONFIG_LOADS_ECHO      1       /* echo on for serial download  */
+#define CFG_LOADS_BAUD_CHANGE  1       /* allow baudrate change        */
+
+
+/***********************************************************
+ * Miscellaneous configurable options
+ **********************************************************/
+#define CFG_LONGHELP                           /* undef to save memory         */
+#define CFG_PROMPT     "=> "           /* Monitor Command Prompt       */
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#define        CFG_CBSIZE      1024            /* Console I/O Buffer Size      */
+#else
+#define        CFG_CBSIZE      256                     /* Console I/O Buffer Size      */
+#endif
+#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */
+#define CFG_MAXARGS    16                      /* max number of command args   */
+#define CFG_BARGSIZE   CFG_CBSIZE      /* Boot Argument Buffer Size    */
+
+#define CFG_MEMTEST_START      0x0400000       /* memtest works on     */
+#define CFG_MEMTEST_END                0x0C00000       /* 4 ... 12 MB in DRAM  */
+
+#undef  CFG_EXT_SERIAL_CLOCK           /* no external serial clock used */
+
+/* The following table includes the supported baudrates */
+#define CFG_BAUDRATE_TABLE      \
+        { 300, 600, 1200, 2400, 4800, 9600, 19200, 38400,     \
+         57600, 115200, 230400, 460800, 921600 }
+
+#define CFG_CLKS_IN_HZ 1               /* everything, incl board info, in Hz */
+
+#define CFG_LOAD_ADDR          0x200000        /* default load address */
+#define CFG_EXTBDINFO          1       /* To use extended board_into (bd_t) */
+
+#define        CFG_HZ          1000            /* decrementer freq: 1 ms ticks */
+
+/*-----------------------------------------------------------------------
+ * PCI stuff
+ *-----------------------------------------------------------------------
+ */
+#define CONFIG_PCI                     /* include pci support          */
+#define CONFIG_PCI_HOST /* configure as pci-host        */
+#define CONFIG_PCI_PNP /* pci plug-and-play                    */
+                                        /* resource configuration       */
+#define CFG_PCI_SUBSYS_VENDORID 0x0000  /* PCI Vendor ID: to-do!!!      */
+#define CFG_PCI_SUBSYS_DEVICEID 0x0000  /* PCI Device ID: to-do!!!      */
+#define CFG_PCI_PTM1LA  0x00000000      /* point to sdram               */
+#define CFG_PCI_PTM1MS  0x80000001      /* 2GB, enable hard-wired to 1  */
+#define CFG_PCI_PTM2LA  0x00000000      /* disabled                     */
+#define CFG_PCI_PTM2MS  0x00000000      /* disabled                     */
+
+/*-----------------------------------------------------------------------
+ * Start addresses for the final memory configuration
+ * (Set up by the startup code)
+ * Please note that CFG_SDRAM_BASE _must_ start at 0
+ */
+#define CFG_SDRAM_BASE         0x00000000
+#define CFG_FLASH_BASE         0xFFF80000
+#define CFG_MONITOR_BASE       CFG_FLASH_BASE
+#define CFG_MONITOR_LEN                (512 * 1024)    /* Reserve 512 kB for Monitor   */
+#define CFG_MALLOC_LEN         (128 * 1024)    /* Reserve 128 kB for malloc()  */
+
+/*
+ * 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    1       /* max number of memory banks           */
+#define CFG_MAX_FLASH_SECT     256     /* 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     16      /* For all MPC8xx CPUs                  */
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#define CFG_CACHELINE_SHIFT    4       /* log base 2 of the above value        */
+#endif
+
+/*
+ * Init Memory Controller:
+ */   
+
+#define FLASH_BASE0_PRELIM     0xFFC00000      /* FLASH bank #0        */
+#define FLASH_BASE1_PRELIM     0               /* FLASH bank #1        */
+
+
+/* On Chip Memory location */
+#define OCM_DATA_ADDR          0xF0000000
+
+/* Configuration Port location */
+#define CONFIG_PORT_ADDR       0xF4000000
+#define MULTI_PURPOSE_SOCKET_ADDR 0xF8000000
+
+
+
+/*-----------------------------------------------------------------------
+ * Definitions for initial stack pointer and data area (in On Chip SRAM)
+ */
+#define CFG_INIT_RAM_ADDR      OCM_DATA_ADDR  /* inside of On Chip SRAM    */
+#define CFG_INIT_RAM_END       0x1000                           /* End of On Chip SRAM        */
+#define CFG_INIT_DATA_SIZE     64                              /* size in bytes reserved for initial data */
+#define CFG_INIT_DATA_OFFSET   (CFG_INIT_RAM_END - CFG_INIT_DATA_SIZE)
+#define CFG_INIT_SP_OFFSET     CFG_INIT_DATA_OFFSET
+
+/*
+ * Internal Definitions
+ *
+ * Boot Flags
+ */
+#define BOOTFLAG_COLD  0x01            /* Normal Power-On: Boot from FLASH     */
+#define BOOTFLAG_WARM  0x02            /* Software reboot                      */
+
+
+/***********************************************************************
+ * External peripheral base address
+ ***********************************************************************/
+#define CFG_ISA_IO_BASE_ADDRESS 0xE8000000
+
+
+/************************************************************
+ * Ethernet Stuff
+ ***********************************************************/
+#define        CONFIG_PHY_ADDR         1       /* PHY address                  */
+
+/************************************************************
+ * RTC
+ ***********************************************************/
+#define CONFIG_RTC_MC146818
+#undef CONFIG_WATCHDOG                 /* watchdog disabled            */
+
+/************************************************************
+ * IDE/ATA stuff
+ ************************************************************/
+#define CFG_IDE_MAXBUS         2   /* max. 2 IDE busses        */
+#define CFG_IDE_MAXDEVICE      (CFG_IDE_MAXBUS*2) /* max. 2 drives per IDE bus */
+
+#define CFG_ATA_BASE_ADDR      CFG_ISA_IO_BASE_ADDRESS /* base address */
+#define CFG_ATA_IDE0_OFFSET 0x01F0     /* ide0 offste */
+#define CFG_ATA_IDE1_OFFSET 0x0170     /* 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     */
+#define CONFIG_IDE_RESET       /* reset for ide supported...   */
+#define CONFIG_IDE_RESET_ROUTINE /* with a special reset function */
+
+/************************************************************
+ * ATAPI support (experimental)
+ ************************************************************/
+#define CONFIG_ATAPI                   /* enable ATAPI Support */
+
+/************************************************************
+ * SCSI support (experimental) only SYM53C8xx supported
+ ************************************************************/
+#define CONFIG_SCSI_SYM53C8XX
+#define CFG_SCSI_MAX_LUN                       8 /* number of supported LUNs */
+#define CFG_SCSI_MAX_SCSI_ID   7 /* maximum SCSI ID (0..6) */
+#define CFG_SCSI_MAX_DEVICE            CFG_SCSI_MAX_SCSI_ID * CFG_SCSI_MAX_LUN /* maximum Target devices */
+
+/************************************************************
+ * DISK Partition support 
+ ************************************************************/
+#define CONFIG_DOS_PARTITION 
+#define CONFIG_MAC_PARTITION 
+#define CONFIG_ISO_PARTITION /* Experimental */
+
+/************************************************************
+ * Keyboard support 
+ ************************************************************/
+#define CONFIG_ISA_KEYBOARD
+
+/************************************************************
+ * Video support 
+ ************************************************************/
+#define CONFIG_VIDEO                   /*To enable video controller support */
+#define CONFIG_VIDEO_CT69000
+
+/************************************************************
+ * Debug support 
+ ************************************************************/
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#define CONFIG_KGDB_BAUDRATE   230400  /* speed to run kgdb serial port */
+#define CONFIG_KGDB_SER_INDEX  2       /* which serial port to use */
+#endif
+
+/************************************************************
+ * Ident 
+ ************************************************************/
+#define VERSION_TAG "REL_1.0.0"
+#define CONFIG_IDENT_STRING "\n(c) 2001 by MPL AG Switzerland, MEV-10066-001 " VERSION_TAG 
+
+
+#endif /* __CONFIG_H */
index 8b7cf7a69d1dd5d0cc0472a0f3d229680cd770f7..3ff9e2fade986ddb0a2a380e9d5ef8a3a50dd06c 100644 (file)
@@ -94,6 +94,8 @@
                                        CFG_CMD_PCI     | \
                                        CFG_CMD_DATE    | \
                                        CFG_CMD_BEDBUG  | \
+                                       CFG_CMD_FDC     | \
+                                       CFG_CMD_SCSI    | \
                                        CFG_CMD_EEPROM  ) )
 
 /* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
index 9510e4c03fd126b6cde49194aa7cb3cde4485a4b..af7b7bdeea8cd00a58801e26748cb7131cbcc5bb 100644 (file)
@@ -127,6 +127,7 @@ int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt);
 #define INTEL_ID_28F160B3T  0x88908890 /*  16M = 1M x 16 top boot sector       */
 #define INTEL_ID_28F160B3B  0x88918891 /*  16M = 1M x 16 bottom boot sector    */
 #define INTEL_ID_28F320B3T  0x88968896 /*  32M = 2M x 16 top boot sector       */
+#define INTEL_ID_28F320C3T  0x88C488C4 /*  32M = 2M x 16 top boot sector       */
 #define INTEL_ID_28F320B3B  0x88978897 /*  32M = 2M x 16 bottom boot sector    */
 #define INTEL_ID_28F640B3T  0x88988898 /*  64M = 4M x 16 top boot sector       */
 #define INTEL_ID_28F640B3B  0x88998899 /*  64M = 4M x 16 bottom boot sector    */
index 953fc62cf8537463e7abd312af76a2b6fa6c7cad..6f3d4beb8f79107ad111e208d59170797a76aadf 100644 (file)
@@ -22,7 +22,8 @@ void  i2c_write (uchar *addr, int alen, uchar *buffer, int len);
 
 
 #if defined(CONFIG_CPCI405) || defined(CONFIG_AR405) || \
-    defined (CONFIG_WALNUT405) || defined (CONFIG_ERIC)
+    defined (CONFIG_WALNUT405) || defined (CONFIG_ERIC) || \
+    defined (CONFIG_PIP405)
 
 void i2c_init(void);
 int  i2c_receive(unsigned char address,
index 2c5c061f7112abedee251f122b16ad2e7b11b861..273d546c7c0d50294f348796e5db579d21de8f35 100644 (file)
@@ -44,6 +44,7 @@
 #define        IH_OS_VXWORKS           14      /* VxWorks      */
 #define        IH_OS_PSOS              15      /* pSOS         */
 #define        IH_OS_QNX               16      /* QNX          */
+#define        IH_OS_PPCBOOT   17      /* Firmware             */
 
 /*
  * CPU Architecture Codes (supported by Linux)
@@ -96,6 +97,7 @@
 #define IH_TYPE_KERNEL         2       /* OS Kernel Image              */
 #define IH_TYPE_RAMDISK                3       /* RAMDisk Image                */
 #define IH_TYPE_MULTI          4       /* Multi-File Image             */
+#define IH_TYPE_FIRMWARE       5       /* Binary Image to be programmed in the flash   */
 
 /*
  * Compression Types
diff --git a/include/part.h b/include/part.h
new file mode 100644 (file)
index 0000000..02fefff
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * (C) Copyright 2000, 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
+ */
+#ifndef _PART_H
+#define _PART_H
+
+
+typedef struct block_dev_desc {
+       int           if_type;    /* type of the interface */
+       int           dev;        /* device number */
+       unsigned char part_type;  /* partition type */
+       unsigned char target;                   /* target SCSI ID */ 
+       unsigned char lun;                              /* target LUN */
+       unsigned char type;                             /* device type */
+       unsigned long lba;        /* number of blocks */                
+       unsigned long blksz;                    /* block size */
+       unsigned char vendor[40]; /* IDE model, SCSI Vendor */
+       unsigned char product[20];/* IDE Serial no, SCSI product */
+       unsigned char revision[8];/* firmware revision */
+       unsigned char removable;        /* removable device */
+       unsigned long (*block_read)(int dev,unsigned long start,unsigned long blkcnt, unsigned long *buffer);
+}block_dev_desc_t;
+/* Interface types: */
+#define IF_TYPE_UNKNOWN        0
+#define IF_TYPE_IDE                    1
+#define IF_TYPE_SCSI           2
+#define IF_TYPE_ATAPI          3
+/* Part types */
+#define        PART_TYPE_UNKNOWN       0x00
+#define PART_TYPE_MAC          0x01
+#define PART_TYPE_DOS          0x02
+#define PART_TYPE_ISO          0x03
+/* device types */
+#define DEV_TYPE_UNKNOWN 0xff /* not connected */
+#define DEV_TYPE_HARDDISK 0x00 /* harddisk */
+#define DEV_TYPE_TAPE          0x01 /* Tape */
+#define DEV_TYPE_CDROM                 0x05 /* CD-ROM */
+#define DEV_TYPE_OPDISK        0x07 /* optical disk */
+
+typedef        struct disk_partition {
+       ulong   start;          /* # of first block in partition        */
+       ulong   size;           /* number of blocks in partition        */
+       ulong   blksz;          /* block size in bytes                  */
+       uchar   name[32];       /* partition name                       */
+       uchar   type[32];       /* string type description              */
+} disk_partition_t;
+
+/* disk/part.c */
+int get_partition_info (block_dev_desc_t * dev_desc, int part, disk_partition_t *info);
+void print_part (block_dev_desc_t *dev_desc);
+void  init_part (block_dev_desc_t *dev_desc);
+void dev_print(block_dev_desc_t *dev_desc);
+
+
+#ifdef CONFIG_MAC_PARTITION
+/* disk/part_mac.c */
+int get_partition_info_mac (block_dev_desc_t * dev_desc, int part, disk_partition_t *info);
+void print_part_mac (block_dev_desc_t *dev_desc);
+int   test_part_mac (block_dev_desc_t *dev_desc);
+#endif
+
+#ifdef CONFIG_DOS_PARTITION
+/* disk/part_dos.c */
+int get_partition_info_dos (block_dev_desc_t * dev_desc, int part, disk_partition_t *info);
+void print_part_dos (block_dev_desc_t *dev_desc);
+int   test_part_dos (block_dev_desc_t *dev_desc);
+#endif
+
+#ifdef CONFIG_ISO_PARTITION
+/* disk/part_iso.c */
+int get_partition_info_iso (block_dev_desc_t * dev_desc, int part, disk_partition_t *info);
+void print_part_iso (block_dev_desc_t *dev_desc);
+int   test_part_iso (block_dev_desc_t *dev_desc);
+#endif
+
+#endif /* _PART_H */
+
+
index 8927ad8ab5dcd889ee2fcd761f84105c0b4ae304..e95293f91a8b37f622b69250134a0f4aec2f4a4b 100644 (file)
@@ -49,6 +49,7 @@ typedef volatile unsigned short       vu_short;
 #include <asm/hymod.h>
 #endif
 
+#include <part.h>
 #include <flash.h>
 #include <image.h>
 
@@ -188,6 +189,7 @@ void inline         setenv (char *, char *);
 #if defined(CONFIG_CPCI405)    || \
     defined(CONFIG_AR405)      || \
     defined (CONFIG_WALNUT405) || \
+    defined (CONFIG_PIP405)    || \
     defined (CONFIG_CPCIISER4) || \
     defined (CONFIG_ERIC)
 /* $(CPU)/405gp_pci.c */
@@ -198,7 +200,7 @@ void    pciinfo       (int);
 #if defined(CONFIG_COGENT)     || defined(CONFIG_SXNI855T)     || \
     defined(CONFIG_RSD_PROTO)  || defined(CONFIG_HYMOD)        || \
     defined(CONFIG_CPCI405)    || defined(CONFIG_PCU_E)        || \
-    defined(CONFIG_EVB64260)
+    defined(CONFIG_EVB64260)   || defined(CONFIG_LWMON)
 /* cogent - $(BOARD)/mb.c */
 /* SXNI855T and HYMOD - $(BOARD)/$(BOARD).c */
 # ifndef CONFIG_PCU_E
@@ -223,6 +225,7 @@ void        reset_phy     (void);
     defined(CONFIG_CPCI405)    || \
     defined(CONFIG_CANBT)      || \
     defined(CONFIG_WALNUT405)  || \
+    defined(CONFIG_PIP405)     || \
     defined(CONFIG_CPCIISER4)  || \
     defined(CONFIG_LWMON)      || \
     defined(CONFIG_TQM8260)    || \
@@ -272,6 +275,7 @@ void  perform_soft_reset(void);
     defined(CONFIG_AR405)      || \
     defined(CONFIG_CANBT)      || \
     defined(CONFIG_WALNUT405)  || \
+    defined(CONFIG_PIP405)     || \
     defined(CONFIG_CPCIISER4)  || \
     defined(CONFIG_ADCIOP)     || \
     defined(CONFIG_LWMON)      || \
@@ -350,6 +354,9 @@ void        prt_8260_clks (void);
       defined(CONFIG_CU824)
 ulong  get_gclk_freq (void);
 ulong get_OPB_freq (void);
+#ifdef CONFIG_PPC405
+ulong get_PCI_freq (void);
+#endif
 #endif
 
 ulong  get_bus_freq  (ulong);
@@ -404,20 +411,6 @@ int        vsprintf(char *buf, const char *fmt, va_list args);
 /* ppc/crc32.c */
 ulong crc32 (ulong, const unsigned char *, uint);
 
-#ifdef CONFIG_MAC_PARTITION
-/* disk/part_mac.c */
-void print_part_mac (int);
-int   test_part_mac (int);
-#endif
-#ifdef CONFIG_DOS_PARTITION
-/* disk/part_dos.c */
-void print_part_dos (int);
-int   test_part_dos (int);
-#endif
-/* disk/part.c */
-void print_part (int);
-void  init_part (int);
-
 /* common/console.c */
 bd_t   *bd_ptr ;
 
diff --git a/include/scsi.h b/include/scsi.h
new file mode 100644 (file)
index 0000000..27ed924
--- /dev/null
@@ -0,0 +1,213 @@
+/*
+ * (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
+ *
+ */
+ #ifndef _SCSI_H
+ #define _SCSI_H
+typedef struct SCSI_cmd_block{
+       unsigned char           cmd[16];                                        /* command                                 */
+       unsigned char           sense_buf[64];          /* for request sense */
+       unsigned char           status;                                         /* SCSI Status                   */
+       unsigned char           target;                                         /* Target ID                             */
+       unsigned char           lun;                                                    /* Target LUN        */
+       unsigned char           cmdlen;                                         /* command len                          */
+       unsigned long           datalen;                                        /* Total data length    */
+       unsigned char   *       pdata;                                          /* pointer to data              */
+       unsigned char           msgout[12];                             /* Messge out buffer (NOT USED) */
+       unsigned char           msgin[12];                              /* Message in buffer    */
+       unsigned char           sensecmdlen;                    /* Sense command len    */
+       unsigned long           sensedatalen;                   /* Sense data len                       */
+       unsigned char           sensecmd[6];                    /* Sense command                        */
+       unsigned long           contr_stat;                             /* Controller Status    */
+       unsigned long           trans_bytes;                    /* tranfered bytes              */
+}ccb;
+
+/*-----------------------------------------------------------
+**
+**     SCSI  constants.
+**
+**-----------------------------------------------------------
+*/
+
+/*
+**     Messages
+*/
+
+#define        M_COMPLETE      (0x00)
+#define        M_EXTENDED      (0x01)
+#define        M_SAVE_DP       (0x02)
+#define        M_RESTORE_DP    (0x03)
+#define        M_DISCONNECT    (0x04)
+#define        M_ID_ERROR      (0x05)
+#define        M_ABORT         (0x06)
+#define        M_REJECT        (0x07)
+#define        M_NOOP          (0x08)
+#define        M_PARITY        (0x09)
+#define        M_LCOMPLETE     (0x0a)
+#define        M_FCOMPLETE     (0x0b)
+#define        M_RESET         (0x0c)
+#define        M_ABORT_TAG     (0x0d)
+#define        M_CLEAR_QUEUE   (0x0e)
+#define        M_INIT_REC      (0x0f)
+#define        M_REL_REC       (0x10)
+#define        M_TERMINATE     (0x11)
+#define        M_SIMPLE_TAG    (0x20)
+#define        M_HEAD_TAG      (0x21)
+#define        M_ORDERED_TAG   (0x22)
+#define        M_IGN_RESIDUE   (0x23)
+#define        M_IDENTIFY      (0x80)
+
+#define        M_X_MODIFY_DP   (0x00)
+#define        M_X_SYNC_REQ    (0x01)
+#define        M_X_WIDE_REQ    (0x03)
+#define        M_X_PPR_REQ     (0x04)
+
+
+/*
+**     Status
+*/
+
+#define        S_GOOD          (0x00)
+#define        S_CHECK_COND    (0x02)
+#define        S_COND_MET      (0x04)
+#define        S_BUSY          (0x08)
+#define        S_INT           (0x10)
+#define        S_INT_COND_MET  (0x14)
+#define        S_CONFLICT      (0x18)
+#define        S_TERMINATED    (0x20)
+#define        S_QUEUE_FULL    (0x28)
+#define        S_ILLEGAL       (0xff)
+#define        S_SENSE         (0x80)
+
+/*
+ * Sense_keys
+ */
+
+#define SENSE_NO_SENSE                         0x0
+#define SENSE_RECOVERED_ERROR  0x1
+#define SENSE_NOT_READY                                0x2
+#define SENSE_MEDIUM_ERROR             0x3
+#define SENSE_HARDWARE_ERROR   0x4
+#define SENSE_ILLEGAL_REQUEST  0x5
+#define SENSE_UNIT_ATTENTION   0x6
+#define SENSE_DATA_PROTECT             0x7
+#define SENSE_BLANK_CHECK                      0x8
+#define SENSE_VENDOR_SPECIFIC  0x9
+#define SENSE_COPY_ABORTED             0xA
+#define SENSE_ABORTED_COMMAND  0xB
+#define SENSE_VOLUME_OVERFLOW  0xD
+#define SENSE_MISCOMPARE                       0xE
+
+
+#define SCSI_CHANGE_DEF        0x40            /* Change Definition (Optional) */
+#define SCSI_COMPARE           0x39            /* Compare (O) */
+#define SCSI_COPY                      0x18            /* Copy (O) */
+#define SCSI_COP_VERIFY        0x3A            /* Copy and Verify (O) */
+#define SCSI_INQUIRY           0x12            /* Inquiry (MANDATORY) */
+#define SCSI_LOG_SELECT        0x4C            /* Log Select (O) */
+#define SCSI_LOG_SENSE 0x4D            /* Log Sense (O) */
+#define SCSI_MODE_SEL6 0x15            /* Mode Select 6-byte (Device Specific) */
+#define SCSI_MODE_SEL10        0x55            /* Mode Select 10-byte (Device Specific) */
+#define SCSI_MODE_SEN6 0x1A            /* Mode Sense 6-byte (Device Specific) */
+#define SCSI_MODE_SEN10        0x5A            /* Mode Sense 10-byte (Device Specific) */
+#define SCSI_READ_BUFF 0x3C            /* Read Buffer (O) */
+#define SCSI_REQ_SENSE 0x03            /* Request Sense (MANDATORY) */
+#define SCSI_SEND_DIAG 0x1D            /* Send Diagnostic (O) */
+#define SCSI_TST_U_RDY 0x00            /* Test Unit Ready (MANDATORY) */
+#define SCSI_WRITE_BUFF        0x3B            /* Write Buffer (O) */
+/***************************************************************************
+ *                       %%% Commands Unique to Direct Access Devices %%%
+ ***************************************************************************/
+#define SCSI_COMPARE           0x39            /* Compare (O) */
+#define SCSI_FORMAT            0x04            /* Format Unit (MANDATORY) */
+#define SCSI_LCK_UN_CAC        0x36            /* Lock Unlock Cache (O) */
+#define SCSI_PREFETCH  0x34            /* Prefetch (O) */
+#define SCSI_MED_REMOVL        0x1E            /* Prevent/Allow medium Removal (O) */
+#define SCSI_READ6             0x08            /* Read 6-byte (MANDATORY) */
+#define SCSI_READ10            0x28            /* Read 10-byte (MANDATORY) */
+#define SCSI_RD_CAPAC  0x25            /* Read Capacity (MANDATORY) */
+#define SCSI_RD_DEFECT 0x37            /* Read Defect Data (O) */
+#define SCSI_READ_LONG 0x3E            /* Read Long (O) */
+#define SCSI_REASS_BLK 0x07            /* Reassign Blocks (O) */
+#define SCSI_RCV_DIAG  0x1C            /* Receive Diagnostic Results (O) */
+#define SCSI_RELEASE   0x17            /* Release Unit (MANDATORY) */
+#define SCSI_REZERO            0x01            /* Rezero Unit (O) */
+#define SCSI_SRCH_DAT_E        0x31            /* Search Data Equal (O) */
+#define SCSI_SRCH_DAT_H        0x30            /* Search Data High (O) */
+#define SCSI_SRCH_DAT_L        0x32            /* Search Data Low (O) */
+#define SCSI_SEEK6             0x0B            /* Seek 6-Byte (O) */
+#define SCSI_SEEK10            0x2B            /* Seek 10-Byte (O) */
+#define SCSI_SEND_DIAG 0x1D            /* Send Diagnostics (MANDATORY) */
+#define SCSI_SET_LIMIT 0x33            /* Set Limits (O) */
+#define SCSI_START_STP 0x1B            /* Start/Stop Unit (O) */
+#define SCSI_SYNC_CACHE        0x35            /* Synchronize Cache (O) */
+#define SCSI_VERIFY            0x2F            /* Verify (O) */
+#define SCSI_WRITE6            0x0A            /* Write 6-Byte (MANDATORY) */
+#define SCSI_WRITE10   0x2A            /* Write 10-Byte (MANDATORY) */
+#define SCSI_WRT_VERIFY        0x2E            /* Write and Verify (O) */
+#define SCSI_WRITE_LONG        0x3F            /* Write Long (O) */
+#define SCSI_WRITE_SAME        0x41            /* Write Same (O) */
+
+/****************************************************************************
+ * decleration of functions which have to reside in the LowLevel Part Driver
+ */
+void scsi_print_error(ccb *pccb);
+int scsi_exec(ccb *pccb);
+void scsi_bus_reset(void);
+void scsi_low_level_init(int busdevfunc);
+
+
+/***************************************************************************
+ * functions residing inside cmd_scsi.c
+ */
+void scsi_init(void);
+
+
+
+#define SCSI_IDENTIFY                                  0xC0  /* not used */
+
+/* Hardware errors  */
+#define SCSI_SEL_TIME_OUT                       0x00000101      /* Selection time out */
+#define SCSI_HNS_TIME_OUT                       0x00000102  /* Handshake */
+#define SCSI_MA_TIME_OUT                        0x00000103  /* Phase error */
+#define SCSI_UNEXP_DIS                          0x00000104  /* unexpected disconnect */
+
+#define SCSI_INT_STATE                          0x00010000  /* unknown Interrupt number is stored in 16 LSB */
+
+
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+
+   
+#endif /* _SCSI_H */
+
index e3e4dcecb228afb19242e47db24b77d87da2fc15..e2d5df5bcd12c153f7b5d26dcb9cb4e930770a14 100644 (file)
@@ -24,6 +24,6 @@
 #ifndef        __VERSION_H__
 #define        __VERSION_H__
 
-#define        PPCBOOT_VERSION "PPCBoot 1.0.1"
+#define        PPCBOOT_VERSION "PPCBoot 1.0.2"
 
 #endif /* __VERSION_H__ */
index 7435d81623927ea25c0090f376b436c3dbc91951..db29c61b8ed9f91e8444da0eb0de09dca90063e8 100644 (file)
@@ -27,7 +27,7 @@ include $(TOPDIR)/config.mk
 
 LIB    = librtc.a
 
-OBJS   = date.o pcf8563.o mpc8xx.o
+OBJS   = date.o pcf8563.o mpc8xx.o mc146818.o
 
 all:   $(LIB)
 
diff --git a/rtc/mc146818.c b/rtc/mc146818.c
new file mode 100644 (file)
index 0000000..6469391
--- /dev/null
@@ -0,0 +1,157 @@
+/*
+ * (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
+ */
+
+/*
+ * Date & Time support for the MC146818 (PIXX4) RTC
+ */
+
+/*#define      DEBUG*/
+
+#include <ppcboot.h>
+#include <command.h>
+#include <rtc.h>
+
+#if defined(CONFIG_RTC_MC146818) && (CONFIG_COMMANDS & CFG_CMD_DATE)
+
+static uchar rtc_read  (uchar reg);
+static void  rtc_write (uchar reg, uchar val);
+static uchar bin2bcd   (unsigned int n);
+static unsigned bcd2bin(uchar c);
+
+#define RTC_PORT_MC146818              CFG_ISA_IO_BASE_ADDRESS +  0x70
+#define RTC_SECONDS            0x00
+#define RTC_SECONDS_ALARM      0x01
+#define RTC_MINUTES                            0x02
+#define RTC_MINUTES_ALARM      0x03
+#define RTC_HOURS                                      0x04
+#define RTC_HOURS_ALARM                0x05
+#define RTC_DAY_OF_WEEK                0x06
+#define RTC_DATE_OF_MONTH      0x07
+#define RTC_MONTH                                      0x08
+#define RTC_YEAR                                               0x09
+#define RTC_CONFIG_A                           0x0A
+#define RTC_CONFIG_B                           0x0B
+#define RTC_CONFIG_C                           0x0C
+#define RTC_CONFIG_D                           0x0D
+
+
+/* ------------------------------------------------------------------------- */
+
+void rtc_get (struct rtc_time *tmp)
+{
+       uchar sec, min, hour, mday, wday, mon, year;
+  /* here check if rtc can be accessed */
+       while((rtc_read(RTC_CONFIG_A)&0x80)==0x80);
+       sec             = rtc_read (RTC_SECONDS);
+       min             = rtc_read (RTC_MINUTES);
+       hour    = rtc_read (RTC_HOURS);
+       mday    = rtc_read (RTC_DATE_OF_MONTH);
+       wday    = rtc_read (RTC_DAY_OF_WEEK);
+       mon             = rtc_read (RTC_MONTH);
+       year    = rtc_read (RTC_YEAR);
+#ifdef RTC_DEBUG
+       printf ( "Get RTC year: %02x mon/cent: %02x mday: %02x wday: %02x "
+               "hr: %02x min: %02x sec: %02x\n",
+               year, mon_cent, mday, wday,
+               hour, min, sec );
+       printf ( "Alarms: month: %02x hour: %02x min: %02x sec: %02x\n",
+               rtc_read (RTC_CONFIG_D) & 0x3F,
+               rtc_read (RTC_HOURS_ALARM),
+               rtc_read (RTC_MINUTES_ALARM),
+               rtc_read (RTC_SECONDS_ALARM) );
+#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)
+{
+#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
+       rtc_write(RTC_CONFIG_B,0x82); /* 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_DATE_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 ));
+       rtc_write(RTC_CONFIG_B,0x02); /* enables the RTC to update the regs */
+       
+}
+
+void rtc_reset (void)
+{
+       rtc_write(RTC_CONFIG_B,0x82); /* disables the RTC to update the regs */
+       rtc_write(RTC_CONFIG_A,0x20); /* Normal OP */
+       rtc_write(RTC_CONFIG_B,0x00); 
+       rtc_write(RTC_CONFIG_B,0x00);  
+       rtc_write(RTC_CONFIG_B,0x02); /* enables the RTC to update the regs */
+}
+
+/* ------------------------------------------------------------------------- */
+
+static uchar rtc_read (uchar reg)
+{
+       out8(RTC_PORT_MC146818,reg);
+       return(in8(RTC_PORT_MC146818+1));
+}
+
+static void rtc_write (uchar reg, uchar val)
+{
+       out8(RTC_PORT_MC146818,reg);
+       out8(RTC_PORT_MC146818+1,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));
+}
+
+#endif /* CONFIG_RTC_MC146818 && CFG_CMD_DATE */
index 7f2a67eecf14ef65b1cf13d0f3923a732c2a28fd..c4e9255ce6db75e069ebce4e07be8613d701e3f3 100644 (file)
@@ -91,6 +91,7 @@ table_entry_t os_name[] = {
     {  IH_OS_VXWORKS,  "vxworks",      "VxWorks",              },
     {  IH_OS_PSOS,     "psos",         "pSOS",                 },
     {  IH_OS_QNX,      "qnx",          "QNX",                  },
+    {  IH_OS_PPCBOOT,  "ppcboot",      "PPCBoot",              },
     {  -1,             "",             "",                     },
 };
 
@@ -100,6 +101,7 @@ table_entry_t type_name[] = {
     {  IH_TYPE_KERNEL,     "kernel",     "Kernel Image",       },
     {  IH_TYPE_RAMDISK,    "ramdisk",    "RAMDisk Image",      },
     {  IH_TYPE_MULTI,      "multi",      "Multi-File Image",   },
+    {  IH_TYPE_FIRMWARE,   "firmware",   "Firmware",           },
     {  -1,                 "",           "",                   },
 };