Modifications for 1.1.2:
======================================================================
+* Patch by Denis Peter, 5 Dec 2001
+ - add USB support for 40x
+ - add support for MIP405 board
+ - Move PIP405 into new manufacturer's directory,
+ separate out common stuff
+ - changed scsi_init in file common/board.c to make it common to IDE
+ init
+ - added last_stage_init in common/board.c (#ifdef
+ CONFIG_LAST_STAGE_INIT) for parts which needs working interrupts
+ (ISA Keyboard etc)
+ - replaced "defined(CONFIG_PIP405)" in common/cmd_i2c.c with
+ "defined(CONFIG_I2C405)" which is also defined for MIP405. Other
+ 405 based boards may also change to this define. (CONFIG_W70
+ CONFIG_CPCI405, CONFIG_AR405, CONFIG_WALNUT405 and CONFIG_ERIC).
+ - add "device_deregister()" in common/devices.c. Used to
+ deregister the USB keyboard.
+ - removed drv_isa_kbd_init() in common/devices.c because it will
+ not work when initializing before setting up the interrupts.
+ - changed type of TimeOut from int to ulong and the sequence how
+ the TimeOut value is calculated (to prevent an overflow for a CPU
+ frequency of 266MHz) in file cpu/ppc4xx/i2c.c.
+ - fix size rounding in disc/part.c
+
+* Fix for broken SanDisk which spuriously set high bit in function ID
+ CIS tuple
+ Patch by Peter Desnoyers, 05 Dec 2001
+
* Add new 8260 mask revision support
* Add support for TTTech C2MON board
N: Murray Jensen
E: Murray.Jensen@cmst.csiro.au
-D: Initial 8260 support; GDB support; Port to Cogent+Hymod boards; Hymod Board Database
+D: Initial 8260 support; GDB support
+D: Port to Cogent+Hymod boards; Hymod Board Database
W: http://www.msa.cmst.csiro.au/ourstaff/MurrayJensen/mjj.html
N: Yoo. Jonghoon
N: Denis Peter
E: d.peter@mpl.ch
-D: Port to PIP405 board, support for SCSI, floppy, CDROM, CT69000 video, ...
+D: Support for 4xx SCSI, floppy, CDROM, CT69000 video, ...
+D: Support for PIP405 board
+D: Support for MIP405 board
N: Bill Pitts
E: wlp@mindspring.com
CANBT CPCI405 \
CPCIISER4 CRAYL1 \
DASA_SIM ERIC \
- OCRTC PIP405 \
- W7OLMC W7OLMG \
- WALNUT405 \
+ MIP405 OCRTC \
+ PIP405 W7OLMC \
+ W7OLMG WALNUT405 \
"
#########################################################################
echo "CPU = ppc4xx" >>config.mk ; \
echo "#include <config_$(@:_config=).h>" >config.h
+MIP405_config:unconfig
+ @echo "Configuring for $(@:_config=) Board..." ; \
+ cd ./include ; \
+ echo "ARCH = ppc" > config.mk ; \
+ echo "BOARD = mip405" >>config.mk ; \
+ echo "CPU = ppc4xx" >>config.mk ; \
+ echo "VENDOR = mpl" >>config.mk ; \
+ echo "#include <config_$(@:_config=).h>" >config.h
+
OCRTC_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 "VENDOR = mpl" >>config.mk ; \
echo "#include <config_$(@:_config=).h>" >config.h
W7OLMC_config \
- board/lantec Files specific to LANTEC boards
- board/lwmon Files specific to LWMON boards
- board/mbx8xx Files specific to MBX boards
-- board/pip405 Files specific to PIP405 boards
+- board/mpl/common Common files for MPL boards
+- board/mpl/pip405 Files specific to PIP405 boards
+- board/mpl/mip405 Files specific to MIP405 boards
- board/RPXlite Files specific to RPXlite boards
- board/rpxsuper
Files specific to RPXsuper boards
- Board Type: Define exactly one of
- 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,
- CONFIG_PCU_E, CONFIG_CCM
+ CONFIG_ADCIOP, CONFIG_FADS, CONFIG_RPXLITE,
+ CONFIG_ADS, CONFIG_FPS850L, CONFIG_RPXSUPER,
+ CONFIG_BSEIP, CONFIG_HERMES, CONFIG_SANDPOINT,
+ CONFIG_CCM, CONFIG_HYMOD, CONFIG_SBC8260,
+ CONFIG_COGENT, CONFIG_IP860, CONFIG_SM850,
+ CONFIG_COGENT, CONFIG_IVMS8, CONFIG_SPD823TS,
+ CONFIG_CPCI405, CONFIG_MBX, CONFIG_SXNI855T,
+ CONFIG_CU824, CONFIG_MIP405, CONFIG_TQM823L,
+ CONFIG_ERIC, CONFIG_PCU_E, CONFIG_TQM8260,
+ CONFIG_ETX094, CONFIG_PIP405, CONFIG_TQM850L,
+ CONFIG_EVB64260, CONFIG_RDSPROTO, CONFIG_TQM855L,
+ CONFIG_EVB64260, CONFIG_RPXCLASSIC, CONFIG_TQM860L
- CPU Module Type: (if CONFIG_COGENT is defined)
Define exactly one of
CFG_CMD_DHCP DHCP support
CFG_CMD_BEDBUG Include BedBug Debugger
CFG_CMD_ELF bootelf, bootvx
- CFG_CMD_FDC Floppy Disk Support
- CFG_CMD_SCSI SCSI Support
+ CFG_CMD_FDC * Floppy Disk Support
+ CFG_CMD_SCSI * SCSI Support
CFG_CMD_SETGETDCR Support for DCR Register access (4xx only)
- CFG_CMD_BSP * Board SPecific functions
+ CFG_CMD_USB * USB support
+ CFG_CMD_BSP * Board SPecific functions
-----------------------------------------------
CFG_CMD_ALL all
maximum numbers of LUNs, SCSI ID's and target
devices.
+- USB Support:
+ At the moment only the UHCI host controller is
+ supported (PIP405, MIP405); define
+ CONFIG_USB_UHCI to enable it.
+ define CONFIG_USB_KEYBOARD to enable the USB Keyboard
+ end define CONFIG_USB_STORAGE to enable the USB
+ storage devices.
+ Note:
+ Supported are USB Keyboards and USB Floppy drives
+ (TEAC FD-05PUB).
+
- Keyboard Support:
CONFIG_ISA_KEYBOARD
--- /dev/null
+/*
+ * (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
+ */
+
+/*
+ * 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>
+#ifdef CONFIG_PIP405
+#include "../pip405/pip405.h"
+#endif
+#ifdef CONFIG_MIP405
+#include "../mip405/mip405.h"
+#endif
+
+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
+
+#ifdef CONFIG_MIP405
+#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;
+ unsigned char rc;
+
+ rc=switch_cs(FALSE); /* map Flash High */
+
+ if(rc)
+ 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(rc); */ /* switch mode back */
+ 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;
+}
+
+/*-----------------------------------------------------------------------
+ */
+
+int flash_erase (flash_info_t *info, int s_first, int s_last)
+{
+ volatile FLASH_WORD_SIZE *addr = (FLASH_WORD_SIZE *)(info->start[0]);
+ volatile FLASH_WORD_SIZE *addr2;
+ int flag, prot, sect, 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 1;
+ }
+
+ if (info->flash_id == FLASH_UNKNOWN) {
+ printf ("Can't erase unknown flash type - aborted\n");
+ return 1;
+ }
+
+ prot = 0;
+ for (sect=s_first; sect<=s_last; ++sect) {
+ if (info->protect[sect]) {
+ prot++;
+ }
+ }
+
+ if (prot) {
+ printf ("- Warning: %d protected sectors will not be erased!\n",
+ prot);
+ } else {
+ printf ("\n");
+ }
+
+ 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");
+ return 0;
+}
+
+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 wp, data;
+ int rc;
+ /* int i, l, rc; */
+ /* unsigned char sw; */
+ ulong *srcp;
+
+
+
+ if((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL){
+ unlock_intel_sectors(info,addr,cnt);
+ }
+ wp=addr;
+ srcp=(ulong *)src;
+ while (cnt >= 4) {
+ data=*srcp++;
+ 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);
+ }
+ return -1;
+#if 0
+ 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);
+ }
+ rc=write_word(info, wp, data);
+ return rc;
+
+#endif
+}
+
+/*-----------------------------------------------------------------------
+ * Write a word to Flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ */
+static FLASH_WORD_SIZE *read_val = (FLASH_WORD_SIZE *)0x200000;
+
+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)0x00500050;
+ dest2[i] = (FLASH_WORD_SIZE)0x00400040;
+ *read_val++ = data2[i];
+ dest2[i] = data2[i];
+ if (flag)
+ enable_interrupts();
+ /* data polling for D7 */
+ start = get_timer (0);
+ udelay(10);
+ 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)0x00FF00FF; /* return to read mode */
+ udelay(10);
+ dest2[i] = (FLASH_WORD_SIZE)0x00FF00FF; /* return to read mode */
+ if(dest2[i]!=data2[i])
+ printf("Error at %p 0x%04X != 0x%04X\n",&dest2[i],dest2[i],data2[i]);
+
+ }
+ 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);
+}
+
+/*-----------------------------------------------------------------------
+ */
--- /dev/null
+/*
+ * (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 "isa.h"
+#include "pci.h"
+#include "kbd.h"
+#include "video.h"
+
+extern int drv_isa_kbd_init (void);
+
+#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 */
+ {0xF1, 00}, /* set PPort to normal */
+ {0x30, 1}, /* and activate the device */
+ {0xFF, 0} /* end of device table */
+};
+/* paralell port (logical device 3) Floppy assigned to lpt */
+const SIO_LOGDEV_TABLE sio_pport_fdc[] = {
+ {0x60, 3}, /* set IO to PPort (378) */
+ {0x61, 0x78}, /* set IO to PPort (378) */
+ {0x70, 07}, /* set IRQ 7 for PPort */
+ {0xF1, 02}, /* set PPort to Floppy */
+ {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 */
+};
+
+
+/*******************************************************************************
+* 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_write_table(SIO_LOGDEV_TABLE *ldt,unsigned char ldev)
+{
+ while (ldt->index != 0xFF) {
+ write_cfg_super_IO(SIO_CFG_PORT, ldev, ldt->index, ldt->val);
+ ldt++;
+ } /* endwhile */
+}
+
+void isa_sio_loadtable(void)
+{
+ unsigned char *s = getenv("floppy");
+ /* setup Floppy device 0*/
+ isa_write_table((SIO_LOGDEV_TABLE *)&sio_fdc,0);
+ /* setup parallel port device 3 */
+ if(s && !strncmp(s, "lpt", 3)) {
+ printf("SIO: Floppy assigned to LPT\n");
+ /* floppy is assigned to the LPT */
+ isa_write_table((SIO_LOGDEV_TABLE *)&sio_pport_fdc,3);
+ }
+ else {
+ /*printf("Floppy assigned to internal port\n");*/
+ isa_write_table((SIO_LOGDEV_TABLE *)&sio_pport,3);
+ }
+ /* setup Com1 port device 4 */
+ isa_write_table((SIO_LOGDEV_TABLE *)&sio_com1,4);
+ /* setup Com2 port device 5 */
+ isa_write_table((SIO_LOGDEV_TABLE *)&sio_com2,5);
+ /* setup keyboards device 7 */
+ isa_write_table((SIO_LOGDEV_TABLE *)&sio_keyboard,7);
+}
+
+
+void isa_sio_setup(void)
+{
+ 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);
+}
+
+
+/******************************************************************
+ * Init the ISA bus and devices.
+ */
+
+
+int isa_init(void)
+{
+ isa_sio_setup();
+ drv_isa_kbd_init();
+ return 0;
+}
+
+
+
--- /dev/null
+/*
+ * (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
--- /dev/null
+/*
+ * (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 "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 2000 /* 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;
+
+#define DEVNAME "kbd"
+
+/* 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);
+ }
+}
+
+#ifdef CFG_CONSOLE_OVERWRITE_ROUTINE
+extern int overwrite_console (void);
+#else
+int overwrite_console (void)
+{
+ return (0);
+}
+#endif
+
+int drv_isa_kbd_init (void)
+{
+ int error;
+ device_t kbddev ;
+ char *stdinname = getenv ("stdin");
+
+ if(isa_kbd_init()==-1)
+ return -1;
+ memset (&kbddev, 0, sizeof(kbddev));
+ strcpy(kbddev.name, DEVNAME);
+ 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);
+ if(error==0) {
+ /* check if this is the standard input device */
+ if(strcmp(stdinname,DEVNAME)==0) {
+ /* reassign the console */
+ if(overwrite_console()) {
+ return 1;
+ }
+ error=console_assign(stdin,DEVNAME);
+ if(error==0)
+ return 1;
+ else
+ return error;
+ }
+ return 1;
+ }
+ return 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;
+}
+
+
+int kb_wait(void)
+{
+ unsigned long timeout = KBC_TIMEOUT * 10;
+
+ do {
+ unsigned char status = handle_kbd_event();
+ if (!(status & KBD_STAT_IBF))
+ return 0; /* ok */
+ udelay(1000);
+ timeout--;
+ } while (timeout);
+ return 1;
+}
+
+void kbd_write_command_w(int data)
+{
+ if(kb_wait())
+ PRINTF("timeout in kbd_write_command_w\n");
+ kbd_write_command(data);
+}
+
+void kbd_write_output_w(int data)
+{
+ if(kb_wait())
+ PRINTF("timeout in kbd_write_output_w\n");
+ 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 "Kbd: 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 "Kbd: interface failed self test";
+ /*
+ * Enable the keyboard by allowing the keyboard clock to run.
+ */
+ kbd_write_command_w(KBD_CCMD_KBD_ENABLE);
+ status = kbd_wait_for_input();
+ /*
+ * 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 "Kbd: reset failed, no ACK";
+ }
+ } while (1);
+ if (kbd_wait_for_input() != KBD_REPLY_POR)
+ return "Kbd: 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 "Kbd: 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 "Kbd: 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 "Kbd: Set rate: no ACK";
+ kbd_write_output_w(0x00);
+ if (kbd_wait_for_input() != KBD_REPLY_ACK)
+ return "Kbd: Set rate: no ACK";
+ return NULL;
+}
+
+void kbd_interrupt(void)
+{
+ handle_kbd_event();
+}
+
+
+
+/* eof */
+
--- /dev/null
+/*
+ * (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
--- /dev/null
+/*
+ * (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
+ *
+ */
+
+/* NOT Used yet...
+ add following code to PIP405.c :
+int testdram (unsigned long ramsize)
+{
+ unsigned char s[32];
+ int i;
+ i=getenv_r("testmem",s,32);
+ if (i!=0) {
+ i=(int)simple_strtoul(s,NULL,10);
+ if((i>0)&&(i<0xf)) {
+ printf("testing ");
+ i=mem_test(0,ramsize,i);
+ if(i>0)
+ printf("ERROR ");
+ else
+ printf("Ok ");
+ }
+ }
+ return(1);
+}
+*/
+
+
+#include <ppcboot.h>
+#include <asm/processor.h>
+#include <405gp_i2c.h>
+
+#define FALSE 0
+#define TRUE 1
+
+#define TEST_QUIET 8
+#define TEST_SHOW_PROG 4
+#define TEST_SHOW_ERR 2
+#define TEST_SHOW_ALL 1
+
+#define TESTPAT1 0xAA55AA55
+#define TESTPAT2 0x55AA55AA
+#define TEST_PASSED 0
+#define TEST_FAILED 1
+#define MEGABYTE (1024*1024)
+
+
+
+
+
+typedef struct {
+ volatile unsigned long pat1;
+ volatile unsigned long pat2;
+} RAM_MEMTEST_PATTERN2;
+
+typedef struct {
+ volatile unsigned long addr;
+} RAM_MEMTEST_ADDRLINE;
+
+static __inline unsigned long Swap_32(unsigned long val)
+{
+ return(((val << 16) & 0xFFFF0000) | ((val >> 16) & 0x0000FFFF));
+}
+
+void testm_puts(int quiet, char *buf)
+{
+ if((quiet&TEST_SHOW_ALL)==TEST_SHOW_ALL)
+ puts(buf);
+}
+
+
+void Write_Error(int mode, unsigned long addr, unsigned long expected, unsigned long actual)
+{
+
+ char dispbuf[64];
+ sprintf(dispbuf,"\n ERROR @ 0x%08lX: (exp: 0x%08lX act: 0x%08lX) ",addr,expected,actual);
+ testm_puts(((mode & TEST_SHOW_ERR)==TEST_SHOW_ERR) ? TEST_SHOW_ALL : mode,dispbuf);
+}
+
+
+/*
+ * fills the memblock of <size> bytes from <startaddr> with pat1 and pat2
+ */
+
+
+void RAM_MemTest_WritePattern2(unsigned long startaddr, unsigned long size,
+ unsigned long pat1, unsigned long pat2)
+{
+ RAM_MEMTEST_PATTERN2 *p, *pe;
+
+ p = (RAM_MEMTEST_PATTERN2 *)startaddr;
+ pe = (RAM_MEMTEST_PATTERN2 *)(startaddr + size);
+
+ while (p < pe) {
+ p->pat1 = pat1;
+ p->pat2 = pat2;
+ p++;
+ } /* endwhile */
+}
+
+/*
+ * checks the memblock of <size> bytes from <startaddr> with pat1 and pat2
+ * returns the address of the first error or NULL if all is well
+ */
+
+void * RAM_MemTest_CheckPattern2(int mode,unsigned long startaddr, unsigned long size,
+ unsigned long pat1, unsigned long pat2)
+{
+ RAM_MEMTEST_PATTERN2 *p, *pe;
+ unsigned long actual1, actual2;
+
+ p = (RAM_MEMTEST_PATTERN2 *)startaddr;
+ pe = (RAM_MEMTEST_PATTERN2 *)(startaddr + size);
+
+ while (p < pe) {
+ actual1 = p->pat1; actual2 = p->pat2;
+
+ if (actual1 != pat1) {
+ Write_Error(mode,(unsigned long)&(p->pat1), pat1, actual1);
+ return((void *)&(p->pat1));
+ } /* endif */
+
+ if (actual2 != pat2) {
+ Write_Error(mode,(unsigned long)&(p->pat2), pat2, actual2);
+ return((void *)&(p->pat2));
+ } /* endif */
+
+ p++;
+ } /* endwhile */
+
+ return(NULL);
+}
+
+/*
+ * fills the memblock of <size> bytes from <startaddr> with the address
+ */
+
+void RAM_MemTest_WriteAddrLine(unsigned long startaddr, unsigned long size, int swapped)
+{
+ RAM_MEMTEST_ADDRLINE *p, *pe;
+
+ p = (RAM_MEMTEST_ADDRLINE *)startaddr;
+ pe = (RAM_MEMTEST_ADDRLINE *)(startaddr + size);
+
+ if (!swapped) {
+ while (p < pe) {
+ p->addr = (unsigned long)p;
+ p++;
+ } /* endwhile */
+ } else {
+ while (p < pe) {
+ p->addr = Swap_32((unsigned long)p);
+ p++;
+ } /* endwhile */
+ } /* endif */
+}
+
+/*
+ * checks the memblock of <size> bytes from <startaddr>
+ * returns the address of the error or NULL if all is well
+ */
+
+void * RAM_MemTest_CheckAddrLine(int mode,unsigned long startaddr, unsigned long size, int swapped)
+{
+ RAM_MEMTEST_ADDRLINE *p, *pe;
+ unsigned long actual, expected;
+
+ p = (RAM_MEMTEST_ADDRLINE *)startaddr;
+ pe = (RAM_MEMTEST_ADDRLINE *)(startaddr + size);
+
+ if (!swapped) {
+ while (p < pe) {
+ actual = p->addr;
+ expected = (unsigned long)p;
+ if (actual != expected) {
+ Write_Error(mode,(unsigned long)&(p->addr), expected, actual);
+ return((void *)&(p->addr));
+ } /* endif */
+ p++;
+ } /* endwhile */
+ }
+ else {
+ while (p < pe) {
+ actual = p->addr;
+ expected = Swap_32((unsigned long)p);
+ if (actual != expected) {
+ Write_Error(mode,(unsigned long)&(p->addr), expected, actual);
+ return((void *)&(p->addr));
+ } /* endif */
+ p++;
+ } /* endwhile */
+ } /* endif */
+
+ return(NULL);
+}
+
+/*
+ * checks the memblock of <size> bytes from <startaddr+size>
+ * returns the address of the error or NULL if all is well
+ */
+
+void * RAM_MemTest_CheckAddrLineReverse(int mode,unsigned long startaddr,
+ unsigned long size, int swapped)
+{
+ RAM_MEMTEST_ADDRLINE *p, *pe;
+ unsigned long actual, expected;
+
+ p = (RAM_MEMTEST_ADDRLINE *)(startaddr + size - sizeof(p->addr));
+ pe = (RAM_MEMTEST_ADDRLINE *)startaddr;
+
+ if (!swapped) {
+ while (p > pe) {
+ actual = p->addr;
+ expected = (unsigned long)p;
+ if (actual != expected) {
+ Write_Error(mode,(unsigned long)&(p->addr), expected, actual);
+ return((void *)&(p->addr));
+ } /* endif */
+ p--;
+ } /* endwhile */
+ } else {
+ while (p > pe) {
+ actual = p->addr;
+ expected = Swap_32((unsigned long)p);
+ if (actual != expected) {
+ Write_Error(mode,(unsigned long)&(p->addr), expected, actual);
+ return((void *)&(p->addr));
+ } /* endif */
+ p--;
+ } /* endwhile */
+ } /* endif */
+
+ return(NULL);
+}
+
+/*
+ * fills the memblock of <size> bytes from <startaddr> with walking bit pattern
+ */
+
+void RAM_MemTest_WriteWalkBit(unsigned long startaddr, unsigned long size)
+{
+ volatile unsigned long *p, *pe;
+ unsigned long i;
+
+ p = (unsigned long *)startaddr;
+ pe = (unsigned long *)(startaddr + size);
+ i = 0;
+
+ while (p < pe) {
+ *p = 1UL << i;
+ i = (i + 1 + (((unsigned long)p) >> 7)) % 32;
+ p++;
+ } /* endwhile */
+}
+
+/*
+ * checks the memblock of <size> bytes from <startaddr>
+ * returns the address of the error or NULL if all is well
+ */
+
+void * RAM_MemTest_CheckWalkBit(int mode,unsigned long startaddr, unsigned long size)
+{
+ volatile unsigned long *p, *pe;
+ unsigned long actual, expected;
+ unsigned long i;
+
+ p = (unsigned long *)startaddr;
+ pe = (unsigned long *)(startaddr + size);
+ i = 0;
+
+ while (p < pe) {
+ actual = *p;
+ expected = (1UL << i);
+ if (actual != expected) {
+ Write_Error(mode,(unsigned long)p, expected, actual);
+ return((void *)p);
+ } /* endif */
+ i = (i + 1 + (((unsigned long)p) >> 7)) % 32;
+ p++;
+ } /* endwhile */
+
+ return(NULL);
+}
+
+/*
+ * fills the memblock of <size> bytes from <startaddr> with "random" pattern
+ */
+
+void RAM_MemTest_WriteRandomPattern(unsigned long startaddr, unsigned long size, unsigned long *pat)
+{
+ unsigned long i, p;
+
+ p = *pat;
+
+ for (i = 0; i < (size / 4); i++) {
+ *(unsigned long *)(startaddr + i*4) = p;
+ if ((p % 2) > 0) {
+ p ^= i;
+ p >>= 1;
+ p |= 0x80000000;
+ } else {
+ p ^= ~i;
+ p >>= 1;
+ } /* endif */
+ } /* endfor */
+ *pat = p;
+}
+
+/*
+ * checks the memblock of <size> bytes from <startaddr>
+ * returns the address of the error or NULL if all is well
+ */
+
+void * RAM_MemTest_CheckRandomPattern(int mode,unsigned long startaddr, unsigned long size, unsigned long *pat)
+{
+ void *perr = NULL;
+ unsigned long i, p, p1;
+
+ p = *pat;
+
+ for (i = 0; i < (size / 4); i++) {
+ p1 = *(unsigned long *)(startaddr + i*4);
+ if ( p1 != p) {
+ if (perr == NULL) {
+ Write_Error(mode,startaddr + i*4, p, p1);
+ perr = (void *)(startaddr + i*4);
+ } /* endif */
+ } /* endif */
+
+ if ((p % 2) > 0) {
+ p ^= i;
+ p >>= 1;
+ p |= 0x80000000;
+ } else {
+ p ^= ~i;
+ p >>= 1;
+ } /* endif */
+ } /* endfor */
+
+ *pat = p;
+ return(perr);
+}
+
+
+void RAM_MemTest_WriteData1(unsigned long startaddr, unsigned long size, unsigned long *pat)
+{
+ RAM_MemTest_WritePattern2(startaddr, size, TESTPAT1, TESTPAT2);
+}
+
+void * RAM_MemTest_CheckData1(int mode, unsigned long startaddr, unsigned long size, unsigned long *pat)
+{
+ return (RAM_MemTest_CheckPattern2(mode, startaddr, size, TESTPAT1, TESTPAT2));
+}
+
+void RAM_MemTest_WriteData2(unsigned long startaddr, unsigned long size, unsigned long *pat)
+{
+ RAM_MemTest_WritePattern2(startaddr, size, TESTPAT2, TESTPAT1);
+}
+
+void * RAM_MemTest_CheckData2(int mode, unsigned long startaddr, unsigned long size, unsigned long *pat)
+{
+ return (RAM_MemTest_CheckPattern2(mode, startaddr, size, TESTPAT2, TESTPAT1));
+}
+
+void RAM_MemTest_WriteAddr1(unsigned long startaddr, unsigned long size, unsigned long *pat)
+{
+ RAM_MemTest_WriteAddrLine(startaddr, size, FALSE);
+}
+
+void * RAM_MemTest_Check1Addr1(int mode, unsigned long startaddr, unsigned long size, unsigned long *pat)
+{
+ return(RAM_MemTest_CheckAddrLine(mode,startaddr,size, FALSE));
+}
+
+void * RAM_MemTest_Check2Addr1(int mode, unsigned long startaddr, unsigned long size, unsigned long *pat)
+{
+ return(RAM_MemTest_CheckAddrLineReverse(mode,startaddr,size, FALSE));
+}
+
+void RAM_MemTest_WriteAddr2(unsigned long startaddr, unsigned long size, unsigned long *pat)
+{
+ RAM_MemTest_WriteAddrLine(startaddr, size, TRUE);
+}
+
+void * RAM_MemTest_Check1Addr2(int mode, unsigned long startaddr, unsigned long size, unsigned long *pat)
+{
+ return(RAM_MemTest_CheckAddrLine(mode,startaddr,size, TRUE));
+}
+
+void * RAM_MemTest_Check2Addr2(int mode, unsigned long startaddr, unsigned long size, unsigned long *pat)
+{
+ return(RAM_MemTest_CheckAddrLineReverse(mode,startaddr,size, TRUE));
+}
+
+
+
+typedef struct {
+ void (*test_write)(unsigned long startaddr, unsigned long size, unsigned long *pat);
+ char *test_write_desc;
+ void * (*test_check1)(int mode, unsigned long startaddr, unsigned long size, unsigned long *pat);
+ void * (*test_check2)(int mode, unsigned long startaddr, unsigned long size, unsigned long *pat);
+} RAM_MEMTEST_FUNC;
+
+
+#define TEST_STAGES 5
+const RAM_MEMTEST_FUNC test_stage[TEST_STAGES] = {
+ {RAM_MemTest_WriteData1, "data test 1...\n", RAM_MemTest_CheckData1, NULL},
+ {RAM_MemTest_WriteData2, "data test 2...\n", RAM_MemTest_CheckData2, NULL},
+ {RAM_MemTest_WriteAddr1, "address line test...\n", RAM_MemTest_Check1Addr1, RAM_MemTest_Check2Addr1},
+ {RAM_MemTest_WriteAddr2, "address line test (swapped)...\n", RAM_MemTest_Check1Addr2, RAM_MemTest_Check2Addr2},
+ {RAM_MemTest_WriteRandomPattern, "random data test...\n", RAM_MemTest_CheckRandomPattern, NULL}
+};
+
+
+
+int mem_test(unsigned long start, unsigned long ramsize, int quiet)
+{
+ unsigned long errors,stage;
+ unsigned long startaddr, size, i;
+ const unsigned long blocksize = 0x80000; /* check in 512KB blocks */
+ unsigned long *perr;
+ unsigned long rdatapat;
+ char dispbuf[80];
+ int status = TEST_PASSED;
+ int prog=0;
+
+ errors = 0;
+ startaddr = start;
+ size = ramsize;
+ if((quiet&TEST_SHOW_PROG)==TEST_SHOW_PROG) {
+ prog++;
+ printf(".");
+ }
+ sprintf(dispbuf,"\n\nMemory Test: addr = 0x%lx size = 0x%lx\n",startaddr,size);
+ testm_puts(quiet,dispbuf);
+ for(stage=0;stage<TEST_STAGES;stage++){
+ sprintf(dispbuf,test_stage[stage].test_write_desc);
+ testm_puts(quiet,dispbuf);
+ /* fill SDRAM */
+ rdatapat = 0x12345678;
+ sprintf(dispbuf,"writing block: ");
+ testm_puts(quiet,dispbuf);
+ for (i = 0; i < size; i += blocksize) {
+ sprintf(dispbuf,"%04lX\b\b\b\b",i / blocksize);
+ testm_puts(quiet,dispbuf);
+ test_stage[stage].test_write(startaddr+i, blocksize, &rdatapat);
+ } /* endfor */
+ sprintf(dispbuf,"\n");
+ testm_puts(quiet,dispbuf);
+ if((quiet&TEST_SHOW_PROG)==TEST_SHOW_PROG) {
+ prog++;
+ printf(".");
+ }
+ /* check SDRAM */
+ rdatapat = 0x12345678;
+ sprintf(dispbuf,"checking block: ");
+ testm_puts(quiet,dispbuf);
+ for (i = 0; i < size; i += blocksize) {
+ sprintf(dispbuf,"%04lX\b\b\b\b",i / blocksize);
+ testm_puts(quiet,dispbuf);
+ if ((perr = test_stage[stage].test_check1(quiet,startaddr+i, blocksize,&rdatapat)) != NULL) {
+ status = TEST_FAILED;
+ } /* endif */
+ } /* endfor */
+ sprintf(dispbuf,"\n");
+ testm_puts(quiet,dispbuf);
+ if((quiet&TEST_SHOW_PROG)==TEST_SHOW_PROG) {
+ prog++;
+ printf(".");
+ }
+ if( test_stage[stage].test_check2!=NULL) {
+ /* check2 SDRAM */
+ sprintf(dispbuf,"2nd checking block: ");
+ rdatapat = 0x12345678;
+ testm_puts(quiet,dispbuf);
+ for (i = 0; i < size; i += blocksize) {
+ sprintf(dispbuf,"%04lX\b\b\b\b",i / blocksize);
+ testm_puts(quiet,dispbuf);
+ if ((perr = test_stage[stage].test_check2(quiet,startaddr+i, blocksize,&rdatapat)) != NULL) {
+ status = TEST_FAILED;
+ } /* endif */
+ } /* endfor */
+ sprintf(dispbuf,"\n");
+ testm_puts(quiet,dispbuf);
+ if((quiet&TEST_SHOW_PROG)==TEST_SHOW_PROG) {
+ prog++;
+ printf(".");
+ }
+ }
+
+ } /* next stage */
+ if((quiet&TEST_SHOW_PROG)==TEST_SHOW_PROG) {
+ while(prog-->0)
+ printf("\b \b");
+ }
+
+ if (status == TEST_FAILED)
+ errors++;
+
+ return(errors);
+}
+
+
--- /dev/null
+/*-----------------------------------------------------------------------------+
+|
+| 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
++-----------------------------------------------------------------------------*/
+/*
+ * Adapted 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.h"
+#include <asm/processor.h>
+#include "isa.h"
+
+
+void pciinfo(int bus_no);
+#ifdef CONFIG_405GP
+
+#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;
+
+
+
+/*-----------------------------------------------------------------------------+
+| pci_init. Initializes the 405GP PCI Configuration regs.
++-----------------------------------------------------------------------------*/
+void pci_init(bd_t *dummy)
+{
+ 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
+
+
+ /*
+ * 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.
+ +--------------------------------------------------------------------------*/
+ PCI_Scan(0);
+#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);
+}
+
+#include "pci_parts.h"
+
+/*
+ * Returns the pointer to the func config table, or NULL, if it not available
+ * if the revision is ff in the table, it will not be chcked
+ */
+
+PCI_DEV_CFG_TABLE *PCI_Get_Func_Table(unsigned short vend_id,unsigned short dev_id,unsigned char revision,unsigned char func)
+{
+ int i;
+ i=0;
+ while(pcidevtbl[i].vendorID!=0xffff) {
+ if((pcidevtbl[i].vendorID == vend_id) &&
+ (pcidevtbl[i].deviceID == dev_id) &&
+ (pcidevtbl[i].func == func) &&
+ ((pcidevtbl[i].revision == 0xff) || (pcidevtbl[i].revision == revision))) {
+#ifdef PCI_DEBUG
+ printf("Table found for 0x%04X 0x%04X\n",vend_id,dev_id);
+#endif
+ return &pcidevtbl[i];
+ }
+ i++; /* proceed all entries */
+ }
+#ifdef PCI_DEBUG
+ printf("No Table found for 0x%04X 0x%04X\n",vend_id,dev_id);
+#endif
+ return NULL;
+}
+
+
+/*-----------------------------------------------------------------------
+|
+| 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 bus_no)
+{
+ int device_no,i;
+ int BusDevFunc;
+ unsigned short vend_id,dev_id;
+ unsigned char revision,func,header;
+ PCI_DEV_CFG_TABLE *pci_dev_table=NULL;
+ /*--------------------------------------------------------------------------+
+ | Start with device 1, the 405GP is device 0. MCG 01/04/99
+ +--------------------------------------------------------------------------*/
+ /* init all known (on Board devices) first */
+ for (device_no = 1; device_no < MAX_PCI_DEVICES; device_no++)
+ {
+ BusDevFunc = (bus_no << 16) | (device_no << 11);
+ if((unsigned short)PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_VENDOR_ID, 2) != 0xffff) {
+ header = (unsigned char)PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_HEADER_TYPE, 1);
+ for(func=0;func<MAX_PCI_FUNCTIONS;func++) { /* scan / init all functions */
+ BusDevFunc = (bus_no << 16) | (device_no << 11) | (func << 8);
+ vend_id = (unsigned short)PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_VENDOR_ID, 2);
+ if(vend_id==0xffff) {
+ #ifdef PCI_DEBUG
+ printf("was last function\n");
+ #endif
+ break;
+ }
+ dev_id = (unsigned short)PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_DEVICE_ID, 2);
+ revision = (unsigned char)PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_REVISION, 1);
+ #ifdef PCI_DEBUG
+ printf("search for 0x%04x 0x%04x 0x%02x %x\n",vend_id,dev_id,revision,func);
+ #endif
+ pci_dev_table=PCI_Get_Func_Table(vend_id,dev_id,revision,func);
+ if(pci_dev_table==NULL) {
+ #ifdef PCI_DEBUG
+ printf("not found\n");
+ #endif
+ break;
+ }
+ /* table found, configure */
+ i=0;
+ while(pci_dev_table->fcntable[i].width!=0) {
+ PCI_Write_CFG_Reg(BusDevFunc,pci_dev_table->fcntable[i].index,
+ pci_dev_table->fcntable[i].val,pci_dev_table->fcntable[i].width);
+ #ifdef PCI_DEBUG
+ printf(" Reg 0x%02X Value 0x%08lX Width %02d written\n",pci_dev_table->fcntable[i].index,
+ pci_dev_table->fcntable[i].val,pci_dev_table->fcntable[i].width);
+ #endif
+ i++;
+ }
+ if((header & 0x80)==0)
+ break; /* no more functions */
+ } /* next function */
+ } /* if device available */
+ } /* all devices */
+#if 0
+ /***************************************************************************
+ * 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 */
+ }
+ }
+ }
+
+ 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
+ }
+ }
+#endif
+
+}
+
+
+/*-----------------------------------------------------------------------
+| 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%08lx\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%lx 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%lx 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%08lx\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%lx 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%lx 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_405GP */
--- /dev/null
+/*
+ * (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_H
+#define _PCI_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 for PCI Initialization */
+
+typedef struct {
+ const int index;
+ const unsigned long val;
+ const int with;
+} PCI_CFG_TABLE;
+
+
+typedef struct {
+ int index; /* address */
+ unsigned long val; /* value */
+ int width; /* data size */
+}PCI_FCN_CFG_TABLE;
+
+typedef struct {
+ unsigned short vendorID; /* Vendor ID */
+ unsigned short deviceID; /* Device ID */
+ unsigned char revision; /* Device ID */
+ unsigned char func; /* Function number */
+ PCI_FCN_CFG_TABLE fcntable[10];
+}PCI_DEV_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);
+
+/***************************************************************************
+* 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
--- /dev/null
+ /*
+ * (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_PARTS_H_
+#define _PCI_PARTS_H_
+
+
+/* Board specific file containing:
+ * - PCI Memory Mapping
+ * - PCI IO Mapping
+ * - PCI Interrupt Mapping
+ */
+
+/* PIP405 PCI INT Routing:
+ * IRQ0 VECTOR
+ * PIXX4 IDSEL = AD16 INTA# 28 (Function 2 USB is INTD# = 31)
+ * VGA IDSEL = AD17 INTB# 29
+ * SCSI IDSEL = AD18 INTC# 30
+ * PC104 IDSEL0 = AD20 INTA# 28
+ * PC104 IDSEL1 = AD21 INTB# 29
+ * PC104 IDSEL2 = AD22 INTC# 30
+ * PC104 IDSEL3 = AD23 INTD# 31
+ *
+ * busdevfunc = EXXX XXXX BBBB BBBB DDDD DFFF RRRR RR00
+ * ^ ^ ^ ^ ^
+ * 31 23 15 10 7
+ * E = Enabled
+ * B = Bussnumber
+ * D = Devicenumber (Device0 = AD10)
+ * F = Functionnumber
+ * R = Registernumber
+ *
+ * Device = (busdevfunc>>11) + 10
+ * Vector = devicenumber % 4 + 28
+ *
+ */
+#define PCI_DEV_NUMBER(x) (((x>>11) & 0x1f) + 10)
+#define PCI_IRQ_VECTOR(x) (PCI_DEV_NUMBER(x) % 4) + 28
+
+
+/* PCI Device List for PIP405 */
+
+/* Mapping:
+ * +-------------+------------+------------+--------------------------------+
+ * ¦ PCI MemAddr | PCI IOAddr | Local Addr | Device / Function |
+ * +-------------+------------+------------+--------------------------------+
+ * | 0x00000000 | | 0xA0000000 | ISA Memory (hard wired) |
+ * | 0x00FFFFFF | | 0xA0FFFFFF | |
+ * +-------------+------------+------------+--------------------------------+
+ * | | 0x00000000 | 0xE8000000 | ISA IO (hard wired) |
+ * | | 0x0000FFFF | 0xE800FFFF | |
+ * +-------------+------------+------------+--------------------------------+
+ * | 0x80000000 | | 0x80000000 | VGA Controller Memory |
+ * | 0x80FFFFFF | | 0x80FFFFFF | |
+ * +-------------+------------+------------+--------------------------------+
+ * | 0x81000000 | | 0x81000000 | SCSI Controller Memory |
+ * | 0x81FFFFFF | | 0x81FFFFFF | |
+ * +-------------+------------+------------+--------------------------------+
+ */
+
+static PCI_DEV_CFG_TABLE pcidevtbl[]={
+/* PIIX4 ISA Bridge Function 0 */
+{0x8086,0x7110, 0xff,0, {
+ {PCI_CFG_PIIX4_SERIRQ, 0xD0, 1},/* enable Continous SERIRQ Pin */
+ {PCI_CFG_PIIX4_GENCFG, 0x00010000, 4},/* enable SERIRQs */
+ {PCI_CFG_PIIX4_XBCS, 0x0080, 2}, /* disable all peri CS */
+ {PCI_CFG_PIIX4_RTCCFG, 0x21, 1}, /* enable RTC */
+ {0xFFFF, 0,0}} /* end of device table */
+},
+/* PIIX4 IDE Controller Function 1 */
+{0x8086,0x7111,0xff,1,{
+ {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 */
+},
+/* PIIX4 USB Controller Function 2 */
+{0x8086,0x7112,0xff,2,{
+ {PCI_CFG_DEV_INT_LINE, 31, 1},/* Int vector = 31 */
+ {PCI_CFG_BASE_ADDRESS_4, 0x0000E001, 4},/* Set IO Address to 0xe000 to 0xe01F */
+ {PCI_CFG_LATENCY_TIMER, 0x80, 1},/* Latency Timer 0x80 */
+ {0xC0, 0x2000, 2}, /* Legacy support */
+ {PCI_CFG_COMMAND, 0x0005, 2},/* enable IO access and Master */
+ {0xFFFF, 0,0}} /* end of device table */
+},
+/* VGA Controller ct69000 (logical device 0) */
+{0x102C,0x00C0,0xff,0,{
+ {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 */
+},
+/* Symbois 810 function 0 */
+{0x1000,0x0001,0xff,0,{
+ {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 */
+},
+/* Terminator */
+{0xffff,0xffff,0xff,0xff,{
+ {0xFFFF, 0,0}} /* end of device table */
+}
+};
+#endif /* _PCI_PARTS_H_ */
+
+
+
+
+
--- /dev/null
+/*
+ * (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.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) */
+
+
--- /dev/null
+/*
+ * (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
--- /dev/null
+/*
+ * (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: Part of this code has been derived from linux
+ *
+ */
+
+/**********************************************************************
+ * How it works:
+ * -------------
+ * The framelist / Transfer descriptor / Queue Heads are similar like
+ * in the linux usb_uhci.c.
+ *
+ * During initialization, the following skeleton is allocated in init_skel:
+ *
+ * framespecific | common chain
+ *
+ * framelist[]
+ * [ 0 ]-----> TD ---------\
+ * [ 1 ]-----> TD ----------> TD ------> QH -------> QH -------> QH ---> NULL
+ * ... TD ---------/
+ * [1023]-----> TD --------/
+ *
+ * ^^ ^^ ^^ ^^ ^^
+ * 7 TDs for 1 TD for Start of Start of End Chain
+ * INT (2-128ms) 1ms-INT CTRL Chain BULK Chain
+ *
+ *
+ * Since this is a bootloader, the isochronous transfer descriptor have been removed.
+ *
+ * Interrupt Transfers.
+ * --------------------
+ * For Interupt transfers USB_MAX_TEMP_INT_TD Transfer descriptor are available. They
+ * will be inserted after the appropriate (depending the interval setting) skeleton TD.
+ * If an interrupt has been detected the dev->irqhandler is called. The status and number
+ * of transfered bytes is stored in dev->irq_status resp. dev->irq_act_len. If the
+ * dev->irqhandler returns 0, the interrupt TD is removed and disabled. If an 1 is returned,
+ * the interrupt TD will be reactivated.
+ *
+ * Control Transfers
+ * -----------------
+ * Control Transfers are issued by filling the tmp_td with the appropriate data and connect
+ * them to the qh_cntrl queue header. Before other control/bulk transfers can be issued,
+ * the programm has to wait for completion. This does not allows asynchronous data transfer.
+ *
+ * Bulk Transfers
+ * --------------
+ * Bulk Transfers are issued by filling the tmp_td with the appropriate data and connect
+ * them to the qh_bulk queue header. Before other control/bulk transfers can be issued,
+ * the programm has to wait for completion. This does not allows asynchronous data transfer.
+ *
+ *
+ */
+
+#include <ppcboot.h>
+
+#ifdef CONFIG_4xx
+#include <405gp_pci.h>
+#endif
+#ifdef CONFIG_USB_UHCI
+
+#include <usb.h>
+#include "usb_uhci.h"
+
+#define USB_MAX_TEMP_TD 128 /* number of temporary TDs for bulk and control transfers */
+#define USB_MAX_TEMP_INT_TD 32 /* number of temporary TDs for Interrupt transfers */
+
+
+#undef USB_UHCI_DEBUG
+
+#ifdef USB_UHCI_DEBUG
+#define USB_UHCI_PRINTF(fmt,args...) printf (fmt ,##args)
+#else
+#define USB_UHCI_PRINTF(fmt,args...)
+#endif
+
+
+static int irqvec = -1; /* irq vector, if -1 uhci is stopped / reseted */
+unsigned long usb_base_addr; /* base address */
+
+static uhci_td_t td_int[8]; /* Interrupt Transfer descriptors */
+static uhci_qh_t qh_cntrl; /* control Queue Head */
+static uhci_qh_t qh_bulk; /* bulk Queue Head */
+static uhci_qh_t qh_end; /* end Queue Head */
+static uhci_td_t td_last; /* last TD (linked with end chain) */
+
+/* temporary tds */
+static uhci_td_t tmp_td[USB_MAX_TEMP_TD]; /* temporary bulk/control td's */
+static uhci_td_t tmp_int_td[USB_MAX_TEMP_INT_TD]; /* temporary interrupt td's */
+
+static unsigned long framelist[1024] __attribute__ ((aligned (0x1000))); /* frame list */
+
+static struct virt_root_hub rh; /* struct for root hub */
+
+/**********************************************************************
+ * some forward decleration
+ */
+int uhci_submit_rh_msg(struct usb_device *dev, unsigned long pipe,
+ void *buffer, int transfer_len,struct devrequest *setup);
+
+/* fill a td with the approproiate data. Link, status, info and buffer
+ * are used by the USB controller itselfes, dev is used to identify the
+ * "connected" device
+ */
+void usb_fill_td(uhci_td_t* td,unsigned long link,unsigned long status,
+ unsigned long info, unsigned long buffer, unsigned long dev)
+{
+ td->link=swap_32(link);
+ td->status=swap_32(status);
+ td->info=swap_32(info);
+ td->buffer=swap_32(buffer);
+ td->dev_ptr=dev;
+}
+
+/* fill a qh with the approproiate data. Head and element are used by the USB controller
+ * itselfes. As soon as a valid dev_ptr is filled, a td chain is connected to the qh.
+ * Please note, that after completion of the td chain, the entry element is removed /
+ * marked invalid by the USB controller.
+ */
+void usb_fill_qh(uhci_qh_t* qh,unsigned long head,unsigned long element)
+{
+ qh->head=swap_32(head);
+ qh->element=swap_32(element);
+ qh->dev_ptr=0L;
+}
+
+/* get the status of a td->status
+ */
+unsigned long usb_uhci_td_stat(unsigned long status)
+{
+ unsigned long result=0;
+ result |= (status & TD_CTRL_NAK) ? USB_ST_NAK_REC : 0;
+ result |= (status & TD_CTRL_STALLED) ? USB_ST_STALLED : 0;
+ result |= (status & TD_CTRL_DBUFERR) ? USB_ST_BUF_ERR : 0;
+ result |= (status & TD_CTRL_BABBLE) ? USB_ST_BABBLE_DET : 0;
+ result |= (status & TD_CTRL_CRCTIMEO) ? USB_ST_CRC_ERR : 0;
+ result |= (status & TD_CTRL_BITSTUFF) ? USB_ST_BIT_ERR : 0;
+ result |= (status & TD_CTRL_ACTIVE) ? USB_ST_NOT_PROC : 0;
+ return result;
+}
+
+/* get the status and the transfered len of a td chain.
+ * called from the completion handler
+ */
+int usb_get_td_status(uhci_td_t *td,struct usb_device *dev)
+{
+ unsigned long temp,info;
+ unsigned long stat;
+ uhci_td_t *mytd=td;
+
+ if(dev->devnum==rh.devnum)
+ return 0;
+ dev->act_len=0;
+ stat=0;
+ do {
+ temp=swap_32((unsigned long)mytd->status);
+ stat=usb_uhci_td_stat(temp);
+ info=swap_32((unsigned long)mytd->info);
+ if(((info & 0xff)!= USB_PID_SETUP) &&
+ (((info >> 21) & 0x7ff)!= 0x7ff) &&
+ (temp & 0x7FF)!=0x7ff)
+ { /* if not setup and not null data pack */
+ dev->act_len+=(temp & 0x7FF) + 1; /* the transfered len is act_len + 1 */
+ }
+ if(stat) { /* status no ok */
+ dev->status=stat;
+ return -1;
+ }
+ temp=swap_32((unsigned long)mytd->link);
+ mytd=(uhci_td_t *)(temp & 0xfffffff0);
+ }while((temp & 0x1)==0); /* process all TDs */
+ dev->status=stat;
+ return 0; /* Ok */
+}
+
+
+/*-------------------------------------------------------------------
+ * LOW LEVEL STUFF
+ * assembles QHs und TDs for control, bulk and iso
+ *-------------------------------------------------------------------*/
+
+/* Submits a control message. That is a Setup, Data and Status transfer.
+ * Routine does not wait for completion.
+ */
+int submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
+ int transfer_len,struct devrequest *setup)
+{
+ unsigned long destination, status;
+ int maxsze = usb_maxpacket(dev, pipe);
+ unsigned long dataptr;
+ int len;
+ int pktsze;
+ int i=0;
+
+ if (!maxsze) {
+ USB_UHCI_PRINTF("uhci_submit_control_urb: pipesize for pipe %lx is zero\n", pipe);
+ return -1;
+ }
+ if(((pipe>>8)&0x7f)==rh.devnum) {
+ /* this is the root hub -> redirect it */
+ return uhci_submit_rh_msg(dev,pipe,buffer,transfer_len,setup);
+ }
+ USB_UHCI_PRINTF("uhci_submit_control start len %x, maxsize %x\n",transfer_len,maxsze);
+ /* The "pipe" thing contains the destination in bits 8--18 */
+ destination = (pipe & PIPE_DEVEP_MASK) | USB_PID_SETUP; /* Setup stage */
+ /* 3 errors */
+ status = (pipe & TD_CTRL_LS) | TD_CTRL_ACTIVE | (3 << 27);
+ /* (urb->transfer_flags & USB_DISABLE_SPD ? 0 : TD_CTRL_SPD); */
+ /* Build the TD for the control request, try forever, 8 bytes of data */
+ usb_fill_td(&tmp_td[i],UHCI_PTR_TERM ,status, destination | (7 << 21),(unsigned long)setup,(unsigned long)dev);
+#if 0
+ {
+ char *sp=(char *)setup;
+ printf("SETUP to pipe %lx: %x %x %x %x %x %x %x %x\n", pipe,
+ sp[0],sp[1],sp[2],sp[3],sp[4],sp[5],sp[6],sp[7]);
+ }
+#endif
+ dataptr = (unsigned long)buffer;
+ len=transfer_len;
+
+ /* If direction is "send", change the frame from SETUP (0x2D)
+ to OUT (0xE1). Else change it from SETUP to IN (0x69). */
+ destination = (pipe & PIPE_DEVEP_MASK) | ((pipe & USB_DIR_IN)==0 ? USB_PID_OUT : USB_PID_IN);
+ while (len > 0) {
+ /* data stage */
+ pktsze = len;
+ i++;
+ if (pktsze > maxsze)
+ pktsze = maxsze;
+ destination ^= 1 << TD_TOKEN_TOGGLE; /* toggle DATA0/1 */
+ usb_fill_td(&tmp_td[i],UHCI_PTR_TERM, status, destination | ((pktsze - 1) << 21),dataptr,(unsigned long)dev); /* Status, pktsze bytes of data */
+ tmp_td[i-1].link=swap_32((unsigned long)&tmp_td[i]);
+
+ dataptr += pktsze;
+ len -= pktsze;
+ }
+
+ /* Build the final TD for control status */
+ /* It's only IN if the pipe is out AND we aren't expecting data */
+
+ destination &= ~UHCI_PID;
+ if (((pipe & USB_DIR_IN)==0) || (transfer_len == 0))
+ destination |= USB_PID_IN;
+ else
+ destination |= USB_PID_OUT;
+ destination |= 1 << TD_TOKEN_TOGGLE; /* End in Data1 */
+ i++;
+ status &=~TD_CTRL_SPD;
+ /* no limit on errors on final packet , 0 bytes of data */
+ usb_fill_td(&tmp_td[i],UHCI_PTR_TERM, status | TD_CTRL_IOC, destination | (UHCI_NULL_DATA_SIZE << 21),0,(unsigned long)dev);
+ tmp_td[i-1].link=swap_32((unsigned long)&tmp_td[i]); /* queue status td */
+ /* usb_show_td(i+1);*/
+ USB_UHCI_PRINTF("uhci_submit_control end (%d tmp_tds used)\n",i);
+ /* first mark the control QH element terminated */
+ qh_cntrl.element=0xffffffffL;
+ /* set qh active */
+ qh_cntrl.dev_ptr=(unsigned long)dev;
+ /* fill in tmp_td_chain */
+ qh_cntrl.element=swap_32((unsigned long)&tmp_td[0]);
+ return 0;
+}
+
+/*-------------------------------------------------------------------
+ * Prepare TDs for bulk transfers.
+ */
+int submit_bulk_msg(struct usb_device *dev, unsigned long pipe, void *buffer,int transfer_len)
+{
+ unsigned long destination, status,info;
+ unsigned long dataptr;
+ int maxsze = usb_maxpacket(dev, pipe);
+ int len;
+ int i=0;
+
+ if(transfer_len < 0) {
+ printf("Negative transfer length in submit_bulk\n");
+ return -1;
+ }
+ if (!maxsze)
+ return -1;
+ /* The "pipe" thing contains the destination in bits 8--18. */
+ destination = (pipe & PIPE_DEVEP_MASK) | usb_packetid (pipe);
+ /* 3 errors */
+ status = (pipe & TD_CTRL_LS) | TD_CTRL_ACTIVE | (3 << 27);
+ /* ((urb->transfer_flags & USB_DISABLE_SPD) ? 0 : TD_CTRL_SPD) | (3 << 27); */
+ /* Build the TDs for the bulk request */
+ len = transfer_len;
+ dataptr = (unsigned long)buffer;
+ do {
+ int pktsze = len;
+ if (pktsze > maxsze)
+ pktsze = maxsze;
+ /* pktsze bytes of data */
+ info = destination | (((pktsze - 1)&UHCI_NULL_DATA_SIZE) << 21) |
+ (usb_gettoggle (dev, usb_pipeendpoint (pipe), usb_pipeout (pipe)) << TD_TOKEN_TOGGLE);
+
+ if((len-pktsze)==0)
+ status |= TD_CTRL_IOC; /* last one generates INT */
+
+ usb_fill_td(&tmp_td[i],UHCI_PTR_TERM, status, info,dataptr,(unsigned long)dev); /* Status, pktsze bytes of data */
+ if(i>0)
+ tmp_td[i-1].link=swap_32((unsigned long)&tmp_td[i]);
+ i++;
+ dataptr += pktsze;
+ len -= pktsze;
+ usb_dotoggle (dev, usb_pipeendpoint (pipe), usb_pipeout (pipe));
+ } while (len > 0);
+ /* first mark the bulk QH element terminated */
+ qh_bulk.element=0xffffffffL;
+ /* set qh active */
+ qh_bulk.dev_ptr=(unsigned long)dev;
+ /* fill in tmp_td_chain */
+ qh_bulk.element=swap_32((unsigned long)&tmp_td[0]);
+ return 0;
+}
+
+
+/* search a free interrupt td
+ */
+uhci_td_t *uhci_alloc_int_td(void)
+{
+ int i;
+ for(i=0;i<USB_MAX_TEMP_INT_TD;i++) {
+ if(tmp_int_td[i].dev_ptr==0) /* no device assigned -> free TD */
+ return &tmp_int_td[i];
+ }
+ return NULL;
+}
+
+#if 0
+void uhci_show_temp_int_td(void)
+{
+ int i;
+ for(i=0;i<USB_MAX_TEMP_INT_TD;i++) {
+ if((tmp_int_td[i].dev_ptr&0x01)!=0x1L) /* no device assigned -> free TD */
+ printf("temp_td %d is assigned to dev %lx\n",i,tmp_int_td[i].dev_ptr);
+ }
+ printf("all others temp_tds are free\n");
+}
+#endif
+/*-------------------------------------------------------------------
+ * submits USB interrupt (ie. polling ;-)
+ */
+int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,int transfer_len, int interval)
+{
+ int nint, n;
+ unsigned long status, destination;
+ unsigned long info,tmp;
+ uhci_td_t *mytd;
+ if (interval < 0 || interval >= 256)
+ return -1;
+
+ if (interval == 0)
+ nint = 0;
+ else {
+ for (nint = 0, n = 1; nint <= 8; nint++, n += n) /* round interval down to 2^n */
+ {
+ if(interval < n) {
+ interval = n / 2;
+ break;
+ }
+ }
+ nint--;
+ }
+
+ USB_UHCI_PRINTF("Rounded interval to %i, chain %i\n", interval, nint);
+ mytd=uhci_alloc_int_td();
+ if(mytd==NULL) {
+ printf("No free INT TDs found\n");
+ return -1;
+ }
+ status = (pipe & TD_CTRL_LS) | TD_CTRL_ACTIVE | TD_CTRL_IOC | (3 << 27);
+/* (urb->transfer_flags & USB_DISABLE_SPD ? 0 : TD_CTRL_SPD) | (3 << 27);
+*/
+
+ destination =(pipe & PIPE_DEVEP_MASK) | usb_packetid (pipe) | (((transfer_len - 1) & 0x7ff) << 21);
+
+ info = destination | (usb_gettoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe)) << TD_TOKEN_TOGGLE);
+ tmp = swap_32(td_int[nint].link);
+ usb_fill_td(mytd,tmp,status, info,(unsigned long)buffer,(unsigned long)dev);
+ /* Link it */
+ tmp = swap_32((unsigned long)mytd);
+ td_int[nint].link=tmp;
+
+ usb_dotoggle (dev, usb_pipeendpoint (pipe), usb_pipeout (pipe));
+
+ return 0;
+}
+
+/**********************************************************************
+ * Low Level functions
+ */
+
+
+void reset_hc(void)
+{
+
+ /* Global reset for 100ms */
+ out16r( usb_base_addr + USBPORTSC1,0x0204);
+ out16r( usb_base_addr + USBPORTSC2,0x0204);
+ out16r( usb_base_addr + USBCMD,USBCMD_GRESET | USBCMD_RS);
+ /* Turn off all interrupts */
+ out16r(usb_base_addr + USBINTR,0);
+ wait_ms(50);
+ out16r( usb_base_addr + USBCMD,0);
+ wait_ms(10);
+}
+
+void start_hc(void)
+{
+ int timeout = 1000;
+
+ while(in16r(usb_base_addr + USBCMD) & USBCMD_HCRESET) {
+ if (!--timeout) {
+ printf("USBCMD_HCRESET timed out!\n");
+ break;
+ }
+ }
+ /* Turn on all interrupts */
+ out16r(usb_base_addr + USBINTR,USBINTR_TIMEOUT | USBINTR_RESUME | USBINTR_IOC | USBINTR_SP);
+ /* Start at frame 0 */
+ out16r(usb_base_addr + USBFRNUM,0);
+ /* set Framebuffer base address */
+ out32r(usb_base_addr+USBFLBASEADD,(unsigned long)&framelist);
+ /* Run and mark it configured with a 64-byte max packet */
+ out16r(usb_base_addr + USBCMD,USBCMD_RS | USBCMD_CF | USBCMD_MAXP);
+}
+
+/* Initialize the skeleton
+ */
+void usb_init_skel(void)
+{
+ unsigned long temp;
+ int n;
+
+ for(n=0;n<USB_MAX_TEMP_INT_TD;n++)
+ tmp_int_td[n].dev_ptr=0L; /* no devices connected */
+ /* last td */
+ usb_fill_td(&td_last,UHCI_PTR_TERM,TD_CTRL_IOC ,0,0,0L);
+ /* usb_fill_td(&td_last,UHCI_PTR_TERM,0,0,0); */
+ /* End Queue Header */
+ usb_fill_qh(&qh_end,UHCI_PTR_TERM,(unsigned long)&td_last);
+ /* Bulk Queue Header */
+ temp=(unsigned long)&qh_end;
+ usb_fill_qh(&qh_bulk,temp | UHCI_PTR_QH,UHCI_PTR_TERM);
+ /* Control Queue Header */
+ temp=(unsigned long)&qh_bulk;
+ usb_fill_qh(&qh_cntrl, temp | UHCI_PTR_QH,UHCI_PTR_TERM);
+ /* 1ms Interrupt td */
+ temp=(unsigned long)&qh_cntrl;
+ usb_fill_td(&td_int[0],temp | UHCI_PTR_QH,0,0,0,0L);
+ temp=(unsigned long)&td_int[0];
+ for(n=1; n<8; n++)
+ usb_fill_td(&td_int[n],temp,0,0,0,0L);
+ for (n = 0; n < 1024; n++) {
+ /* link all framelist pointers to one of the interrupts */
+ int m, o;
+ if ((n&127)==127)
+ framelist[n]= swap_32((unsigned long)&td_int[0]);
+ else
+ for (o = 1, m = 2; m <= 128; o++, m += m)
+ if ((n & (m - 1)) == ((m - 1) / 2))
+ framelist[n]= swap_32((unsigned long)&td_int[o]);
+ }
+}
+
+/* check the common skeleton for completed transfers, and update the status
+ * of the "connected" device. Called from the IRQ routine.
+ */
+void usb_check_skel(void)
+{
+ struct usb_device *dev;
+ /* start with the control qh */
+ if(qh_cntrl.dev_ptr!=0) /* it's a device assigned check if this caused IRQ */
+ {
+ dev=(struct usb_device *)qh_cntrl.dev_ptr;
+ usb_get_td_status(&tmp_td[0],dev); /* update status */
+ if(!(dev->status & USB_ST_NOT_PROC)) { /* is not active anymore, disconnect devices */
+ qh_cntrl.dev_ptr=0;
+ }
+ }
+ /* now process the bulk */
+ if(qh_bulk.dev_ptr!=0) /* it's a device assigned check if this caused IRQ */
+ {
+ dev=(struct usb_device *)qh_bulk.dev_ptr;
+ usb_get_td_status(&tmp_td[0],dev); /* update status */
+ if(!(dev->status & USB_ST_NOT_PROC)) { /* is not active anymore, disconnect devices */
+ qh_bulk.dev_ptr=0;
+ }
+ }
+}
+
+/* check the interrupt chain, ubdate the status of the appropriate device,
+ * call the appropriate irqhandler and reactivate the TD if the irqhandler
+ * returns with 1
+ */
+void usb_check_int_chain(void)
+{
+ int i,res;
+ unsigned long link,status;
+ struct usb_device *dev;
+ uhci_td_t *td,*prevtd;
+
+ for(i=0;i<8;i++) {
+ prevtd=&td_int[i]; /* the first previous td is the skeleton td */
+ link=swap_32(td_int[i].link) & 0xfffffff0; /* next in chain */
+ td=(uhci_td_t *)link; /* assign it */
+ /* all interrupt TDs are finally linked to the td_int[0].
+ * so we process all until we find the td_int[0].
+ * if int0 chain points to a QH, we're also done
+ */
+ while(((i>0) && (link != (unsigned long)&td_int[0])) ||
+ ((i==0) && !(swap_32(td->link) & UHCI_PTR_QH)))
+ {
+ /* check if a device is assigned with this td */
+ status=swap_32(td->status);
+ if((td->dev_ptr!=0L) && !(status & TD_CTRL_ACTIVE)) {
+ /* td is not active and a device is assigned -> call irqhandler */
+ dev=(struct usb_device *)td->dev_ptr;
+ dev->irq_act_len=((status & 0x7FF)==0x7FF) ? 0 : (status & 0x7FF) + 1; /* transfered length */
+ dev->irq_status=usb_uhci_td_stat(status); /* get status */
+ res=dev->irq_handle(dev); /* call irqhandler */
+ if(res==1) {
+ /* reactivate */
+ status|=TD_CTRL_ACTIVE;
+ td->status=swap_32(status);
+ prevtd=td; /* previous td = this td */
+ }
+ else {
+ prevtd->link=td->link; /* link previous td directly to the nex td -> unlinked */
+ /* remove device pointer */
+ td->dev_ptr=0L;
+ }
+ } /* if we call the irq handler */
+ link=swap_32(td->link) & 0xfffffff0; /* next in chain */
+ td=(uhci_td_t *)link; /* assign it */
+ } /* process all td in this int chain */
+ } /* next interrupt chain */
+}
+
+
+/* usb interrupt service routine.
+ */
+void handle_usb_interrupt(void)
+{
+ unsigned short status;
+
+ /*
+ * Read the interrupt status, and write it back to clear the
+ * interrupt cause
+ */
+
+ status = in16r(usb_base_addr + USBSTS);
+
+ if (!status) /* shared interrupt, not mine */
+ return;
+ if (status != 1) {
+ /* remove host controller halted state */
+ if ((status&0x20) && ((in16r(usb_base_addr+USBCMD) && USBCMD_RS)==0)) {
+ out16r(usb_base_addr + USBCMD, USBCMD_RS | in16r(usb_base_addr + USBCMD));
+ }
+ }
+ usb_check_int_chain(); /* call interrupt handlers for int tds */
+ usb_check_skel(); /* call completion handler for common transfer routines */
+ out16r(usb_base_addr+USBSTS,status);
+}
+
+
+/* init uhci
+ */
+int usb_lowlevel_init(void)
+{
+ unsigned long temp;
+ int busdevfunc;
+
+ busdevfunc=PCI_Find_Device(USB_UHCI_VEND_ID,USB_UHCI_DEV_ID); /* get PCI Device ID */
+ if(busdevfunc==-1) {
+ printf("Error USB UHCI (%04X,%04X) not found\n",USB_UHCI_VEND_ID,USB_UHCI_DEV_ID);
+ return -1;
+ }
+ irqvec=PCI_Read_CFG_Reg(busdevfunc,PCI_CFG_DEV_INT_LINE,1);
+ irq_free_handler(irqvec);
+ USB_UHCI_PRINTF("Interrupt Line = %d, is %d\n",irqvec);
+ temp=PCI_Read_CFG_Reg(busdevfunc,PCI_CFG_DEV_INT_PIN,1);
+ USB_UHCI_PRINTF("Interrupt Pin = %ld\n",temp);
+ usb_base_addr=PCI_Read_CFG_Reg(busdevfunc,PCI_CFG_BASE_ADDRESS_4,4);
+ USB_UHCI_PRINTF("IO Base Address = 0x%lx\n",usb_base_addr);
+ usb_base_addr&=0xFFFFFFF0;
+ usb_base_addr+=CFG_ISA_IO_BASE_ADDRESS;
+ rh.devnum = 0;
+ usb_init_skel();
+ reset_hc();
+ start_hc();
+ irq_install_handler(irqvec, (interrupt_handler_t *)handle_usb_interrupt, NULL);
+ return 0;
+}
+
+/* stop uhci
+ */
+int usb_lowlevel_stop(void)
+{
+ if(irqvec==-1)
+ return 1;
+ irq_free_handler(irqvec);
+ reset_hc();
+ irqvec=-1;
+ return 0;
+}
+
+/*******************************************************************************************
+ * Virtual Root Hub
+ * Since the uhci does not have a real HUB, we simulate one ;-)
+ */
+#undef USB_RH_DEBUG
+
+#ifdef USB_RH_DEBUG
+#define USB_RH_PRINTF(fmt,args...) printf (fmt ,##args)
+static void usb_display_wValue(unsigned short wValue,unsigned short wIndex);
+static void usb_display_Req(unsigned short req);
+#else
+#define USB_RH_PRINTF(fmt,args...)
+static void usb_display_wValue(unsigned short wValue,unsigned short wIndex) {}
+static void usb_display_Req(unsigned short req) {}
+#endif
+
+static unsigned char root_hub_dev_des[] =
+{
+ 0x12, /* __u8 bLength; */
+ 0x01, /* __u8 bDescriptorType; Device */
+ 0x00, /* __u16 bcdUSB; v1.0 */
+ 0x01,
+ 0x09, /* __u8 bDeviceClass; HUB_CLASSCODE */
+ 0x00, /* __u8 bDeviceSubClass; */
+ 0x00, /* __u8 bDeviceProtocol; */
+ 0x08, /* __u8 bMaxPacketSize0; 8 Bytes */
+ 0x00, /* __u16 idVendor; */
+ 0x00,
+ 0x00, /* __u16 idProduct; */
+ 0x00,
+ 0x00, /* __u16 bcdDevice; */
+ 0x00,
+ 0x01, /* __u8 iManufacturer; */
+ 0x00, /* __u8 iProduct; */
+ 0x00, /* __u8 iSerialNumber; */
+ 0x01 /* __u8 bNumConfigurations; */
+};
+
+
+/* Configuration descriptor */
+static unsigned char root_hub_config_des[] =
+{
+ 0x09, /* __u8 bLength; */
+ 0x02, /* __u8 bDescriptorType; Configuration */
+ 0x19, /* __u16 wTotalLength; */
+ 0x00,
+ 0x01, /* __u8 bNumInterfaces; */
+ 0x01, /* __u8 bConfigurationValue; */
+ 0x00, /* __u8 iConfiguration; */
+ 0x40, /* __u8 bmAttributes;
+ Bit 7: Bus-powered, 6: Self-powered, 5 Remote-wakwup, 4..0: resvd */
+ 0x00, /* __u8 MaxPower; */
+
+ /* interface */
+ 0x09, /* __u8 if_bLength; */
+ 0x04, /* __u8 if_bDescriptorType; Interface */
+ 0x00, /* __u8 if_bInterfaceNumber; */
+ 0x00, /* __u8 if_bAlternateSetting; */
+ 0x01, /* __u8 if_bNumEndpoints; */
+ 0x09, /* __u8 if_bInterfaceClass; HUB_CLASSCODE */
+ 0x00, /* __u8 if_bInterfaceSubClass; */
+ 0x00, /* __u8 if_bInterfaceProtocol; */
+ 0x00, /* __u8 if_iInterface; */
+
+ /* endpoint */
+ 0x07, /* __u8 ep_bLength; */
+ 0x05, /* __u8 ep_bDescriptorType; Endpoint */
+ 0x81, /* __u8 ep_bEndpointAddress; IN Endpoint 1 */
+ 0x03, /* __u8 ep_bmAttributes; Interrupt */
+ 0x08, /* __u16 ep_wMaxPacketSize; 8 Bytes */
+ 0x00,
+ 0xff /* __u8 ep_bInterval; 255 ms */
+};
+
+
+static unsigned char root_hub_hub_des[] =
+{
+ 0x09, /* __u8 bLength; */
+ 0x29, /* __u8 bDescriptorType; Hub-descriptor */
+ 0x02, /* __u8 bNbrPorts; */
+ 0x00, /* __u16 wHubCharacteristics; */
+ 0x00,
+ 0x01, /* __u8 bPwrOn2pwrGood; 2ms */
+ 0x00, /* __u8 bHubContrCurrent; 0 mA */
+ 0x00, /* __u8 DeviceRemovable; *** 7 Ports max *** */
+ 0xff /* __u8 PortPwrCtrlMask; *** 7 ports max *** */
+};
+
+static unsigned char root_hub_str_index0[] =
+{
+ 0x04, /* __u8 bLength; */
+ 0x03, /* __u8 bDescriptorType; String-descriptor */
+ 0x09, /* __u8 lang ID */
+ 0x04, /* __u8 lang ID */
+};
+
+static unsigned char root_hub_str_index1[] =
+{
+ 28, /* __u8 bLength; */
+ 0x03, /* __u8 bDescriptorType; String-descriptor */
+ 'U', /* __u8 Unicode */
+ 0, /* __u8 Unicode */
+ 'H', /* __u8 Unicode */
+ 0, /* __u8 Unicode */
+ 'C', /* __u8 Unicode */
+ 0, /* __u8 Unicode */
+ 'I', /* __u8 Unicode */
+ 0, /* __u8 Unicode */
+ ' ', /* __u8 Unicode */
+ 0, /* __u8 Unicode */
+ 'R', /* __u8 Unicode */
+ 0, /* __u8 Unicode */
+ 'o', /* __u8 Unicode */
+ 0, /* __u8 Unicode */
+ 'o', /* __u8 Unicode */
+ 0, /* __u8 Unicode */
+ 't', /* __u8 Unicode */
+ 0, /* __u8 Unicode */
+ ' ', /* __u8 Unicode */
+ 0, /* __u8 Unicode */
+ 'H', /* __u8 Unicode */
+ 0, /* __u8 Unicode */
+ 'u', /* __u8 Unicode */
+ 0, /* __u8 Unicode */
+ 'b', /* __u8 Unicode */
+ 0, /* __u8 Unicode */
+};
+
+
+/*
+ * Root Hub Control Pipe (interrupt Pipes are not supported)
+ */
+
+
+int uhci_submit_rh_msg(struct usb_device *dev, unsigned long pipe, void *buffer,int transfer_len,struct devrequest *cmd)
+{
+ void *data = buffer;
+ int leni = transfer_len;
+ int len = 0;
+ int status = 0;
+ int stat = 0;
+ int i;
+
+ unsigned short cstatus;
+
+ unsigned short bmRType_bReq;
+ unsigned short wValue;
+ unsigned short wIndex;
+ unsigned short wLength;
+
+ if ((pipe & PIPE_INTERRUPT) == PIPE_INTERRUPT) {
+ printf("Root-Hub submit IRQ: NOT implemented\n");
+#if 0
+ uhci->rh.urb = urb;
+ uhci->rh.send = 1;
+ uhci->rh.interval = urb->interval;
+ rh_init_int_timer (urb);
+#endif
+ return 0;
+ }
+ bmRType_bReq = cmd->requesttype | cmd->request << 8;
+ wValue = swap_16(cmd->value);
+ wIndex = swap_16(cmd->index);
+ wLength = swap_16(cmd->length);
+ usb_display_Req(bmRType_bReq);
+ for (i = 0; i < 8; i++)
+ rh.c_p_r[i] = 0;
+ USB_RH_PRINTF("Root-Hub: adr: %2x cmd(%1x): %02x%02x %04x %04x %04x\n",
+ dev->devnum, 8, cmd->requesttype,cmd->request, wValue, wIndex, wLength);
+
+ switch (bmRType_bReq) {
+ /* Request Destination:
+ without flags: Device,
+ RH_INTERFACE: interface,
+ RH_ENDPOINT: endpoint,
+ RH_CLASS means HUB here,
+ RH_OTHER | RH_CLASS almost ever means HUB_PORT here
+ */
+
+ case RH_GET_STATUS:
+ *(unsigned short *) data = swap_16(1);
+ len=2;
+ break;
+ case RH_GET_STATUS | RH_INTERFACE:
+ *(unsigned short *) data = swap_16(0);
+ len=2;
+ break;
+ case RH_GET_STATUS | RH_ENDPOINT:
+ *(unsigned short *) data = swap_16(0);
+ len=2;
+ break;
+ case RH_GET_STATUS | RH_CLASS:
+ *(unsigned long *) data = swap_32(0);
+ len=4;
+ break; /* hub power ** */
+ case RH_GET_STATUS | RH_OTHER | RH_CLASS:
+
+ status = in16r(usb_base_addr + USBPORTSC1 + 2 * (wIndex - 1));
+ cstatus = ((status & USBPORTSC_CSC) >> (1 - 0)) |
+ ((status & USBPORTSC_PEC) >> (3 - 1)) |
+ (rh.c_p_r[wIndex - 1] << (0 + 4));
+ status = (status & USBPORTSC_CCS) |
+ ((status & USBPORTSC_PE) >> (2 - 1)) |
+ ((status & USBPORTSC_SUSP) >> (12 - 2)) |
+ ((status & USBPORTSC_PR) >> (9 - 4)) |
+ (1 << 8) | /* power on ** */
+ ((status & USBPORTSC_LSDA) << (-8 + 9));
+
+ *(unsigned short *) data = swap_16(status);
+ *(unsigned short *) (data + 2) = swap_16(cstatus);
+ len=4;
+ break;
+ case RH_CLEAR_FEATURE | RH_ENDPOINT:
+ switch (wValue) {
+ case (RH_ENDPOINT_STALL):
+ len=0;
+ break;
+ }
+ break;
+
+ case RH_CLEAR_FEATURE | RH_CLASS:
+ switch (wValue) {
+ case (RH_C_HUB_OVER_CURRENT):
+ len=0; /* hub power over current ** */
+ break;
+ }
+ break;
+
+ case RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS:
+ usb_display_wValue(wValue,wIndex);
+ switch (wValue) {
+ case (RH_PORT_ENABLE):
+ status = in16r(usb_base_addr+USBPORTSC1+2*(wIndex-1));
+ status = (status & 0xfff5) & ~USBPORTSC_PE;
+ out16r(usb_base_addr+USBPORTSC1+2*(wIndex-1),status);
+ len=0;
+ break;
+ case (RH_PORT_SUSPEND):
+ status = in16r(usb_base_addr+USBPORTSC1+2*(wIndex-1));
+ status = (status & 0xfff5) & ~USBPORTSC_SUSP;
+ out16r(usb_base_addr+USBPORTSC1+2*(wIndex-1),status);
+ len=0;
+ break;
+ case (RH_PORT_POWER):
+ len=0; /* port power ** */
+ break;
+ case (RH_C_PORT_CONNECTION):
+ status = in16r(usb_base_addr+USBPORTSC1+2*(wIndex-1));
+ status = (status & 0xfff5) | USBPORTSC_CSC;
+ out16r(usb_base_addr+USBPORTSC1+2*(wIndex-1),status);
+ len=0;
+ break;
+ case (RH_C_PORT_ENABLE):
+ status = in16r(usb_base_addr+USBPORTSC1+2*(wIndex-1));
+ status = (status & 0xfff5) | USBPORTSC_PEC;
+ out16r(usb_base_addr+USBPORTSC1+2*(wIndex-1),status);
+ len=0;
+ break;
+ case (RH_C_PORT_SUSPEND):
+/*** WR_RH_PORTSTAT(RH_PS_PSSC); */
+ len=0;
+ break;
+ case (RH_C_PORT_OVER_CURRENT):
+ len=0;
+ break;
+ case (RH_C_PORT_RESET):
+ rh.c_p_r[wIndex - 1] = 0;
+ len=0;
+ break;
+ }
+ break;
+ case RH_SET_FEATURE | RH_OTHER | RH_CLASS:
+ usb_display_wValue(wValue,wIndex);
+ switch (wValue) {
+ case (RH_PORT_SUSPEND):
+ status = in16r(usb_base_addr+USBPORTSC1+2*(wIndex-1));
+ status = (status & 0xfff5) | USBPORTSC_SUSP;
+ out16r(usb_base_addr+USBPORTSC1+2*(wIndex-1),status);
+ len=0;
+ break;
+ case (RH_PORT_RESET):
+ status = in16r(usb_base_addr+USBPORTSC1+2*(wIndex-1));
+ status = (status & 0xfff5) | USBPORTSC_PR;
+ out16r(usb_base_addr+USBPORTSC1+2*(wIndex-1),status);
+ wait_ms(10);
+ status = (status & 0xfff5) & ~USBPORTSC_PR;
+ out16r(usb_base_addr+USBPORTSC1+2*(wIndex-1),status);
+ udelay(10);
+ status = (status & 0xfff5) | USBPORTSC_PE;
+ out16r(usb_base_addr+USBPORTSC1+2*(wIndex-1),status);
+ wait_ms(10);
+ status = (status & 0xfff5) | 0xa;
+ out16r(usb_base_addr+USBPORTSC1+2*(wIndex-1),status);
+ len=0;
+ break;
+ case (RH_PORT_POWER):
+ len=0; /* port power ** */
+ break;
+ case (RH_PORT_ENABLE):
+ status = in16r(usb_base_addr+USBPORTSC1+2*(wIndex-1));
+ status = (status & 0xfff5) | USBPORTSC_PE;
+ out16r(usb_base_addr+USBPORTSC1+2*(wIndex-1),status);
+ len=0;
+ break;
+ }
+ break;
+
+ case RH_SET_ADDRESS:
+ rh.devnum = wValue;
+ len=0;
+ break;
+ case RH_GET_DESCRIPTOR:
+ switch ((wValue & 0xff00) >> 8) {
+ case (0x01): /* device descriptor */
+ i=sizeof(root_hub_config_des);
+ status=i > wLength ? wLength : i;
+ len = leni > status ? status : leni;
+ memcpy (data, root_hub_dev_des, len);
+ break;
+ case (0x02): /* configuration descriptor */
+ i=sizeof(root_hub_config_des);
+ status=i > wLength ? wLength : i;
+ len = leni > status ? status : leni;
+ memcpy (data, root_hub_config_des, len);
+ break;
+ case (0x03): /*string descriptors */
+ if(wValue==0x0300) {
+ i=sizeof(root_hub_str_index0);
+ status = i > wLength ? wLength : i;
+ len = leni > status ? status : leni;
+ memcpy (data, root_hub_str_index0, len);
+ break;
+ }
+ if(wValue==0x0301) {
+ i=sizeof(root_hub_str_index1);
+ status = i > wLength ? wLength : i;
+ len = leni > status ? status : leni;
+ memcpy (data, root_hub_str_index1, len);
+ break;
+ }
+ stat = USB_ST_STALLED;
+ }
+ break;
+
+ case RH_GET_DESCRIPTOR | RH_CLASS:
+ root_hub_hub_des[2] = 2;
+ i=sizeof(root_hub_hub_des);
+ status= i > wLength ? wLength : i;
+ len = leni > status ? status : leni;
+ memcpy (data, root_hub_hub_des, len);
+ break;
+ case RH_GET_CONFIGURATION:
+ *(unsigned char *) data = 0x01;
+ len = 1;
+ break;
+ case RH_SET_CONFIGURATION:
+ len=0;
+ break;
+ default:
+ stat = USB_ST_STALLED;
+ }
+ USB_RH_PRINTF("Root-Hub stat %lx port1: %x port2: %x\n\n",stat,
+ in16r(usb_base_addr + USBPORTSC1), in16r(usb_base_addr + USBPORTSC2));
+ dev->act_len=len;
+ dev->status=stat;
+ return stat;
+
+}
+
+/********************************************************************************
+ * Some Debug Routines
+ */
+
+#ifdef USB_RH_DEBUG
+
+static void usb_display_Req(unsigned short req)
+{
+ USB_RH_PRINTF("- Root-Hub Request: ");
+ switch (req) {
+ case RH_GET_STATUS:
+ USB_RH_PRINTF("Get Status ");
+ break;
+ case RH_GET_STATUS | RH_INTERFACE:
+ USB_RH_PRINTF("Get Status Interface ");
+ break;
+ case RH_GET_STATUS | RH_ENDPOINT:
+ USB_RH_PRINTF("Get Status Endpoint ");
+ break;
+ case RH_GET_STATUS | RH_CLASS:
+ USB_RH_PRINTF("Get Status Class");
+ break; /* hub power ** */
+ case RH_GET_STATUS | RH_OTHER | RH_CLASS:
+ USB_RH_PRINTF("Get Status Class Others");
+ break;
+ case RH_CLEAR_FEATURE | RH_ENDPOINT:
+ USB_RH_PRINTF("Clear Feature Endpoint ");
+ break;
+ case RH_CLEAR_FEATURE | RH_CLASS:
+ USB_RH_PRINTF("Clear Feature Class ");
+ break;
+ case RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS:
+ USB_RH_PRINTF("Clear Feature Other Class ");
+ break;
+ case RH_SET_FEATURE | RH_OTHER | RH_CLASS:
+ USB_RH_PRINTF("Set Feature Other Class ");
+ break;
+ case RH_SET_ADDRESS:
+ USB_RH_PRINTF("Set Address ");
+ break;
+ case RH_GET_DESCRIPTOR:
+ USB_RH_PRINTF("Get Descriptor ");
+ break;
+ case RH_GET_DESCRIPTOR | RH_CLASS:
+ USB_RH_PRINTF("Get Descriptor Class ");
+ break;
+ case RH_GET_CONFIGURATION:
+ USB_RH_PRINTF("Get Configuration ");
+ break;
+ case RH_SET_CONFIGURATION:
+ USB_RH_PRINTF("Get Configuration ");
+ break;
+ default:
+ USB_RH_PRINTF("****UNKNOWN**** 0x%04X ",req);
+ }
+ USB_RH_PRINTF("\n");
+
+}
+
+static void usb_display_wValue(unsigned short wValue,unsigned short wIndex)
+{
+ switch (wValue) {
+ case (RH_PORT_ENABLE):
+ USB_RH_PRINTF("Root-Hub: Enable Port %d\n",wIndex);
+ break;
+ case (RH_PORT_SUSPEND):
+ USB_RH_PRINTF("Root-Hub: Suspend Port %d\n",wIndex);
+ break;
+ case (RH_PORT_POWER):
+ USB_RH_PRINTF("Root-Hub: Port Power %d\n",wIndex);
+ break;
+ case (RH_C_PORT_CONNECTION):
+ USB_RH_PRINTF("Root-Hub: C Port Connection Port %d\n",wIndex);
+ break;
+ case (RH_C_PORT_ENABLE):
+ USB_RH_PRINTF("Root-Hub: C Port Enable Port %d\n",wIndex);
+ break;
+ case (RH_C_PORT_SUSPEND):
+ USB_RH_PRINTF("Root-Hub: C Port Suspend Port %d\n",wIndex);
+ break;
+ case (RH_C_PORT_OVER_CURRENT):
+ USB_RH_PRINTF("Root-Hub: C Port Over Current Port %d\n",wIndex);
+ break;
+ case (RH_C_PORT_RESET):
+ USB_RH_PRINTF("Root-Hub: C Port reset Port %d\n",wIndex);
+ break;
+ default:
+ USB_RH_PRINTF("Root-Hub: unknown %x %x\n",wValue,wIndex);
+ break;
+ }
+}
+
+#endif
+
+
+
+#ifdef USB_UHCI_DEBUG
+
+static int usb_display_td(uhci_td_t *td)
+{
+ unsigned long tmp;
+ int valid;
+
+ printf("TD at %p:\n",td);
+
+ tmp=swap_32(td->link);
+ printf("Link points to 0x%08lX, %s first, %s, %s\n",tmp&0xfffffff0,
+ ((tmp & 0x4)==0x4) ? "Depth" : "Breath",
+ ((tmp & 0x2)==0x2) ? "QH" : "TD",
+ ((tmp & 0x1)==0x1) ? "invalid" : "valid");
+ valid=((tmp & 0x1)==0x0);
+ tmp=swap_32(td->status);
+ printf(" %s %ld Errors %s %s %s \n %s %s %s %s %s %s\n Len 0x%lX\n",
+ (((tmp>>29)&0x1)==0x1) ? "SPD Enable" : "SPD Disable",
+ ((tmp>>28)&0x3),
+ (((tmp>>26)&0x1)==0x1) ? "Low Speed" : "Full Speed",
+ (((tmp>>25)&0x1)==0x1) ? "ISO " : "",
+ (((tmp>>24)&0x1)==0x1) ? "IOC " : "",
+ (((tmp>>23)&0x1)==0x1) ? "Active " : "Inactive ",
+ (((tmp>>22)&0x1)==0x1) ? "Stalled" : "",
+ (((tmp>>21)&0x1)==0x1) ? "Data Buffer Error" : "",
+ (((tmp>>20)&0x1)==0x1) ? "Babble" : "",
+ (((tmp>>19)&0x1)==0x1) ? "NAK" : "",
+ (((tmp>>18)&0x1)==0x1) ? "Bitstuff Error" : "",
+ (tmp&0x7ff));
+ tmp=swap_32(td->info);
+ printf(" MaxLen 0x%lX\n",((tmp>>21)&0x7FF));
+ printf(" %s Endpoint 0x%lX Dev Addr 0x%lX PID 0x%lX\n",((tmp>>19)&0x1)==0x1 ? "TOGGLE" : "",
+ ((tmp>>15)&0xF),((tmp>>8)&0x7F),tmp&0xFF);
+ tmp=swap_32(td->buffer);
+ printf(" Buffer 0x%08lX\n",tmp);
+ printf(" DEV %08lX\n",td->dev_ptr);
+ return valid;
+}
+
+
+void usb_show_td(int max)
+{
+ int i;
+ if(max>0) {
+ for(i=0;i<max;i++) {
+ usb_display_td(&tmp_td[i]);
+ }
+ }
+ else {
+ i=0;
+ do {
+ printf("tmp_td[%d]\n",i);
+ }while(usb_display_td(&tmp_td[i++]));
+ }
+}
+
+
+#endif
+#endif /* CONFIG_USB_UHCI */
+
+/* EOF */
--- /dev/null
+/*
+ * (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: Part of this code has been derived from linux
+ *
+ */
+#ifndef _USB_UHCI_H_
+#define _USB_UHCI_H_
+
+
+/* Command register */
+#define USBCMD 0
+#define USBCMD_RS 0x0001 /* Run/Stop */
+#define USBCMD_HCRESET 0x0002 /* Host reset */
+#define USBCMD_GRESET 0x0004 /* Global reset */
+#define USBCMD_EGSM 0x0008 /* Global Suspend Mode */
+#define USBCMD_FGR 0x0010 /* Force Global Resume */
+#define USBCMD_SWDBG 0x0020 /* SW Debug mode */
+#define USBCMD_CF 0x0040 /* Config Flag (sw only) */
+#define USBCMD_MAXP 0x0080 /* Max Packet (0 = 32, 1 = 64) */
+
+/* Status register */
+#define USBSTS 2
+#define USBSTS_USBINT 0x0001 /* Interrupt due to IOC */
+#define USBSTS_ERROR 0x0002 /* Interrupt due to error */
+#define USBSTS_RD 0x0004 /* Resume Detect */
+#define USBSTS_HSE 0x0008 /* Host System Error - basically PCI problems */
+#define USBSTS_HCPE 0x0010 /* Host Controller Process Error - the scripts were buggy */
+#define USBSTS_HCH 0x0020 /* HC Halted */
+
+/* Interrupt enable register */
+#define USBINTR 4
+#define USBINTR_TIMEOUT 0x0001 /* Timeout/CRC error enable */
+#define USBINTR_RESUME 0x0002 /* Resume interrupt enable */
+#define USBINTR_IOC 0x0004 /* Interrupt On Complete enable */
+#define USBINTR_SP 0x0008 /* Short packet interrupt enable */
+
+#define USBFRNUM 6
+#define USBFLBASEADD 8
+#define USBSOF 12
+
+/* USB port status and control registers */
+#define USBPORTSC1 16
+#define USBPORTSC2 18
+#define USBPORTSC_CCS 0x0001 /* Current Connect Status ("device present") */
+#define USBPORTSC_CSC 0x0002 /* Connect Status Change */
+#define USBPORTSC_PE 0x0004 /* Port Enable */
+#define USBPORTSC_PEC 0x0008 /* Port Enable Change */
+#define USBPORTSC_LS 0x0030 /* Line Status */
+#define USBPORTSC_RD 0x0040 /* Resume Detect */
+#define USBPORTSC_LSDA 0x0100 /* Low Speed Device Attached */
+#define USBPORTSC_PR 0x0200 /* Port Reset */
+#define USBPORTSC_SUSP 0x1000 /* Suspend */
+
+/* Legacy support register */
+#define USBLEGSUP 0xc0
+#define USBLEGSUP_DEFAULT 0x2000 /* only PIRQ enable set */
+
+#define UHCI_NULL_DATA_SIZE 0x7ff /* for UHCI controller TD */
+#define UHCI_PID 0xff /* PID MASK */
+
+#define UHCI_PTR_BITS 0x000F
+#define UHCI_PTR_TERM 0x0001
+#define UHCI_PTR_QH 0x0002
+#define UHCI_PTR_DEPTH 0x0004
+
+/* for TD <status>: */
+#define TD_CTRL_SPD (1 << 29) /* Short Packet Detect */
+#define TD_CTRL_C_ERR_MASK (3 << 27) /* Error Counter bits */
+#define TD_CTRL_LS (1 << 26) /* Low Speed Device */
+#define TD_CTRL_IOS (1 << 25) /* Isochronous Select */
+#define TD_CTRL_IOC (1 << 24) /* Interrupt on Complete */
+#define TD_CTRL_ACTIVE (1 << 23) /* TD Active */
+#define TD_CTRL_STALLED (1 << 22) /* TD Stalled */
+#define TD_CTRL_DBUFERR (1 << 21) /* Data Buffer Error */
+#define TD_CTRL_BABBLE (1 << 20) /* Babble Detected */
+#define TD_CTRL_NAK (1 << 19) /* NAK Received */
+#define TD_CTRL_CRCTIMEO (1 << 18) /* CRC/Time Out Error */
+#define TD_CTRL_BITSTUFF (1 << 17) /* Bit Stuff Error */
+#define TD_CTRL_ACTLEN_MASK 0x7ff /* actual length, encoded as n - 1 */
+
+#define TD_CTRL_ANY_ERROR (TD_CTRL_STALLED | TD_CTRL_DBUFERR | \
+ TD_CTRL_BABBLE | TD_CTRL_CRCTIME | TD_CTRL_BITSTUFF)
+
+#define TD_TOKEN_TOGGLE 19
+
+/* ------------------------------------------------------------------------------------
+ Virtual Root HUB
+ ------------------------------------------------------------------------------------ */
+/* destination of request */
+#define RH_INTERFACE 0x01
+#define RH_ENDPOINT 0x02
+#define RH_OTHER 0x03
+
+#define RH_CLASS 0x20
+#define RH_VENDOR 0x40
+
+/* Requests: bRequest << 8 | bmRequestType */
+#define RH_GET_STATUS 0x0080
+#define RH_CLEAR_FEATURE 0x0100
+#define RH_SET_FEATURE 0x0300
+#define RH_SET_ADDRESS 0x0500
+#define RH_GET_DESCRIPTOR 0x0680
+#define RH_SET_DESCRIPTOR 0x0700
+#define RH_GET_CONFIGURATION 0x0880
+#define RH_SET_CONFIGURATION 0x0900
+#define RH_GET_STATE 0x0280
+#define RH_GET_INTERFACE 0x0A80
+#define RH_SET_INTERFACE 0x0B00
+#define RH_SYNC_FRAME 0x0C80
+/* Our Vendor Specific Request */
+#define RH_SET_EP 0x2000
+
+/* Hub port features */
+#define RH_PORT_CONNECTION 0x00
+#define RH_PORT_ENABLE 0x01
+#define RH_PORT_SUSPEND 0x02
+#define RH_PORT_OVER_CURRENT 0x03
+#define RH_PORT_RESET 0x04
+#define RH_PORT_POWER 0x08
+#define RH_PORT_LOW_SPEED 0x09
+#define RH_C_PORT_CONNECTION 0x10
+#define RH_C_PORT_ENABLE 0x11
+#define RH_C_PORT_SUSPEND 0x12
+#define RH_C_PORT_OVER_CURRENT 0x13
+#define RH_C_PORT_RESET 0x14
+
+/* Hub features */
+#define RH_C_HUB_LOCAL_POWER 0x00
+#define RH_C_HUB_OVER_CURRENT 0x01
+
+#define RH_DEVICE_REMOTE_WAKEUP 0x00
+#define RH_ENDPOINT_STALL 0x01
+
+/* Our Vendor Specific feature */
+#define RH_REMOVE_EP 0x00
+
+
+#define RH_ACK 0x01
+#define RH_REQ_ERR -1
+#define RH_NACK 0x00
+
+
+/* Transfer descriptor structure */
+typedef struct {
+ unsigned long link; /* next td/qh (LE)*/
+ unsigned long status; /* status of the td */
+ unsigned long info; /* Max Lenght / Endpoint / device address and PID */
+ unsigned long buffer; /* pointer to data buffer (LE) */
+ unsigned long dev_ptr; /* pointer to the assigned device (BE) */
+ unsigned long res[3]; /* reserved (TDs must be 8Byte aligned) */
+} uhci_td_t, *puhci_td_t;
+
+/* Queue Header structure */
+typedef struct {
+ unsigned long head; /* Next QH (LE)*/
+ unsigned long element; /* Queue element pointer (LE) */
+ unsigned long res[5]; /* reserved */
+ unsigned long dev_ptr; /* if 0 no tds have been assigned to this qh */
+} uhci_qh_t, *puhci_qh_t;
+
+struct virt_root_hub {
+ int devnum; /* Address of Root Hub endpoint */
+ int numports; /* number of ports */
+ int c_p_r[8]; /* C_PORT_RESET */
+};
+
+
+#endif /* _USB_UHCI_H_ */
+
+
--- /dev/null
+/*
+ * (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 */
--- /dev/null
+/*
+ * (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_4xx
+#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;
+#if 0
+ char buf[48];
+ char buf1[16];
+ static int i=0;
+
+ sprintf(buf1,"%02X ",ch);
+ serial_puts(buf1);
+ buf[i++]=((ch>=0x20)&&(ch<=0x7f)) ? ch : '.';
+ if(i>=16) {
+ buf[i++]='\n';
+ buf[i]='\0';
+ i=0;
+ serial_puts(" ");
+ serial_puts(buf);
+ }
+#endif
+ 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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
--- /dev/null
+/*
+ * (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
--- /dev/null
+#
+# (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
+#
+
+include $(TOPDIR)/config.mk
+
+LIB = lib$(BOARD).a
+
+OBJS = $(BOARD).o ../common/flash.o cmd_mip405.o ../common/pci.o ../common/usb_uhci.o ../common/memtst.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
+
+#########################################################################
--- /dev/null
+/*
+ * (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 "mip405.h"
+#include <rtc.h>
+#include "../common/isa.h"
+#include "../common/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);
+extern void print_mip405_info(void);
+
+
+
+
+
+#define TRUE 1
+#define FALSE 0
+
+#define IMAGE_SIZE 0x80000
+
+image_header_t header;
+
+
+
+int mip405_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 */
+ /* now erase flash */
+ if(magic[0]!=IH_MAGIC) {
+ printf("Bad Magic number\n");
+ return -1;
+ }
+ 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 from 0x%lx 0x%lx Bytes\n",src,size);
+ switch (rc = flash_write ((uchar *)src, start, size))
+ {
+ case 0: printf ("programming done\n"); return 0;
+ case 1: printf ("Timeout writing to Flash\n"); return 1;
+ case 2: printf ("Flash not Erased\n"); return 1;
+ case 4: printf ("Can't write to protected Flash sectors\n"); return 1;
+ case 8: printf ("Outside available Flash\n"); return 1;
+ default: printf ("%s[%d] FIXME: rc=%d\n",__FILE__,__LINE__,rc); return 1;
+ }
+ return 1;
+}
+
+
+int mip405_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 1;
+ }
+ if (hdr->ih_os != IH_OS_PPCBOOT) {
+ printf ("No PPCBOOT Image\n");
+ return 1;
+ }
+ if (hdr->ih_type != IH_TYPE_FIRMWARE) {
+ printf ("No Firmware Image\n");
+ return 1;
+ }
+ 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 1;
+ }
+ 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 1;
+ }
+ printf ("OK\n");
+ return(mip405_prg(data,len));
+}
+
+
+/* ------------------------------------------------------------------------- */
+
+int do_mip405(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
+{
+
+ ulong size,src,device,load_addr;
+ int result;
+ backup_t back;
+ src = MULTI_PURPOSE_SOCKET_ADDR;
+ size = IMAGE_SIZE;
+
+ if (strcmp(argv[1], "flash") == 0)
+ {
+ 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);
+ result=mip405_prg_image(load_addr);
+ return result;
+ }
+ if (strcmp(argv[2], "mps") == 0) {
+ printf ("\nupdating bootloader image from MSP\n");
+ result=mip405_prg(src,size);
+ return result;
+ }
+
+ }
+ if (strcmp(argv[1], "mem") == 0)
+ {
+ result=0;
+ if(argc==3)
+ {
+ result = (int)simple_strtol(argv[2], NULL, 16);
+ }
+ src=(unsigned long)&result;
+ src-=CFG_MEMTEST_START;
+ src-=(100*1024); /* - 100k */
+ src&=0xfff00000;
+ size=0;
+ do {
+ size++;
+ printf("Pass %ld\n",size);
+ mem_test(CFG_MEMTEST_START,src,1);
+ if(ctrlc())
+ break;
+ if(result>0)
+ result--;
+
+ }while(result);
+ return 0;
+ }
+ if (strcmp(argv[1], "info") == 0)
+ {
+ print_mip405_info();
+ return 0;
+ }
+ if (strcmp(argv[1], "led") == 0)
+ {
+ device = (ulong)simple_strtoul(argv[2], NULL, 10);
+ user_led0((device==1));
+ return 0;
+ }
+ if (strcmp(argv[1], "getback") == 0) {
+ get_backup_values(&back);
+ back.signature[3]=0;
+ back.serial_name[16]=0;
+ back.eth_addr[20]=0;
+ printf("GetBackUp: signature: %s\n",back.signature);
+ printf(" serial#: %s\n",back.serial_name);
+ printf(" ethaddr: %s\n",back.eth_addr);
+ return 0;
+ }
+ if (strcmp(argv[1], "setback") == 0) {
+ set_backup_values(1);
+ return 0;
+ }
+ printf("Usage:\n%s\n", cmdtp->usage);
+ return 1;
+}
+
+/* ------------------------------------------------------------------------- */
--- /dev/null
+#
+# (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
+#
+
+#
+# esd ADCIOP boards
+#
+
+#TEXT_BASE = 0xFFFE0000
+TEXT_BASE = 0xFFF80000
--- /dev/null
+/*------------------------------------------------------------------------------+
+ *
+ * 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 (set in C-Code)
+ * Bank 2 - UART 1 (set in C-Code)
+ * Bank 3 - UART 2 (set in C-Code)
+ * Bank 4 - not used
+ * Bank 5 - not used
+ * Bank 6 - not used
+ * Bank 7 - PLD Register
+ *-----------------------------------------------------------------------------*/
+#include <ppc4xx.h>
+
+#define _LINUX_CONFIG_H 1 /* avoid reading Linux autoconf.h file */
+
+#include "config_MIP405.h"
+#include <ppc_asm.tmpl>
+#include <ppc_defs.h>
+
+#include <asm/cache.h>
+#include <asm/mmu.h>
+#include "mip405.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 (Flash Boot)
+ *-----------------------------------------------------------------------
+ * Memory Bank 0 (16 Bit Flash) initialization
+ *---------------------------------------------------------------------- */
+
+ addi r4,0,pb0ap
+ mtdcr ebccfga,r4
+// addis r4,0,0xFF8F
+// ori r4,r4,0xFE80
+// addis r4,0,0x9B01
+// ori r4,r4,0x5480
+ addis r4,0,(FLASH_AP_B)@h
+ ori r4,r4,(FLASH_AP_B)@l
+ mtdcr ebccfgd,r4
+
+ addi r4,0,pb0cr
+ mtdcr ebccfga,r4
+ /* BS=0x010(4MB),BU=0x3(R/W), */
+// addis r4,0,((FLASH_BASE0_PRELIM & 0xFFF00000) | 0x00050000)@h
+// ori r4,r4,0xA000 /* BW=0x01(16 bits) */
+ addis r4,0,(FLASH_CR_B)@h
+ ori r4,r4,(FLASH_CR_B)@l
+ mtdcr ebccfgd,r4
+ b 1f
+
+0:
+
+ /* 8Bit boot mode: */
+ /*-----------------------------------------------------------------------
+ * Memory Bank 0 Multi Purpose Socket initialization
+ *----------------------------------------------------------------------- */
+ /* 0x7F8FFE80 slowest boot */
+ addi r4,0,pb0ap
+ mtdcr ebccfga,r4
+#if 0
+ addis r4,0,0x9B01
+ ori r4,r4,0x5480
+#else
+ addis r4,0,(MPS_AP_B)@h
+ ori r4,r4,(MPS_AP_B)@l
+#endif
+ mtdcr ebccfgd,r4
+
+ addi r4,0,pb0cr
+ mtdcr ebccfga,r4
+ /* BS=0x010(4MB),BU=0x3(R/W), */
+// addis r4,0,((FLASH_BASE0_PRELIM & 0xFFF00000) | 0x00050000)@h
+// ori r4,r4,0x8000 /* BW=0x0( 8 bits) */
+
+ addis r4,0,(MPS_CR_B)@h
+ ori r4,r4,(MPS_CR_B)@l
+
+ mtdcr ebccfgd,r4
+
+
+1:
+ /*-----------------------------------------------------------------------
+ * Memory Bank 2-3-4-5-6 (not used) initialization
+ *-----------------------------------------------------------------------*/
+ addi r4,0,pb1cr
+ mtdcr ebccfga,r4
+ addis r4,0,0x0000
+ ori r4,r4,0x0000
+ mtdcr ebccfgd,r4
+
+ 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
+
+ addi r4,0,pb7cr
+ mtdcr ebccfga,r4
+ addis r4,0,0x0000
+ ori r4,r4,0x0000
+ 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
+
--- /dev/null
+/*
+ * (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
+ */
+
+/*
+ * How do I program the SDRAM Timing Register (SDRAM0_TR) for a specific SDRAM or DIMM?
+ *
+ * As an example, consider a case where PC133 memory with CAS Latency equal to 2 is being
+ * used with a 200MHz 405GP. For a typical 128Mb, PC133 SDRAM, the relevant minimum
+ * parameters from the datasheet are:
+ * Tclk = 7.5ns (CL = 2)
+ * Trp = 15ns
+ * Trc = 60ns
+ * Trcd = 15ns
+ * Trfc = 66ns
+ *
+ * If we are operating the 405GP with the MemClk output frequency set to 100 MHZ, the clock
+ * period is 10ns and the parameters needed for the Timing Register are:
+ * CASL = CL = 2 clock cycles
+ * PTA = Trp = 15ns / 10ns = 2 clock cycles
+ * CTP = Trc - Trcd - Trp = (60ns - 15ns - 15ns) / 10ns= 3 clock cycles
+ * LDF = 2 clock cycles (but can be extended to meet board-level timing)
+ * RFTA = Trfc = 66ns / 10ns= 7 clock cycles
+ * RCD = Trcd = 15ns / 10ns= 2 clock cycles
+ *
+ * The actual bit settings in the register would be:
+ *
+ * CASL = 0b01
+ * PTA = 0b01
+ * CTP = 0b10
+ * LDF = 0b01
+ * RFTA = 0b011
+ * RCD = 0b01
+ *
+ * If Trfc is not specified in the datasheet for PC100 or PC133 memory, set RFTA = Trc
+ * instead. Figure 24 in the PC SDRAM Specification Rev. 1.7 shows refresh to active delay
+ * defined as Trc rather than Trfc.
+ * When using DIMM modules, most but not all of the required timing parameters can be read
+ * from the Serial Presence Detect (SPD) EEPROM on the module. Specifically, Trc and Trfc
+ * are not available from the EEPROM
+ */
+
+#include <ppcboot.h>
+#include "mip405.h"
+#include <asm/processor.h>
+#include <405gp_i2c.h>
+#include <miiphy.h>
+#include <devices.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
+
+
+#define PLD_PART_REG PER_PLD_ADDR + 0
+#define PLD_VERS_REG PER_PLD_ADDR + 1
+#define PLD_BOARD_CFG_REG PER_PLD_ADDR + 2
+#define PLD_IRQ_REG PER_PLD_ADDR + 3
+#define PLD_COM_MODE_REG PER_PLD_ADDR + 4
+#define PLD_EXT_CONF_REG PER_PLD_ADDR + 5
+
+#define MEGA_BYTE (1024*1024)
+
+typedef struct {
+ unsigned char boardtype; /* Board revision and Population Options */
+ unsigned char cal; /* cas Latency (will be programmend as cal-1) */
+ unsigned char trp; /* datain27 in clocks */
+ unsigned char trcd; /* datain29 in clocks */
+ unsigned char tras; /* datain30 in clocks */
+ unsigned char tctp; /* tras - trcd in clocks */
+ unsigned char am; /* Address Mod (will be programmed as am-1) */
+ unsigned char sz; /* log binary => Size = (4MByte<<sz) 5 = 128, 4 = 64, 3 = 32, 2 = 16, 1=8 */
+ unsigned char ecc; /* if true, ecc is enabled */
+} sdram_t;
+
+const sdram_t sdram_table[] = {
+ { 0x0f, /* Rev A, 128MByte -1 Board */
+ 3, /* Case Latenty = 3 */
+ 3, /* trp 20ns / 7.5 ns datain[27] */
+ 3, /* trcd 20ns /7.5 ns (datain[29]) */
+ 6, /* tras 44ns /7.5 ns (datain[30]) */
+ 4, /* tcpt 44 - 20ns = 24ns */
+ 3, /* Address Mode = 3 */
+ 5, /* size value */
+ 1}, /* ECC enabled */
+ { 0x07, /* Rev A, 64MByte -2 Board */
+ 3, /* Case Latenty = 3 */
+ 3, /* trp 20ns / 7.5 ns datain[27] */
+ 3, /* trcd 20ns /7.5 ns (datain[29]) */
+ 6, /* tras 44ns /7.5 ns (datain[30]) */
+ 4, /* tcpt 44 - 20ns = 24ns */
+ 2, /* Address Mode = 2 */
+ 4, /* size value */
+ 1}, /* ECC enabled */
+ { 0xff, /* terminator */
+ 0xff,
+ 0xff,
+ 0xff,
+ 0xff,
+ 0xff,
+ 0xff,
+ 0xff }
+};
+
+void SDRAM_err(const char *s)
+{
+#ifndef SDRAM_DEBUG
+ serial_init(get_gclk_freq(),9600);
+#endif
+ serial_puts("\n");
+ serial_puts(s);
+ serial_puts("\n enable SDRAM_DEBUG for more info\n");
+ for (;;);
+}
+
+
+unsigned char get_board_revcfg(void)
+{
+ out8(PER_BOARD_ADDR,0);
+ return(in8(PER_BOARD_ADDR));
+}
+
+
+#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);
+}
+
+void write_4hex(unsigned long val)
+{
+ write_hex((unsigned char)(val>>24));
+ write_hex((unsigned char)(val>>16));
+ write_hex((unsigned char)(val>>8));
+ write_hex((unsigned char)val);
+}
+
+#endif
+
+
+int init_sdram (void)
+{
+ unsigned long tmp, baseaddr;
+ unsigned short i;
+ unsigned char trp_clocks, trcd_clocks, tras_clocks, trc_clocks,tctp_clocks;
+ unsigned char cal_val;
+ unsigned char bc;
+ unsigned long pbcr,sdram_tim,sdram_bank;
+ unsigned long *p;
+
+
+
+ serial_init(get_gclk_freq(),9600);
+ serial_puts("\nInitializing SDRAM, Please stand by");
+ mtdcr(ebccfga, pb0cr); /* get cs0 config reg */
+ pbcr = mfdcr(ebccfgd);
+ if((pbcr&0x00002000)==0) {
+ /* MPS Boot, set up the flash */
+ mtdcr(ebccfga, pb1ap);
+ mtdcr(ebccfgd, FLASH_AP);
+ mtdcr(ebccfga, pb1cr);
+ mtdcr(ebccfgd, FLASH_CR);
+ }
+ else {
+ /* Flash boot, set up the MPS */
+ mtdcr(ebccfga, pb1ap);
+ mtdcr(ebccfgd, MPS_AP);
+ mtdcr(ebccfga, pb1cr);
+ mtdcr(ebccfgd, MPS_CR);
+ }
+ /* set up UART0 (CS2) and UART1 (CS3) */
+ mtdcr(ebccfga, pb2ap);
+ mtdcr(ebccfgd, UART0_AP);
+ mtdcr(ebccfga, pb2cr);
+ mtdcr(ebccfgd, UART0_CR);
+ mtdcr(ebccfga, pb3ap);
+ mtdcr(ebccfgd, UART1_AP);
+ mtdcr(ebccfga, pb3cr);
+ mtdcr(ebccfgd, UART1_CR);
+
+ /* set up the pld */
+ mtdcr(ebccfga, pb7ap);
+ mtdcr(ebccfgd, PLD_AP);
+ mtdcr(ebccfga, pb7cr);
+ mtdcr(ebccfgd, PLD_CR);
+ /* set up the board rev reg */
+ mtdcr(ebccfga, pb5ap);
+ mtdcr(ebccfgd, BOARD_AP);
+ mtdcr(ebccfga, pb5cr);
+ mtdcr(ebccfgd, BOARD_CR);
+
+
+#ifdef SDRAM_DEBUG
+ out8(PER_BOARD_ADDR,0);
+ bc=in8(PER_BOARD_ADDR);
+ serial_puts("\nBoard Rev: ");
+ write_hex(bc);
+ serial_puts(" (PLD=");
+ bc=in8(PLD_BOARD_CFG_REG);
+ write_hex(bc);
+ serial_puts(")\n");
+#endif
+ bc=get_board_revcfg();
+#ifdef SDRAM_DEBUG
+ serial_puts("\nstart SDRAM Setup\n");
+ serial_puts("\nBoard Rev: ");
+ write_hex(bc);
+ serial_puts("\n");
+#endif
+ i=0;
+ baseaddr=CFG_SDRAM_BASE;
+ while(sdram_table[i].sz!=0xff) {
+ if(sdram_table[i].boardtype==bc)
+ break;
+ i++;
+ }
+ if(sdram_table[i].boardtype!=bc)
+ SDRAM_err("No SDRAM table found for this board!!!\n");
+#ifdef SDRAM_DEBUG
+ serial_puts(" found table ");
+ write_hex(i);
+ serial_puts(" \n");
+#endif
+ cal_val = sdram_table[i].cal-1; /* Cas Latency */
+ trp_clocks = sdram_table[i].trp; /* 20ns / 7.5 ns datain[27] */
+ trcd_clocks = sdram_table[i].trcd; /* 20ns /7.5 ns (datain[29]) */
+ tras_clocks = sdram_table[i].tras; /* 44ns /7.5 ns (datain[30]) */
+ /* ctp = ((trp + tras) - trp - trcd) => tras - trcd */
+ tctp_clocks = sdram_table[i].tctp; /* 44 - 20ns = 24ns */
+ /* trc_clocks is sum of trp_clocks + tras_clocks */
+ trc_clocks = trp_clocks + tras_clocks;
+ /* get SDRAM timing register */
+ mtdcr(memcfga,mem_sdtr1);
+ sdram_tim = mfdcr(memcfgd) & ~0x018FC01F;
+ /* insert CASL value */
+ sdram_tim |= ((unsigned long)(cal_val)) << 23;
+ /* insert PTA value */
+ sdram_tim |= ((unsigned long)(trp_clocks - 1)) << 18;
+ /* insert CTP value */
+ sdram_tim |= ((unsigned long)(trc_clocks - trp_clocks - trcd_clocks)) << 16;
+ /* insert LDF (always 01) */
+ sdram_tim |= ((unsigned long)0x01) << 14;
+ /* insert RFTA value */
+ sdram_tim |= ((unsigned long)(trc_clocks - 4)) << 2;
+ /* insert RCD value */
+ sdram_tim |= ((unsigned long)(trcd_clocks - 1)) << 0;
+
+ tmp = ((unsigned long)(sdram_table[i].am-1) << 13); /* AM = 3 */
+ /* insert SZ value; */
+ tmp |= ((unsigned long)sdram_table[i].sz << 17);
+ /* get SDRAM bank 0 register */
+ mtdcr(memcfga,mem_mb0cf);
+ sdram_bank = mfdcr(memcfgd) & ~0xFFCEE001;
+ sdram_bank |= (baseaddr | tmp | 0x01);
+
+#ifdef SDRAM_DEBUG
+ serial_puts("sdtr: ");
+ write_4hex(sdram_tim);
+ serial_puts("\n");
+#endif
+
+ /* write SDRAM timing register */
+ mtdcr(memcfga,mem_sdtr1);
+ mtdcr(memcfgd,sdram_tim);
+
+#ifdef SDRAM_DEBUG
+ serial_puts("mb0cf: ");
+ write_4hex(sdram_bank);
+ serial_puts("\n");
+#endif
+
+ /* write SDRAM bank 0 register */
+ mtdcr(memcfga,mem_mb0cf);
+ mtdcr(memcfgd,sdram_bank);
+
+ if(get_bus_freq(tmp)>110000000) { /* > 110MHz */
+ /* get SDRAM refresh interval register */
+ mtdcr(memcfga,mem_rtr);
+ tmp = mfdcr(memcfgd) & ~0x3FF80000;
+ tmp |= 0x07F00000;
+ }
+ else {
+ /* get SDRAM refresh interval register */
+ mtdcr(memcfga,mem_rtr);
+ tmp = mfdcr(memcfgd) & ~0x3FF80000;
+ tmp |= 0x05F00000;
+ }
+ /* write SDRAM refresh interval register */
+ mtdcr(memcfga,mem_rtr);
+ mtdcr(memcfgd,tmp);
+ /* enable ECC if used */
+#if 1
+ if(sdram_table[i].ecc) {
+ /* disable checking for all banks */
+#ifdef SDRAM_DEBUG
+ serial_puts("disable ECC.. ");
+#endif
+ mtdcr(memcfga,mem_ecccf);
+ tmp=mfdcr(memcfgd);
+ tmp&=0xff0fffff; /* disable all banks */
+ mtdcr(memcfga,mem_ecccf);
+ /* set up SDRAM Controller with ECC enabled */
+#ifdef SDRAM_DEBUG
+ serial_puts("setup SDRAM Controller.. ");
+#endif
+ mtdcr(memcfgd,tmp);
+ mtdcr(memcfga,mem_mcopt1);
+ tmp = (mfdcr(memcfgd) & ~0xFFE00000) | 0x90800000;
+ mtdcr(memcfga,mem_mcopt1);
+ mtdcr(memcfgd,tmp);
+ udelay(600);
+#ifdef SDRAM_DEBUG
+ serial_puts("fill the memory..\n");
+#endif
+ serial_puts(".");
+ /* now, fill all the memory */
+ tmp=((4*MEGA_BYTE)<<sdram_table[i].sz);
+ p=(unsigned long)0;
+ while((unsigned long)p<tmp) {
+ *p++=0L;
+ if(!((unsigned long)p%0x00800000)) /* every 8MByte */
+ serial_puts(".");
+
+
+ }
+ /* enable bank 0 */
+ serial_puts(".");
+#ifdef SDRAM_DEBUG
+ serial_puts("enable ECC\n");
+#endif
+ udelay(400);
+ mtdcr(memcfga,mem_ecccf);
+ tmp=mfdcr(memcfgd);
+ tmp|=0x00800000; /* enable bank 0 */
+ mtdcr(memcfgd,tmp);
+ udelay(400);
+ }
+ else
+#endif
+ {
+ /* 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);
+ udelay(400);
+ }
+ serial_puts("\n");
+ return (0);
+}
+
+int board_pre_init (void)
+{
+ init_sdram();
+
+ /*-------------------------------------------------------------------------+
+ | 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) SouthBridge; 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 MIP405 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;
+}
+
+
+/*
+ * Get some PLD Registers
+ */
+
+unsigned short get_pld_parvers(void)
+{
+ unsigned short result;
+ unsigned char rc;
+ rc=in8(PLD_PART_REG);
+ result=(unsigned short)rc<<8;
+ rc=in8(PLD_VERS_REG);
+ result|=rc;
+ return result;
+}
+
+
+
+void user_led0(unsigned char on)
+{
+ if(on)
+ out8(PLD_COM_MODE_REG,(in8(PLD_COM_MODE_REG)|0x4));
+ else
+ out8(PLD_COM_MODE_REG,(in8(PLD_COM_MODE_REG)&0xfb));
+}
+
+
+void ide_set_reset(int idereset)
+{
+ /* if reset = 1 IDE reset will be asserted */
+ if(idereset)
+ out8(PLD_COM_MODE_REG,(in8(PLD_COM_MODE_REG)|0x1));
+ else
+ out8(PLD_COM_MODE_REG,(in8(PLD_COM_MODE_REG)&0xfe));
+}
+
+#define I2C_BACKUP_ADDR 0x7C00 /* 0x200 bytes for backup */
+
+void get_backup_values(backup_t *buf)
+{
+ eeprom_read (CFG_DEF_EEPROM_ADDR,
+ I2C_BACKUP_ADDR,
+ (void *)buf,
+ sizeof(backup_t));
+}
+
+void set_backup_values(int overwrite)
+{
+ backup_t back;
+ int i;
+
+ get_backup_values(&back);
+ if(!overwrite) {
+ if(strncmp(back.signature,"MPL\0",4)==0) {
+ printf("Not possible to write Backup\n");
+ return;
+ }
+ }
+ memcpy(back.signature,"MPL\0",4);
+ i=getenv_r("serial#",back.serial_name,16);
+ if(i==0) {
+ printf("Not possible to write Backup\n");
+ return;
+ }
+ back.serial_name[16]=0;
+ i=getenv_r("ethaddr",back.eth_addr,20);
+ if(i==0) {
+ printf("Not possible to write Backup\n");
+ return;
+ }
+ back.eth_addr[20]=0;
+ eeprom_write (CFG_DEF_EEPROM_ADDR,
+ CFG_ENV_OFFSET+I2C_BACKUP_ADDR,
+ (void *)&back,
+ sizeof(backup_t));
+}
+
+
+
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * Check Board Identity:
+ */
+
+int checkboard (void)
+{
+ unsigned char s[50];
+ unsigned char bc,var,rc;
+ int i;
+ backup_t *b=(backup_t *)s;
+
+ bc=get_board_revcfg();
+ var=~bc;
+ var&=0xf;
+ rc=0;
+ for(i=0;i<4;i++) {
+ rc<<=1;
+ rc+=(var & 0x1);
+ var>>=1;
+ }
+ rc++;
+ i=getenv_r("serial#",s,32);
+ if ((i==0) || strncmp(s, "MIP405", 6)) {
+ get_backup_values(b);
+ if(strncmp(b->signature,"MPL\0",4)!=0) {
+ printf("### No HW ID - assuming MIP405");
+ printf("-%d Rev %c",rc, 'A'+((bc>>4)&0xf));
+ }
+ else {
+ b->serial_name[6]=0;
+ printf("%s-%d Rev %c SN: %s",b->serial_name,rc, 'A'+((bc>>4)&0xf),&b->serial_name[7]);
+ }
+ }
+ else {
+ s[6]=0;
+ printf("%s-%d Rev %c SN: %s",s,rc, 'A'+((bc>>4)&0xf),&s[7]);
+ }
+ bc=in8(PLD_EXT_CONF_REG);
+ 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
+*/
+/* ------------------------------------------------------------------------- */
+/* ------------------------------------------------------------------------- */
+int testdram (unsigned long ramsize);
+
+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;
+ }
+ mtdcr(memcfga,mem_ecccf);
+ tmp= mfdcr(memcfgd);
+
+ if(!tmp)
+ printf("No ");
+ printf("ECC ");
+
+ testdram(TotalSize*MEGA_BYTE);
+ return (TotalSize*MEGA_BYTE);
+}
+
+/* ------------------------------------------------------------------------- */
+
+extern int mem_test(unsigned long start, unsigned long ramsize, int quiet);
+
+int testdram (unsigned long ramsize)
+{
+#ifdef SDRAM_DEBUG
+ mem_test(0L, ramsize, 1);
+#endif
+ /* not yet implemented */
+ return(1);
+}
+
+/* ------------------------------------------------------------------------- */
+
+ /* 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 */
+
+#undef SW_CS_DBG
+#ifdef SW_CS_DBG
+#define SW_CS_PRINTF(fmt,args...) printf (fmt ,##args)
+#else
+#define SW_CS_PRINTF(fmt,args...)
+#endif
+
+
+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 */
+ SW_CS_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);
+ SW_CS_PRINTF(" new cs0 cfg: %lx\n",pbcr);
+ mtdcr(ebccfga, pb1cr); /* get cs1 config reg (flash) */
+ pbcr = mfdcr(ebccfgd);
+ SW_CS_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);
+ SW_CS_PRINTF(" new cs1 cfg: %lx, MPS is on High Address\n",pbcr);
+ }
+ else
+ {
+ /* map flash to boot area, */
+ SW_CS_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);
+ SW_CS_PRINTF(" new cs0 cfg: %lx\n",pbcr);
+ mtdcr(ebccfga, pb1cr); /* get cs1 config reg (flash) */
+ pbcr = mfdcr(ebccfgd);
+ SW_CS_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);
+ SW_CS_PRINTF(" new cs1 cfg: %lx Flash is on High Address\n",pbcr);
+ }
+ return TRUE;
+ }
+ else {
+ SW_CS_PRINTF("Normal boot, no switching necessary\n");
+ return FALSE;
+ }
+}
+
+void misc_init_r(bd_t *bd)
+{
+#if 0
+ unsigned char bc;
+ char buf[128];
+ unsigned char *s;
+ bc=in8(PLD_EXT_CONF_REG);
+ bc>>=4;
+ bc &= 0x0f;
+ sprintf(buf,"bootcmd%d",bc);
+ s = getenv(buf);
+ if(s) {
+ sprintf(buf,"%s",s);
+ setenv("bootcmd",buf);
+ }
+ sprintf(buf,"bootargs%d",bc);
+ s = getenv(buf);
+ if(s) {
+ sprintf(buf,"%s",s);
+ setenv("bootargs",buf);
+ }
+#endif
+ /* it is time to swap the flash permanently to the flash area */
+ switch_cs(FALSE);
+}
+
+
+
+void set_init_backup(void)
+{
+ unsigned char *s;
+ char buf[32];
+ backup_t back;
+
+ s=getenv("serial#");
+ if(!s) {
+ get_backup_values(&back);
+ if(strncmp(back.signature,"MPL\0",4)==0) {
+ sprintf(buf,"%s",back.serial_name);
+ setenv("serial#",buf);
+ sprintf(buf,"%s",back.eth_addr);
+ setenv("ethaddr",buf);
+ printf("INFO: serial# and ethaddr recovered, use saveenv\n");
+ }
+ }
+ else {
+ /* check if back up is set */
+ get_backup_values(&back);
+ if(strncmp(back.signature,"MPL\0",4)!=0) {
+ set_backup_values(0);
+ }
+ }
+}
+
+extern device_t *stdio_devices[];
+extern char *stdio_names[];
+
+void show_stdio_dev(void)
+{
+ /* 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);
+ }
+}
+
+
+
+int last_stage_init(void)
+{
+ set_init_backup();
+ if(miiphy_write(0x1, 0x14, 0x2402) != 0) {
+ printf("Error writing to the PHY\n");
+ }
+ show_stdio_dev();
+ return 0;
+}
+
+/***************************************************************************
+ * some helping routines
+ */
+
+int overwrite_console(void)
+{
+ return(in8(PLD_EXT_CONF_REG) & 0x1); /* return TRUE if console should be overwritten */
+}
+
+
+/************************************************************************
+* Print MIP405 Info
+************************************************************************/
+void print_mip405_info(void)
+{
+ unsigned char part,vers,cfg,irq_reg,com_mode,ext;
+
+ part=in8(PLD_PART_REG);
+ vers=in8(PLD_VERS_REG);
+ cfg=in8(PLD_BOARD_CFG_REG);
+ irq_reg=in8(PLD_IRQ_REG);
+ com_mode=in8(PLD_COM_MODE_REG);
+ ext=in8(PLD_EXT_CONF_REG);
+
+ printf("PLD Part %d version %d\n",part,vers);
+ printf("Board Revision %c\n",((cfg>>4)&0xf)+'A');
+ printf("Population Options %d %d %d %d\n",(cfg)&0x1,(cfg>>1)&0x1,(cfg>>2)&0x1,(cfg>>3)&0x1);
+ printf("User LED %s\n",(com_mode & 0x4) ? "on" : "off");
+ printf("UART Clocks %d\n",(com_mode>>4)&0x3);
+ printf("User Config Switch %d %d %d %d %d %d %d %d\n",
+ (ext)&0x1,(ext>>1)&0x1,(ext>>2)&0x1,(ext>>3)&0x1,(ext>>4)&0x1,(ext>>5)&0x1,(ext>>6)&0x1,(ext>>7)&0x1);
+ printf("SER1 uses handshakes %s\n",(ext & 0x80) ? "DTR/DSR" : "RTS/CTS");
+ printf("IDE Reset %s\n",(ext & 0x01) ? "asserted" : "not asserted");
+ printf("IRQs:\n");
+ printf(" PIIX INTR: %s\n",(irq_reg & 0x80) ? "inactive" : "active");
+ printf(" UART0 IRQ: %s\n",(irq_reg & 0x40) ? "inactive" : "active");
+ printf(" UART1 IRQ: %s\n",(irq_reg & 0x20) ? "inactive" : "active");
+ printf(" PIIX SMI: %s\n",(irq_reg & 0x10) ? "inactive" : "active");
+ printf(" PIIX INIT: %s\n",(irq_reg & 0x8) ? "inactive" : "active");
+ printf(" PIIX NMI: %s\n",(irq_reg & 0x4) ? "inactive" : "active");
+}
+
+
+/******************************************************
+ * Routines to display the Board information
+ * to the screen (since the VGA will be initialized as last,
+ * we must resend the infos)
+ */
+#ifdef CONFIG_VIDEO
+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;
+ case PVR_405GP_RE: video_putc('E'); 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 */
+#if 0
+ 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");
+#endif
+}
+
+#endif
+
+
+
+
+
--- /dev/null
+/*
+ * (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 MIP405
+ *****************************************************************************/
+#ifndef __ASSEMBLY__
+int switch_cs(unsigned char boot);
+
+extern int mem_test(unsigned long start, unsigned long ramsize,int mode);
+
+void user_led0(unsigned char on);
+
+typedef struct {
+ char signature[4];
+ char serial_name[17]; /* "MIP405_1000xxxxx" */
+ char eth_addr[21]; /* "00:60:C2:0a:00:00" */
+} backup_t;
+void get_backup_values(backup_t *buf);
+void set_backup_values(int overwrite);
+
+
+#endif
+/* timings */
+/* PLD (CS7) */
+#define PLD_BME 0 /* Burst disable */
+#define PLD_TWE 5 /* 5 * 30ns 120ns Waitstates (access=TWT+1+TH) */
+#define PLD_CSN 1 /* Chipselect is driven inactive for 1 Cycle BTW transfers */
+#define PLD_OEN 1 /* Cycles from CS low to OE low */
+#define PLD_WBN 1 /* Cycles from CS low to WE low */
+#define PLD_WBF 1 /* Cycles from WE high to CS high */
+#define PLD_TH 2 /* Number of hold cycles after transfer */
+#define PLD_RE 0 /* Ready disabled */
+#define PLD_SOR 1 /* Sample on Ready disabled */
+#define PLD_BEM 0 /* Byte Write only active on Write cycles */
+#define PLD_PEN 0 /* Parity disable */
+#define PLD_AP ((PLD_BME << 31) + (PLD_TWE << 23) + (PLD_CSN << 18) + (PLD_OEN << 16) + (PLD_WBN << 14) + \
+ (PLD_WBF << 12) + (PLD_TH << 9) + (PLD_RE << 8) + (PLD_SOR << 7) + (PLD_BEM << 6) + (PLD_PEN << 5))
+
+/* Size: 0=1MB, 1=2MB, 2=4MB, 3=8MB, 4=16MB, 5=32MB, 6=64MB, 7=128MB */
+#define PLD_BS 0 /* 1 MByte */
+/* Usage: 0=disabled, 1=Read only, 2=Write Only, 3=R/W */
+#define PLD_BU 3 /* R/W */
+/* Bus width: 0=8Bit, 1=16Bit, 2=32Bit, 3=Reserved */
+#define PLD_BW 0 /* 16Bit */
+#define PLD_CR ((PER_PLD_ADDR & 0xfff00000) + (PLD_BS << 17) + (PLD_BU << 15) + (PLD_BW << 13))
+
+
+/* timings */
+
+#define PER_BOARD_ADDR (PER_UART1_ADDR+(1024*1024))
+/* Dummy CS to get the board revision */
+#define BOARD_BME 0 /* Burst disable */
+#define BOARD_TWE 255 /* 255 * 30ns 120ns Waitstates (access=TWT+1+TH) */
+#define BOARD_CSN 1 /* Chipselect is driven inactive for 1 Cycle BTW transfers */
+#define BOARD_OEN 1 /* Cycles from CS low to OE low */
+#define BOARD_WBN 1 /* Cycles from CS low to WE low */
+#define BOARD_WBF 1 /* Cycles from WE high to CS high */
+#define BOARD_TH 2 /* Number of hold cycles after transfer */
+#define BOARD_RE 0 /* Ready disabled */
+#define BOARD_SOR 1 /* Sample on Ready disabled */
+#define BOARD_BEM 0 /* Byte Write only active on Write cycles */
+#define BOARD_PEN 0 /* Parity disable */
+#define BOARD_AP ((BOARD_BME << 31) + (BOARD_TWE << 23) + (BOARD_CSN << 18) + (BOARD_OEN << 16) + (BOARD_WBN << 14) + \
+ (BOARD_WBF << 12) + (BOARD_TH << 9) + (BOARD_RE << 8) + (BOARD_SOR << 7) + (BOARD_BEM << 6) + (BOARD_PEN << 5))
+
+/* Size: 0=1MB, 1=2MB, 2=4MB, 3=8MB, 4=16MB, 5=32MB, 6=64MB, 7=128MB */
+#define BOARD_BS 0 /* 1 MByte */
+/* Usage: 0=disabled, 1=Read only, 2=Write Only, 3=R/W */
+#define BOARD_BU 3 /* R/W */
+/* Bus width: 0=8Bit, 1=16Bit, 2=32Bit, 3=Reserved */
+#define BOARD_BW 0 /* 16Bit */
+#define BOARD_CR ((PER_BOARD_ADDR & 0xfff00000) + (BOARD_BS << 17) + (BOARD_BU << 15) + (BOARD_BW << 13))
+
+
+/* UART0 CS2 */
+#define UART0_BME 0 /* Burst disable */
+#define UART0_TWE 7 /* 7 * 30ns 210ns Waitstates (access=TWT+1+TH) */
+#define UART0_CSN 1 /* Chipselect is driven inactive for 1 Cycle BTW transfers */
+#define UART0_OEN 1 /* Cycles from CS low to OE low */
+#define UART0_WBN 1 /* Cycles from CS low to WE low */
+#define UART0_WBF 1 /* Cycles from WE high to CS high */
+#define UART0_TH 2 /* Number of hold cycles after transfer */
+#define UART0_RE 0 /* Ready disabled */
+#define UART0_SOR 1 /* Sample on Ready disabled */
+#define UART0_BEM 0 /* Byte Write only active on Write cycles */
+#define UART0_PEN 0 /* Parity disable */
+#define UART0_AP ((UART0_BME << 31) + (UART0_TWE << 23) + (UART0_CSN << 18) + (UART0_OEN << 16) + (UART0_WBN << 14) + \
+ (UART0_WBF << 12) + (UART0_TH << 9) + (UART0_RE << 8) + (UART0_SOR << 7) + (UART0_BEM << 6) + (UART0_PEN << 5))
+
+/* Size: 0=1MB, 1=2MB, 2=4MB, 3=8MB, 4=16MB, 5=32MB, 6=64MB, 7=128MB */
+#define UART0_BS 0 /* 1 MByte */
+/* Usage: 0=disabled, 1=Read only, 2=Write Only, 3=R/W */
+#define UART0_BU 3 /* R/W */
+/* Bus width: 0=8Bit, 1=16Bit, 2=32Bit, 3=Reserved */
+#define UART0_BW 0 /* 8Bit */
+#define UART0_CR ((PER_UART0_ADDR & 0xfff00000) + (UART0_BS << 17) + (UART0_BU << 15) + (UART0_BW << 13))
+
+/* UART1 CS3 */
+#define UART1_AP UART0_AP /* same timing as UART0 */
+#define UART1_CR ((PER_UART1_ADDR & 0xfff00000) + (UART0_BS << 17) + (UART0_BU << 15) + (UART0_BW << 13))
+
+
+
+/* Flash CS0 or CS 1 */
+/* 0x7F8FFE80 slowest timing at all... */
+#define FLASH_BME_B 1 /* Burst enable */
+#define FLASH_FWT_B 0x6 /* 6 * 30ns 210ns First Wait Access */
+#define FLASH_BWT_B 0x6 /* 6 * 30ns 210ns Burst Wait Access */
+#define FLASH_BME 0 /* Burst disable */
+#define FLASH_TWE 0xb/* 11 * 30ns 330ns Waitstates (access=TWT+1+TH) */
+#define FLASH_CSN 0 /* Chipselect is driven inactive for 1 Cycle BTW transfers */
+#define FLASH_OEN 1 /* Cycles from CS low to OE low */
+#define FLASH_WBN 1 /* Cycles from CS low to WE low */
+#define FLASH_WBF 1 /* Cycles from WE high to CS high */
+#define FLASH_TH 2 /* Number of hold cycles after transfer */
+#define FLASH_RE 0 /* Ready disabled */
+#define FLASH_SOR 1 /* Sample on Ready disabled */
+#define FLASH_BEM 0 /* Byte Write only active on Write cycles */
+#define FLASH_PEN 0 /* Parity disable */
+/* Access Parameter Register for non Boot */
+#define FLASH_AP ((FLASH_BME << 31) + (FLASH_TWE << 23) + (FLASH_CSN << 18) + (FLASH_OEN << 16) + (FLASH_WBN << 14) + \
+ (FLASH_WBF << 12) + (FLASH_TH << 9) + (FLASH_RE << 8) + (FLASH_SOR << 7) + (FLASH_BEM << 6) + (FLASH_PEN << 5))
+/* Access Parameter Register for Boot */
+#define FLASH_AP_B ((FLASH_BME_B << 31) + (FLASH_FWT_B << 26) + (FLASH_BWT_B << 23) + (FLASH_CSN << 18) + (FLASH_OEN << 16) + (FLASH_WBN << 14) + \
+ (FLASH_WBF << 12) + (FLASH_TH << 9) + (FLASH_RE << 8) + (FLASH_SOR << 7) + (FLASH_BEM << 6) + (FLASH_PEN << 5))
+
+/* Size: 0=1MB, 1=2MB, 2=4MB, 3=8MB, 4=16MB, 5=32MB, 6=64MB, 7=128MB */
+#define FLASH_BS 2 /* 4 MByte */
+/* Usage: 0=disabled, 1=Read only, 2=Write Only, 3=R/W */
+#define FLASH_BU 3 /* R/W */
+/* Bus width: 0=8Bit, 1=16Bit, 2=32Bit, 3=Reserved */
+#define FLASH_BW 1 /* 16Bit */
+/* CR register for Boot */
+#define FLASH_CR_B ((FLASH_BASE0_PRELIM & 0xfff00000) + (FLASH_BS << 17) + (FLASH_BU << 15) + (FLASH_BW << 13))
+/* CR register for non Boot */
+#define FLASH_CR ((MULTI_PURPOSE_SOCKET_ADDR & 0xfff00000) + (FLASH_BS << 17) + (FLASH_BU << 15) + (FLASH_BW << 13))
+
+/* MPS CS1 or CS0 */
+/* Boot CS: */
+#define MPS_BME_B 1 /* Burst enable */
+#define MPS_FWT_B 0x6/* 6 * 30ns 210ns First Wait Access */
+#define MPS_BWT_B 0x6 /* 6 * 30ns 210ns Burst Wait Access */
+#define MPS_BME 0 /* Burst disable */
+#define MPS_TWE 0xb/* 11 * 30ns 330ns Waitstates (access=TWT+1+TH) */
+#define MPS_CSN 0 /* Chipselect is driven inactive for 1 Cycle BTW transfers */
+#define MPS_OEN 1 /* Cycles from CS low to OE low */
+#define MPS_WBN 1 /* Cycles from CS low to WE low */
+#define MPS_WBF 1 /* Cycles from WE high to CS high */
+#define MPS_TH 2 /* Number of hold cycles after transfer */
+#define MPS_RE 0 /* Ready disabled */
+#define MPS_SOR 1 /* Sample on Ready disabled */
+#define MPS_BEM 0 /* Byte Write only active on Write cycles */
+#define MPS_PEN 0 /* Parity disable */
+/* Access Parameter Register for non Boot */
+#define MPS_AP ((MPS_BME << 31) + (MPS_TWE << 23) + (MPS_CSN << 18) + (MPS_OEN << 16) + (MPS_WBN << 14) + \
+ (MPS_WBF << 12) + (MPS_TH << 9) + (MPS_RE << 8) + (MPS_SOR << 7) + (MPS_BEM << 6) + (MPS_PEN << 5))
+/* Access Parameter Register for Boot */
+#define MPS_AP_B ((MPS_BME_B << 31) + (MPS_FWT_B << 26) + (MPS_BWT_B << 23) + (MPS_CSN << 18) + (MPS_OEN << 16) + (MPS_WBN << 14) + \
+ (MPS_WBF << 12) + (MPS_TH << 9) + (MPS_RE << 8) + (MPS_SOR << 7) + (MPS_BEM << 6) + (MPS_PEN << 5))
+
+/* Size: 0=1MB, 1=2MB, 2=4MB, 3=8MB, 4=16MB, 5=32MB, 6=64MB, 7=128MB */
+#define MPS_BS 2 /* 4 MByte */
+/* Usage: 0=disabled, 1=Read only, 2=Write Only, 3=R/W */
+#define MPS_BU 3 /* R/W */
+/* Bus width: 0=8Bit, 1=16Bit, 2=32Bit, 3=Reserved */
+#define MPS_BW 0 /* 8Bit */
+/* CR register for Boot */
+#define MPS_CR_B ((FLASH_BASE0_PRELIM & 0xfff00000) + (MPS_BS << 17) + (MPS_BU << 15) + (MPS_BW << 13))
+/* CR register for non Boot */
+#define MPS_CR ((MULTI_PURPOSE_SOCKET_ADDR & 0xfff00000) + (MPS_BS << 17) + (MPS_BU << 15) + (MPS_BW << 13))
+
+
+
--- /dev/null
+/*
+ * (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
+ */
+
+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/mpl/mip405/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 = .);
+}
--- /dev/null
+#
+# (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
+#
+
+include $(TOPDIR)/config.mk
+
+LIB = lib$(BOARD).a
+
+OBJS = $(BOARD).o ../common/flash.o cmd_pip405.o ../common/pci.o ../common/isa.o ../common/kbd.o ../common/video.o ../common/sym53c8xx.o ../common/usb_uhci.o ../common/memtst.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
+
+#########################################################################
--- /dev/null
+/*
+ * (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 "../common/isa.h"
+#include "../common/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 -1;
+ }
+ 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 0;
+ case 1: printf ("Timeout writing to Flash\n"); return 1;
+ case 2: printf ("Flash not Erased\n"); return 1;
+ case 4: printf ("Can't write to protected Flash sectors\n"); return 1;
+ case 8: printf ("Outside available Flash\n"); return 1;
+ default: printf ("%s[%d] FIXME: rc=%d\n",__FILE__,__LINE__,rc); return 1;
+ }
+ return 1;
+}
+
+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 1;
+ }
+ if (hdr->ih_os != IH_OS_PPCBOOT) {
+ printf ("No PPCBOOT Image\n");
+ return 1;
+ }
+ if (hdr->ih_type != IH_TYPE_FIRMWARE) {
+ printf ("No Firmware Image\n");
+ return 1;
+ }
+ 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 1;
+ }
+ 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 1;
+ }
+ printf ("OK\n");
+ return(pip405_prg(data,len));
+}
+
+
+/* ------------------------------------------------------------------------- */
+
+int 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];
+ int result;
+ backup_t back;
+ 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 int 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);
+ result=do_fdcboot(cmdtp, bd, 0, 2, local_args);
+ }
+ else {
+ local_args[1] = NULL;
+ load_addr=CFG_LOAD_ADDR;
+ result=do_fdcboot(cmdtp, bd, 0, 1, local_args);
+ }
+ result=pip405_prg_image(load_addr);
+ return result;
+ }
+ 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);
+ result=pip405_prg_image(load_addr);
+ return result;
+ }
+ if (strcmp(argv[2], "mps") == 0) {
+ printf ("\nupdating bootloader image from MSP\n");
+ result=pip405_prg(src,size);
+ return result;
+ }
+ }
+ if (strcmp(argv[1], "getback") == 0) {
+ get_backup_values(&back);
+ back.signature[3]=0;
+ back.serial_name[16]=0;
+ back.eth_addr[20]=0;
+ printf("GetBackUp: signature: %s\n",back.signature);
+ printf(" serial#: %s\n",back.serial_name);
+ printf(" ethaddr: %s\n",back.eth_addr);
+ return 0;
+ }
+ if (strcmp(argv[1], "setback") == 0) {
+ set_backup_values(1);
+ return 0;
+ }
+ if (strcmp(argv[1], "mem") == 0)
+ {
+ result=0;
+ if(argc==3)
+ {
+ result = (int)simple_strtol(argv[2], NULL, 16);
+ }
+ src=(unsigned long)&result;
+ src-=CFG_MEMTEST_START;
+ src-=(100*1024); /* - 100k */
+ src&=0xfff00000;
+ size=0;
+ do {
+ size++;
+ printf("Pass %ld\n",size);
+ mem_test(CFG_MEMTEST_START,src,1);
+ if(ctrlc())
+ break;
+ if(result>0)
+ result--;
+
+ }while(result);
+ return 0;
+ }
+ if (strcmp(argv[1], "info") == 0)
+ {
+ print_pip405_info();
+ return 0;
+ }
+ if (strcmp(argv[1], "i2c") == 0)
+ {
+ i2c[0]=CFG_I2C_EEPROM_ADDR;
+ i2c[1]=0;
+ i2c[2]=0;
+ i2c_read(&i2c[0],3,(unsigned char *)CFG_LOAD_ADDR,512);
+ return 0;
+ }
+ if (strcmp(argv[1], "led") == 0)
+ {
+ 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 0;
+ }
+ printf("Usage:\n%s\n", cmdtp->usage);
+ return 1;
+}
+
+/* ------------------------------------------------------------------------- */
--- /dev/null
+#
+# (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
+#
+
+#
+# esd ADCIOP boards
+#
+
+#TEXT_BASE = 0xFFFE0000
+TEXT_BASE = 0xFFF80000
--- /dev/null
+/*------------------------------------------------------------------------------+
+ *
+ * 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
+
--- /dev/null
+/*
+ * (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 <devices.h>
+#include "../common/isa.h"
+#include "../common/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);
+}
+
+void SDRAM_err(const char *s)
+{
+#ifndef SDRAM_DEBUG
+ serial_init(get_gclk_freq(),9600);
+#endif
+ serial_puts("\n");
+ serial_puts(s);
+ serial_puts("\n enable SDRAM_DEBUG for more info\n");
+ for (;;);
+}
+
+
+#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);
+}
+
+void write_4hex(unsigned long val)
+{
+ write_hex((unsigned char)(val>>24));
+ write_hex((unsigned char)(val>>16));
+ write_hex((unsigned char)(val>>8));
+ write_hex((unsigned char)val);
+}
+
+#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,tctp_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(get_gclk_freq(),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;
+ i=i2c_send(SDRAM_EEPROM_WRITE_ADDRESS,1,dataout);
+#ifdef SDRAM_DEBUG
+ serial_puts("i2c_send returns ");
+ write_hex(i);
+#endif
+ i=i2c_receive(SDRAM_EEPROM_READ_ADDRESS,128,datain);
+#ifdef SDRAM_DEBUG
+ serial_puts("\ni2c_receive returns ");
+ write_hex(i);
+ serial_puts("\n");
+#endif
+
+#ifdef SDRAM_DEBUG
+ 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
+ SDRAM_err("SPD checksum Error");
+ }
+ /* 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 */
+ SDRAM_err("unsupported SDRAM");
+#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("rows: ");
+ write_hex(rows);
+ serial_puts(" cols: ");
+ write_hex(cols);
+ serial_puts(" banks: ");
+ write_hex(banks);
+ serial_puts(" mode: ");
+ write_hex(t->mode);
+ serial_puts("\n");
+#endif
+ if (t->mode == 0)
+ SDRAM_err("unsupported SDRAM");
+ /* 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;
+ /* ctp = ((trp + tras) - trp - trcd) => tras - trcd */
+ tctp_clocks = ((NSto10PS(datain[30])-NSto10PS(datain[29]))+(tmemclk-1)) / tmemclk;
+
+#ifdef SDRAM_DEBUG
+ serial_puts("c_RP: ");
+ write_hex(trp_clocks);
+ serial_puts("\nc_RCD: ");
+ write_hex(trcd_clocks);
+ serial_puts("\nc_RAS: ");
+ write_hex(tras_clocks);
+ serial_puts("\nc_RC: (RP+RAS): ");
+ write_hex(trc_clocks);
+ serial_puts("\nc_CTP: ((RP+RAS)-RP-RCD): ");
+ write_hex(tctp_clocks);
+ serial_puts("\nt_CTP: RAS - RCD: ");
+ write_hex((unsigned char)((NSto10PS(datain[30])-NSto10PS(datain[29]))>>8));
+ write_hex((unsigned char)(NSto10PS(datain[30])-NSto10PS(datain[29])));
+ serial_puts("\ntmemclk: ");
+ write_hex((unsigned char)(tmemclk>>8));
+ write_hex((unsigned char)(tmemclk));
+ serial_puts("\n");
+#endif
+
+
+ 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)
+ SDRAM_err("unsupported SDRAM");
+
+ /* get SDRAM timing register */
+ mtdcr(memcfga,mem_sdtr1);
+ tmp=mfdcr(memcfgd) & ~0x018FC01F;
+ /* insert CASL value */
+/* tmp |= ((unsigned long)cal_val) << 23; */
+ 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; */
+ tmp |= ((unsigned long)(trc_clocks - trp_clocks - trcd_clocks)) << 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;
+
+#ifdef SDRAM_DEBUG
+ serial_puts("sdtr: ");
+ write_4hex(tmp);
+ serial_puts("\n");
+#endif
+
+ /* 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: SDRAM_err("unsupported SDRAM");
+ } /* endswitch */
+ /* get SDRAM bank 0 register */
+ mtdcr(memcfga,mem_mb0cf);
+ bank = mfdcr(memcfgd) & ~0xFFCEE001;
+ bank |= (baseaddr | tmp | 0x01);
+#ifdef SDRAM_DEBUG
+ serial_puts("bank0: baseaddr: ");
+ write_4hex(baseaddr);
+ serial_puts(" banksize: ");
+ write_4hex(bank_size);
+ serial_puts(" mb0cf: ");
+ write_4hex(bank);
+ serial_puts("\n");
+#endif
+ 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;
+
+#ifdef SDRAM_DEBUG
+ serial_puts("bank1: baseaddr: ");
+ write_4hex(baseaddr);
+ serial_puts(" banksize: ");
+ write_4hex(bank_size);
+#endif
+ if (banks == 2) {
+ bank |= (baseaddr | tmp | 0x01);
+ baseaddr += bank_size;
+ sdram_size += bank_size;
+ } /* endif */
+#ifdef SDRAM_DEBUG
+ serial_puts(" mb1cf: ");
+ write_4hex(bank);
+ serial_puts("\n");
+#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);
+
+#ifdef SDRAM_DEBUG
+ serial_puts("bank2: baseaddr: ");
+ write_4hex(baseaddr);
+ serial_puts(" banksize: ");
+ write_4hex(bank_size);
+ serial_puts(" mb2cf: ");
+ write_4hex(bank);
+ serial_puts("\n");
+#endif
+
+ 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;
+
+#ifdef SDRAM_DEBUG
+ serial_puts("bank3: baseaddr: ");
+ write_4hex(baseaddr);
+ serial_puts(" banksize: ");
+ write_4hex(bank_size);
+#endif
+
+ if (banks == 2) {
+ bank |= (baseaddr | tmp | 0x01);
+ baseaddr += bank_size;
+ sdram_size += bank_size;
+ } /* endif */
+
+#ifdef SDRAM_DEBUG
+ serial_puts(" mb3cf: ");
+ write_4hex(bank);
+ serial_puts("\n");
+#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) | 0x80E00000;
+ 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;
+}
+
+
+/* ------------------------------------------------------------------------- */
+#define I2C_BACKUP_ADDR 0x7C00 /* 0x200 bytes for backup */
+
+void get_backup_values(backup_t *buf)
+{
+ eeprom_read (CFG_DEF_EEPROM_ADDR,
+ I2C_BACKUP_ADDR,
+ (void *)buf,
+ sizeof(backup_t));
+}
+
+void set_backup_values(int overwrite)
+{
+ backup_t back;
+ int i;
+
+ get_backup_values(&back);
+ if(!overwrite) {
+ if(strncmp(back.signature,"MPL\0",4)==0) {
+ printf("Not possible to write Backup\n");
+ return;
+ }
+ }
+ memcpy(back.signature,"MPL\0",4);
+ i=getenv_r("serial#",back.serial_name,16);
+ if(i==0) {
+ printf("Not possible to write Backup\n");
+ return;
+ }
+ back.serial_name[16]=0;
+ i=getenv_r("ethaddr",back.eth_addr,20);
+ if(i==0) {
+ printf("Not possible to write Backup\n");
+ return;
+ }
+ back.eth_addr[20]=0;
+ eeprom_write (CFG_DEF_EEPROM_ADDR,
+ CFG_ENV_OFFSET+I2C_BACKUP_ADDR,
+ (void *)&back,
+ sizeof(backup_t));
+}
+
+
+/*
+ * Check Board Identity:
+ */
+
+int checkboard (void)
+{
+ unsigned char s[50];
+ unsigned char bc;
+ int i;
+ backup_t *b=(backup_t *)s;
+
+ i=getenv_r("serial#",s,32);
+ if ((i==0) || strncmp(s, "PIP405", 6)) {
+ get_backup_values(b);
+ if(strncmp(b->signature,"MPL\0",4)!=0) {
+ printf("### No HW ID - assuming PIP405");
+ }
+ else {
+ b->serial_name[6]=0;
+ printf("%s SN: %s",b->serial_name,&b->serial_name[7]);
+ }
+ }
+ 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
+*/
+/* ------------------------------------------------------------------------- */
+/* ------------------------------------------------------------------------- */
+int testdram (unsigned long ramsize);
+
+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 ");
+ testdram(TotalSize*1024*1024);
+ /* bank 2 (SDRAM Clock 2) is not usable if 133MHz SDRAM IF */
+ if(get_gclk_freq()>220000000)
+ TotalSize/=2;
+ return (TotalSize*1024*1024);
+}
+
+/* ------------------------------------------------------------------------- */
+
+
+int testdram (unsigned long ramsize)
+{
+ /* not yet implemented */
+ return(1);
+}
+
+/* ------------------------------------------------------------------------- */
+
+ /* 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 */
+
+
+#undef SW_CS_DBG
+#ifdef SW_CS_DBG
+#define SW_CS_PRINTF(fmt,args...) printf (fmt ,##args)
+#else
+#define SW_CS_PRINTF(fmt,args...)
+#endif
+
+
+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 */
+ SW_CS_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 */
+ SW_CS_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);
+ SW_CS_PRINTF(" new cs0 cfg: %lx\n",pbcr);
+ mtdcr(ebccfga, pb1cr); /* get cs1 config reg (flash) */
+ pbcr = mfdcr(ebccfgd);
+ SW_CS_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);
+ SW_CS_PRINTF(" new cs1 cfg: %lx, MPS is on High Address\n",pbcr);
+ }
+ else
+ {
+ /* map flash to boot area, */
+ SW_CS_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);
+ SW_CS_PRINTF(" new cs0 cfg: %lx\n",pbcr);
+ mtdcr(ebccfga, pb1cr); /* get cs1 config reg (flash) */
+ pbcr = mfdcr(ebccfgd);
+ SW_CS_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);
+ SW_CS_PRINTF(" new cs1 cfg: %lx Flash is on High Address\n",pbcr);
+ }
+ return TRUE;
+ }
+ else {
+ SW_CS_PRINTF("Normal boot, no switching necessary\n");
+ return FALSE;
+ }
+}
+
+void misc_init_r(bd_t *bd)
+{
+ unsigned char bc;
+ char buf[128];
+ unsigned char *s;
+
+ bc=in8(CONFIG_PORT_ADDR);
+ bc>>=4;
+ bc &= 0x0f;
+ sprintf(buf,"bootcmd%d",bc);
+ s = getenv(buf);
+ if(s) {
+ sprintf(buf,"%s",s);
+ setenv("bootcmd",buf);
+ }
+ sprintf(buf,"bootargs%d",bc);
+ s = getenv(buf);
+ if(s) {
+ sprintf(buf,"%s",s);
+ setenv("bootargs",buf);
+ }
+}
+
+/***************************************************************************
+ * some helping routines
+ */
+
+int overwrite_console(void)
+{
+ return(in8(CONFIG_PORT_ADDR) & 0x1); /* return TRUE if console should be overwritten */
+}
+
+
+void set_init_backup(void)
+{
+ unsigned char *s;
+ char buf[32];
+ backup_t back;
+
+ s=getenv("serial#");
+ if(!s) {
+ get_backup_values(&back);
+ if(strncmp(back.signature,"MPL\0",4)==0) {
+ sprintf(buf,"%s",back.serial_name);
+ setenv("serial#",buf);
+ sprintf(buf,"%s",back.eth_addr);
+ setenv("ethaddr",buf);
+ printf("INFO: serial# and ethaddr recovered, use saveenv\n");
+ }
+ }
+ else {
+ /* check if back up is set */
+ get_backup_values(&back);
+ if(strncmp(back.signature,"MPL\0",4)!=0) {
+ set_backup_values(0);
+ }
+ }
+}
+
+extern int isa_init(void);
+
+
+void print_pip405_rev(void)
+{
+ unsigned char part,vers,cfg;
+ part=in8(PLD_PART_REG);
+ vers=in8(PLD_VERS_REG);
+ cfg=in8(PLD_BOARD_CFG_REG);
+ printf("Rev: PIP405-%d Rev %c PLD%d %d PLD%d %d\n",16-((cfg>>4)&0xf),(cfg&0xf)+'A',
+ part&0xf,vers&0xf,(part>>4)&0xf,(vers>>4)&0xf);
+}
+
+extern device_t *stdio_devices[];
+extern char *stdio_names[];
+
+void show_stdio_dev(void)
+{
+ /* 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);
+ }
+}
+
+
+
+int last_stage_init(void)
+{
+ print_pip405_rev();
+ set_init_backup();
+ isa_init();
+ show_stdio_dev();
+ return 0;
+}
+
+/************************************************************************
+* 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,gb;
+ 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 */
+ /* we do NOT round, because if we round 0.95MByte up, we get 0.10MByte !!*/
+ mb.rem *= 10;
+ mb.rem /= 2048;
+ 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 {
+ 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;
+
+ /* 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;
+ case PVR_405GP_RE: video_putc('E'); 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 {
+ 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);
+}
+
+
+
+
+
+
--- /dev/null
+/*
+ * (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);
+
+extern int mem_test(unsigned long start, unsigned long ramsize,int mode);
+
+void print_pip405_info(void);
+
+void user_led0(unsigned char on);
+void user_led1(unsigned char on);
+
+typedef struct {
+ char signature[4];
+ char serial_name[17]; /* "PIP405_1000xxxxx" */
+ char eth_addr[21]; /* "00:60:C2:08:00:00" */
+} backup_t;
+
+void get_backup_values(backup_t *buf);
+void set_backup_values(int overwrite);
+
+#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
+
+
--- /dev/null
+/*
+ * (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
+ */
+
+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/mpl/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 = .);
+}
--- /dev/null
+/*
+ * (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
+ */
+
+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 = .);
+}
+
cmd_nvedit.o cmd_pcmcia.o \
cmd_reginfo.o cmd_scsi.o \
console.o devices.o dlmalloc.o \
+ usb.o usb_storage.o usb_kbd.o cmd_usb.o \
flash.o hush.o kgdb.o \
lists.o miiphybb.o miiphyutil.o \
s_record.o
defined(CONFIG_LWMON) || \
defined(CONFIG_MPC8260ADS)|| \
defined(CONFIG_OCRTC) || \
- defined(CONFIG_PIP405) || \
defined(CONFIG_RPXSUPER) || \
defined(CONFIG_WALNUT405) || \
defined(CONFIG_W7O)
#if (CONFIG_COMMANDS & CFG_CMD_SCSI)
WATCHDOG_RESET();
+ puts ("SCSI: ");
scsi_init();
#endif
+#ifdef CONFIG_LAST_STAGE_INIT
+ WATCHDOG_RESET();
+ /*
+ * Some parts can be only initialized if all others (like
+ * Interrupts) are up and running (i.e. the PC-style ISA
+ * keyboard).
+ */
+ last_stage_init ();
+#endif
+
#if (CONFIG_COMMANDS & CFG_CMD_BEDBUG)
WATCHDOG_RESET();
bedbug_init();
#if !defined(CONFIG_CPCI405) && !defined(CONFIG_AR405) && \
- !defined(CONFIG_PIP405) && !defined(CONFIG_W7O) && \
+ !defined(CONFIG_I2C405) && !defined(CONFIG_W7O) && \
!defined (CONFIG_WALNUT405) && !defined (CONFIG_ERIC)
i2c_state_t state;
if (strncmp (argv[1], "res", 3) == 0) {
printf ("I2C reset 50kHz ... ");
#if defined(CONFIG_CPCI405) || defined(CONFIG_AR405) || \
- defined(CONFIG_PIP405) || defined(CONFIG_W7O) || \
+ defined(CONFIG_I2C405) || defined(CONFIG_W7O) || \
defined (CONFIG_WALNUT405) || defined (CONFIG_ERIC)
i2c_init ();
#else
else
printf ("I2C reset %dkHz ... ", speed/1000);
#if defined(CONFIG_CPCI405) || defined(CONFIG_AR405) || \
- defined(CONFIG_PIP405) || defined(CONFIG_W7O) || \
+ defined(CONFIG_I2C405) || defined(CONFIG_W7O) || \
defined (CONFIG_WALNUT405) || defined (CONFIG_ERIC)
i2c_init ();
#else
, i2c_addr, (ulong)data_addr, size);
#if defined(CONFIG_CPCI405) || defined(CONFIG_AR405) || \
- defined(CONFIG_PIP405) || defined(CONFIG_W7O) || \
+ defined(CONFIG_I2C405) || defined(CONFIG_W7O) || \
defined (CONFIG_WALNUT405) || defined (CONFIG_ERIC)
#else
#if defined(CONFIG_CPCI405) || defined(CONFIG_AR405) || \
- defined(CONFIG_PIP405) || defined(CONFIG_W7O) || \
+ defined(CONFIG_I2C405) || defined(CONFIG_W7O) || \
defined (CONFIG_WALNUT405) || defined (CONFIG_ERIC)
rc = i2c_receive (i2c_addr, size, data_addr);
}
#if defined(CONFIG_CPCI405) || defined(CONFIG_AR405) || \
- defined(CONFIG_PIP405) || defined(CONFIG_W7O) || \
+ defined(CONFIG_I2C405) || defined(CONFIG_W7O) || \
defined (CONFIG_WALNUT405) || defined (CONFIG_ERIC)
#else
#if defined(CONFIG_CPCI405) || defined(CONFIG_AR405) || \
- defined(CONFIG_PIP405) || defined(CONFIG_W7O) || \
+ defined(CONFIG_I2C405) || defined(CONFIG_W7O) || \
defined (CONFIG_WALNUT405) || defined (CONFIG_ERIC)
#else
#endif
#if defined(CONFIG_CPCI405) || defined(CONFIG_AR405) || \
- defined(CONFIG_PIP405) || defined(CONFIG_W7O) || \
+ defined(CONFIG_I2C405) || defined(CONFIG_W7O) || \
defined (CONFIG_WALNUT405) || defined (CONFIG_ERIC)
rc = i2c_send (i2c_addr, size, data_addr);
}
#if defined(CONFIG_CPCI405) || defined(CONFIG_AR405) || \
- defined(CONFIG_PIP405) || defined(CONFIG_W7O) || \
+ defined(CONFIG_I2C405) || defined(CONFIG_W7O) || \
defined (CONFIG_WALNUT405) || defined (CONFIG_ERIC)
#else
i2c_addr, sec_addr, (ulong)data_addr, size);
#if defined(CONFIG_CPCI405) || defined(CONFIG_AR405) || \
- defined(CONFIG_PIP405) || defined(CONFIG_W7O) || \
+ defined(CONFIG_I2C405) || defined(CONFIG_W7O) || \
defined (CONFIG_WALNUT405) || defined (CONFIG_ERIC)
#else
#endif
#if defined(CONFIG_CPCI405) || defined(CONFIG_AR405) || \
- defined(CONFIG_PIP405) || defined(CONFIG_W7O) || \
+ defined(CONFIG_I2C405) || defined(CONFIG_W7O) || \
defined (CONFIG_WALNUT405) || defined (CONFIG_ERIC)
rc = i2c_receive (i2c_addr, size, data_addr);
}
#if defined(CONFIG_CPCI405) || defined(CONFIG_AR405) || \
- defined(CONFIG_PIP405) || defined(CONFIG_W7O) || \
+ defined(CONFIG_I2C405) || defined(CONFIG_W7O) || \
defined (CONFIG_WALNUT405) || defined (CONFIG_ERIC)
#else
i2c_addr, sec_addr, (ulong)data_addr, size);
#if defined(CONFIG_CPCI405) || defined(CONFIG_AR405) || \
- defined(CONFIG_PIP405) || defined(CONFIG_W7O) || \
+ defined(CONFIG_I2C405) || defined(CONFIG_W7O) || \
defined (CONFIG_WALNUT405) || defined (CONFIG_ERIC)
#else
#endif
#if defined(CONFIG_CPCI405) || defined(CONFIG_AR405) || \
- defined(CONFIG_PIP405) || defined(CONFIG_W7O) || \
+ defined(CONFIG_I2C405) || defined(CONFIG_W7O) || \
defined (CONFIG_WALNUT405) || defined (CONFIG_ERIC)
rc = i2c_send (i2c_addr, size, data_addr);
}
#if defined(CONFIG_CPCI405) || defined(CONFIG_AR405) || \
- defined(CONFIG_PIP405) || defined(CONFIG_W7O) || \
+ defined(CONFIG_I2C405) || defined(CONFIG_W7O) || \
defined (CONFIG_WALNUT405) || defined (CONFIG_ERIC)
#else
ident = p + 4;
break;
case CISTPL_FUNCID:
- func_id = *p;
+ /* Fix for broken SanDisk which may have 0x80 bit set */
+ func_id = *p & 0x7F;
break;
case CISTPL_FUNCE:
if (n_features < MAX_FEATURES)
ccb* pccb=(ccb *)&tempccb;
if(mode==1) {
- printf("SCSI: scanning bus for devices...\n");
+ printf("scanning bus for devices...\n");
}
for(i=0;i<CFG_SCSI_MAX_DEVICE;i++) {
scsi_dev_desc[i].target=0xff;
--- /dev/null
+/*
+ * (C) Copyright 2001
+ * Denis Peter, MPL AG Switzerland
+ *
+ * Most of this source has been derived from the Linux USB
+ * project.
+ *
+ * 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>
+
+#if (CONFIG_COMMANDS & CFG_CMD_USB)
+
+#include <usb.h>
+#include <cmd_disk.h>
+
+#undef CMD_USB_DEBUG
+
+#ifdef CMD_USB_DEBUG
+#define CMD_USB_PRINTF(fmt,args...) printf (fmt ,##args)
+#else
+#define CMD_USB_PRINTF(fmt,args...)
+#endif
+static int usb_stor_curr_dev=-1; /* current device */
+
+/* somme display routines (info command) */
+char * usb_get_class_desc(unsigned char dclass)
+{
+ switch(dclass) {
+ case USB_CLASS_PER_INTERFACE:
+ return("See Interface");
+ case USB_CLASS_AUDIO:
+ return("Audio");
+ case USB_CLASS_COMM:
+ return("Communication");
+ case USB_CLASS_HID:
+ return("Human Interface");
+ case USB_CLASS_PRINTER:
+ return("Printer");
+ case USB_CLASS_MASS_STORAGE:
+ return("Mass Storage");
+ case USB_CLASS_HUB:
+ return("Hub");
+ case USB_CLASS_DATA:
+ return("CDC Data");
+ case USB_CLASS_VENDOR_SPEC:
+ return("Vendor specific");
+ default :
+ return("");
+ }
+}
+
+void usb_display_class_sub(unsigned char dclass,unsigned char subclass,unsigned char proto)
+{
+ switch(dclass) {
+ case USB_CLASS_PER_INTERFACE:
+ printf("See Interface");
+ break;
+ case USB_CLASS_HID:
+ printf("Human Interface, Subclass: ");
+ switch(subclass) {
+ case USB_SUB_HID_NONE:
+ printf("None");
+ break;
+ case USB_SUB_HID_BOOT:
+ printf("Boot ");
+ switch(proto) {
+ case USB_PROT_HID_NONE:
+ printf("None");
+ break;
+ case USB_PROT_HID_KEYBOARD:
+ printf("Keyboard");
+ break;
+ case USB_PROT_HID_MOUSE:
+ printf("Mouse");
+ break;
+ default:
+ printf("reserved");
+ }
+ break;
+ default:
+ printf("reserved");
+ }
+ break;
+ case USB_CLASS_MASS_STORAGE:
+ printf("Mass Storage, ");
+ switch(subclass) {
+ case US_SC_RBC:
+ printf("RBC ");
+ break;
+ case US_SC_8020:
+ printf("SFF-8020i (ATAPI)");
+ break;
+ case US_SC_QIC:
+ printf("QIC-157 (Tape)");
+ break;
+ case US_SC_UFI:
+ printf("UFI");
+ break;
+ case US_SC_8070:
+ printf("SFF-8070");
+ break;
+ case US_SC_SCSI:
+ printf("Transp. SCSI");
+ break;
+ default:
+ printf("reserved");
+ break;
+ }
+ printf(", ");
+ switch(proto) {
+ case US_PR_CB:
+ printf("Command/Bulk");
+ break;
+ case US_PR_CBI:
+ printf("Command/Bulk/Int");
+ break;
+ case US_PR_BULK:
+ printf("Bulk only");
+ break;
+ default:
+ printf("reserved");
+ }
+ break;
+ default:
+ printf("%s",usb_get_class_desc(dclass));
+ }
+}
+
+void usb_display_string(struct usb_device *dev,int index)
+{
+ char buffer[256];
+ if(index!=0) {
+ if(usb_string(dev,index,&buffer[0],256)>0);
+ printf("String: \"%s\"",buffer);
+ }
+}
+
+void usb_display_desc(struct usb_device *dev)
+{
+ if(dev->descriptor.bDescriptorType==USB_DT_DEVICE) {
+ printf("%d: %s, USB Revision %x.%x\n",dev->devnum,usb_get_class_desc(dev->config.if_desc[0].bInterfaceClass),
+ (dev->descriptor.bcdUSB>>8) & 0xff,dev->descriptor.bcdUSB & 0xff);
+ if(strlen(dev->mf) || strlen(dev->prod) || strlen(dev->serial))
+ printf(" - %s %s %s\n",dev->mf,dev->prod,dev->serial);
+ if(dev->descriptor.bDeviceClass) {
+ printf(" - Class: ");
+ usb_display_class_sub(dev->descriptor.bDeviceClass,dev->descriptor.bDeviceSubClass,dev->descriptor.bDeviceProtocol);
+ printf("\n");
+ }
+ else {
+ printf(" - Class: (from Interface) %s\n",usb_get_class_desc(dev->config.if_desc[0].bInterfaceClass));
+ }
+ printf(" - PacketSize: %d Configurations: %d\n",dev->descriptor.bMaxPacketSize0,dev->descriptor.bNumConfigurations);
+ printf(" - Vendor: 0x%04x Product 0x%04x Version %d.%d\n",dev->descriptor.idVendor,dev->descriptor.idProduct,(dev->descriptor.bcdDevice>>8) & 0xff,dev->descriptor.bcdDevice & 0xff);
+ }
+
+}
+
+void usb_display_conf_desc(struct usb_config_descriptor *config,struct usb_device *dev)
+{
+ printf(" Configuration: %d\n",config->bConfigurationValue);
+ printf(" - Interfaces: %d %s%s%dmA\n",config->bNumInterfaces,(config->bmAttributes & 0x40) ? "Self Powered " : "Bus Powered ",
+ (config->bmAttributes & 0x20) ? "Remote Wakeup " : "",config->MaxPower*2);
+ if(config->iConfiguration) {
+ printf(" - ");
+ usb_display_string(dev,config->iConfiguration);
+ printf("\n");
+ }
+}
+
+void usb_display_if_desc(struct usb_interface_descriptor *ifdesc,struct usb_device *dev)
+{
+ printf(" Interface: %d\n",ifdesc->bInterfaceNumber);
+ printf(" - Alternate Settings %d, Endpoints: %d\n",ifdesc->bAlternateSetting,ifdesc->bNumEndpoints);
+ printf(" - Class ");
+ usb_display_class_sub(ifdesc->bInterfaceClass,ifdesc->bInterfaceSubClass,ifdesc->bInterfaceProtocol);
+ printf("\n");
+ if(ifdesc->iInterface) {
+ printf(" - ");
+ usb_display_string(dev,ifdesc->iInterface);
+ printf("\n");
+ }
+}
+
+void usb_display_ep_desc(struct usb_endpoint_descriptor *epdesc)
+{
+ printf(" - Endpoint %d %s ",epdesc->bEndpointAddress & 0xf,(epdesc->bEndpointAddress & 0x80) ? "In" : "Out");
+ switch((epdesc->bmAttributes & 0x03))
+ {
+ case 0: printf("Control"); break;
+ case 1: printf("Isochronous"); break;
+ case 2: printf("Bulk"); break;
+ case 3: printf("Interrupt"); break;
+ }
+ printf(" MaxPacket %d",epdesc->wMaxPacketSize);
+ if((epdesc->bmAttributes & 0x03)==0x3)
+ printf(" Interval %dms",epdesc->bInterval);
+ printf("\n");
+}
+
+/* main routine to diasplay the configs, interfaces and endpoints */
+void usb_display_config(struct usb_device *dev)
+{
+ struct usb_config_descriptor *config;
+ struct usb_interface_descriptor *ifdesc;
+ struct usb_endpoint_descriptor *epdesc;
+ int i,ii;
+
+ config= &dev->config;
+ usb_display_conf_desc(config,dev);
+ for(i=0;i<config->no_of_if;i++) {
+ ifdesc= &config->if_desc[i];
+ usb_display_if_desc(ifdesc,dev);
+ for(ii=0;ii<ifdesc->no_of_ep;ii++) {
+ epdesc= &ifdesc->ep_desc[ii];
+ usb_display_ep_desc(epdesc);
+ }
+ }
+ printf("\n");
+}
+
+/* shows the device tree recursively */
+void usb_show_tree_graph(struct usb_device *dev,char *pre)
+{
+ int i,index;
+ int has_child,last_child,port;
+
+ index=strlen(pre);
+ printf(" %s",pre);
+ /* check if the device has connected children */
+ has_child=0;
+ for(i=0;i<dev->maxchild;i++) {
+ if(dev->children[i]!=NULL)
+ has_child=1;
+ }
+ /* check if we are the last one */
+ last_child=1;
+ if(dev->parent!=NULL) {
+ for(i=0;i<dev->parent->maxchild;i++) {
+ /* search for children */
+ if(dev->parent->children[i]==dev) {
+ /* found our pointer, see if we have a little sister */
+ port=i;
+ while(i++<dev->parent->maxchild) {
+ if(dev->parent->children[i]!=NULL) {
+ /* found a sister */
+ last_child=0;
+ break;
+ } /* if */
+ } /* while */
+ } /* device found */
+ } /* for all children of the parent */
+ printf("\b+-");
+ /* correct last child */
+ if(last_child) {
+ pre[index-1]=' ';
+ }
+ } /* if not root hub */
+ else
+ printf(" ");
+ printf("%d ",dev->devnum);
+ pre[index++]=' ';
+ pre[index++]= has_child ? '|' : ' ';
+ pre[index]=0;
+ printf(" %s (%s, %dmA)\n",usb_get_class_desc(dev->config.if_desc[0].bInterfaceClass),
+ dev->slow ? "1.5MBit/s" : "12MBit/s",dev->config.MaxPower * 2);
+ if(strlen(dev->mf) ||
+ strlen(dev->prod) ||
+ strlen(dev->serial))
+ printf(" %s %s %s %s\n",pre,dev->mf,dev->prod,dev->serial);
+ printf(" %s\n",pre);
+ if(dev->maxchild>0) {
+ for(i=0;i<dev->maxchild;i++) {
+ if(dev->children[i]!=NULL) {
+ usb_show_tree_graph(dev->children[i],pre);
+ pre[index]=0;
+ }
+ }
+ }
+}
+
+/* main routine for the tree command */
+void usb_show_tree(struct usb_device *dev)
+{
+ char preamble[32];
+
+ memset(preamble,0,32);
+ usb_show_tree_graph(dev,&preamble[0]);
+}
+
+
+
+/******************************************************************************
+ * usb boot command intepreter. Derived from diskboot
+ */
+#ifdef CONFIG_USB_STORAGE
+int do_usbboot (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
+{
+ char *boot_device = NULL;
+ char *ep;
+ int dev, part,rcode;
+ ulong cnt;
+ ulong addr;
+ disk_partition_t info;
+ image_header_t *hdr;
+ block_dev_desc_t *stor_dev;
+
+
+ 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 1;
+ }
+
+ if (!boot_device) {
+ puts ("\n** No boot device **\n");
+ return 1;
+ }
+
+ dev = simple_strtoul(boot_device, &ep, 16);
+ stor_dev=usb_stor_get_dev(dev);
+ if (stor_dev->type == DEV_TYPE_UNKNOWN) {
+ printf ("\n** Device %d not available\n", dev);
+ return 1;
+ }
+ if(stor_dev->block_read==NULL) {
+ printf("storage device not initialized. Use usb scan\n");
+ return 1;
+ }
+ if (*ep) {
+ if (*ep != ':') {
+ puts ("\n** Invalid boot device, use `dev[:part]' **\n");
+ return 1;
+ }
+ part = simple_strtoul(++ep, NULL, 16);
+ }
+
+ if (get_partition_info (stor_dev, part, &info)) {
+ /* try to boot raw .... */
+ strncpy(&info.type[0], BOOT_PART_TYPE, sizeof(BOOT_PART_TYPE));
+ strncpy(&info.name[0], "Raw", 4);
+ info.start=0;
+ info.blksz=0x200;
+ info.size=2880;
+ printf("error reading partinfo...try to boot raw\n");
+ }
+ 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 1;
+ }
+ printf ("\nLoading from USB 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 (stor_dev->block_read(dev, info.start, 1, (ulong *)addr) != 1) {
+ printf ("** Read error on %d:%d\n", dev, part);
+ return 1;
+ }
+
+ 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 {
+ printf("\n** Bad Magic Number **\n");
+ return 1;
+ }
+
+ if (stor_dev->block_read (dev, info.start+1, cnt,
+ (ulong *)(addr+info.blksz)) != cnt) {
+ printf ("\n** Read error on %d:%d\n", dev, part);
+ return 1;
+ }
+ /* 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 int 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);
+ rcode=do_bootm (cmdtp, bd, 0, 1, local_args);
+ return rcode;
+ }
+ return 0;
+}
+#endif /* CONFIG_USB_STORAGE */
+
+
+
+
+/*********************************************************************************
+ * usb command intepreter
+ */
+int do_usb (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
+{
+
+ int i;
+ struct usb_device *dev;
+ block_dev_desc_t *stor_dev;
+
+ if ((strncmp(argv[1],"reset",5) == 0) ||
+ (strncmp(argv[1],"start",5) == 0)){
+ usb_stop();
+ printf("(Re)start USB...\n");
+ usb_init();
+ return 0;
+ }
+ if (strncmp(argv[1],"stop",4) == 0) {
+#ifdef CONFIG_USB_KEYBOARD
+ if(argc==2) {
+ if(usb_kbd_deregister()!=0) {
+ printf("USB not stopped: usbkbd still using USB\n");
+ return 1;
+ }
+ }
+ else { /* forced stop, switch console in to serial */
+ console_assign(stdin,"serial");
+ usb_kbd_deregister();
+ }
+#endif
+ printf("stopping USB..\n");
+ usb_stop();
+ return 0;
+ }
+ if (strncmp(argv[1],"tree",4) == 0) {
+ printf("\nDevice Tree:\n");
+ usb_show_tree(usb_get_dev_index(0));
+ return 0;
+ }
+ if (strncmp(argv[1],"inf",3) == 0) {
+ int d;
+ if(argc==2) {
+ for(d=0;d<USB_MAX_DEVICE;d++) {
+ dev=usb_get_dev_index(d);
+ if(dev==NULL)
+ break;
+ usb_display_desc(dev);
+ usb_display_config(dev);
+ }
+ return 0;
+ }
+ else {
+ int d;
+
+ i=simple_strtoul(argv[2], NULL, 16);
+ printf("config for device %d\n",i);
+ for(d=0;d<USB_MAX_DEVICE;d++) {
+ dev=usb_get_dev_index(d);
+ if(dev==NULL)
+ break;
+ if(dev->devnum==i)
+ break;
+ }
+ if(dev==NULL) {
+ printf("*** NO Device avaiable ***\n");
+ return 0;
+ }
+ else {
+ usb_display_desc(dev);
+ usb_display_config(dev);
+ }
+ }
+ return 0;
+ }
+#ifdef CONFIG_USB_STORAGE
+ if (strncmp(argv[1],"scan",4) == 0) {
+ printf("Scan for storage device:\n");
+ usb_stor_curr_dev=usb_stor_scan(1);
+ if(usb_stor_curr_dev==-1) {
+ printf("No device found. Not initialized?\n");
+ return 1;
+ }
+ return 0;
+ }
+ if (strncmp(argv[1],"part",4) == 0) {
+ int devno, ok;
+ for (ok=0, devno=0; devno<USB_MAX_STOR_DEV; ++devno) {
+ stor_dev=usb_stor_get_dev(devno);
+ if (stor_dev->type!=DEV_TYPE_UNKNOWN) {
+ ok++;
+ if (devno)
+ printf("\n");
+ printf("print_part of %x\n",devno);
+ print_part(stor_dev);
+ }
+ }
+ if (!ok) {
+ printf("\nno USB devices available\n");
+ return 1;
+ }
+ return 0;
+ }
+ if (strcmp(argv[1],"read") == 0) {
+ if(usb_stor_curr_dev<0) {
+ printf("no current device selected\n");
+ return 1;
+ }
+ if(argc==5) {
+ unsigned long addr = simple_strtoul(argv[2], NULL, 16);
+ unsigned long blk = simple_strtoul(argv[3], NULL, 16);
+ unsigned long cnt = simple_strtoul(argv[4], NULL, 16);
+ unsigned long n;
+ printf ("\nUSB read: device %d block # %ld, count %ld ... ",
+ usb_stor_curr_dev, blk, cnt);
+ stor_dev=usb_stor_get_dev(usb_stor_curr_dev);
+ n = stor_dev->block_read(usb_stor_curr_dev, blk, cnt, (ulong *)addr);
+ printf ("%ld blocks read: %s\n",n,(n==cnt) ? "OK" : "ERROR");
+ if(n==cnt)
+ return 0;
+ return 1;
+ }
+ }
+ if (strcmp(argv[1],"dev") == 0) {
+ if(argc==3) {
+ int dev = (int)simple_strtoul(argv[2], NULL, 10);
+ printf ("\nUSB device %d: ", dev);
+ if (dev >= USB_MAX_STOR_DEV) {
+ printf("unknown device\n");
+ return 1;
+ }
+ printf ("\n Device %d: ", dev);
+ stor_dev=usb_stor_get_dev(dev);
+ dev_print(stor_dev);
+ if(stor_dev->type == DEV_TYPE_UNKNOWN) {
+ return 1;
+ }
+ usb_stor_curr_dev = dev;
+ printf("... is now current device\n");
+ return 0;
+ }
+ else {
+ printf ("\nUSB device %d: ", usb_stor_curr_dev);
+ stor_dev=usb_stor_get_dev(usb_stor_curr_dev);
+ dev_print(stor_dev);
+ if(stor_dev->type == DEV_TYPE_UNKNOWN) {
+ return 1;
+ }
+ return 0;
+ }
+ return 0;
+ }
+#endif /* CONFIG_USB_STORAGE */
+ printf ("Usage:\n%s\n", cmdtp->usage);
+ return 1;
+}
+
+
+#endif /* (CONFIG_COMMANDS & CFG_CMD_USB) */
+
+
#include <cmd_rtc.h>
#include <cmd_fdc.h> /* Floppy support */
+#include <cmd_usb.h> /* USB support */
#include <cmd_scsi.h>
#include <cmd_mii.h>
#include <cmd_dcr.h> /* 4xx DCR register access */
CMD_TBL_STACK
CMD_TBL_STEP
CMD_TBL_TFTPB
+ CMD_TBL_USBBOOT
+ CMD_TBL_USB
CMD_TBL_VERS
CMD_TBL_BSP
CMD_TBL_QUES
* MA 02111-1307 USA
*/
+#include <config.h>
#include <ppcboot.h>
#include <stdarg.h>
#include <malloc.h>
return 0;
}
+/* deregister the device "devname".
+ * returns 0 if success, -1 if device is assigned and 1 if devname not found
+ */
+#ifdef CFG_DEVICE_DEREGISTER
+int device_deregister(char *devname)
+{
+ int i,l,dev_index;
+ device_t *dev;
+ char temp_names[3][8];
+
+ dev_index=-1;
+ for (i=1; i<=ListNumItems(devlist); i++) {
+ dev = ListGetPtrToItem (devlist, i);
+ if(strcmp(dev->name,devname)==0) {
+ dev_index=i;
+ break;
+ }
+ }
+ if(dev_index<0) /* device not found */
+ return 0;
+ /* get stdio devices (ListRemoveItem changes the dev list) */
+ for (l=0 ; l< MAX_FILES; l++) {
+ if (stdio_devices[l] == dev) {
+ /* Device is assigned -> report error */
+ return -1;
+ }
+ memcpy (&temp_names[l][0],
+ stdio_devices[l]->name,
+ sizeof(stdio_devices[l]->name));
+ }
+ ListRemoveItem(devlist,NULL,dev_index);
+ /* reassign Device list */
+ for (i=1; i<=ListNumItems(devlist); i++) {
+ dev = ListGetPtrToItem (devlist, i);
+ for (l=0 ; l< MAX_FILES; l++) {
+ if(strcmp(dev->name,temp_names[l])==0) {
+ stdio_devices[l] = dev;
+ }
+ }
+ }
+ return 0;
+}
+#endif /* CFG_DEVICE_DEREGISTER */
int devices_init (bd_t *bd, 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 ();
#define MIN(a,b) (((a)<(b)) ? (a) : (b))
#define CAT4CHARS(a,b,c,d) ((a<<24) | (b<<16) | (c<<8) | d)
-#define kDefaultAllocationPercentIncrease 10 /* increase list size by 10% every time it is full */
-#define kDefaultAllocationminNumItemsIncrease 4 /* always increase list size by 4 items when it is full */
+/* increase list size by 10% every time it is full */
+#define kDefaultAllocationPercentIncrease 10
- /* how many items to expand the list by when it becomes full = current listSize (in items) + (hiword percent of list size) + loword */
-#define NUMITEMSPERALLOC(list) MAX(((*list)->listSize * ((*list)->percentIncrease + 100)) / 100 , (*list)->minNumItemsIncrease)
+/* always increase list size by 4 items when it is full */
+#define kDefaultAllocationminNumItemsIncrease 4
-#define ITEMPTR(list, item) &(((char *)&(*list)->itemList)[ (*(list))->itemSize * (item)])
+/*
+ * how many items to expand the list by when it becomes full
+ * = current listSize (in items) + (hiword percent of list size) + loword
+ */
+#define NUMITEMSPERALLOC(list) MAX(((*list)->listSize * \
+ ((*list)->percentIncrease + 100)) / 100, \
+ (*list)->minNumItemsIncrease )
-#define LIST_SIGNATURE CAT4CHARS('L', 'I', 'S', 'T');
+#define ITEMPTR(list,item) &(((char *)&(*list)->itemList)[(*(list))->itemSize * (item)])
+
+#define LIST_SIGNATURE CAT4CHARS('L', 'I', 'S', 'T');
#define calloc(size,num) malloc(size*num)
/********************************************************************/
-Handle NewHandle(unsigned int numBytes)
+Handle NewHandle (unsigned int numBytes)
{
- void *memPtr;
- HandleRecord *hanPtr;
+ void *memPtr;
+ HandleRecord *hanPtr;
- memPtr = calloc(numBytes, 1);
- hanPtr = (HandleRecord*)calloc(sizeof(HandleRecord), 1);
- if (hanPtr && (memPtr || numBytes == 0))
- {
- hanPtr->ptr = memPtr;
- hanPtr->size = numBytes;
- return (Handle)hanPtr;
- }
- else
- {
- free(memPtr);
- free(hanPtr);
- return NULL;
- }
+ memPtr = calloc (numBytes, 1);
+ hanPtr = (HandleRecord *) calloc (sizeof (HandleRecord), 1);
+ if (hanPtr && (memPtr || numBytes == 0)) {
+ hanPtr->ptr = memPtr;
+ hanPtr->size = numBytes;
+ return (Handle) hanPtr;
+ } else {
+ free (memPtr);
+ free (hanPtr);
+ return NULL;
+ }
}
-
/********************************************************************/
-void DisposeHandle(Handle handle)
+void DisposeHandle (Handle handle)
{
- if (handle)
- {
- free(*handle);
- free((void *)handle);
- }
+ if (handle) {
+ free (*handle);
+ free ((void *) handle);
+ }
}
-
/********************************************************************/
-unsigned int GetHandleSize(Handle handle)
+unsigned int GetHandleSize (Handle handle)
{
- return ((HandleRecord *)handle)->size;
+ return ((HandleRecord *) handle)->size;
}
-
/********************************************************************/
-int SetHandleSize(Handle handle, unsigned int newSize)
+int SetHandleSize (Handle handle, unsigned int newSize)
{
- HandleRecord *hanRecPtr = (HandleRecord *)handle;
- void *newPtr, *oldPtr;
- unsigned int oldSize;
+ HandleRecord *hanRecPtr = (HandleRecord *) handle;
+ void *newPtr, *oldPtr;
+ unsigned int oldSize;
- oldPtr = hanRecPtr->ptr;
- oldSize = hanRecPtr->size;
+ oldPtr = hanRecPtr->ptr;
+ oldSize = hanRecPtr->size;
- if (oldSize == newSize)
- return 1;
+ if (oldSize == newSize)
+ return 1;
- if (oldPtr == NULL)
- {
- newPtr = malloc(newSize);
- }
- else
- {
- newPtr = realloc(oldPtr, newSize);
- }
- if (newPtr || (newSize == 0))
- {
- hanRecPtr->ptr = newPtr;
- hanRecPtr->size = newSize;
- if (newSize > oldSize)
- memset ((char *)newPtr+oldSize, 0, newSize-oldSize);
- return 1;
- }
- else
- return 0;
+ if (oldPtr == NULL) {
+ newPtr = malloc (newSize);
+ } else {
+ newPtr = realloc (oldPtr, newSize);
+ }
+ if (newPtr || (newSize == 0)) {
+ hanRecPtr->ptr = newPtr;
+ hanRecPtr->size = newSize;
+ if (newSize > oldSize)
+ memset ((char *) newPtr + oldSize, 0, newSize - oldSize);
+ return 1;
+ } else
+ return 0;
}
#ifdef CFG_ALL_LIST_FUNCTIONS
- /* Used to compare list elements by their raw data contents */
-static int ListMemBlockCmp(void *a, void *b, int size)
+/* Used to compare list elements by their raw data contents */
+static int ListMemBlockCmp (void *a, void *b, int size)
{
- return memcmp(a, b, size);
+ return memcmp (a, b, size);
}
-
/***************************************************************************/
- /* Binary search numElements of size elementSize in array for a match
- to the. item. Return the index of the element that matches (0 - numElements - 1).
- If no match is found return the -i-1 where i is the index (0 - numElements)
- where the item should be placed. (*theCmp)(a,b) should return <0 if a<b,
- 0 if a==b, >0 if a>b.
-
- This function is like the C-Library function bsearch() except that this
- function returns the index where the item should be placed if it is not
- found.
- */
-int BinSearch(void *array, int numElements, int elementSize, void *itemPtr, CompareFunction compareFunction)
-{
- int low, high, mid, cmp;
- void *arrayItemPtr;
-
- for(low=0, high= numElements-1, mid=0, cmp= -1; low <= high; )
- {
- mid = (low + high) >> 1;
-
- arrayItemPtr = (void *) (((char *)array) + (mid*elementSize));
- cmp = compareFunction ? compareFunction(itemPtr, arrayItemPtr)
- : ListMemBlockCmp(itemPtr, arrayItemPtr, elementSize);
- if (cmp == 0)
- return mid;
- else
- if (cmp < 0)
- high= mid - 1;
- else
- low= mid + 1;
- }
- if (cmp > 0)
- mid++;
-
- return -mid-1;
+/*
+ * Binary search numElements of size elementSize in array for a match
+ * to the. item. Return the index of the element that matches
+ * (0 - numElements - 1). If no match is found return the -i-1 where
+ * i is the index (0 - numElements) where the item should be placed.
+ * (*theCmp)(a,b) should return <0 if a<b, 0 if a==b, >0 if a>b.
+ *
+ * This function is like the C-Library function bsearch() except that
+ * this function returns the index where the item should be placed if
+ * it is not found.
+ */
+int BinSearch ( void *array, int numElements, int elementSize,
+ void *itemPtr, CompareFunction compareFunction)
+{
+ int low, high, mid, cmp;
+ void *arrayItemPtr;
+
+ for (low = 0, high = numElements - 1, mid = 0, cmp = -1; low <= high;) {
+ mid = (low + high) >> 1;
+
+ arrayItemPtr = (void *) (((char *) array) + (mid * elementSize));
+ cmp = compareFunction
+ ? compareFunction (itemPtr, arrayItemPtr)
+ : ListMemBlockCmp (itemPtr, arrayItemPtr, elementSize);
+ if (cmp == 0) {
+ return mid;
+ } else if (cmp < 0) {
+ high = mid - 1;
+ } else {
+ low = mid + 1;
+ }
+ }
+ if (cmp > 0)
+ mid++;
+
+ return -mid - 1;
}
#endif /* CFG_ALL_LIST_FUNCTIONS */
/*******************************************************************************/
- /* BEGIN PATCH to 4.0.1 - jag 8-29-96 */
- /* If numNewItems == 0 then expand the list by the number of items
- indicated by its allocation policy.
- If numNewItems > 0 then expand the list by exactly the number of
- items indicated.
- If numNewItems < 0 then expand the list by the absolute value of
- numNewItems plus the number of items indicated by its allocation
- policy.
- Returns 1 for success, 0 if out of memory
- */
-static int ExpandListSpace (list_t list, int numNewItems)
-{
- if (numNewItems == 0)
- numNewItems = NUMITEMSPERALLOC(list);
- else
- if (numNewItems < 0)
- numNewItems = (-numNewItems) + NUMITEMSPERALLOC(list);
-
- if (SetHandleSize ((Handle)list,
- sizeof(ListStruct) +
- ((*list)->listSize + numNewItems) * (*list)->itemSize))
- {
- (*list)->listSize += numNewItems;
- return 1;
- }
- else
- {
- return 0;
- }
+/*
+ * If numNewItems == 0 then expand the list by the number of items
+ * indicated by its allocation policy.
+ * If numNewItems > 0 then expand the list by exactly the number of
+ * items indicated.
+ * If numNewItems < 0 then expand the list by the absolute value of
+ * numNewItems plus the number of items indicated by its allocation
+ * policy.
+ * Returns 1 for success, 0 if out of memory
+*/
+static int ExpandListSpace (list_t list, int numNewItems)
+{
+ if (numNewItems == 0) {
+ numNewItems = NUMITEMSPERALLOC (list);
+ } else if (numNewItems < 0) {
+ numNewItems = (-numNewItems) + NUMITEMSPERALLOC (list);
+ }
+
+ if (SetHandleSize ((Handle) list,
+ sizeof (ListStruct) +
+ ((*list)->listSize +
+ numNewItems) * (*list)->itemSize)) {
+ (*list)->listSize += numNewItems;
+ return 1;
+ } else {
+ return 0;
+ }
}
/*******************************/
#ifdef CFG_ALL_LIST_FUNCTIONS
- /* This function reallocate the list, minus any currently unused portion of its allotted memory. */
-void ListCompact (list_t list)
+/*
+ * This function reallocate the list, minus any currently unused
+ * portion of its allotted memory.
+ */
+void ListCompact (list_t list)
{
- if (!SetHandleSize ((Handle)list,
- sizeof (ListStruct) + (*list)->numItems * (*list)->itemSize))
- return;
+ if (!SetHandleSize ((Handle) list,
+ sizeof (ListStruct) +
+ (*list)->numItems * (*list)->itemSize)) {
+ return;
+ }
- (*list)->listSize = (*list)->numItems;
+ (*list)->listSize = (*list)->numItems;
}
#endif /* CFG_ALL_LIST_FUNCTIONS */
/*******************************/
-list_t ListCreate (int elementSize)
+list_t ListCreate (int elementSize)
{
- list_t list;
+ list_t list;
- list = (list_t)(NewHandle (sizeof(ListStruct))); /* create empty list */
- if (list)
- {
- (*list)->signature = LIST_SIGNATURE;
- (*list)->numItems = 0;
- (*list)->listSize = 0;
- (*list)->itemSize = elementSize;
- (*list)->percentIncrease = kDefaultAllocationPercentIncrease;
- (*list)->minNumItemsIncrease = kDefaultAllocationminNumItemsIncrease;
- }
+ list = (list_t) (NewHandle (sizeof (ListStruct))); /* create empty list */
+ if (list) {
+ (*list)->signature = LIST_SIGNATURE;
+ (*list)->numItems = 0;
+ (*list)->listSize = 0;
+ (*list)->itemSize = elementSize;
+ (*list)->percentIncrease = kDefaultAllocationPercentIncrease;
+ (*list)->minNumItemsIncrease =
+ kDefaultAllocationminNumItemsIncrease;
+ }
- return list;
+ return list;
}
/*******************************/
-void ListSetAllocationPolicy (list_t list, int minItemsPerAlloc, int percentIncreasePerAlloc)
+void ListSetAllocationPolicy (list_t list, int minItemsPerAlloc,
+ int percentIncreasePerAlloc)
{
-
- (*list)->percentIncrease = percentIncreasePerAlloc;
- (*list)->minNumItemsIncrease = minItemsPerAlloc;
+ (*list)->percentIncrease = percentIncreasePerAlloc;
+ (*list)->minNumItemsIncrease = minItemsPerAlloc;
}
/*******************************/
-void ListDispose (list_t list)
+void ListDispose (list_t list)
{
- DisposeHandle ((Handle)list);
+ DisposeHandle ((Handle) list);
}
-
/*******************************/
#ifdef CFG_ALL_LIST_FUNCTIONS
-void ListDisposePtrList(list_t list)
+void ListDisposePtrList (list_t list)
{
- int index;
- int numItems;
+ int index;
+ int numItems;
- if (list)
- {
- numItems = ListNumItems(list);
+ if (list) {
+ numItems = ListNumItems (list);
- for (index = 1; index <= numItems; index++)
- free(*(void **)ListGetPtrToItem(list, index));
+ for (index = 1; index <= numItems; index++)
+ free (*(void **) ListGetPtrToItem (list, index));
- ListDispose(list);
- }
+ ListDispose (list);
+ }
}
/*******************************/
-void ListClear (list_t list) /* keeps memory, resets the number of items to 0 */
+/*
+ * keeps memory, resets the number of items to 0
+ */
+void ListClear (list_t list)
{
- if (!list)
- return;
- (*list)->numItems = 0;
+ if (!list)
+ return;
+ (*list)->numItems = 0;
}
/*******************************/
-list_t ListCopy (list_t originalList) /* copy is only as large as necessary */
+/*
+ * copy is only as large as necessary
+ */
+list_t ListCopy (list_t originalList)
{
- list_t tempList = NULL;
- int numItems;
+ list_t tempList = NULL;
+ int numItems;
- if (!originalList)
- return NULL;
+ if (!originalList)
+ return NULL;
- tempList = ListCreate ((*originalList)->itemSize);
- if (tempList) {
- numItems = ListNumItems (originalList);
+ tempList = ListCreate ((*originalList)->itemSize);
+ if (tempList) {
+ numItems = ListNumItems (originalList);
- if (!SetHandleSize ((Handle)tempList,
- sizeof (ListStruct) + numItems * (*tempList)->itemSize)) {
- ListDispose (tempList);
- return NULL;
- }
+ if (!SetHandleSize ((Handle) tempList,
+ sizeof (ListStruct) +
+ numItems * (*tempList)->itemSize)) {
+ ListDispose (tempList);
+ return NULL;
+ }
- (*tempList)->numItems = (*originalList)->numItems;
- (*tempList)->listSize = (*originalList)->numItems;
- (*tempList)->itemSize = (*originalList)->itemSize;
- (*tempList)->percentIncrease = (*originalList)->percentIncrease;
- (*tempList)->minNumItemsIncrease = (*originalList)->minNumItemsIncrease;
+ (*tempList)->numItems = (*originalList)->numItems;
+ (*tempList)->listSize = (*originalList)->numItems;
+ (*tempList)->itemSize = (*originalList)->itemSize;
+ (*tempList)->percentIncrease = (*originalList)->percentIncrease;
+ (*tempList)->minNumItemsIncrease =
+ (*originalList)->minNumItemsIncrease;
- memcpy (ITEMPTR(tempList,0), ITEMPTR(originalList,0),
- numItems * (*tempList)->itemSize);
- }
+ memcpy (ITEMPTR (tempList, 0), ITEMPTR (originalList, 0),
+ numItems * (*tempList)->itemSize);
+ }
- return tempList;
+ return tempList;
}
/********************************/
-int ListAppend (list_t list1, list_t list2) /* list1 = list1 + list2 */
+/*
+ * list1 = list1 + list2
+ */
+int ListAppend (list_t list1, list_t list2)
{
- int numItemsL1, numItemsL2;
+ int numItemsL1, numItemsL2;
- if (!list2)
- return 1;
+ if (!list2)
+ return 1;
- if (!list1)
- return 0;
- if ((*list1)->itemSize != (*list2)->itemSize)
- return 0;
+ if (!list1)
+ return 0;
+ if ((*list1)->itemSize != (*list2)->itemSize)
+ return 0;
- numItemsL1 = ListNumItems (list1);
- numItemsL2 = ListNumItems (list2);
+ numItemsL1 = ListNumItems (list1);
+ numItemsL2 = ListNumItems (list2);
- if (numItemsL2 == 0)
- return 1;
+ if (numItemsL2 == 0)
+ return 1;
- if (!SetHandleSize ((Handle)list1,
- sizeof (ListStruct) + (numItemsL1 + numItemsL2) * (*list1)->itemSize))
- return 0;
+ if (!SetHandleSize ((Handle) list1,
+ sizeof (ListStruct) + (numItemsL1 + numItemsL2) *
+ (*list1)->itemSize)) {
+ return 0;
+ }
- (*list1)->numItems = numItemsL1 + numItemsL2;
- (*list1)->listSize = numItemsL1 + numItemsL2;
+ (*list1)->numItems = numItemsL1 + numItemsL2;
+ (*list1)->listSize = numItemsL1 + numItemsL2;
- memmove (ITEMPTR(list1,numItemsL1), ITEMPTR(list2,0),
- numItemsL2 * (*list2)->itemSize);
+ memmove (ITEMPTR (list1, numItemsL1),
+ ITEMPTR (list2, 0),
+ numItemsL2 * (*list2)->itemSize);
- return 1;
+ return 1;
}
#endif /* CFG_ALL_LIST_FUNCTIONS */
/*******************************/
- /* returns 1 if the item is inserted, returns 0 if out of memory or
- bad arguments were passed.
- */
-int ListInsertItem (list_t list, void *ptrToItem, int itemPosition)
+/*
+ * returns 1 if the item is inserted, returns 0 if out of memory or
+ * bad arguments were passed.
+ */
+int ListInsertItem (list_t list, void *ptrToItem, int itemPosition)
{
- return ListInsertItems (list, ptrToItem, itemPosition, 1);
+ return ListInsertItems (list, ptrToItem, itemPosition, 1);
}
/*******************************/
-int ListInsertItems (list_t list, void *ptrToItems, int firstItemPosition, int numItemsToInsert)
-{
- int numItems = (*list)->numItems;
-
- if (firstItemPosition == numItems + 1)
- firstItemPosition = LIST_END;
- else
- if (firstItemPosition > numItems)
- return 0;
-
- if ((*list)->numItems >= (*list)->listSize)
- {
- if (!ExpandListSpace (list, -numItemsToInsert)) /* PATCH to 4.0.1 - jag 8-29-96 */
- return 0;
- }
-
- if (firstItemPosition == LIST_START)
- {
- if (numItems == 0)
- firstItemPosition = LIST_END; /* special case for empty list */
- else
- firstItemPosition = 1;
- }
-
- if (firstItemPosition == LIST_END) /* add at the end of the list */
- {
- if (ptrToItems)
- memcpy (ITEMPTR(list, numItems), ptrToItems, (*list)->itemSize * numItemsToInsert);
- else
- memset (ITEMPTR(list, numItems), 0,
- (*list)->itemSize * numItemsToInsert);
-
- (*list)->numItems += numItemsToInsert;
- }
- else
- { /* move part of list up to make room for new item */
- memmove (ITEMPTR(list,firstItemPosition-1+numItemsToInsert),
- ITEMPTR(list,firstItemPosition-1),
- (numItems + 1 - firstItemPosition) * (*list)->itemSize);
-
- if (ptrToItems)
- memmove (ITEMPTR(list,firstItemPosition-1), ptrToItems,
- (*list)->itemSize * numItemsToInsert);
- else
- memset (ITEMPTR(list,firstItemPosition-1), 0,
- (*list)->itemSize * numItemsToInsert);
-
- (*list)->numItems += numItemsToInsert;
- }
-
- return 1;
+int ListInsertItems (list_t list, void *ptrToItems, int firstItemPosition,
+ int numItemsToInsert)
+{
+ int numItems = (*list)->numItems;
+
+ if (firstItemPosition == numItems + 1)
+ firstItemPosition = LIST_END;
+ else if (firstItemPosition > numItems)
+ return 0;
+
+ if ((*list)->numItems >= (*list)->listSize) {
+ if (!ExpandListSpace (list, -numItemsToInsert))
+ return 0;
+ }
+
+ if (firstItemPosition == LIST_START) {
+ if (numItems == 0) {
+ /* special case for empty list */
+ firstItemPosition = LIST_END;
+ } else {
+ firstItemPosition = 1;
+ }
+ }
+
+ if (firstItemPosition == LIST_END) { /* add at the end of the list */
+ if (ptrToItems)
+ memcpy (ITEMPTR (list, numItems), ptrToItems,
+ (*list)->itemSize * numItemsToInsert);
+ else
+ memset (ITEMPTR (list, numItems), 0,
+ (*list)->itemSize * numItemsToInsert);
+
+ (*list)->numItems += numItemsToInsert;
+ } else { /* move part of list up to make room for new item */
+ memmove (ITEMPTR (list, firstItemPosition - 1 + numItemsToInsert),
+ ITEMPTR (list, firstItemPosition - 1),
+ (numItems + 1 - firstItemPosition) * (*list)->itemSize);
+
+ if (ptrToItems)
+ memmove (ITEMPTR (list, firstItemPosition - 1), ptrToItems,
+ (*list)->itemSize * numItemsToInsert);
+ else
+ memset (ITEMPTR (list, firstItemPosition - 1), 0,
+ (*list)->itemSize * numItemsToInsert);
+
+ (*list)->numItems += numItemsToInsert;
+ }
+
+ return 1;
}
-#ifdef CFG_ALL_LIST_FUNCTIONS
+#ifdef CFG_ALL_LIST_FUNCTIONS
/*******************************/
-int ListEqual (list_t list1, list_t list2)
+int ListEqual (list_t list1, list_t list2)
{
- if (list1 == list2)
- return 1;
+ if (list1 == list2)
+ return 1;
- if (list1 == NULL || list2 == NULL)
- return 0;
+ if (list1 == NULL || list2 == NULL)
+ return 0;
- if ((*list1)->itemSize == (*list1)->itemSize)
- if ((*list1)->numItems == (*list2)->numItems)
- return (memcmp (ITEMPTR(list1,0), ITEMPTR(list2,0),
- (*list1)->itemSize * (*list1)->numItems) == 0);
+ if ((*list1)->itemSize == (*list1)->itemSize) {
+ if ((*list1)->numItems == (*list2)->numItems) {
+ return (memcmp (ITEMPTR (list1, 0), ITEMPTR (list2, 0),
+ (*list1)->itemSize * (*list1)->numItems) == 0);
+ }
+ }
- return 0;
+ return 0;
}
/*******************************/
- /* The item pointed to by ptrToItem is copied over the current item at itemPosition */
-void ListReplaceItem (list_t list, void *ptrToItem, int itemPosition)
+/*
+ * The item pointed to by ptrToItem is copied over the current item
+ * at itemPosition
+ */
+void ListReplaceItem (list_t list, void *ptrToItem, int itemPosition)
{
- ListReplaceItems (list, ptrToItem, itemPosition, 1);
+ ListReplaceItems (list, ptrToItem, itemPosition, 1);
}
/*******************************/
- /* The item pointed to by ptrToItems is copied over the current item at itemPosition */
-void ListReplaceItems (list_t list, void *ptrToItems, int firstItemPosition, int numItemsToReplace)
+/*
+ * The item pointed to by ptrToItems is copied over the current item
+ * at itemPosition
+ */
+void ListReplaceItems ( list_t list, void *ptrToItems,
+ int firstItemPosition, int numItemsToReplace)
{
- if (firstItemPosition == LIST_END)
- firstItemPosition = (*list)->numItems;
- else
- if (firstItemPosition == LIST_START)
- firstItemPosition = 1;
+ if (firstItemPosition == LIST_END)
+ firstItemPosition = (*list)->numItems;
+ else if (firstItemPosition == LIST_START)
+ firstItemPosition = 1;
- memmove (ITEMPTR(list,firstItemPosition-1), ptrToItems,
- (*list)->itemSize * numItemsToReplace);
+ memmove (ITEMPTR (list, firstItemPosition - 1), ptrToItems,
+ (*list)->itemSize * numItemsToReplace);
}
/*******************************/
-void ListRemoveItem (list_t list, void *itemDestination, int itemPosition)
+void ListGetItem (list_t list, void *itemDestination, int itemPosition)
{
- ListRemoveItems (list, itemDestination, itemPosition, 1);
+ ListGetItems (list, itemDestination, itemPosition, 1);
}
+#endif /* CFG_ALL_LIST_FUNCTIONS */
+
/*******************************/
-void ListRemoveItems (list_t list, void *itemsDestination, int firstItemPosition, int numItemsToRemove)
+#if defined(CFG_ALL_LIST_FUNCTIONS) || defined(CFG_DEVICE_DEREGISTER)
+
+void ListRemoveItem (list_t list, void *itemDestination, int itemPosition)
{
- int firstItemAfterChunk, numToMove;
+ ListRemoveItems (list, itemDestination, itemPosition, 1);
+}
- if (firstItemPosition == LIST_START)
- firstItemPosition = 1;
- else
- if (firstItemPosition == LIST_END)
- firstItemPosition = (*list)->numItems;
+/*******************************/
- if (itemsDestination != NULL)
- memcpy (itemsDestination, ITEMPTR(list,firstItemPosition-1),
- (*list)->itemSize * numItemsToRemove);
+void ListRemoveItems (list_t list, void *itemsDestination,
+ int firstItemPosition, int numItemsToRemove)
+{
+ int firstItemAfterChunk, numToMove;
- firstItemAfterChunk = firstItemPosition + numItemsToRemove;
- numToMove = (*list)->numItems - (firstItemAfterChunk - 1);
+ if (firstItemPosition == LIST_START)
+ firstItemPosition = 1;
+ else if (firstItemPosition == LIST_END)
+ firstItemPosition = (*list)->numItems;
- if (numToMove > 0) /* move part of list down to cover hole left by removed item */
- memmove (ITEMPTR(list,firstItemPosition-1),
- ITEMPTR(list,firstItemAfterChunk-1),
- (*list)->itemSize * numToMove);
+ if (itemsDestination != NULL)
+ memcpy (itemsDestination, ITEMPTR (list, firstItemPosition - 1),
+ (*list)->itemSize * numItemsToRemove);
- (*list)->numItems -= numItemsToRemove;
-}
+ firstItemAfterChunk = firstItemPosition + numItemsToRemove;
+ numToMove = (*list)->numItems - (firstItemAfterChunk - 1);
-/*******************************/
+ if (numToMove > 0) {
+ /*
+ * move part of list down to cover hole left by removed item
+ */
+ memmove (ITEMPTR (list, firstItemPosition - 1),
+ ITEMPTR (list, firstItemAfterChunk - 1),
+ (*list)->itemSize * numToMove);
+ }
-void ListGetItem (list_t list, void *itemDestination, int itemPosition)
-{
- ListGetItems (list, itemDestination, itemPosition, 1);
+ (*list)->numItems -= numItemsToRemove;
}
-
-#endif /* CFG_ALL_LIST_FUNCTIONS */
+#endif /* CFG_ALL_LIST_FUNCTIONS || CFG_DEVICE_DEREGISTER */
/*******************************/
-void ListGetItems(list_t list, void *itemsDestination, int firstItemPosition, int numItemsToGet)
+void ListGetItems (list_t list, void *itemsDestination,
+ int firstItemPosition, int numItemsToGet)
{
- if (firstItemPosition == LIST_START)
- firstItemPosition = 1;
- else
- if (firstItemPosition == LIST_END)
- firstItemPosition = (*list)->numItems;
+ if (firstItemPosition == LIST_START)
+ firstItemPosition = 1;
+ else if (firstItemPosition == LIST_END)
+ firstItemPosition = (*list)->numItems;
- memcpy (itemsDestination, ITEMPTR(list,firstItemPosition-1),
- (*list)->itemSize * numItemsToGet);
+ memcpy (itemsDestination,
+ ITEMPTR (list, firstItemPosition - 1),
+ (*list)->itemSize * numItemsToGet);
}
/*******************************/
- /* Returns a pointer to the item at itemPosition. returns null if an errors occurred.
- */
-void * ListGetPtrToItem (list_t list, int itemPosition)
+/*
+ * Returns a pointer to the item at itemPosition. returns null if an
+ * errors occurred.
+ */
+void *ListGetPtrToItem (list_t list, int itemPosition)
{
- if (itemPosition == LIST_START)
- itemPosition = 1;
- else
- if (itemPosition == LIST_END)
- itemPosition = (*list)->numItems;
+ if (itemPosition == LIST_START)
+ itemPosition = 1;
+ else if (itemPosition == LIST_END)
+ itemPosition = (*list)->numItems;
- return ITEMPTR(list,itemPosition-1);
+ return ITEMPTR (list, itemPosition - 1);
}
/*******************************/
- /* returns a pointer the lists data (abstraction violation for optimization) */
-void * ListGetDataPtr (list_t list)
+/*
+ * returns a pointer the lists data (abstraction violation for
+ * optimization)
+ */
+void *ListGetDataPtr (list_t list)
{
- return &((*list)->itemList[0]);
+ return &((*list)->itemList[0]);
}
/********************************/
#ifdef CFG_ALL_LIST_FUNCTIONS
-int ListApplyToEach (list_t list, int ascending, ListApplicationFunc funcToApply, void *callbackData)
-{
- int result = 0, index;
-
- if (!list || !funcToApply)
- goto Error;
-
- if (ascending)
- {
- for (index = 1; index <= ListNumItems (list); index++)
- {
- result = funcToApply (index, ListGetPtrToItem (list, index),
- callbackData);
- if (result < 0)
- goto Error;
- }
- }
- else
- {
- for (index = ListNumItems (list); index > 0 &&
- index <= ListNumItems (list); index--)
- {
- result = funcToApply (index, ListGetPtrToItem (list, index),
- callbackData);
- if (result < 0)
- goto Error;
- }
- }
+int ListApplyToEach (list_t list, int ascending,
+ ListApplicationFunc funcToApply,
+ void *callbackData)
+{
+ int result = 0, index;
+
+ if (!list || !funcToApply)
+ goto Error;
+
+ if (ascending) {
+ for (index = 1; index <= ListNumItems (list); index++) {
+ result = funcToApply (index,
+ ListGetPtrToItem (list, index),
+ callbackData);
+ if (result < 0)
+ goto Error;
+ }
+ } else {
+ for (index = ListNumItems (list);
+ index > 0 && index <= ListNumItems (list);
+ index--) {
+ result = funcToApply (index,
+ ListGetPtrToItem (list, index),
+ callbackData);
+ if (result < 0)
+ goto Error;
+ }
+ }
Error:
- return result;
+ return result;
}
-#endif /* CFG_ALL_LIST_FUNCTIONS */
+#endif /* CFG_ALL_LIST_FUNCTIONS */
/********************************/
-int ListGetItemSize (list_t list)
+int ListGetItemSize (list_t list)
{
- return (*list)->itemSize;
+ return (*list)->itemSize;
}
/********************************/
-int ListNumItems (list_t list)
+int ListNumItems (list_t list)
{
- return (*list)->numItems;
+ return (*list)->numItems;
}
/*******************************/
#ifdef CFG_ALL_LIST_FUNCTIONS
-void ListRemoveDuplicates (list_t list, CompareFunction compareFunction)
+void ListRemoveDuplicates (list_t list, CompareFunction compareFunction)
{
- int numItems, index, startIndexForFind, duplicatesIndex;
+ int numItems, index, startIndexForFind, duplicatesIndex;
- numItems = ListNumItems (list);
+ numItems = ListNumItems (list);
- for (index = 1; index < numItems; index++)
- {
- startIndexForFind = index + 1;
- while (startIndexForFind <= numItems)
- {
- duplicatesIndex = ListFindItem (list, ListGetPtrToItem (list, index),
- startIndexForFind, compareFunction);
- if (duplicatesIndex > 0)
- {
- ListRemoveItem (list, NULL, duplicatesIndex);
- numItems--;
- startIndexForFind = duplicatesIndex;
- }
- else
- break;
- }
- }
+ for (index = 1; index < numItems; index++) {
+ startIndexForFind = index + 1;
+ while (startIndexForFind <= numItems) {
+ duplicatesIndex =
+ ListFindItem (list,
+ ListGetPtrToItem (list, index),
+ startIndexForFind,
+ compareFunction);
+ if (duplicatesIndex > 0) {
+ ListRemoveItem (list, NULL, duplicatesIndex);
+ numItems--;
+ startIndexForFind = duplicatesIndex;
+ } else {
+ break;
+ }
+ }
+ }
}
/*******************************/
/*******************************/
-int ListFindItem (list_t list, void *ptrToItem, int startingPosition, CompareFunction compareFunction)
+int ListFindItem (list_t list, void *ptrToItem, int startingPosition,
+ CompareFunction compareFunction)
{
- int numItems, size, index, cmp;
- void *listItemPtr;
+ int numItems, size, index, cmp;
+ void *listItemPtr;
- if ((numItems = (*list)->numItems) == 0)
- return 0;
+ if ((numItems = (*list)->numItems) == 0)
+ return 0;
- size = (*list)->itemSize;
+ size = (*list)->itemSize;
- if (startingPosition == LIST_START)
- startingPosition = 1;
- else
- if (startingPosition == LIST_END)
- startingPosition = numItems;
+ if (startingPosition == LIST_START)
+ startingPosition = 1;
+ else if (startingPosition == LIST_END)
+ startingPosition = numItems;
- for (index = startingPosition; index <= numItems; index++)
- {
- listItemPtr = ITEMPTR(list,index-1);
- cmp = compareFunction ? compareFunction(ptrToItem, listItemPtr)
- : ListMemBlockCmp(ptrToItem, listItemPtr, size);
- if (cmp == 0)
- return index;
- }
+ for (index = startingPosition; index <= numItems; index++) {
+ listItemPtr = ITEMPTR (list, index - 1);
+ cmp = compareFunction
+ ? compareFunction (ptrToItem, listItemPtr)
+ : ListMemBlockCmp (ptrToItem, listItemPtr, size);
+ if (cmp == 0)
+ return index;
+ }
- return 0;
+ return 0;
}
/*******************************/
-int ShortCompare(void *a, void *b)
+int ShortCompare (void *a, void *b)
{
- if (*(short *)a < *(short *)b) return -1;
- if (*(short *)a > *(short *)b) return 1;
- return 0;
+ if (*(short *) a < *(short *) b)
+ return -1;
+ if (*(short *) a > *(short *) b)
+ return 1;
+ return 0;
}
/*******************************/
-int IntCompare(void *a, void *b)
+int IntCompare (void *a, void *b)
{
- if (*(int *)a < *(int *)b) return -1;
- if (*(int *)a > *(int *)b) return 1;
- return 0;
+ if (*(int *) a < *(int *) b)
+ return -1;
+ if (*(int *) a > *(int *) b)
+ return 1;
+ return 0;
}
/*******************************/
-int CStringCompare(void *a, void *b)
+int CStringCompare (void *a, void *b)
{
- return strcmp(*(char **)a, *(char **)b);
+ return strcmp (*(char **) a, *(char **) b);
}
/*******************************/
-int ListBinSearch (list_t list, void *ptrToItem, CompareFunction compareFunction)
+int ListBinSearch (list_t list, void *ptrToItem,
+ CompareFunction compareFunction)
{
- int index;
+ int index;
- index = BinSearch (ITEMPTR(list,0), (int)(*list)->numItems,
- (int)(*list)->itemSize, ptrToItem, compareFunction);
+ index = BinSearch (ITEMPTR (list, 0),
+ (int) (*list)->numItems,
+ (int) (*list)->itemSize, ptrToItem,
+ compareFunction);
- if (index >= 0)
- index++; /* lists start from 1 */
- else
- index = 0; /* item not found */
+ if (index >= 0)
+ index++; /* lists start from 1 */
+ else
+ index = 0; /* item not found */
- return index;
+ return index;
}
/**************************************************************************/
- /* Reserves memory for numItems in the list. If it succeeds then
- numItems items can be inserted without possibility of an
- out of memory error (useful to simplify error recovery in
- complex functions). Returns 1 if success, 0 if
- out of memory.
- */
-int ListPreAllocate (list_t list, int numItems)
+/*
+ * Reserves memory for numItems in the list. If it succeeds then
+ * numItems items can be inserted without possibility of an out of
+ * memory error (useful to simplify error recovery in complex
+ * functions). Returns 1 if success, 0 if out of memory.
+ */
+int ListPreAllocate (list_t list, int numItems)
{
-
- if ((*list)->listSize - (*list)->numItems < numItems)
- return ExpandListSpace (list,
- numItems - ((*list)->listSize - (*list)->numItems));
- else
- return 1; /* enough items are already pre-allocated */
+ if ((*list)->listSize - (*list)->numItems < numItems) {
+ return ExpandListSpace (list,
+ numItems - ((*list)->listSize -
+ (*list)->numItems));
+ } else {
+ return 1; /* enough items are already pre-allocated */
+ }
}
-#endif /* CFG_ALL_LIST_FUNCTIONS */
+#endif /* CFG_ALL_LIST_FUNCTIONS */
--- /dev/null
+/*
+ * (C) Copyright 2001
+ * Denis Peter, MPL AG Switzerland
+ *
+ * Most of this source has been derived from the Linux USB
+ * project.
+ *
+ * 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
+ *
+ */
+
+
+/*
+ * How it works:
+ *
+ * Since this is a bootloader, the devices will not be automatic
+ * (re)configured on hotplug, but after a restart of the USB the
+ * device should work.
+ *
+ * For each transfer (except "Interrupt") we wait for completion.
+ */
+#include <ppcboot.h>
+#include <command.h>
+#include <asm/processor.h>
+
+#if (CONFIG_COMMANDS & CFG_CMD_USB)
+
+#include <usb.h>
+#ifdef CONFIG_4xx
+#include <405gp_pci.h>
+#endif
+
+
+
+#undef USB_DEBUG
+
+#ifdef USB_DEBUG
+#define USB_PRINTF(fmt,args...) printf (fmt ,##args)
+#else
+#define USB_PRINTF(fmt,args...)
+#endif
+
+static struct usb_device usb_dev[USB_MAX_DEVICE];
+static int dev_index;
+static int running;
+static int asynch_allowed;
+static struct devrequest setup_packet;
+
+/**********************************************************************
+ * some forward declerations...
+ */
+void usb_scan_devices(void);
+
+int usb_hub_probe(struct usb_device *dev, int ifnum);
+void usb_hub_reset(void);
+
+/***********************************************************************
+ * wait_ms
+ */
+
+void __inline__ wait_ms(unsigned long ms)
+{
+ while(ms-->0)
+ udelay(1000);
+}
+/***************************************************************************
+ * Init USB Device
+ */
+
+int usb_init(void)
+{
+ int result;
+
+ running=0;
+ dev_index=0;
+ asynch_allowed=1;
+ usb_hub_reset();
+ /* init low_level USB */
+ printf("USB: ");
+ result = usb_lowlevel_init();
+ /* if lowlevel init is OK, scan the bus for devices i.e. search HUBs and configure them */
+ if(result==0) {
+ printf("scanning bus for devices... ");
+ running=1;
+ usb_scan_devices();
+ return 0;
+ }
+ else {
+ printf("Error, couldn't init Lowlevel part\n");
+ return -1;
+ }
+}
+
+/******************************************************************************
+ * Stop USB this stops the LowLevel Part and deregisters USB devices.
+ */
+int usb_stop(void)
+{
+ asynch_allowed=1;
+ usb_hub_reset();
+ return usb_lowlevel_stop();
+}
+
+/*
+ * disables the asynch behaviour of the control message. This is used for data
+ * transfers that uses the exclusiv access to the control and bulk messages.
+ */
+void usb_disable_asynch(int disable)
+{
+ asynch_allowed=!disable;
+}
+
+
+/*-------------------------------------------------------------------
+ * Message wrappers.
+ *
+ */
+
+/*
+ * submits an Interrupt Message
+ */
+int usb_submit_int_msg(struct usb_device *dev, unsigned long pipe,
+ void *buffer,int transfer_len, int interval)
+{
+ return submit_int_msg(dev,pipe,buffer,transfer_len,interval);
+}
+
+/*
+ * submits a control message and waits for comletion (at least timeout * 1ms)
+ * If timeout is 0, we don't wait for completion (used as example to set and
+ * clear keyboards LEDs). For data transfers, (storage transfers) we don't
+ * allow control messages with 0 timeout, by previousely resetting the flag
+ * asynch_allowed (usb_disable_asynch(1)).
+ * returns the transfered length if OK or -1 if error. The transfered length
+ * and the current status are stored in the dev->act_len and dev->status.
+ */
+int usb_control_msg(struct usb_device *dev, unsigned int pipe,
+ unsigned char request, unsigned char requesttype,
+ unsigned short value, unsigned short index,
+ void *data, unsigned short size, int timeout)
+{
+ if((timeout==0)&&(!asynch_allowed)) /* request for a asynch control pipe is not allowed */
+ return -1;
+ /* set setup command */
+ setup_packet.requesttype = requesttype;
+ setup_packet.request = request;
+ setup_packet.value = swap_16(value);
+ setup_packet.index = swap_16(index);
+ setup_packet.length = swap_16(size);
+ USB_PRINTF("usb_control_msg: request: 0x%X, requesttype: 0x%X\nvalue 0x%X index 0x%X length 0x%X\n",
+ request,requesttype,value,index,size);
+ dev->status=USB_ST_NOT_PROC; /*not yet processed */
+
+ submit_control_msg(dev,pipe,data,size,&setup_packet);
+ if(timeout==0) {
+ return (int)size;
+ }
+ while(timeout--) {
+ if(!((volatile unsigned long)dev->status & USB_ST_NOT_PROC))
+ break;
+ wait_ms(1);
+ }
+ if(dev->status==0)
+ return dev->act_len;
+ else {
+ return -1;
+ }
+}
+
+/*-------------------------------------------------------------------
+ * submits bulk message, and waits for completion. returns 0 if Ok or
+ * -1 if Error.
+ * synchronous behavior
+ */
+int usb_bulk_msg(struct usb_device *dev, unsigned int pipe,
+ void *data, int len, int *actual_length, int timeout)
+{
+ if (len < 0)
+ return -1;
+ dev->status=USB_ST_NOT_PROC; /*not yet processed */
+ submit_bulk_msg(dev,pipe,data,len);
+ while(timeout--) {
+ if(!((volatile unsigned long)dev->status & USB_ST_NOT_PROC))
+ break;
+ wait_ms(1);
+ }
+ *actual_length=dev->act_len;
+ if(dev->status==0)
+ return 0;
+ else
+ return -1;
+}
+
+
+/*-------------------------------------------------------------------
+ * Max Packet stuff
+ */
+
+/*
+ * returns the max packet size, depending on the pipe direction and
+ * the configurations values
+ */
+int usb_maxpacket(struct usb_device *dev,unsigned long pipe)
+{
+ if((pipe & USB_DIR_IN)==0) /* direction is out -> use emaxpacket out */
+ return(dev->epmaxpacketout[((pipe>>15) & 0xf)]);
+ else
+ return(dev->epmaxpacketin[((pipe>>15) & 0xf)]);
+}
+
+/*
+ * set the max packed value of all endpoints in the given configuration
+ */
+int usb_set_maxpacket(struct usb_device *dev)
+{
+ int i,ii,b;
+ struct usb_endpoint_descriptor *ep;
+
+ for(i=0; i<dev->config.bNumInterfaces;i++) {
+ for(ii=0; ii<dev->config.if_desc[i].bNumEndpoints; ii++) {
+ ep=&dev->config.if_desc[i].ep_desc[ii];
+ b=ep->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
+
+ if((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)==USB_ENDPOINT_XFER_CONTROL) { /* Control => bidirectional */
+ dev->epmaxpacketout[b] = ep->wMaxPacketSize;
+ dev->epmaxpacketin [b] = ep->wMaxPacketSize;
+ USB_PRINTF("##Control EP epmaxpacketout/in[%d] = %d\n",b,dev->epmaxpacketin[b]);
+ }
+ else {
+ if ((ep->bEndpointAddress & 0x80)==0) { /* OUT Endpoint */
+ if(ep->wMaxPacketSize > dev->epmaxpacketout[b]) {
+ dev->epmaxpacketout[b] = ep->wMaxPacketSize;
+ USB_PRINTF("##EP epmaxpacketout[%d] = %d\n",b,dev->epmaxpacketout[b]);
+ }
+ }
+ else { /* IN Endpoint */
+ if(ep->wMaxPacketSize > dev->epmaxpacketin[b]) {
+ dev->epmaxpacketin[b] = ep->wMaxPacketSize;
+ USB_PRINTF("##EP epmaxpacketin[%d] = %d\n",b,dev->epmaxpacketin[b]);
+ }
+ } /* if out */
+ } /* if control */
+ } /* for each endpoint */
+ }
+ return 0;
+}
+
+/*******************************************************************************
+ * Parse the config, located in buffer, and fills the dev->config structure.
+ * Note that all little/big endian swapping are done automatically.
+ */
+int usb_parse_config(struct usb_device *dev, unsigned char *buffer, int cfgno)
+{
+ struct usb_descriptor_header *head;
+ int index,ifno,epno;
+ ifno=-1;
+ epno=-1;
+
+ dev->configno=cfgno;
+ head =(struct usb_descriptor_header *)&buffer[0];
+ if(head->bDescriptorType!=USB_DT_CONFIG) {
+ printf(" ERROR: NOT USB_CONFIG_DESC %x\n",head->bDescriptorType);
+ return -1;
+ }
+ memcpy(&dev->config,buffer,buffer[0]);
+ dev->config.wTotalLength=swap_16(dev->config.wTotalLength);
+ dev->config.no_of_if=0;
+
+ index=dev->config.bLength;
+ /* Ok the first entry must be a configuration entry, now process the others */
+ head=(struct usb_descriptor_header *)&buffer[index];
+ while(index+1 < dev->config.wTotalLength) {
+ switch(head->bDescriptorType) {
+ case USB_DT_INTERFACE:
+ ifno=dev->config.no_of_if;
+ dev->config.no_of_if++; /* found an interface desc, increase numbers */
+ memcpy(&dev->config.if_desc[ifno],&buffer[index],buffer[index]); /* copy new desc */
+ dev->config.if_desc[ifno].no_of_ep=0;
+
+ break;
+ case USB_DT_ENDPOINT:
+ epno=dev->config.if_desc[ifno].no_of_ep;
+ dev->config.if_desc[ifno].no_of_ep++; /* found an endpoint */
+ memcpy(&dev->config.if_desc[ifno].ep_desc[epno],&buffer[index],buffer[index]);
+ dev->config.if_desc[ifno].ep_desc[epno].wMaxPacketSize
+ =swap_16(dev->config.if_desc[ifno].ep_desc[epno].wMaxPacketSize);
+ USB_PRINTF("if %d, ep %d\n",ifno,epno);
+ break;
+ default:
+ if(head->bLength==0)
+ return 1;
+ USB_PRINTF("unknown Description Type : %x\n",head->bDescriptorType);
+ {
+ int i;
+ unsigned char *ch;
+ ch=(unsigned char *)head;
+ for(i=0;i<head->bLength; i++)
+ USB_PRINTF("%02X ",*ch++);
+ USB_PRINTF("\n\n\n");
+ }
+ break;
+ }
+ index+=head->bLength;
+ head=(struct usb_descriptor_header *)&buffer[index];
+ }
+ return 1;
+}
+
+/***********************************************************************
+ * Clears an endpoint
+ * endp: endpoint number in bits 0-3;
+ * direction flag in bit 7 (1 = IN, 0 = OUT)
+ */
+int usb_clear_halt(struct usb_device *dev, int pipe)
+{
+ int result;
+ unsigned short status;
+ int endp=usb_pipeendpoint(pipe)|(usb_pipein(pipe)<<7);
+
+ result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
+ USB_REQ_CLEAR_FEATURE, USB_RECIP_ENDPOINT, 0, endp, NULL, 0, USB_CNTL_TIMEOUT * 3);
+
+ /* don't clear if failed */
+ if (result < 0)
+ return result;
+ result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
+ USB_REQ_GET_STATUS, USB_DIR_IN | USB_RECIP_ENDPOINT, 0, endp,
+ &status, sizeof(status), USB_CNTL_TIMEOUT * 3);
+ if (result < 0)
+ return result;
+ USB_PRINTF("usb_clear_halt: status 0x%x\n",status);
+ if (status & 1)
+ return -1; /* still halted */
+ usb_endpoint_running(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe));
+ /* toggle is reset on clear */
+ usb_settoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe), 0);
+ return 0;
+}
+
+
+/**********************************************************************
+ * get_descriptor type
+ */
+int usb_get_descriptor(struct usb_device *dev, unsigned char type, unsigned char index, void *buf, int size)
+{
+ int res;
+ res = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
+ USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
+ (type << 8) + index, 0,
+ buf, size, USB_CNTL_TIMEOUT);
+ return res;
+}
+
+/**********************************************************************
+ * gets configuration cfgno and store it in the buffer
+ */
+int usb_get_configuration_no(struct usb_device *dev,unsigned char *buffer,int cfgno)
+{
+ int result;
+ unsigned int tmp;
+ struct usb_config_descriptor *config;
+
+
+ config=(struct usb_config_descriptor *)&buffer[0];
+ result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, buffer, 8);
+ if (result < 8) {
+ if (result < 0)
+ printf("unable to get descriptor, error %lX\n",dev->status);
+ else
+ printf("config descriptor too short (expected %i, got %i)\n",8,result);
+ return -1;
+ }
+ tmp=swap_16(config->wTotalLength);
+
+ result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, buffer, tmp);
+ USB_PRINTF("get_conf_no %d Result %d, wLength %d\n",cfgno,result,tmp);
+ return result;
+}
+
+/********************************************************************
+ * set address of a device to the value in dev->devnum.
+ * This can only be done by addressing the device via the default address (0)
+ */
+int usb_set_address(struct usb_device *dev)
+{
+ int res;
+
+ USB_PRINTF("set address %d\n",dev->devnum);
+ res=usb_control_msg(dev, usb_snddefctrl(dev),
+ USB_REQ_SET_ADDRESS, 0,
+ (dev->devnum),0,
+ NULL,0, USB_CNTL_TIMEOUT);
+ return res;
+}
+
+/********************************************************************
+ * set interface number to interface
+ */
+int usb_set_interface(struct usb_device *dev, int interface, int alternate)
+{
+ struct usb_interface_descriptor *if_face = NULL;
+ int ret, i;
+
+ for (i=0; i<dev->config.bNumInterfaces; i++) {
+ if (dev->config.if_desc[i].bInterfaceNumber == interface) {
+ if_face = &dev->config.if_desc[i];
+ break;
+ }
+ }
+ if (!if_face) {
+ printf("selecting invalid interface %d", interface);
+ return -1;
+ }
+
+ if ((ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
+ USB_REQ_SET_INTERFACE, USB_RECIP_INTERFACE, alternate,
+ interface, NULL, 0, USB_CNTL_TIMEOUT * 5)) < 0)
+ return ret;
+
+ if_face->act_altsetting = (unsigned char)alternate;
+ usb_set_maxpacket(dev);
+ return 0;
+}
+
+/********************************************************************
+ * set configuration number to configuration
+ */
+int usb_set_configuration(struct usb_device *dev, int configuration)
+{
+ int res;
+ USB_PRINTF("set configuration %d\n",configuration);
+ /* set setup command */
+ res=usb_control_msg(dev, usb_sndctrlpipe(dev,0),
+ USB_REQ_SET_CONFIGURATION, 0,
+ configuration,0,
+ NULL,0, USB_CNTL_TIMEOUT);
+ if(res==0) {
+ dev->toggle[0] = 0;
+ dev->toggle[1] = 0;
+ return 0;
+ }
+ else
+ return -1;
+}
+
+/********************************************************************
+ * set protocol to protocol
+ */
+int usb_set_protocol(struct usb_device *dev, int ifnum, int protocol)
+{
+ return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
+ USB_REQ_SET_PROTOCOL, USB_TYPE_CLASS | USB_RECIP_INTERFACE,
+ protocol, ifnum, NULL, 0, USB_CNTL_TIMEOUT);
+}
+
+/********************************************************************
+ * set idle
+ */
+int usb_set_idle(struct usb_device *dev, int ifnum, int duration, int report_id)
+{
+ return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
+ USB_REQ_SET_IDLE, USB_TYPE_CLASS | USB_RECIP_INTERFACE,
+ (duration << 8) | report_id, ifnum, NULL, 0, USB_CNTL_TIMEOUT);
+}
+
+/********************************************************************
+ * get report
+ */
+int usb_get_report(struct usb_device *dev, int ifnum, unsigned char type, unsigned char id, void *buf, int size)
+{
+ return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
+ USB_REQ_GET_REPORT, USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
+ (type << 8) + id, ifnum, buf, size, USB_CNTL_TIMEOUT);
+}
+
+/********************************************************************
+ * get class descriptor
+ */
+int usb_get_class_descriptor(struct usb_device *dev, int ifnum,
+ unsigned char type, unsigned char id, void *buf, int size)
+{
+ return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
+ USB_REQ_GET_DESCRIPTOR, USB_RECIP_INTERFACE | USB_DIR_IN,
+ (type << 8) + id, ifnum, buf, size, USB_CNTL_TIMEOUT);
+}
+
+/********************************************************************
+ * get string index in buffer
+ */
+int usb_get_string(struct usb_device *dev, unsigned short langid, unsigned char index, void *buf, int size)
+{
+ return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
+ USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
+ (USB_DT_STRING << 8) + index, langid, buf, size, USB_CNTL_TIMEOUT);
+}
+
+/********************************************************************
+ * usb_string:
+ * Get string index and translate it to ascii.
+ * returns string length (> 0) or error (< 0)
+ */
+int usb_string(struct usb_device *dev, int index, char *buf, size_t size)
+{
+
+ unsigned char mybuf[256];
+ unsigned char *tbuf;
+ int err;
+ unsigned int u, idx;
+
+ if (size <= 0 || !buf || !index)
+ return -1;
+ buf[0] = 0;
+ tbuf=&mybuf[0];
+
+ /* get langid for strings if it's not yet known */
+ if (!dev->have_langid) {
+ err = usb_get_string(dev, 0, 0, tbuf, 4);
+ if (err < 0) {
+ USB_PRINTF("error getting string descriptor 0 (error=%x)\n",dev->status);
+ return -1;
+ } else if (tbuf[0] < 4) {
+ USB_PRINTF("string descriptor 0 too short\n");
+ return -1;
+ } else {
+ dev->have_langid = -1;
+ dev->string_langid = tbuf[2] | (tbuf[3]<< 8);
+ /* always use the first langid listed */
+ USB_PRINTF("USB device number %d default language ID 0x%x\n",
+ dev->devnum, dev->string_langid);
+ }
+ }
+ /* Just ask for a maximum length string and then take the length
+ * that was returned. */
+ err = usb_get_string(dev, dev->string_langid, index, tbuf, 4);
+ if (err < 0)
+ return err;
+ u=tbuf[0];
+ USB_PRINTF("Strn Len %d, index %d\n",u,index);
+ err = usb_get_string(dev, dev->string_langid, index, tbuf, u);
+ if (err < 0)
+ return err;
+ size--; /* leave room for trailing NULL char in output buffer */
+ for (idx = 0, u = 2; u < err; u += 2) {
+ if (idx >= size)
+ break;
+ if (tbuf[u+1]) /* high byte */
+ buf[idx++] = '?'; /* non-ASCII character */
+ else
+ buf[idx++] = tbuf[u];
+ }
+ buf[idx] = 0;
+ err = idx;
+ return err;
+}
+
+
+/********************************************************************
+ * USB device handling:
+ * the USB device are static allocated [USB_MAX_DEVICE].
+ */
+
+
+/* returns a pointer to the device with the index [index].
+ * if the device is not assigned (dev->devnum==-1) returns NULL
+ */
+struct usb_device * usb_get_dev_index(int index)
+{
+ if(usb_dev[index].devnum==-1)
+ return NULL;
+ else
+ return &usb_dev[index];
+}
+
+
+/* returns a pointer of a new device structure or NULL, if
+ * no device struct is available
+ */
+struct usb_device * usb_alloc_new_device(void)
+{
+ int i;
+ USB_PRINTF("New Device %d\n",dev_index);
+ if(dev_index==USB_MAX_DEVICE) {
+ printf("ERROR, to many USB Devices max=%d\n",USB_MAX_DEVICE);
+ return NULL;
+ }
+ usb_dev[dev_index].devnum=dev_index+1; /* default Address is 0, real addresses start with 1 */
+ usb_dev[dev_index].maxchild=0;
+ for(i=0;i<USB_MAXCHILDREN;i++)
+ usb_dev[dev_index].children[i]=NULL;
+ usb_dev[dev_index].parent=NULL;
+ dev_index++;
+ return &usb_dev[dev_index-1];
+}
+
+
+/*
+ * By the time we get here, the device has gotten a new device ID
+ * and is in the default state. We need to identify the thing and
+ * get the ball rolling..
+ *
+ * Returns 0 for success, != 0 for error.
+ */
+int usb_new_device(struct usb_device *dev)
+{
+ int addr, err;
+ int tmp;
+ unsigned char tmpbuf[256];
+
+ dev->descriptor.bMaxPacketSize0 = 8; /* Start off at 8 bytes */
+ dev->maxpacketsize = 0; /* Default to 8 byte max packet size */
+ dev->epmaxpacketin [0] = 8;
+ dev->epmaxpacketout[0] = 8;
+
+ /* We still haven't set the Address yet */
+ addr = dev->devnum;
+ dev->devnum = 0;
+ err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, &dev->descriptor, 8);
+ if (err < 8) {
+ printf("\n USB device not responding, giving up (status=%lX)\n",dev->status);
+ return 1;
+ }
+ dev->epmaxpacketin [0] = dev->descriptor.bMaxPacketSize0;
+ dev->epmaxpacketout[0] = dev->descriptor.bMaxPacketSize0;
+ switch (dev->descriptor.bMaxPacketSize0) {
+ case 8: dev->maxpacketsize = 0; break;
+ case 16: dev->maxpacketsize = 1; break;
+ case 32: dev->maxpacketsize = 2; break;
+ case 64: dev->maxpacketsize = 3; break;
+ }
+ dev->devnum = addr;
+
+ err = usb_set_address(dev); /* set address */
+
+ if (err < 0) {
+ printf("\n USB device not accepting new address (error=%lX)\n", dev->status);
+ return 1;
+ }
+
+ wait_ms(10); /* Let the SET_ADDRESS settle */
+
+ tmp = sizeof(dev->descriptor);
+
+ err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, &dev->descriptor, sizeof(dev->descriptor));
+ if (err < tmp) {
+ if (err < 0)
+ printf("unable to get device descriptor (error=%d)\n",err);
+ else
+ printf("USB device descriptor short read (expected %i, got %i)\n",tmp,err);
+ return 1;
+ }
+ /* correct le values */
+ dev->descriptor.bcdUSB=swap_16(dev->descriptor.bcdUSB);
+ dev->descriptor.idVendor=swap_16(dev->descriptor.idVendor);
+ dev->descriptor.idProduct=swap_16(dev->descriptor.idProduct);
+ dev->descriptor.bcdDevice=swap_16(dev->descriptor.bcdDevice);
+ /* only support for one config for now */
+ usb_get_configuration_no(dev,&tmpbuf[0],0);
+ usb_parse_config(dev,&tmpbuf[0],0);
+ usb_set_maxpacket(dev);
+ /* we set the default configuration here */
+ if (usb_set_configuration(dev, dev->config.bConfigurationValue)) {
+ printf("failed to set default configuration len %d, status %lX\n",dev->act_len,dev->status);
+ return -1;
+ }
+ USB_PRINTF("new device strings: Mfr=%d, Product=%d, SerialNumber=%d\n",
+ dev->descriptor.iManufacturer, dev->descriptor.iProduct, dev->descriptor.iSerialNumber);
+ memset(dev->mf, 0, sizeof(dev->mf));
+ memset(dev->prod, 0, sizeof(dev->prod));
+ memset(dev->serial, 0, sizeof(dev->serial));
+ if (dev->descriptor.iManufacturer)
+ usb_string(dev, dev->descriptor.iManufacturer, dev->mf, sizeof(dev->mf));
+ if (dev->descriptor.iProduct)
+ usb_string(dev, dev->descriptor.iProduct, dev->prod, sizeof(dev->prod));
+ if (dev->descriptor.iSerialNumber)
+ usb_string(dev, dev->descriptor.iSerialNumber, dev->serial, sizeof(dev->serial));
+ USB_PRINTF("Manufacturer %s\n", dev->mf);
+ USB_PRINTF("Product %s\n", dev->prod);
+ USB_PRINTF("SerialNumber %s\n", dev->serial);
+ /* now prode if the device is a hub */
+ usb_hub_probe(dev,0);
+ return 0;
+}
+
+/* build device Tree */
+void usb_scan_devices(void)
+{
+ int i;
+ struct usb_device *dev;
+
+ /* first make all devices unknown */
+ for(i=0;i<USB_MAX_DEVICE;i++) {
+ memset(&usb_dev[i],0,sizeof(struct usb_device));
+ usb_dev[i].devnum=-1;
+ }
+ dev_index=0;
+ /* device 0 is always present (root hub, so let it analyze) */
+ dev=usb_alloc_new_device();
+ usb_new_device(dev);
+ printf("%d USB Devices found\n",dev_index);
+ /* insert "driver" if possible */
+#ifdef CONFIG_USB_KEYBOARD
+ drv_usb_kbd_init();
+ USB_PRINTF("scan end\n");
+#endif
+}
+
+
+/****************************************************************************
+ * HUB "Driver"
+ * Probes device for being a hub and configurate it
+ */
+
+#undef USB_HUB_DEBUG
+
+#ifdef USB_HUB_DEBUG
+#define USB_HUB_PRINTF(fmt,args...) printf (fmt ,##args)
+#else
+#define USB_HUB_PRINTF(fmt,args...)
+#endif
+
+
+static struct usb_hub_device hub_dev[USB_MAX_HUB];
+static int usb_hub_index;
+
+
+int usb_get_hub_descriptor(struct usb_device *dev, void *data, int size)
+{
+ return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
+ USB_REQ_GET_DESCRIPTOR, USB_DIR_IN | USB_RT_HUB,
+ USB_DT_HUB << 8, 0, data, size, USB_CNTL_TIMEOUT);
+}
+
+int usb_clear_hub_feature(struct usb_device *dev, int feature)
+{
+ return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
+ USB_REQ_CLEAR_FEATURE, USB_RT_HUB, feature, 0, NULL, 0, USB_CNTL_TIMEOUT);
+}
+
+int usb_clear_port_feature(struct usb_device *dev, int port, int feature)
+{
+ return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
+ USB_REQ_CLEAR_FEATURE, USB_RT_PORT, feature, port, NULL, 0, USB_CNTL_TIMEOUT);
+}
+
+int usb_set_port_feature(struct usb_device *dev, int port, int feature)
+{
+ return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
+ USB_REQ_SET_FEATURE, USB_RT_PORT, feature, port, NULL, 0, USB_CNTL_TIMEOUT);
+}
+
+int usb_get_hub_status(struct usb_device *dev, void *data)
+{
+ return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
+ USB_REQ_GET_STATUS, USB_DIR_IN | USB_RT_HUB, 0, 0,
+ data, sizeof(struct usb_hub_status), USB_CNTL_TIMEOUT);
+}
+
+int usb_get_port_status(struct usb_device *dev, int port, void *data)
+{
+ return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
+ USB_REQ_GET_STATUS, USB_DIR_IN | USB_RT_PORT, 0, port,
+ data, sizeof(struct usb_hub_status), USB_CNTL_TIMEOUT);
+}
+
+
+static void usb_hub_power_on(struct usb_hub_device *hub)
+{
+ int i;
+ struct usb_device *dev;
+
+ dev=hub->pusb_dev;
+ /* Enable power to the ports */
+ USB_HUB_PRINTF("enabling power on all ports\n");
+ for (i = 0; i < dev->maxchild; i++) {
+ usb_set_port_feature(dev, i + 1, USB_PORT_FEAT_POWER);
+ USB_HUB_PRINTF("port %d returns %lX\n",i+1,dev->status);
+ wait_ms(hub->desc.bPwrOn2PwrGood * 2);
+ }
+}
+
+void usb_hub_reset(void)
+{
+ usb_hub_index=0;
+}
+
+struct usb_hub_device *usb_hub_allocate(void)
+{
+ if(usb_hub_index<USB_MAX_HUB) {
+ return &hub_dev[usb_hub_index++];
+ }
+ printf("ERROR: USB_MAX_HUB (%d) reached\n",USB_MAX_HUB);
+ return NULL;
+}
+
+#define MAX_TRIES 5
+
+void usb_hub_port_connect_change(struct usb_device *dev, int port)
+{
+ struct usb_device *usb;
+ struct usb_port_status portsts;
+ unsigned short portstatus, portchange;
+ int tries;
+
+ /* Check status */
+ if (usb_get_port_status(dev, port + 1, &portsts)<0) {
+ USB_HUB_PRINTF("get_port_status failed\n");
+ return;
+ }
+
+ portstatus = swap_16(portsts.wPortStatus);
+ portchange = swap_16(portsts.wPortChange);
+ USB_HUB_PRINTF("portstatus %x, change %x, %s\n", portstatus, portchange,
+ portstatus&(1<<USB_PORT_FEAT_LOWSPEED) ? "Low Speed" : "High Speed");
+
+ /* Clear the connection change status */
+ usb_clear_port_feature(dev, port + 1, USB_PORT_FEAT_C_CONNECTION);
+
+ /* Disconnect any existing devices under this port */
+ if (((!(portstatus & USB_PORT_STAT_CONNECTION)) &&
+ (!(portstatus & USB_PORT_STAT_ENABLE)))|| (dev->children[port])) {
+ USB_HUB_PRINTF("usb_disconnect(&hub->children[port]);\n");
+ /* Return now if nothing is connected */
+ if (!(portstatus & USB_PORT_STAT_CONNECTION))
+ return;
+ }
+ wait_ms(200);
+
+ /* Reset the port */
+
+ for(tries=0;tries<MAX_TRIES;tries++) {
+
+ usb_set_port_feature(dev, port + 1, USB_PORT_FEAT_RESET);
+ wait_ms(200);
+
+ if (usb_get_port_status(dev, port + 1, &portsts)<0) {
+ USB_HUB_PRINTF("get_port_status failed status %lX\n",dev->status);
+ return;
+ }
+ portstatus = swap_16(portsts.wPortStatus);
+ portchange = swap_16(portsts.wPortChange);
+ USB_HUB_PRINTF("portstatus %x, change %x, %s\n", portstatus ,portchange,
+ portstatus&(1<<USB_PORT_FEAT_LOWSPEED) ? "Low Speed" : "High Speed");
+ USB_HUB_PRINTF("STAT_C_CONNECTION = %d STAT_CONNECTION = %d USB_PORT_STAT_ENABLE %d\n",
+ (portchange & USB_PORT_STAT_C_CONNECTION) ? 1 : 0,
+ (portstatus & USB_PORT_STAT_CONNECTION) ? 1 : 0,
+ (portstatus & USB_PORT_STAT_ENABLE) ? 1 : 0);
+ if ((portchange & USB_PORT_STAT_C_CONNECTION) ||
+ !(portstatus & USB_PORT_STAT_CONNECTION))
+ return;
+
+ if (portstatus & USB_PORT_STAT_ENABLE)
+ break;
+
+ wait_ms(200);
+ }
+
+ if (tries==MAX_TRIES) {
+ USB_HUB_PRINTF("Cannot enable port %i after %i retries, disabling port.\n", port+1, MAX_TRIES);
+ USB_HUB_PRINTF("Maybe the USB cable is bad?\n");
+ return;
+ }
+
+ usb_clear_port_feature(dev, port + 1, USB_PORT_FEAT_C_RESET);
+ wait_ms(200);
+
+ /* Allocate a new device struct for it */
+ usb=usb_alloc_new_device();
+ usb->slow = (portstatus & USB_PORT_STAT_LOW_SPEED) ? 1 : 0;
+
+ dev->children[port] = usb;
+ usb->parent=dev;
+ /* Run it through the hoops (find a driver, etc) */
+ if (usb_new_device(usb)) {
+ /* Woops, disable the port */
+ USB_HUB_PRINTF("hub: disabling port %d\n", port + 1);
+ usb_clear_port_feature(dev, port + 1, USB_PORT_FEAT_ENABLE);
+ }
+}
+
+
+int usb_hub_configure(struct usb_device *dev)
+{
+ unsigned char buffer[256], *bitmap;
+ struct usb_hub_descriptor *descriptor;
+ struct usb_hub_status *hubsts;
+ int i;
+ struct usb_hub_device *hub;
+
+ /* "allocate" Hub device */
+ hub=usb_hub_allocate();
+ if(hub==NULL)
+ return -1;
+ hub->pusb_dev=dev;
+ /* Get the the hub descriptor */
+ if (usb_get_hub_descriptor(dev, buffer, 4) < 0) {
+ USB_HUB_PRINTF("usb_hub_configure: failed to get hub descriptor, giving up %lX\n",dev->status);
+ return -1;
+ }
+ descriptor = (struct usb_hub_descriptor *)buffer;
+ if (usb_get_hub_descriptor(dev, buffer, descriptor->bLength) < 0) {
+ USB_HUB_PRINTF("usb_hub_configure: failed to get hub descriptor 2nd giving up %lX\n",dev->status);
+ return -1;
+ }
+ memcpy((unsigned char *)&hub->desc,buffer,descriptor->bLength);
+ /* adjust 16bit values */
+ hub->desc.wHubCharacteristics=swap_16(descriptor->wHubCharacteristics);
+ /* set the bitmap */
+ bitmap=(unsigned char *)&hub->desc.DeviceRemovable[0];
+ memset(bitmap,0xff,(USB_MAXCHILDREN+1+7)/8); /* devices not removable by default */
+ bitmap=(unsigned char *)&hub->desc.PortPowerCtrlMask[0];
+ memset(bitmap,0xff,(USB_MAXCHILDREN+1+7)/8); /* PowerMask = 1B */
+ for(i=0;i<((hub->desc.bNbrPorts + 1 + 7)/8);i++) {
+ hub->desc.DeviceRemovable[i]=descriptor->DeviceRemovable[i];
+ }
+ for(i=0;i<((hub->desc.bNbrPorts + 1 + 7)/8);i++) {
+ hub->desc.DeviceRemovable[i]=descriptor->PortPowerCtrlMask[i];
+ }
+ dev->maxchild = descriptor->bNbrPorts;
+ USB_HUB_PRINTF("%d ports detected\n", dev->maxchild);
+
+ switch (hub->desc.wHubCharacteristics & HUB_CHAR_LPSM) {
+ case 0x00:
+ USB_HUB_PRINTF("ganged power switching\n");
+ break;
+ case 0x01:
+ USB_HUB_PRINTF("individual port power switching\n");
+ break;
+ case 0x02:
+ case 0x03:
+ USB_HUB_PRINTF("unknown reserved power switching mode\n");
+ break;
+ }
+
+ if (hub->desc.wHubCharacteristics & HUB_CHAR_COMPOUND)
+ USB_HUB_PRINTF("part of a compound device\n");
+ else
+ USB_HUB_PRINTF("standalone hub\n");
+
+ switch (hub->desc.wHubCharacteristics & HUB_CHAR_OCPM) {
+ case 0x00:
+ USB_HUB_PRINTF("global over-current protection\n");
+ break;
+ case 0x08:
+ USB_HUB_PRINTF("individual port over-current protection\n");
+ break;
+ case 0x10:
+ case 0x18:
+ USB_HUB_PRINTF("no over-current protection\n");
+ break;
+ }
+ USB_HUB_PRINTF("power on to power good time: %dms\n", descriptor->bPwrOn2PwrGood * 2);
+ USB_HUB_PRINTF("hub controller current requirement: %dmA\n", descriptor->bHubContrCurrent);
+ for (i = 0; i < dev->maxchild; i++)
+ USB_HUB_PRINTF("port %d is%s removable\n", i + 1,
+ hub->desc.DeviceRemovable[(i + 1)/8] & (1 << ((i + 1)%8)) ? " not" : "");
+ if (usb_get_hub_status(dev, buffer) < 0) {
+ USB_HUB_PRINTF("usb_hub_configure: failed to get Status %lX\n",dev->status);
+ return -1;
+ }
+ hubsts = (struct usb_hub_status *)buffer;
+ USB_HUB_PRINTF("get_hub_status returned status %X, change %X\n",
+ swap_16(hubsts->wHubStatus),swap_16(hubsts->wHubChange));
+ USB_HUB_PRINTF("local power source is %s\n",
+ (swap_16(hubsts->wHubStatus) & HUB_STATUS_LOCAL_POWER) ? "lost (inactive)" : "good");
+ USB_HUB_PRINTF("%sover-current condition exists\n",
+ (swap_16(hubsts->wHubStatus) & HUB_STATUS_OVERCURRENT) ? "" : "no ");
+ usb_hub_power_on(hub);
+ for (i = 0; i < dev->maxchild; i++) {
+ struct usb_port_status portsts;
+ unsigned short portstatus, portchange;
+
+ if (usb_get_port_status(dev, i + 1, &portsts) < 0) {
+ USB_HUB_PRINTF("get_port_status failed\n");
+ continue;
+ }
+ portstatus = swap_16(portsts.wPortStatus);
+ portchange = swap_16(portsts.wPortChange);
+ USB_HUB_PRINTF("Port %d Status %X Change %X\n",i+1,portstatus,portchange);
+ if (portchange & USB_PORT_STAT_C_CONNECTION) {
+ USB_HUB_PRINTF("port %d connection change\n", i + 1);
+ usb_hub_port_connect_change(dev, i);
+ }
+ if (portchange & USB_PORT_STAT_C_ENABLE) {
+ USB_HUB_PRINTF("port %d enable change, status %x\n", i + 1, portstatus);
+ usb_clear_port_feature(dev, i + 1, USB_PORT_FEAT_C_ENABLE);
+
+ /* EM interference sometimes causes bad shielded USB devices to
+ * be shutdown by the hub, this hack enables them again.
+ * Works at least with mouse driver */
+ if (!(portstatus & USB_PORT_STAT_ENABLE) &&
+ (portstatus & USB_PORT_STAT_CONNECTION) && (dev->children[i])) {
+ USB_HUB_PRINTF("already running port %i disabled by hub (EMI?), re-enabling...\n",
+ i + 1);
+ usb_hub_port_connect_change(dev, i);
+ }
+ }
+ if (portstatus & USB_PORT_STAT_SUSPEND) {
+ USB_HUB_PRINTF("port %d suspend change\n", i + 1);
+ usb_clear_port_feature(dev, i + 1, USB_PORT_FEAT_SUSPEND);
+ }
+
+ if (portchange & USB_PORT_STAT_C_OVERCURRENT) {
+ USB_HUB_PRINTF("port %d over-current change\n", i + 1);
+ usb_clear_port_feature(dev, i + 1, USB_PORT_FEAT_C_OVER_CURRENT);
+ usb_hub_power_on(hub);
+ }
+
+ if (portchange & USB_PORT_STAT_C_RESET) {
+ USB_HUB_PRINTF("port %d reset change\n", i + 1);
+ usb_clear_port_feature(dev, i + 1, USB_PORT_FEAT_C_RESET);
+ }
+ } /* end for i all ports */
+
+ return 0;
+}
+
+int usb_hub_probe(struct usb_device *dev, int ifnum)
+{
+ struct usb_interface_descriptor *iface;
+ struct usb_endpoint_descriptor *ep;
+ int ret;
+
+ iface = &dev->config.if_desc[ifnum];
+ /* Is it a hub? */
+ if (iface->bInterfaceClass != USB_CLASS_HUB)
+ return 0;
+ /* Some hubs have a subclass of 1, which AFAICT according to the */
+ /* specs is not defined, but it works */
+ if ((iface->bInterfaceSubClass != 0) &&
+ (iface->bInterfaceSubClass != 1))
+ return 0;
+ /* Multiple endpoints? What kind of mutant ninja-hub is this? */
+ if (iface->bNumEndpoints != 1)
+ return 0;
+ ep = &iface->ep_desc[0];
+ /* Output endpoint? Curiousier and curiousier.. */
+ if (!(ep->bEndpointAddress & USB_DIR_IN))
+ return 0;
+ /* If it's not an interrupt endpoint, we'd better punt! */
+ if ((ep->bmAttributes & 3) != 3)
+ return 0;
+ /* We found a hub */
+ USB_HUB_PRINTF("USB hub found\n");
+ ret=usb_hub_configure(dev);
+ return ret;
+}
+
+#endif /* (CONFIG_COMMANDS & CFG_CMD_USB) */
+
+/* EOF */
--- /dev/null
+/*
+ * (C) Copyright 2001
+ * Denis Peter, MPL AG Switzerland
+ *
+ * Part of this source has been derived from the Linux USB
+ * project.
+ *
+ * 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 <devices.h>
+
+#ifdef CONFIG_USB_KEYBOARD
+
+#include <usb.h>
+
+#undef USB_KBD_DEBUG
+/*
+ * 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
+
+#ifdef USB_KBD_DEBUG
+#define USB_KBD_PRINTF(fmt,args...) printf (fmt ,##args)
+#else
+#define USB_KBD_PRINTF(fmt,args...)
+#endif
+
+
+#define REPEAT_RATE 40/4 /* 40msec -> 25cps */
+#define REPEAT_DELAY 10 /* 10 x REAPEAT_RATE = 400msec */
+
+#define NUM_LOCK 0x53
+#define CAPS_LOCK 0x39
+#define SCROLL_LOCK 0x47
+
+
+/* Modifier bits */
+#define LEFT_CNTR 0
+#define LEFT_SHIFT 1
+#define LEFT_ALT 2
+#define LEFT_GUI 3
+#define RIGHT_CNTR 4
+#define RIGHT_SHIFT 5
+#define RIGHT_ALT 6
+#define RIGHT_GUI 7
+
+#define USB_KBD_BUFFER_LEN 0x20 /* size of the keyboardbuffer */
+
+static volatile char usb_kbd_buffer[USB_KBD_BUFFER_LEN];
+static volatile int usb_in_pointer = 0;
+static volatile int usb_out_pointer = 0;
+
+unsigned char new[8];
+unsigned char old[8];
+int repeat_delay;
+#define DEVNAME "usbkbd"
+static unsigned char num_lock = 0;
+static unsigned char caps_lock = 0;
+static unsigned char scroll_lock = 0;
+
+static unsigned char leds __attribute__ ((aligned (0x4)));
+
+static unsigned char usb_kbd_numkey[] = {
+ '1', '2', '3', '4', '5', '6', '7', '8', '9', '0','\r',0x1b,'\b','\t',' ', '-',
+ '=', '[', ']','\\', '#', ';', '\'', '`', ',', '.', '/'
+};
+static unsigned char usb_kbd_numkey_shifted[] = {
+ '!', '@', '#', '$', '%', '^', '&', '*', '(', ')','\r',0x1b,'\b','\t',' ', '_',
+ '+', '{', '}', '|', '~', ':', '"', '~', '<', '>', '?'
+};
+
+/******************************************************************
+ * Queue handling
+ ******************************************************************/
+/* puts character in the queue and sets up the in and out pointer */
+static void usb_kbd_put_queue(char data)
+{
+ if((usb_in_pointer+1)==USB_KBD_BUFFER_LEN) {
+ if(usb_out_pointer==0) {
+ return; /* buffer full */
+ } else{
+ usb_in_pointer=0;
+ }
+ } else {
+ if((usb_in_pointer+1)==usb_out_pointer)
+ return; /* buffer full */
+ usb_in_pointer++;
+ }
+ usb_kbd_buffer[usb_in_pointer]=data;
+ return;
+}
+
+/* test if a character is in the queue */
+static int usb_kbd_testc(void)
+{
+ if(usb_in_pointer==usb_out_pointer)
+ return(0); /* no data */
+ else
+ return(1);
+}
+/* gets the character from the queue */
+static int usb_kbd_getc(void)
+{
+ char c;
+ while(usb_in_pointer==usb_out_pointer);
+ if((usb_out_pointer+1)==USB_KBD_BUFFER_LEN)
+ usb_out_pointer=0;
+ else
+ usb_out_pointer++;
+ c=usb_kbd_buffer[usb_out_pointer];
+ return (int)c;
+
+}
+
+/* forward decleration */
+static int usb_kbd_probe(struct usb_device *dev, unsigned int ifnum);
+
+/* search for keyboard and register it if found */
+int drv_usb_kbd_init(void)
+{
+ int error,i,index;
+ device_t usb_kbd_dev,*old_dev;
+ struct usb_device *dev;
+ char *stdinname = getenv ("stdin");
+
+ usb_in_pointer=0;
+ usb_out_pointer=0;
+ /* scan all USB Devices */
+ for(i=0;i<USB_MAX_DEVICE;i++) {
+ dev=usb_get_dev_index(i); /* get device */
+ if(dev->devnum!=-1) {
+ if(usb_kbd_probe(dev,0)==1) { /* Ok, we found a keyboard */
+ /* check, if it is already registered */
+ USB_KBD_PRINTF("USB KBD found set up device.\n");
+ for (index=1; index<=ListNumItems(devlist); index++) {
+ old_dev = ListGetPtrToItem(devlist, index);
+ if(strcmp(old_dev->name,DEVNAME)==0) {
+ /* ok, already registered, just return ok */
+ USB_KBD_PRINTF("USB KBD is already registered.\n");
+ return 1;
+ }
+ }
+ /* register the keyboard */
+ USB_KBD_PRINTF("USB KBD register.\n");
+ memset (&usb_kbd_dev, 0, sizeof(device_t));
+ strcpy(usb_kbd_dev.name, DEVNAME);
+ usb_kbd_dev.flags = DEV_FLAGS_INPUT | DEV_FLAGS_SYSTEM;
+ usb_kbd_dev.putc = NULL;
+ usb_kbd_dev.puts = NULL;
+ usb_kbd_dev.getc = usb_kbd_getc;
+ usb_kbd_dev.tstc = usb_kbd_testc;
+ error = device_register (&usb_kbd_dev);
+ if(error==0) {
+ /* check if this is the standard input device */
+ if(strcmp(stdinname,DEVNAME)==0) {
+ /* reassign the console */
+ if(overwrite_console()) {
+ return 1;
+ }
+ error=console_assign(stdin,DEVNAME);
+ if(error==0)
+ return 1;
+ else
+ return error;
+ }
+ return 1;
+ }
+ return error;
+ }
+ }
+ }
+ /* no USB Keyboard found */
+ return -1;
+}
+
+
+/* deregistering the keyboard */
+int usb_kbd_deregister(void)
+{
+ return device_deregister(DEVNAME);
+}
+
+/**************************************************************************
+ * Low Level drivers
+ */
+
+/* set the LEDs. Since this is used in the irq routine, the control job
+ is issued with a timeout of 0. This means, that the job is queued without
+ waiting for job completion */
+
+static void usb_kbd_setled(struct usb_device *dev)
+{
+ struct usb_interface_descriptor *iface;
+ iface = &dev->config.if_desc[0];
+ leds=0;
+ if(scroll_lock!=0)
+ leds|=1;
+ leds<<=1;
+ if(caps_lock!=0)
+ leds|=1;
+ leds<<=1;
+ if(num_lock!=0)
+ leds|=1;
+ usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
+ USB_REQ_SET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE,
+ 0x200, iface->bInterfaceNumber,(void *)&leds, 1, 0);
+
+}
+
+
+#define CAPITAL_MASK 0x20
+/* Translate the scancode in ASCII */
+static int usb_kbd_translate(unsigned char scancode,unsigned char modifier,int pressed)
+{
+ unsigned char keycode;
+
+ if(pressed==0) {
+ /* key released */
+ repeat_delay=0;
+ return 0;
+ }
+ if(pressed==2) {
+ repeat_delay++;
+ if(repeat_delay<REPEAT_DELAY)
+ return 0;
+ repeat_delay=REPEAT_DELAY;
+ }
+ keycode=0;
+ if((scancode>3) && (scancode<0x1d)) { /* alpha numeric values */
+ keycode=scancode-4 + 0x61;
+ if(caps_lock)
+ keycode&=~CAPITAL_MASK; /* switch to capital Letters */
+ if(((modifier&(1<<LEFT_SHIFT))!=0)||((modifier&(1<<RIGHT_SHIFT))!=0)) {
+ if(keycode & CAPITAL_MASK)
+ keycode&=~CAPITAL_MASK; /* switch to capital Letters */
+ else
+ keycode|=CAPITAL_MASK; /* switch to non capital Letters */
+ }
+ }
+ if((scancode>0x1d) && (scancode<0x3A)) {
+ if(((modifier&(1<<LEFT_SHIFT))!=0)||((modifier&(1<<RIGHT_SHIFT))!=0)) /* shifted */
+ keycode=usb_kbd_numkey_shifted[scancode-0x1e];
+ else /* non shifted */
+ keycode=usb_kbd_numkey[scancode-0x1e];
+ }
+ if(pressed==1) {
+ if(scancode==NUM_LOCK) {
+ num_lock=~num_lock;
+ return 1;
+ }
+ if(scancode==CAPS_LOCK) {
+ caps_lock=~caps_lock;
+ return 1;
+ }
+ if(scancode==SCROLL_LOCK) {
+ scroll_lock=~scroll_lock;
+ return 1;
+ }
+ }
+ if(keycode!=0) {
+ USB_KBD_PRINTF("%c",keycode);
+ usb_kbd_put_queue(keycode);
+ }
+ return 0;
+}
+
+/* Interrupt service routine */
+static int usb_kbd_irq(struct usb_device *dev)
+{
+ int i,res;
+
+ if((dev->irq_status!=0)||(dev->irq_act_len!=8))
+ {
+ USB_KBD_PRINTF("usb_keyboard Error %lX, len %d\n",dev->irq_status,dev->irq_act_len);
+ return 1;
+ }
+ res=0;
+ for (i = 2; i < 8; i++) {
+ if (old[i] > 3 && memscan(&new[2], old[i], 6) == &new[8]) {
+ res|=usb_kbd_translate(old[i],new[0],0);
+ }
+ if (new[i] > 3 && memscan(&old[2], new[i], 6) == &old[8]) {
+ res|=usb_kbd_translate(new[i],new[0],1);
+ }
+ }
+ if((new[2]>3) && (old[2]==new[2])) /* still pressed */
+ res|=usb_kbd_translate(new[2],new[0],2);
+ if(res==1)
+ usb_kbd_setled(dev);
+ memcpy(&old[0],&new[0], 8);
+ return 1; /* install IRQ Handler again */
+}
+
+/* probes the USB device dev for keyboard type */
+static int usb_kbd_probe(struct usb_device *dev, unsigned int ifnum)
+{
+ struct usb_interface_descriptor *iface;
+ struct usb_endpoint_descriptor *ep;
+ int pipe,maxp;
+
+ if (dev->descriptor.bNumConfigurations != 1) return 0;
+ iface = &dev->config.if_desc[ifnum];
+
+ if (iface->bInterfaceClass != 3) return 0;
+ if (iface->bInterfaceSubClass != 1) return 0;
+ if (iface->bInterfaceProtocol != 1) return 0;
+ if (iface->bNumEndpoints != 1) return 0;
+
+ ep = &iface->ep_desc[0];
+
+ if (!(ep->bEndpointAddress & 0x80)) return 0;
+ if ((ep->bmAttributes & 3) != 3) return 0;
+ USB_KBD_PRINTF("USB KBD found set protocol...\n");
+ /* ok, we found a USB Keyboard, install it */
+ /* usb_kbd_get_hid_desc(dev); */
+ usb_set_protocol(dev, iface->bInterfaceNumber, 0);
+ USB_KBD_PRINTF("USB KBD found set idle...\n");
+ usb_set_idle(dev, iface->bInterfaceNumber, REPEAT_RATE, 0);
+ memset(&new[0], 0, 8);
+ memset(&old[0], 0, 8);
+ repeat_delay=0;
+ pipe = usb_rcvintpipe(dev, ep->bEndpointAddress);
+ maxp = usb_maxpacket(dev, pipe);
+ dev->irq_handle=usb_kbd_irq;
+ USB_KBD_PRINTF("USB KBD enable interrupt pipe...\n");
+ usb_submit_int_msg(dev,pipe,&new[0], maxp > 8 ? 8 : maxp,ep->bInterval);
+ return 1;
+}
+
+
+#if 0
+struct usb_hid_descriptor {
+ unsigned char bLength;
+ unsigned char bDescriptorType; /* 0x21 for HID */
+ unsigned short bcdHID; /* release number */
+ unsigned char bCountryCode;
+ unsigned char bNumDescriptors;
+ unsigned char bReportDescriptorType;
+ unsigned short wDescriptorLength;
+} __attribute__ ((packed));
+
+/*
+ * We parse each description item into this structure. Short items data
+ * values are expanded to 32-bit signed int, long items contain a pointer
+ * into the data area.
+ */
+
+struct hid_item {
+ unsigned char format;
+ unsigned char size;
+ unsigned char type;
+ unsigned char tag;
+ union {
+ unsigned char u8;
+ char s8;
+ unsigned short u16;
+ short s16;
+ unsigned long u32;
+ long s32;
+ unsigned char *longdata;
+ } data;
+};
+
+/*
+ * HID report item format
+ */
+
+#define HID_ITEM_FORMAT_SHORT 0
+#define HID_ITEM_FORMAT_LONG 1
+
+/*
+ * Special tag indicating long items
+ */
+
+#define HID_ITEM_TAG_LONG 15
+
+
+
+static struct usb_hid_descriptor usb_kbd_hid_desc;
+
+void usb_kbd_display_hid(struct usb_hid_descriptor *hid)
+{
+ printf("USB_HID_DESC:\n");
+ printf(" bLenght 0x%x\n",hid->bLength);
+ printf(" bcdHID 0x%x\n",hid->bcdHID);
+ printf(" bCountryCode %d\n",hid->bCountryCode);
+ printf(" bNumDescriptors 0x%x\n",hid->bNumDescriptors);
+ printf(" bReportDescriptorType 0x%x\n",hid->bReportDescriptorType);
+ printf(" wDescriptorLength 0x%x\n",hid->wDescriptorLength);
+}
+
+
+/*
+ * Fetch a report description item from the data stream. We support long
+ * items, though they are not used yet.
+ */
+
+static int fetch_item(unsigned char *start,unsigned char *end, struct hid_item *item)
+{
+ if((end - start) > 0) {
+ unsigned char b = *start++;
+ item->type = (b >> 2) & 3;
+ item->tag = (b >> 4) & 15;
+ if (item->tag == HID_ITEM_TAG_LONG) {
+ item->format = HID_ITEM_FORMAT_LONG;
+ if ((end - start) >= 2) {
+ item->size = *start++;
+ item->tag = *start++;
+ if ((end - start) >= item->size) {
+ item->data.longdata = start;
+ start += item->size;
+ return item->size;
+ }
+ }
+ } else {
+ item->format = HID_ITEM_FORMAT_SHORT;
+ item->size = b & 3;
+ switch (item->size) {
+ case 0:
+ return item->size;
+ case 1:
+ if ((end - start) >= 1) {
+ item->data.u8 = *start++;
+ return item->size;
+ }
+ break;
+ case 2:
+ if ((end - start) >= 2) {
+ item->data.u16 = swap_16((unsigned short *)start);
+ start+=2;
+ return item->size;
+ }
+ case 3:
+ item->size++;
+ if ((end - start) >= 4) {
+ item->data.u32 = swap_32((unsigned long *)start);
+ start+=4;
+ return item->size;
+ }
+ }
+ }
+ }
+ return -1;
+}
+
+/*
+ * HID report descriptor item type (prefix bit 2,3)
+ */
+
+#define HID_ITEM_TYPE_MAIN 0
+#define HID_ITEM_TYPE_GLOBAL 1
+#define HID_ITEM_TYPE_LOCAL 2
+#define HID_ITEM_TYPE_RESERVED 3
+/*
+ * HID report descriptor main item tags
+ */
+
+#define HID_MAIN_ITEM_TAG_INPUT 8
+#define HID_MAIN_ITEM_TAG_OUTPUT 9
+#define HID_MAIN_ITEM_TAG_FEATURE 11
+#define HID_MAIN_ITEM_TAG_BEGIN_COLLECTION 10
+#define HID_MAIN_ITEM_TAG_END_COLLECTION 12
+/*
+ * HID report descriptor main item contents
+ */
+
+#define HID_MAIN_ITEM_CONSTANT 0x001
+#define HID_MAIN_ITEM_VARIABLE 0x002
+#define HID_MAIN_ITEM_RELATIVE 0x004
+#define HID_MAIN_ITEM_WRAP 0x008
+#define HID_MAIN_ITEM_NONLINEAR 0x010
+#define HID_MAIN_ITEM_NO_PREFERRED 0x020
+#define HID_MAIN_ITEM_NULL_STATE 0x040
+#define HID_MAIN_ITEM_VOLATILE 0x080
+#define HID_MAIN_ITEM_BUFFERED_BYTE 0x100
+
+/*
+ * HID report descriptor collection item types
+ */
+
+#define HID_COLLECTION_PHYSICAL 0
+#define HID_COLLECTION_APPLICATION 1
+#define HID_COLLECTION_LOGICAL 2
+/*
+ * HID report descriptor global item tags
+ */
+
+#define HID_GLOBAL_ITEM_TAG_USAGE_PAGE 0
+#define HID_GLOBAL_ITEM_TAG_LOGICAL_MINIMUM 1
+#define HID_GLOBAL_ITEM_TAG_LOGICAL_MAXIMUM 2
+#define HID_GLOBAL_ITEM_TAG_PHYSICAL_MINIMUM 3
+#define HID_GLOBAL_ITEM_TAG_PHYSICAL_MAXIMUM 4
+#define HID_GLOBAL_ITEM_TAG_UNIT_EXPONENT 5
+#define HID_GLOBAL_ITEM_TAG_UNIT 6
+#define HID_GLOBAL_ITEM_TAG_REPORT_SIZE 7
+#define HID_GLOBAL_ITEM_TAG_REPORT_ID 8
+#define HID_GLOBAL_ITEM_TAG_REPORT_COUNT 9
+#define HID_GLOBAL_ITEM_TAG_PUSH 10
+#define HID_GLOBAL_ITEM_TAG_POP 11
+
+/*
+ * HID report descriptor local item tags
+ */
+
+#define HID_LOCAL_ITEM_TAG_USAGE 0
+#define HID_LOCAL_ITEM_TAG_USAGE_MINIMUM 1
+#define HID_LOCAL_ITEM_TAG_USAGE_MAXIMUM 2
+#define HID_LOCAL_ITEM_TAG_DESIGNATOR_INDEX 3
+#define HID_LOCAL_ITEM_TAG_DESIGNATOR_MINIMUM 4
+#define HID_LOCAL_ITEM_TAG_DESIGNATOR_MAXIMUM 5
+#define HID_LOCAL_ITEM_TAG_STRING_INDEX 7
+#define HID_LOCAL_ITEM_TAG_STRING_MINIMUM 8
+#define HID_LOCAL_ITEM_TAG_STRING_MAXIMUM 9
+#define HID_LOCAL_ITEM_TAG_DELIMITER 10
+
+
+
+static void usb_kbd_show_item(struct hid_item *item)
+{
+ switch(item->type) {
+ case HID_ITEM_TYPE_MAIN:
+ switch(item->tag) {
+ case HID_MAIN_ITEM_TAG_INPUT:
+ printf("Main Input");
+ break;
+ case HID_MAIN_ITEM_TAG_OUTPUT:
+ printf("Main Output");
+ break;
+ case HID_MAIN_ITEM_TAG_FEATURE:
+ printf("Main Feature");
+ break;
+ case HID_MAIN_ITEM_TAG_BEGIN_COLLECTION:
+ printf("Main Begin Collection");
+ break;
+ case HID_MAIN_ITEM_TAG_END_COLLECTION:
+ printf("Main End Collection");
+ break;
+ default:
+ printf("Main reserved %d",item->tag);
+ break;
+ }
+ break;
+ case HID_ITEM_TYPE_GLOBAL:
+ switch(item->tag) {
+ case HID_GLOBAL_ITEM_TAG_USAGE_PAGE:
+ printf("- Global Usage Page");
+ break;
+ case HID_GLOBAL_ITEM_TAG_LOGICAL_MINIMUM:
+ printf("- Global Logical Minimum");
+ break;
+ case HID_GLOBAL_ITEM_TAG_LOGICAL_MAXIMUM:
+ printf("- Global Logical Maximum");
+ break;
+ case HID_GLOBAL_ITEM_TAG_PHYSICAL_MINIMUM:
+ printf("- Global physical Minimum");
+ break;
+ case HID_GLOBAL_ITEM_TAG_PHYSICAL_MAXIMUM:
+ printf("- Global physical Maximum");
+ break;
+ case HID_GLOBAL_ITEM_TAG_UNIT_EXPONENT:
+ printf("- Global Unit Exponent");
+ break;
+ case HID_GLOBAL_ITEM_TAG_UNIT:
+ printf("- Global Unit");
+ break;
+ case HID_GLOBAL_ITEM_TAG_REPORT_SIZE:
+ printf("- Global Report Size");
+ break;
+ case HID_GLOBAL_ITEM_TAG_REPORT_ID:
+ printf("- Global Report ID");
+ break;
+ case HID_GLOBAL_ITEM_TAG_REPORT_COUNT:
+ printf("- Global Report Count");
+ break;
+ case HID_GLOBAL_ITEM_TAG_PUSH:
+ printf("- Global Push");
+ break;
+ case HID_GLOBAL_ITEM_TAG_POP:
+ printf("- Global Pop");
+ break;
+ default:
+ printf("- Global reserved %d",item->tag);
+ break;
+ }
+ break;
+ case HID_ITEM_TYPE_LOCAL:
+ switch(item->tag) {
+ case HID_LOCAL_ITEM_TAG_USAGE:
+ printf("-- Local Usage");
+ break;
+ case HID_LOCAL_ITEM_TAG_USAGE_MINIMUM:
+ printf("-- Local Usage Minimum");
+ break;
+ case HID_LOCAL_ITEM_TAG_USAGE_MAXIMUM:
+ printf("-- Local Usage Maximum");
+ break;
+ case HID_LOCAL_ITEM_TAG_DESIGNATOR_INDEX:
+ printf("-- Local Designator Index");
+ break;
+ case HID_LOCAL_ITEM_TAG_DESIGNATOR_MINIMUM:
+ printf("-- Local Designator Minimum");
+ break;
+ case HID_LOCAL_ITEM_TAG_DESIGNATOR_MAXIMUM:
+ printf("-- Local Designator Maximum");
+ break;
+ case HID_LOCAL_ITEM_TAG_STRING_INDEX:
+ printf("-- Local String Index");
+ break;
+ case HID_LOCAL_ITEM_TAG_STRING_MINIMUM:
+ printf("-- Local String Minimum");
+ break;
+ case HID_LOCAL_ITEM_TAG_STRING_MAXIMUM:
+ printf("-- Local String Maximum");
+ break;
+ case HID_LOCAL_ITEM_TAG_DELIMITER:
+ printf("-- Local Delimiter");
+ break;
+ default:
+ printf("-- Local reserved %d",item->tag);
+ break;
+ }
+ break;
+ default:
+ printf("--- reserved %d",item->type);
+ break;
+ }
+ switch(item->size) {
+ case 1:
+ printf(" %d",item->data.u8);
+ break;
+ case 2:
+ printf(" %d",item->data.u16);
+ break;
+ case 4:
+ printf(" %ld",item->data.u32);
+ break;
+ }
+ printf("\n");
+}
+
+
+
+static int usb_kbd_get_hid_desc(struct usb_device *dev)
+{
+ unsigned char buffer[256];
+ struct usb_descriptor_header *head;
+ struct usb_config_descriptor *config;
+ int index,len,i;
+ unsigned char *start, *end;
+ struct hid_item item;
+
+ if(usb_get_configuration_no(dev,&buffer[0],0)==-1)
+ return -1;
+ head =(struct usb_descriptor_header *)&buffer[0];
+ if(head->bDescriptorType!=USB_DT_CONFIG) {
+ printf(" ERROR: NOT USB_CONFIG_DESC %x\n",head->bDescriptorType);
+ return -1;
+ }
+ index=head->bLength;
+ config=(struct usb_config_descriptor *)&buffer[0];
+ len=swap_16(config->wTotalLength);
+ /* Ok the first entry must be a configuration entry, now process the others */
+ head=(struct usb_descriptor_header *)&buffer[index];
+ while(index+1 < len) {
+ if(head->bDescriptorType==USB_DT_HID) {
+ printf("HID desc found\n");
+ memcpy(&usb_kbd_hid_desc,&buffer[index],buffer[index]);
+ usb_kbd_hid_desc.bcdHID=swap_16(usb_kbd_hid_desc.bcdHID);
+ usb_kbd_hid_desc.wDescriptorLength=swap_16(usb_kbd_hid_desc.wDescriptorLength);
+ usb_kbd_display_hid(&usb_kbd_hid_desc);
+ len=0;
+ break;
+ }
+ index+=head->bLength;
+ head=(struct usb_descriptor_header *)&buffer[index];
+ }
+ if(len>0)
+ return -1;
+ len=usb_kbd_hid_desc.wDescriptorLength;
+ if((index = usb_get_class_descriptor(dev, 0, USB_DT_REPORT, 0, &buffer[0], len)) < 0) {
+ printf("reading report descriptor failed\n");
+ return -1;
+ }
+ printf(" report descriptor (size %u, read %d)\n", len, index);
+ start=&buffer[0];
+ end=&buffer[len];
+ i=0;
+ do {
+ index=fetch_item(start,end,&item);
+ i+=index;
+ i++;
+ if(index>=0)
+ usb_kbd_show_item(&item);
+
+ start+=index;
+ start++;
+ } while(index>=0);
+
+}
+
+
+#endif
+
+#endif /* CONFIG_USB_KEYBOARD */
+
+/* eof */
+
--- /dev/null
+/*
+ * (C) Copyright 2001
+ * Denis Peter, MPL AG Switzerland
+ *
+ * Most of this source has been derived from the Linux USB
+ * project.
+ *
+ * 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:
+ * Currently only the CBI transport protocoll has been implemented, and it
+ * is only tested with a TEAC USB Floppy. Other Massstorages with CBI or CB
+ * transport protocoll may work as well.
+ */
+
+
+
+#include <ppcboot.h>
+#include <command.h>
+#include <asm/processor.h>
+
+
+#if (CONFIG_COMMANDS & CFG_CMD_USB)
+#include <usb.h>
+
+#ifdef CONFIG_USB_STORAGE
+
+#undef USB_STOR_DEBUG
+
+#ifdef USB_STOR_DEBUG
+#define USB_STOR_PRINTF(fmt,args...) printf (fmt ,##args)
+#else
+#define USB_STOR_PRINTF(fmt,args...)
+#endif
+
+#include <scsi.h>
+/* direction table -- this indicates the direction of the data
+ * transfer for each command code -- a 1 indicates input
+ */
+unsigned char us_direction[256/8] = {
+ 0x28, 0x81, 0x14, 0x14, 0x20, 0x01, 0x90, 0x77,
+ 0x0C, 0x20, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+#define US_DIRECTION(x) ((us_direction[x>>3] >> (x & 7)) & 1)
+
+static unsigned char usb_stor_buf[512];
+static ccb usb_ccb;
+
+/*
+ * CBI style
+ */
+
+#define US_CBI_ADSC 0
+
+
+#define USB_MAX_STOR_DEV 5
+static int usb_max_devs; /* number of highest available usb device */
+
+static block_dev_desc_t usb_dev_desc[USB_MAX_STOR_DEV];
+
+struct us_data;
+typedef int (*trans_cmnd)(ccb*, struct us_data*);
+typedef int (*trans_reset)(struct us_data*);
+
+struct us_data {
+ struct usb_device *pusb_dev; /* this usb_device */
+ unsigned int flags; /* from filter initially */
+ unsigned char ifnum; /* interface number */
+ unsigned char ep_in; /* in endpoint */
+ unsigned char ep_out; /* out ....... */
+ unsigned char ep_int; /* interrupt . */
+ unsigned char subclass; /* as in overview */
+ unsigned char protocol; /* .............. */
+ unsigned char attention_done; /* force attn on first cmd */
+ unsigned short ip_data; /* interrupt data */
+ int action; /* what to do */
+ int ip_wanted; /* needed */
+ int *irq_handle; /* for USB int requests */
+ unsigned int irqpipe; /* pipe for release_irq */
+ unsigned char irqmaxp; /* max packed for irq Pipe */
+ unsigned char irqinterval; /* Intervall for IRQ Pipe */
+ ccb *srb; /* current srb */
+ trans_reset transport_reset; /* reset routine */
+ trans_cmnd transport; /* transport routine */
+};
+
+static struct us_data usb_stor[USB_MAX_STOR_DEV];
+
+
+
+#define USB_STOR_TRANSPORT_GOOD 0
+#define USB_STOR_TRANSPORT_FAILED -1
+#define USB_STOR_TRANSPORT_ERROR -2
+
+
+
+
+
+
+int usb_stor_get_info(struct usb_device *dev, struct us_data *us, block_dev_desc_t *dev_desc);
+int usb_storage_probe(struct usb_device *dev, unsigned int ifnum,struct us_data *ss);
+unsigned long usb_stor_read(int device, unsigned long blknr, unsigned long blkcnt, unsigned long *buffer);
+struct usb_device * usb_get_dev_index(int index);
+void uhci_show_temp_int_td(void);
+
+block_dev_desc_t *usb_stor_get_dev(int index)
+{
+ return &usb_dev_desc[index];
+}
+
+
+void usb_show_progress(void)
+{
+ printf(".");
+}
+
+/*********************************************************************************
+ * (re)-scan the usb and reports device info
+ * to the user if mode = 1
+ * returns current device or -1 if no
+ */
+int usb_stor_scan(int mode)
+{
+ unsigned char i;
+ struct usb_device *dev;
+
+ if(mode==1) {
+ printf("scanning bus for storage devices...\n");
+ }
+ usb_disable_asynch(1); /* asynch transfer not allowed */
+
+ for(i=0;i<USB_MAX_STOR_DEV;i++) {
+ memset(&usb_dev_desc[i],0,sizeof(block_dev_desc_t));
+ usb_dev_desc[i].target=0xff;
+ usb_dev_desc[i].if_type=IF_TYPE_SCSI;
+ usb_dev_desc[i].dev=i;
+ usb_dev_desc[i].part_type=PART_TYPE_UNKNOWN;
+ usb_dev_desc[i].block_read=usb_stor_read;
+ }
+ usb_max_devs=0;
+ for(i=0;i<USB_MAX_DEVICE;i++) {
+ dev=usb_get_dev_index(i); /* get device */
+ USB_STOR_PRINTF("i=%d\n",i);
+ if(dev==NULL) {
+ break; /* no more devices avaiable */
+ }
+ if(usb_storage_probe(dev,0,&usb_stor[usb_max_devs])) { /* ok, it is a storage devices */
+ /* get info and fill it in */
+
+ if(usb_stor_get_info(dev, &usb_stor[usb_max_devs], &usb_dev_desc[usb_max_devs])) {
+ if(mode==1) {
+ printf (" Device %d: ", usb_max_devs);
+ dev_print(&usb_dev_desc[usb_max_devs]);
+ } /* if mode */
+ usb_max_devs++;
+ } /* if get info ok */
+ } /* if storage device */
+ if(usb_max_devs==USB_MAX_STOR_DEV) {
+ printf("max USB Storage Device reached: %d stopping\n",usb_max_devs);
+ break;
+ }
+ } /* for */
+ usb_disable_asynch(0); /* asynch transfer allowed */
+ if(usb_max_devs>0)
+ return 0;
+ else
+ return-1;
+}
+
+static int usb_stor_irq(struct usb_device *dev)
+{
+ struct us_data *us;
+ us=(struct us_data *)dev->privptr;
+
+ if(us->ip_wanted) {
+ us->ip_wanted=0;
+ }
+ return 0;
+}
+
+
+#ifdef USB_STOR_DEBUG
+
+static void usb_show_srb(ccb * pccb)
+{
+ int i;
+ printf("SRB: len %d datalen 0x%lX\n ",pccb->cmdlen,pccb->datalen);
+ for(i=0;i<12;i++) {
+ printf("%02X ",pccb->cmd[i]);
+ }
+ printf("\n");
+}
+
+static void display_int_status(unsigned long tmp)
+{
+ printf("Status: %s %s %s %s %s %s %s\n",
+ (tmp & USB_ST_ACTIVE) ? "Active" : "",
+ (tmp & USB_ST_STALLED) ? "Stalled" : "",
+ (tmp & USB_ST_BUF_ERR) ? "Buffer Error" : "",
+ (tmp & USB_ST_BABBLE_DET) ? "Babble Det" : "",
+ (tmp & USB_ST_NAK_REC) ? "NAKed" : "",
+ (tmp & USB_ST_CRC_ERR) ? "CRC Error" : "",
+ (tmp & USB_ST_BIT_ERR) ? "Bitstuff Error" : "");
+}
+#endif
+/***********************************************************************
+ * Data transfer routines
+ ***********************************************************************/
+
+static int us_one_transfer(struct us_data *us, int pipe, char *buf, int length)
+{
+ int max_size;
+ int this_xfer;
+ int result;
+ int partial;
+ int maxtry;
+ int stat;
+
+ /* determine the maximum packet size for these transfers */
+ max_size = usb_maxpacket(us->pusb_dev, pipe) * 16;
+
+ /* while we have data left to transfer */
+ while (length) {
+
+ /* calculate how long this will be -- maximum or a remainder */
+ this_xfer = length > max_size ? max_size : length;
+ length -= this_xfer;
+
+ /* setup the retry counter */
+ maxtry = 10;
+
+ /* set up the transfer loop */
+ do {
+ /* transfer the data */
+ USB_STOR_PRINTF("Bulk xfer 0x%x(%d) try #%d\n",
+ (unsigned int)buf, this_xfer, 11 - maxtry);
+ result = usb_bulk_msg(us->pusb_dev, pipe, buf,
+ this_xfer, &partial, USB_CNTL_TIMEOUT*5);
+ USB_STOR_PRINTF("bulk_msg returned %d xferred %d/%d\n",
+ result, partial, this_xfer);
+ if(us->pusb_dev->status!=0) {
+ /* if we stall, we need to clear it before we go on */
+#ifdef USB_STOR_DEBUG
+ display_int_status(us->pusb_dev->status);
+#endif
+ if (us->pusb_dev->status & USB_ST_STALLED) {
+ USB_STOR_PRINTF("stalled ->clearing endpoint halt for pipe 0x%x\n", pipe);
+ stat = us->pusb_dev->status;
+ usb_clear_halt(us->pusb_dev, pipe);
+ us->pusb_dev->status=stat;
+ if(this_xfer == partial) {
+ USB_STOR_PRINTF("bulk transferred with error %X, but data ok\n",us->pusb_dev->status);
+ return 0;
+ }
+ else
+ return result;
+ }
+ if (us->pusb_dev->status & USB_ST_NAK_REC) {
+ USB_STOR_PRINTF("Device NAKed bulk_msg\n");
+ return result;
+ }
+ if(this_xfer == partial) {
+ USB_STOR_PRINTF("bulk transferred with error %d, but data ok\n",us->pusb_dev->status);
+ return 0;
+ }
+ /* if our try counter reaches 0, bail out */
+ USB_STOR_PRINTF("bulk transferred with error %d, data %d\n",us->pusb_dev->status,partial);
+ if (!maxtry--)
+ return result;
+ }
+ /* update to show what data was transferred */
+ this_xfer -= partial;
+ buf += partial;
+ /* continue until this transfer is done */
+ } while ( this_xfer );
+ }
+
+ /* if we get here, we're done and successful */
+ return 0;
+}
+
+/* FIXME: this reset function doesn't really reset the port, and it
+ * should. Actually it should probably do what it's doing here, and
+ * reset the port physically
+ */
+static int usb_stor_CB_reset(struct us_data *us)
+{
+ unsigned char cmd[12];
+ int result;
+
+ USB_STOR_PRINTF("CB_reset\n");
+ memset(cmd, 0xFF, sizeof(cmd));
+ cmd[0] = SCSI_SEND_DIAG;
+ cmd[1] = 4;
+ result = usb_control_msg(us->pusb_dev, usb_sndctrlpipe(us->pusb_dev,0),
+ US_CBI_ADSC, USB_TYPE_CLASS | USB_RECIP_INTERFACE,
+ 0, us->ifnum, cmd, sizeof(cmd), USB_CNTL_TIMEOUT*5);
+
+ /* long wait for reset */
+ wait_ms(1500);
+ USB_STOR_PRINTF("CB_reset result %d: status %X clearing endpoint halt\n",result,us->pusb_dev->status);
+ usb_clear_halt(us->pusb_dev, usb_rcvbulkpipe(us->pusb_dev, us->ep_in));
+ usb_clear_halt(us->pusb_dev, usb_rcvbulkpipe(us->pusb_dev, us->ep_out));
+
+ USB_STOR_PRINTF("CB_reset done\n");
+ return 0;
+}
+
+/* FIXME: we also need a CBI_command which sets up the completion
+ * interrupt, and waits for it
+ */
+int usb_stor_CB_comdat(ccb *srb, struct us_data *us)
+{
+ int result;
+ int dir_in,retry;
+ unsigned int pipe;
+ unsigned long status;
+
+ retry=5;
+ dir_in=US_DIRECTION(srb->cmd[0]);
+
+ if(dir_in)
+ pipe=usb_rcvbulkpipe(us->pusb_dev, us->ep_in);
+ else
+ pipe=usb_sndbulkpipe(us->pusb_dev, us->ep_out);
+ while(retry--) {
+ USB_STOR_PRINTF("CBI gets a command: Try %d\n",5-retry);
+#ifdef USB_STOR_DEBUG
+ usb_show_srb(srb);
+#endif
+ /* let's send the command via the control pipe */
+ result = usb_control_msg(us->pusb_dev, usb_sndctrlpipe(us->pusb_dev,0),
+ US_CBI_ADSC, USB_TYPE_CLASS | USB_RECIP_INTERFACE,
+ 0, us->ifnum,
+ srb->cmd, srb->cmdlen, USB_CNTL_TIMEOUT*5);
+ USB_STOR_PRINTF("CB_transport: control msg returned %d, status %X\n",result,us->pusb_dev->status);
+ /* check the return code for the command */
+ if (result < 0) {
+ if(us->pusb_dev->status & USB_ST_STALLED) {
+ status=us->pusb_dev->status;
+ USB_STOR_PRINTF(" stall during command found, clear pipe\n");
+ usb_clear_halt(us->pusb_dev, usb_sndctrlpipe(us->pusb_dev,0));
+ us->pusb_dev->status=status;
+ }
+ USB_STOR_PRINTF(" error during command %02X Stat = %X\n",srb->cmd[0],us->pusb_dev->status);
+ return result;
+ }
+ /* transfer the data payload for this command, if one exists*/
+
+ USB_STOR_PRINTF("CB_transport: control msg returned %d, direction is %s to go 0x%lx\n",result,dir_in ? "IN" : "OUT",srb->datalen);
+ if (srb->datalen) {
+ result = us_one_transfer(us, pipe, srb->pdata,srb->datalen);
+ USB_STOR_PRINTF("CBI attempted to transfer data, result is %d status %lX, len %d\n", result,us->pusb_dev->status,us->pusb_dev->act_len);
+ if(!(us->pusb_dev->status & USB_ST_NAK_REC))
+ break;
+ } /* if (srb->datalen) */
+ else
+ break;
+ }
+ /* return result */
+
+ return result;
+}
+
+
+int usb_stor_CBI_get_status(ccb *srb, struct us_data *us)
+{
+ int timeout;
+
+ us->ip_wanted=1;
+ submit_int_msg(us->pusb_dev,us->irqpipe,
+ (void *)&us->ip_data,us->irqmaxp ,us->irqinterval);
+ timeout=1000;
+ while(timeout--) {
+ if((volatile int *)us->ip_wanted==0)
+ break;
+ wait_ms(10);
+ }
+ if (us->ip_wanted) {
+ printf(" Did not get interrupt on CBI\n");
+ us->ip_wanted = 0;
+ return USB_STOR_TRANSPORT_ERROR;
+ }
+ USB_STOR_PRINTF("Got interrupt data 0x%x, transfered %d status 0x%lX\n", us->ip_data,us->pusb_dev->irq_act_len,us->pusb_dev->irq_status);
+ /* UFI gives us ASC and ASCQ, like a request sense */
+ if (us->subclass == US_SC_UFI) {
+ if (srb->cmd[0] == SCSI_REQ_SENSE ||
+ srb->cmd[0] == SCSI_INQUIRY)
+ return USB_STOR_TRANSPORT_GOOD; /* Good */
+ else
+ if (us->ip_data)
+ return USB_STOR_TRANSPORT_FAILED;
+ else
+ return USB_STOR_TRANSPORT_GOOD;
+ }
+ /* otherwise, we interpret the data normally */
+ switch (us->ip_data) {
+ case 0x0001:
+ return USB_STOR_TRANSPORT_GOOD;
+ case 0x0002:
+ return USB_STOR_TRANSPORT_FAILED;
+ default:
+ return USB_STOR_TRANSPORT_ERROR;
+ } /* switch */
+ return USB_STOR_TRANSPORT_ERROR;
+}
+
+#define USB_TRANSPORT_UNKNOWN_RETRY 5
+#define USB_TRANSPORT_NOT_READY_RETRY 10
+
+int usb_stor_CB_transport(ccb *srb, struct us_data *us)
+{
+ int result,status;
+ ccb *psrb;
+ ccb reqsrb;
+ int retry,notready;
+
+ psrb=&reqsrb;
+ status=USB_STOR_TRANSPORT_GOOD;
+ retry=0;
+ notready=0;
+ /* issue the command */
+do_retry:
+ result=usb_stor_CB_comdat(srb,us);
+ USB_STOR_PRINTF("command / Data returned %d, status %X\n",result,us->pusb_dev->status);
+ /* if this is an CBI Protocol, get IRQ */
+ if(us->protocol==US_PR_CBI) {
+ status=usb_stor_CBI_get_status(srb,us);
+ /* if the status is error, report it */
+ if(status==USB_STOR_TRANSPORT_ERROR) {
+ USB_STOR_PRINTF(" USB CBI Command Error\n");
+ return status;
+ }
+ srb->sense_buf[12]=(unsigned char)(us->ip_data>>8);
+ srb->sense_buf[13]=(unsigned char)(us->ip_data&0xff);
+ if(!us->ip_data) {
+ /* if the status is good, report it */
+ if(status==USB_STOR_TRANSPORT_GOOD) {
+ USB_STOR_PRINTF(" USB CBI Command Good\n");
+ return status;
+ }
+ }
+ }
+ /* do we have to issue an auto request? */
+ /* HERE we have to check the result */
+ if((result<0) && !(us->pusb_dev->status & USB_ST_STALLED)) {
+ USB_STOR_PRINTF("ERROR %X\n",us->pusb_dev->status);
+ us->transport_reset(us);
+ return USB_STOR_TRANSPORT_ERROR;
+ }
+ if((us->protocol==US_PR_CBI) &&
+ ((srb->cmd[0]==SCSI_REQ_SENSE) ||
+ (srb->cmd[0]==SCSI_INQUIRY))) { /* do not issue an autorequest after request sense */
+ USB_STOR_PRINTF("No auto request and good\n");
+ return USB_STOR_TRANSPORT_GOOD;
+ }
+ /* issue an request_sense */
+ memset(&psrb->cmd[0],0,12);
+ psrb->cmd[0]=SCSI_REQ_SENSE;
+ psrb->cmd[1]=srb->lun<<5;
+ psrb->cmd[4]=18;
+ psrb->datalen=18;
+ psrb->pdata=&srb->sense_buf[0];
+ psrb->cmdlen=12;
+ /* issue the command */
+ result=usb_stor_CB_comdat(psrb,us);
+ USB_STOR_PRINTF("auto request returned %d\n",result);
+ /* if this is an CBI Protocol, get IRQ */
+ if(us->protocol==US_PR_CBI) {
+ status=usb_stor_CBI_get_status(psrb,us);
+ }
+ if((result<0)&&!(us->pusb_dev->status & USB_ST_STALLED)) {
+ USB_STOR_PRINTF(" AUTO REQUEST ERROR %d\n",us->pusb_dev->status);
+ return USB_STOR_TRANSPORT_ERROR;
+ }
+ USB_STOR_PRINTF("autorequest returned 0x%02X 0x%02X 0x%02X 0x%02X\n",srb->sense_buf[0],srb->sense_buf[2],srb->sense_buf[12],srb->sense_buf[13]);
+ /* Check the auto request result */
+ if((srb->sense_buf[2]==0) &&
+ (srb->sense_buf[12]==0) &&
+ (srb->sense_buf[13]==0)) /* ok, no sense */
+ return USB_STOR_TRANSPORT_GOOD;
+ /* Check the auto request result */
+ switch(srb->sense_buf[2]) {
+ case 0x01: /* Recovered Error */
+ return USB_STOR_TRANSPORT_GOOD;
+ break;
+ case 0x02: /* Not Ready */
+ if(notready++ > USB_TRANSPORT_NOT_READY_RETRY) {
+ printf("cmd 0x%02X returned 0x%02X 0x%02X 0x%02X 0x%02X (NOT READY)\n",
+ srb->cmd[0],srb->sense_buf[0],srb->sense_buf[2],srb->sense_buf[12],srb->sense_buf[13]);
+ return USB_STOR_TRANSPORT_FAILED;
+ }
+ else {
+ wait_ms(100);
+ goto do_retry;
+ }
+ break;
+ default:
+ if(retry++ > USB_TRANSPORT_UNKNOWN_RETRY) {
+ printf("cmd 0x%02X returned 0x%02X 0x%02X 0x%02X 0x%02X\n",
+ srb->cmd[0],srb->sense_buf[0],srb->sense_buf[2],srb->sense_buf[12],srb->sense_buf[13]);
+ return USB_STOR_TRANSPORT_FAILED;
+ }
+ else
+ goto do_retry;
+ break;
+ }
+ return USB_STOR_TRANSPORT_FAILED;
+}
+
+
+
+static int usb_inquiry(ccb *srb,struct us_data *ss)
+{
+ int retry,i;
+ retry=3;
+ do {
+ memset(&srb->cmd[0],0,12);
+ srb->cmd[0]=SCSI_INQUIRY;
+ srb->cmd[1]=srb->lun<<5;
+ srb->cmd[4]=36;
+ srb->datalen=36;
+ srb->cmdlen=12;
+ i=ss->transport(srb,ss);
+ USB_STOR_PRINTF("inquiry returns %d\n",i);
+ if(i==0)
+ break;
+ }while(retry--);
+ if(!retry) {
+ printf("error in inquiry\n");
+ return -1;
+ }
+ return 0;
+}
+
+static int usb_request_sense(ccb *srb,struct us_data *ss)
+{
+ char *ptr;
+ return 0;
+ ptr=srb->pdata;
+ memset(&srb->cmd[0],0,12);
+ srb->cmd[0]=SCSI_REQ_SENSE;
+ srb->cmd[1]=srb->lun<<5;
+ srb->cmd[4]=18;
+ srb->datalen=18;
+ srb->pdata=&srb->sense_buf[0];
+ srb->cmdlen=12;
+ ss->transport(srb,ss);
+ USB_STOR_PRINTF("Request Sense returned %02X %02X %02X\n",srb->sense_buf[2],srb->sense_buf[12],srb->sense_buf[13]);
+ srb->pdata=ptr;
+ return 0;
+}
+
+static int usb_test_unit_ready(ccb *srb,struct us_data *ss)
+{
+ int retries=10;
+ do {
+ memset(&srb->cmd[0],0,12);
+ srb->cmd[0]=SCSI_TST_U_RDY;
+ srb->cmd[1]=srb->lun<<5;
+ srb->datalen=0;
+ srb->cmdlen=12;
+ if(ss->transport(srb,ss)==USB_STOR_TRANSPORT_GOOD)
+ {
+ return 0;
+ }
+ } while(retries--);
+ return -1;
+}
+
+static int usb_read_capacity(ccb *srb,struct us_data *ss)
+{
+ int retry;
+ retry=2; /* retries */
+ do {
+ memset(&srb->cmd[0],0,12);
+ srb->cmd[0]=SCSI_RD_CAPAC;
+ srb->cmd[1]=srb->lun<<5;
+ srb->datalen=8;
+ srb->cmdlen=12;
+ if(ss->transport(srb,ss)==USB_STOR_TRANSPORT_GOOD) {
+ return 0;
+ }
+ }while(retry--);
+ return -1;
+}
+
+static int usb_read_10(ccb *srb,struct us_data *ss, unsigned long start, unsigned short blocks)
+{
+ memset(&srb->cmd[0],0,12);
+ srb->cmd[0]=SCSI_READ10;
+ srb->cmd[1]=srb->lun<<5;
+ srb->cmd[2]=((unsigned char) (start>>24))&0xff;
+ srb->cmd[3]=((unsigned char) (start>>16))&0xff;
+ srb->cmd[4]=((unsigned char) (start>>8))&0xff;
+ srb->cmd[5]=((unsigned char) (start))&0xff;
+ srb->cmd[7]=((unsigned char) (blocks>>8))&0xff;
+ srb->cmd[8]=(unsigned char) blocks & 0xff;
+ srb->cmdlen=12;
+ USB_STOR_PRINTF("read10: start %lx blocks %x\n",start,blocks);
+ return ss->transport(srb,ss);
+}
+
+
+#define USB_MAX_READ_BLK 20
+
+unsigned long usb_stor_read(int device, unsigned long blknr, unsigned long blkcnt, unsigned long *buffer)
+{
+ unsigned long start,blks, buf_addr;
+ unsigned short smallblks;
+ struct usb_device *dev;
+ int retry,i;
+ ccb *srb=&usb_ccb;
+ device&=0xff;
+ /* Setup device
+ */
+ USB_STOR_PRINTF("\nusb_read: dev %d \n",device);
+ dev=NULL;
+ for(i=0;i<USB_MAX_DEVICE;i++) {
+ dev=usb_get_dev_index(i);
+ if(dev==NULL) {
+ return 0;
+ }
+ if(dev->devnum==usb_dev_desc[device].target)
+ break;
+ }
+
+ usb_disable_asynch(1); /* asynch transfer not allowed */
+ srb->lun=usb_dev_desc[device].lun;
+ buf_addr=(unsigned long)buffer;
+ start=blknr;
+ blks=blkcnt;
+ if(usb_test_unit_ready(srb,(struct us_data *)dev->privptr)) {
+ printf("Device NOT ready\n Request Sense returned %02X %02X %02X\n",
+ srb->sense_buf[2],srb->sense_buf[12],srb->sense_buf[13]);
+ return 0;
+ }
+ USB_STOR_PRINTF("\nusb_read: dev %d startblk %lx, blccnt %lx buffer %lx\n",device,start,blks, buf_addr);
+ do {
+ retry=2;
+ srb->pdata=(unsigned char *)buf_addr;
+ if(blks>USB_MAX_READ_BLK) {
+ smallblks=USB_MAX_READ_BLK;
+ }
+ else {
+ smallblks=(unsigned short) blks;
+ }
+retry_it:
+ if(smallblks==USB_MAX_READ_BLK)
+ usb_show_progress();
+ srb->datalen=usb_dev_desc[device].blksz * smallblks;
+ srb->pdata=(unsigned char *)buf_addr;
+ if(usb_read_10(srb,(struct us_data *)dev->privptr, start, smallblks)) {
+ USB_STOR_PRINTF("Read ERROR\n");
+ usb_request_sense(srb,(struct us_data *)dev->privptr);
+ if(retry--)
+ goto retry_it;
+ blkcnt-=blks;
+ break;
+ }
+ start+=smallblks;
+ blks-=smallblks;
+ buf_addr+=srb->datalen;
+ } while(blks!=0);
+ USB_STOR_PRINTF("usb_read: end startblk %lx, blccnt %x buffer %lx\n",start,smallblks,buf_addr);
+ usb_disable_asynch(0); /* asynch transfer allowed */
+ if(blkcnt>=USB_MAX_READ_BLK)
+ printf("\n");
+ return(blkcnt);
+}
+
+
+/* Probe to see if a new device is actually a Storage device */
+int usb_storage_probe(struct usb_device *dev, unsigned int ifnum,struct us_data *ss)
+{
+ struct usb_interface_descriptor *iface;
+ int i;
+ unsigned int flags = 0;
+
+ int protocol = 0;
+ int subclass = 0;
+
+
+ memset(ss, 0, sizeof(struct us_data));
+
+ /* let's examine the device now */
+ iface = &dev->config.if_desc[ifnum];
+
+#if 0
+ /* this is the place to patch some storage devices */
+ USB_STOR_PRINTF("iVendor %X iProduct %X\n",dev->descriptor.idVendor,dev->descriptor.idProduct);
+ if ((dev->descriptor.idVendor) == 0x066b && (dev->descriptor.idProduct) == 0x0103) {
+ USB_STOR_PRINTF("patched for E-USB\n");
+ protocol = US_PR_CB;
+ subclass = US_SC_UFI; /* an assumption */
+ }
+#endif
+
+ if (dev->descriptor.bDeviceClass != 0 ||
+ iface->bInterfaceClass != USB_CLASS_MASS_STORAGE ||
+ iface->bInterfaceSubClass < US_SC_MIN ||
+ iface->bInterfaceSubClass > US_SC_MAX) {
+ /* if it's not a mass storage, we go no further */
+ return 0;
+ }
+
+ /* At this point, we know we've got a live one */
+ USB_STOR_PRINTF("\n\nUSB Mass Storage device detected\n");
+
+ /* Initialize the us_data structure with some useful info */
+ ss->flags = flags;
+ ss->ifnum = ifnum;
+ ss->pusb_dev = dev;
+ ss->attention_done = 0;
+
+ /* If the device has subclass and protocol, then use that. Otherwise,
+ * take data from the specific interface.
+ */
+ if (subclass) {
+ ss->subclass = subclass;
+ ss->protocol = protocol;
+ } else {
+ ss->subclass = iface->bInterfaceSubClass;
+ ss->protocol = iface->bInterfaceProtocol;
+ }
+
+ /* set the handler pointers based on the protocol */
+ USB_STOR_PRINTF("Transport: ");
+ switch (ss->protocol) {
+ case US_PR_CB:
+ USB_STOR_PRINTF("Control/Bulk\n");
+ ss->transport = usb_stor_CB_transport;
+ ss->transport_reset = usb_stor_CB_reset;
+ break;
+
+ case US_PR_CBI:
+ USB_STOR_PRINTF("Control/Bulk/Interrupt\n");
+ ss->transport = usb_stor_CB_transport;
+ ss->transport_reset = usb_stor_CB_reset;
+ break;
+ default:
+ printf("USB Starage Transport unknown / not yet implemented\n");
+ return 0;
+ break;
+ }
+
+ /*
+ * We are expecting a minimum of 2 endpoints - in and out (bulk).
+ * An optional interrupt is OK (necessary for CBI protocol).
+ * We will ignore any others.
+ */
+ for (i = 0; i < iface->bNumEndpoints; i++) {
+ /* is it an BULK endpoint? */
+ if ((iface->ep_desc[i].bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
+ == USB_ENDPOINT_XFER_BULK) {
+ if (iface->ep_desc[i].bEndpointAddress & USB_DIR_IN)
+ ss->ep_in = iface->ep_desc[i].bEndpointAddress &
+ USB_ENDPOINT_NUMBER_MASK;
+ else
+ ss->ep_out = iface->ep_desc[i].bEndpointAddress &
+ USB_ENDPOINT_NUMBER_MASK;
+ }
+
+ /* is it an interrupt endpoint? */
+ if ((iface->ep_desc[i].bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
+ == USB_ENDPOINT_XFER_INT) {
+ ss->ep_int = iface->ep_desc[i].bEndpointAddress &
+ USB_ENDPOINT_NUMBER_MASK;
+ ss->irqinterval = iface->ep_desc[i].bInterval;
+ }
+ }
+ USB_STOR_PRINTF("Endpoints In %d Out %d Int %d\n",
+ ss->ep_in, ss->ep_out, ss->ep_int);
+
+ /* Do some basic sanity checks, and bail if we find a problem */
+ if (usb_set_interface(dev, iface->bInterfaceNumber, 0) ||
+ !ss->ep_in || !ss->ep_out ||
+ (ss->protocol == US_PR_CBI && ss->ep_int == 0)) {
+ USB_STOR_PRINTF("Problems with device\n");
+ return 0;
+ }
+ /* set class specific stuff */
+ /* We only handle certain protocols. Currently, this is
+ * the only one.
+ */
+ if (ss->subclass != US_SC_UFI) {
+ printf("Sorry, protocol %d not yet supported.\n",ss->subclass);
+ return 0;
+ }
+ if(ss->ep_int) /* we had found an interrupt endpoint, prepare irq pipe */
+ {
+ /* set up the IRQ pipe and handler */
+
+ ss->irqinterval = (ss->irqinterval > 0) ? ss->irqinterval : 255;
+ ss->irqpipe = usb_rcvintpipe(ss->pusb_dev, ss->ep_int);
+ ss->irqmaxp = usb_maxpacket(dev, ss->irqpipe);
+ dev->irq_handle=usb_stor_irq;
+ dev->privptr=(void *)ss;
+ }
+ return 1;
+}
+
+int usb_stor_get_info(struct usb_device *dev,struct us_data *ss,block_dev_desc_t *dev_desc)
+{
+ unsigned char perq,modi;
+ unsigned long cap[2];
+ unsigned long *capacity,*blksz;
+ ccb *pccb=&usb_ccb;
+
+ ss->transport_reset(ss);
+ pccb->pdata=usb_stor_buf;
+
+ dev_desc->target=dev->devnum;
+ pccb->lun=dev_desc->lun;
+ USB_STOR_PRINTF(" address %d\n",dev_desc->target);
+
+ if(usb_inquiry(pccb,ss))
+ return -1;
+ perq=usb_stor_buf[0];
+ modi=usb_stor_buf[1];
+ if((perq & 0x1f)==0x1f) {
+ return 0; /* skip unknown devices */
+ }
+ if((modi&0x80)==0x80) {/* drive is removable */
+ dev_desc->removable=1;
+ }
+ memcpy(&dev_desc->vendor[0], &usb_stor_buf[8], 8);
+ memcpy(&dev_desc->product[0], &usb_stor_buf[16], 16);
+ memcpy(&dev_desc->revision[0], &usb_stor_buf[32], 4);
+ dev_desc->vendor[8]=0;
+ dev_desc->product[16]=0;
+ dev_desc->revision[4]=0;
+ USB_STOR_PRINTF("ISO Vers %X, Response Data %X\n",usb_stor_buf[2],usb_stor_buf[3]);
+ if(usb_test_unit_ready(pccb,ss)) {
+ printf("Device NOT ready\n Request Sense returned %02X %02X %02X\n",pccb->sense_buf[2],pccb->sense_buf[12],pccb->sense_buf[13]);
+ if(dev_desc->removable==1) {
+ dev_desc->type=perq;
+ return 1;
+ }
+ else
+ return 0;
+ }
+ pccb->pdata=(unsigned char *)&cap[0];
+ memset(pccb->pdata,0,8);
+ if(usb_read_capacity(pccb,ss)!=0) {
+ printf("READ_CAP ERROR\n");
+ cap[0]=2880;
+ cap[1]=0x200;
+ }
+ USB_STOR_PRINTF("Read Capacity returns: 0x%lx, 0x%lx\n",cap[0],cap[1]);
+#if 0
+ if(cap[0]>(0x200000 * 10)) /* greater than 10 GByte */
+ cap[0]>>=16;
+#endif
+ cap[0]+=1;
+ capacity=&cap[0];
+ blksz=&cap[1];
+ USB_STOR_PRINTF("Capacity = 0x%lx, blocksz = 0x%lx\n",*capacity,*blksz);
+ dev_desc->lba=*capacity;
+ dev_desc->blksz=*blksz;
+ dev_desc->type=perq;
+ USB_STOR_PRINTF(" address %d\n",dev_desc->target);
+ USB_STOR_PRINTF("partype: %d\n",dev_desc->part_type);
+
+ init_part(dev_desc);
+
+ USB_STOR_PRINTF("partype: %d\n",dev_desc->part_type);
+ return 1;
+}
+
+#endif
+#endif /* CONFIG_USB_STORAGE */
+
+
+
#include <405gp_pci.h>
#include <asm/processor.h>
-#ifndef CONFIG_PIP405
+#if !(defined(CONFIG_PIP405) || defined (CONFIG_MIP405))
void pciinfo(int bus_no);
int bytes_transfered;
int result;
int status;
- int i, TimeReady, TimeOut;
+ int i, TimeReady;
ulong freqOPB,freqProc;
+ ulong TimeOut; /* _must_ be unsigned long for fast speeds */
result = IIC_OK;
bytes_transfered = 0;
/* IIC time out => wait for TimeOut cycles */
/* TimeOut /= 2; because waiting-loop is 2-instruction loop */
- TimeOut = freqProc*IIC_TIMEOUT*10;
- TimeOut /= 2;
+ /* Take care we get no overflow (266MHz = 0x0FDAD680) first divide */
+ TimeOut = freqProc/2;
+ TimeOut *= IIC_TIMEOUT*10;
while ((bytes_transfered < size_to_transfer) && (result == IIC_OK))
{
#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)
+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");
+ puts ("not available\n");
return;
}
- if(dev_desc->if_type==IF_TYPE_SCSI) {
+ 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) {
+ 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,
dev_desc->revision);
}
- printf(" Type: ");
- if(dev_desc->removable)
- printf ("Removable ");
- switch(dev_desc->type & 0x1F) {
- case DEV_TYPE_HARDDISK: printf("Hard Disk");
+ puts (" Type: ");
+ if (dev_desc->removable)
+ puts ("Removable ");
+ switch (dev_desc->type & 0x1F) {
+ case DEV_TYPE_HARDDISK: puts ("Hard Disk");
break;
- case DEV_TYPE_CDROM: printf("CD ROM");
+ case DEV_TYPE_CDROM: puts ("CD ROM");
break;
- case DEV_TYPE_OPDISK: printf("Optical Device");
+ case DEV_TYPE_OPDISK: puts ("Optical Device");
break;
- case DEV_TYPE_TAPE: printf("Tape");
+ case DEV_TYPE_TAPE: puts ("Tape");
break;
- default: printf("# %02X #", dev_desc->type & 0x1F);
+ 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 */
+ puts ("\n");
+ if ((dev_desc->lba * dev_desc->blksz)>0L) {
+ ulong mb, mb_quot, mb_rem, gb, gb_quot, gb_rem;
+
+ lba512 = (dev_desc->lba * (dev_desc->blksz/512));
+
+ mb = (10 * lba512) / 2048; /* 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;
+ mb_quot = mb / 10;
+ mb_rem = mb - (10 * mb_quot);
+
+ gb = mb / 1024;
+ gb_quot = gb / 10;
+ gb_rem = gb - (10 * gb_quot);
+
printf (" Capacity: %ld.%ld MB = %ld.%ld GB (%ld x %ld)\n",
- mb.quot, mb.rem,
- gb.quot, gb.rem,
+ mb_quot, mb_rem,
+ gb_quot, gb_rem,
dev_desc->lba,
dev_desc->blksz);
- }
- else {
- printf (" Capacity: not available\n");
+ } else {
+ puts (" Capacity: not available\n");
}
}
}
-int get_partition_info(block_dev_desc_t *dev_desc, int part, disk_partition_t *info)
+int get_partition_info (block_dev_desc_t *dev_desc, int part, disk_partition_t *info)
{
- switch(dev_desc->part_type) {
+ switch (dev_desc->part_type) {
#ifdef CONFIG_MAC_PARTITION
case PART_TYPE_MAC:
if (get_partition_info_mac(dev_desc,part,info) == 0) {
static void print_part_header (const char *type, block_dev_desc_t * dev_desc)
{
- printf ("\nPartition Map for ");
- switch(dev_desc->if_type) {
- case IF_TYPE_IDE: printf("IDE");
+ puts ("\nPartition Map for ");
+ switch (dev_desc->if_type) {
+ case IF_TYPE_IDE: puts ("IDE");
break;
- case IF_TYPE_SCSI: printf("SCSI");
+ case IF_TYPE_SCSI: puts ("SCSI");
break;
- case IF_TYPE_ATAPI: printf("ATAPI");
+ case IF_TYPE_ATAPI: puts ("ATAPI");
break;
- default: printf("UNKNOWN");
+ default: puts ("UNKNOWN");
break;
}
- printf(" device %d -- Partition Type: %s\n\n",
+ printf (" device %d -- Partition Type: %s\n\n",
dev_desc->dev, type);
}
void print_part (block_dev_desc_t * dev_desc)
{
- switch(dev_desc->part_type) {
+ switch (dev_desc->part_type) {
#ifdef CONFIG_MAC_PARTITION
case PART_TYPE_MAC:
PRINTF ("## Testing for valid MAC partition ##\n");
return;
#endif
}
- printf ("## Unknown partition table\n");
+ puts ("## Unknown partition table\n");
}
stack 5
step 4
tftpboot 4
+usbboot 5
+usb 4
version 4
? 1
--- /dev/null
+/*
+ * (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
+ *
+ */
+
+USB Support for PIP405 and MIP405 (UHCI)
+========================================
+
+The USB support is implemented on the base of the UHCI Host
+controller.
+
+Currently supported are USB Hubs, USB Keyboards and USB Floppys.
+Tested with a TEAC Floppy TEAC FD-05PUB and Chicony KU-8933 Keyboard.
+
+How it works:
+-------------
+
+The USB (at least the USB UHCI) needs a frame list (4k), transfer
+descripor and queue headers which are all located in the main memory.
+The UHCI allocates every milisecond the PCI bus and reads the current
+frame pointer. This may cause to crash the OS during boot. So the USB
+_MUST_ be stopped during OS boot. This is the reason, why the USB is
+NOT automatically started during start-up. If someone needs the USB
+he has to start it and should therefore be aware that he had to stop
+it before booting the OS.
+
+For USB keyboards this can be done by a script which is automatically
+started after the ppcboot is up and running. To boot an OS with a an
+USB keyboard another script is necessary, which first disables the
+USB and then executes the boot command. If the boot command fails,
+the script can reenable the USB kbd.
+
+Common USB Commands:
+- usb start:
+- usb reset: (re)starts the USB. All USB devices will be
+ initialized and a device tree is build for them.
+- usb tree: shows all USB devices in a tree like display
+- usb info [dev]: shows all USB infos of the device dev, or of all
+ the devices
+- usb stop [f]: stops the USB. If f==1 the USB will also stop if
+ an USB keyboard is assigned as stdin. The stdin
+ is then switched to serial input.
+Storage USB Commands:
+- usb scan: scans the USB for storage devices.The USB must be
+ running for this command (usb start)
+- usb device [dev]: show or set current USB staorage device
+- usb part [dev]: print partition table of one or all USB storage
+ devices
+- usb read addr blk# cnt:
+ read `cnt' blocks starting at block `blk#'to
+ memory address `addr'
+- usbboot addr dev:part:
+ boot from USB device
+
+Config Switches:
+----------------
+CFG_CMD_USB enables basic USB support and the usb command
+CONFIG_USB_UHCI defines the lowlevel part.A lowlevel part must be defined if
+ using CFG_CMD_USB
+CONFIG_USB_KEYBOARD enables the USB Keyboard
+CONFIG_USB_STORAGE enables the USB storage devices
#endif /* CONFIG_PIP405 */
/* ----------------------------------------------------------------------------*/
+/* ----- MIP405 -----------------------------------------------------------------
+ */
+#if defined(CONFIG_MIP405)
+
+#define CMD_TBL_BSP MK_CMD_TBL_ENTRY( \
+ "mip405", 4, 6, 1, do_mip405, \
+ "mip405 - MIP405 specific Cmds\n", \
+ "flash mem [SrcAddr] - updates PPCBOOT with image in memory\n" \
+ "mip405 flash mps - updates PPCBOOT with image from MPS\n" \
+),
+int do_mip405 (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]);
+
+#endif /* CONFIG_MIP405 */
+/* ----------------------------------------------------------------------------*/
/* ----- DASA_SIM ---------------------------------------------------------------
*/
#define CFG_CMD_ELF 0x0000000100000000 /* ELF (VxWorks) load/boot cmd */
#define CFG_CMD_MISC 0x0000000200000000 /* Misc functions like sleep etc*/
+#define CFG_CMD_USB 0x0000000400000000 /* USB Support */
#define CFG_CMD_ALL 0xFFFFFFFFFFFFFFFF /* ALL commands */
CFG_CMD_DATE | \
CFG_CMD_BEDBUG | \
CFG_CMD_ELF | \
+ CFG_CMD_USB | \
CFG_CMD_MII | \
CFG_CMD_BSP )
--- /dev/null
+/*
+ * (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_USB_H
+#define _CMD_USB_H
+
+#include <ppcboot.h>
+#include <command.h>
+
+
+#if (CONFIG_COMMANDS & CFG_CMD_USB)
+
+#ifdef CONFIG_USB_STORAGE
+#define CMD_TBL_USB MK_CMD_TBL_ENTRY( \
+ "usb", 4, 5, 1, do_usb, \
+ "usb - USB sub-system\n", \
+ "reset - reset (rescan) USB controller\n" \
+ "usb stop [f] - stop USB [f]=force stop\n" \
+ "usb tree - show USB device tree\n" \
+ "usb info [dev] - show available USB devices\n" \
+ "usb scan - (re-)scan USB bus for storage devices\n" \
+ "usb device [dev] - show or set current USB staorage device\n" \
+ "usb part [dev] - print partition table of one or all USB storage devices\n" \
+ "usb read addr blk# cnt - read `cnt' blocks starting at block `blk#'\n"\
+ " to memory address `addr'\n" \
+),
+
+
+#define CMD_TBL_USBBOOT MK_CMD_TBL_ENTRY( \
+ "usbboot", 5, 3, 1, do_usbboot, \
+ "usbboot - boot from USB device\n", \
+ "loadAddr dev:part\n" \
+),
+
+#else
+#define CMD_TBL_USB MK_CMD_TBL_ENTRY( \
+ "usb", 4, 5, 1, do_usb, \
+ "usb - USB sub-system\n", \
+ "reset - reset (rescan) USB controller\n" \
+ "usb tree - show USB device tree\n" \
+ "usb info [dev] - show available USB devices\n" \
+),
+
+#define CMD_TBL_USBBOOT
+#endif
+
+int do_usb (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]);
+int do_usbboot (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]);
+
+
+#else
+#define CMD_TBL_USB
+#define CMD_TBL_USBBOOT
+#endif
+
+#endif /* _CMD_SCSI_H */
+
& ~CFG_CMD_MII \
& ~CFG_CMD_PCI \
& ~CFG_CMD_PCMCIA \
+ & ~CFG_CMD_USB \
& ~CFG_CMD_SCSI )
#if CONFIG_LANTEC >= 2
--- /dev/null
+/*
+ * (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_405GP 1 /* This is a PPC405 CPU */
+#define CONFIG_4xx 1 /* ...member of PPC4xx family */
+#define CONFIG_MIP405 1 /* ...on a MIP405 board */
+/***********************************************************
+ * Clock
+ ***********************************************************/
+#define CONFIG_SYS_CLK_FREQ 33000000 /* external frequency to pll */
+
+/***********************************************************
+ * Command definitions
+ ***********************************************************/
+#define CONFIG_COMMANDS \
+ (CONFIG_CMD_DFL | \
+ CFG_CMD_IDE | \
+ CFG_CMD_DHCP | \
+ CFG_CMD_PCI | \
+ CFG_CMD_IRQ | \
+ CFG_CMD_EEPROM | \
+ CFG_CMD_I2C | \
+ CFG_CMD_REGINFO | \
+ CFG_CMD_DATE | \
+ CFG_CMD_ELF | \
+ CFG_CMD_USB | \
+ CFG_CMD_MII | \
+ CFG_CMD_BSP )
+
+/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
+#include <cmd_confdefs.h>
+
+#define CFG_HUSH_PARSER
+#define CFG_PROMPT_HUSH_PS2 "> "
+/**************************************************************
+ * 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_I2C405
+#define CONFIG_I2C
+#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 0x00000 /* environment starts at the beginning of the EEPROM */
+#define CFG_ENV_SIZE 0x00800 /* 2k 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
+#define CFG_CONSOLE_INFO_QUIET
+/***************************************************************
+ * 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 */
+
+#define CONFIG_MISC_INIT_R
+/***********************************************************
+ * 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_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 */
+
+#define CONFIG_BOARD_PRE_INIT
+
+/* On Chip Memory location */
+#define OCM_DATA_ADDR 0xF0000000
+
+/* Peripheral Bus Mapping */
+#define PER_PLD_ADDR 0xF4000000 /* smallest window is 1MByte 0x10 0000*/
+#define PER_UART0_ADDR 0xF4100000 /* smallest window is 1MByte 0x10 0000*/
+#define PER_UART1_ADDR 0xF4200000 /* smallest window is 1MByte 0x10 0000*/
+
+#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
+
+/***********************************************************************
+ * Last Stage Init
+ ***********************************************************************/
+#define CONFIG_LAST_STAGE_INIT
+/************************************************************
+ * Ethernet Stuff
+ ***********************************************************/
+#define CONFIG_MII 1 /* MII PHY management */
+#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
+ ************************************************************/
+#undef CONFIG_SCSI_SYM53C8XX
+
+#ifdef 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 */
+#endif /* CONFIG_SCSI_SYM53C8XX */
+/************************************************************
+ * DISK Partition support
+ ************************************************************/
+#define CONFIG_DOS_PARTITION
+#define CONFIG_MAC_PARTITION
+#define CONFIG_ISO_PARTITION /* Experimental */
+
+/************************************************************
+ * Keyboard support
+ ************************************************************/
+#undef CONFIG_ISA_KEYBOARD
+
+/************************************************************
+ * Video support
+ ************************************************************/
+#undef CONFIG_VIDEO /*To enable video controller support */
+#undef CONFIG_VIDEO_CT69000
+
+/************************************************************
+ * USB support EXPERIMENTAL
+ ************************************************************/
+#define CONFIG_USB_UHCI
+#define CONFIG_USB_KEYBOARD
+#define CONFIG_USB_STORAGE
+
+/* Enable needed helper functions */
+#define CFG_DEVICE_DEREGISTER /* needs device_deregister */
+
+/************************************************************
+ * 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_1_1"
+#define CONFIG_IDENT_STRING "\n(c) 2001 by MPL AG Switzerland, MEV-10072-001 " VERSION_TAG
+
+
+#endif /* __CONFIG_H */
CFG_CMD_EEPROM | \
CFG_CMD_FDC | \
CFG_CMD_IDE | \
+ CFG_CMD_USB | \
CFG_CMD_KGDB | \
CFG_CMD_MII | \
CFG_CMD_PCI | \
* 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 )
-
+ (CONFIG_CMD_DFL | \
+ CFG_CMD_IDE | \
+ CFG_CMD_DHCP | \
+ CFG_CMD_PCI | \
+ CFG_CMD_IRQ | \
+ CFG_CMD_EEPROM | \
+ CFG_CMD_I2C | \
+ CFG_CMD_REGINFO | \
+ CFG_CMD_FDC | \
+ CFG_CMD_SCSI | \
+ CFG_CMD_DATE | \
+ CFG_CMD_ELF | \
+ CFG_CMD_USB | \
+ CFG_CMD_MII | \
+ CFG_CMD_BSP )
/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
#include <cmd_confdefs.h>
-
+#define CFG_HUSH_PARSER
+#define CFG_PROMPT_HUSH_PS2 "> "
/**************************************************************
* I2C Stuff:
* the PIP405 is equiped with an Atmel 24C128/256 EEPROM at address
- * 0x53.
+ * 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 CONFIG_I2C405
#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 */
+#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
+#define CONFIG_BOARD_PRE_INIT
/**************************************************************
* Environment definitions
**************************************************************/
/***************************************************************
* defines if the console is stored in the environment
- ***************************************************************/
-#define CFG_CONSOLE_IS_IN_ENV /* stdin, stdout and stderr are in evironment */
+ ***************************************************************/
+#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
-
+#define CFG_CONSOLE_INFO_QUIET
/***************************************************************
* defines if the overwrite_console should be stored in the
* environment
/*
* Init Memory Controller:
- */
+ */
#define FLASH_BASE0_PRELIM 0xFFC00000 /* FLASH bank #0 */
#define FLASH_BASE1_PRELIM 0 /* FLASH bank #1 */
***********************************************************************/
#define CFG_ISA_IO_BASE_ADDRESS 0xE8000000
-
+/***********************************************************************
+ * Last Stage Init
+ ***********************************************************************/
+#define CONFIG_LAST_STAGE_INIT
/************************************************************
* Ethernet Stuff
***********************************************************/
#define CFG_SCSI_MAX_DEVICE CFG_SCSI_MAX_SCSI_ID * CFG_SCSI_MAX_LUN /* maximum Target devices */
/************************************************************
- * DISK Partition support
+ * DISK Partition support
************************************************************/
-#define CONFIG_DOS_PARTITION
-#define CONFIG_MAC_PARTITION
+#define CONFIG_DOS_PARTITION
+#define CONFIG_MAC_PARTITION
#define CONFIG_ISO_PARTITION /* Experimental */
/************************************************************
- * Keyboard support
+ * Keyboard support
************************************************************/
#define CONFIG_ISA_KEYBOARD
/************************************************************
- * Video support
+ * Video support
************************************************************/
#define CONFIG_VIDEO /*To enable video controller support */
#define CONFIG_VIDEO_CT69000
/************************************************************
- * Debug support
+ * USB support
+ ************************************************************/
+#define CONFIG_USB_UHCI
+#define CONFIG_USB_KEYBOARD
+#define CONFIG_USB_STORAGE
+
+/* Enable needed helper functions */
+#define CFG_DEVICE_DEREGISTER /* needs device_deregister */
+
+/************************************************************
+ * Debug support
************************************************************/
#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
#define CONFIG_KGDB_BAUDRATE 230400 /* speed to run kgdb serial port */
#endif
/************************************************************
- * Ident
+ * Ident
************************************************************/
-#define VERSION_TAG "REL_1.0.0"
-#define CONFIG_IDENT_STRING "\n(c) 2001 by MPL AG Switzerland, MEV-10066-001 " VERSION_TAG
+#define VERSION_TAG "REL_1_1_1"
+#define CONFIG_IDENT_STRING "\n(c) 2001 by MPL AG Switzerland, MEV-10066-001 " VERSION_TAG
#endif /* __CONFIG_H */
CFG_CMD_MII | \
CFG_CMD_PCMCIA | \
CFG_CMD_PCI | \
+ CFG_CMD_USB | \
CFG_CMD_SCSI ) )
/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
int device_register (device_t * dev);
int devices_init (bd_t *, ulong);
int devices_done (void);
+int device_deregister(char *devname);
#ifdef CONFIG_LCD
int drv_lcd_init (bd_t *);
#endif
#ifdef CONFIG_WL_4PPM_KEYBOARD
int drv_wlkbd_init (void);
#endif
-#ifdef CONFIG_ISA_KEYBOARD
-int drv_isa_kbd_init (void);
-#endif
#endif /* _DEVICES_H_ */
int ListInsertItems(list_t list, void *ptrToItems, int firstItemPosition, int numItemsToInsert);
void ListDispose(list_t list);
void *ListGetPtrToItem(list_t list, int itemPosition);
+void ListRemoveItem(list_t list, void *itemDestination, int itemPosition);
+void ListRemoveItems(list_t list, void *itemsDestination, int firstItemPosition, int numItemsToRemove);
/*
-
void ListDisposePtrList(list_t list);
void ListGetItem(list_t list, void *itemDestination, int itemPosition);
void ListReplaceItem(list_t list, void *ptrToItem, int itemPosition);
int checkflash (void);
int checkdram (void);
char * strmhz(char *buf, long hz);
+#ifdef CONFIG_LAST_STAGE_INIT
+int last_stage_init(void);
+#endif
/* common/cmd_bootm.c */
void print_image_hdr (image_header_t *hdr);
defined(CONFIG_AR405) || \
defined (CONFIG_WALNUT405) || \
defined (CONFIG_PIP405) || \
+ defined (CONFIG_MIP405) || \
defined (CONFIG_CPCIISER4) || \
defined (CONFIG_OCRTC) || \
defined (CONFIG_DASA_SIM) || \
defined(CONFIG_OCRTC) || \
defined(CONFIG_PCU_E) || \
defined(CONFIG_PIP405) || \
+ defined(CONFIG_MIP405) || \
defined(CONFIG_PM826) || \
defined(CONFIG_SXNI855T) || \
defined(CONFIG_TQM8260) || \
defined(CONFIG_CANBT) || \
defined(CONFIG_WALNUT405) || \
defined(CONFIG_PIP405) || \
+ defined(CONFIG_MIP405) || \
defined(CONFIG_CPCIISER4) || \
defined(CONFIG_OCRTC) || \
defined(CONFIG_ADCIOP) || \
--- /dev/null
+/*
+ * (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: Part of this code has been derived from linux
+ *
+ */
+#ifndef _USB_H_
+#define _USB_H_
+
+#include <usb_defs.h>
+
+/* Everything is aribtrary */
+#define USB_ALTSETTINGALLOC 4
+#define USB_MAXALTSETTING 128 /* Hard limit */
+
+#define USB_MAX_DEVICE 32
+#define USB_MAXCONFIG 8
+#define USB_MAXINTERFACES 8
+#define USB_MAXENDPOINTS 16
+#define USB_MAXCHILDREN 8 /* This is arbitrary */
+#define USB_MAX_HUB 16
+
+#define USB_CNTL_TIMEOUT 100 /* 100ms timeout */
+
+
+/* String descriptor */
+struct usb_string_descriptor {
+ unsigned char bLength;
+ unsigned char bDescriptorType;
+ unsigned short wData[1];
+} __attribute__ ((packed));
+
+/* device request (setup) */
+struct devrequest {
+ unsigned char requesttype;
+ unsigned char request;
+ unsigned short value;
+ unsigned short index;
+ unsigned short length;
+} __attribute__ ((packed));
+
+
+
+/* All standard descriptors have these 2 fields in common */
+struct usb_descriptor_header {
+ unsigned char bLength;
+ unsigned char bDescriptorType;
+} __attribute__ ((packed));
+
+/* Device descriptor */
+struct usb_device_descriptor {
+ unsigned char bLength;
+ unsigned char bDescriptorType;
+ unsigned short bcdUSB;
+ unsigned char bDeviceClass;
+ unsigned char bDeviceSubClass;
+ unsigned char bDeviceProtocol;
+ unsigned char bMaxPacketSize0;
+ unsigned short idVendor;
+ unsigned short idProduct;
+ unsigned short bcdDevice;
+ unsigned char iManufacturer;
+ unsigned char iProduct;
+ unsigned char iSerialNumber;
+ unsigned char bNumConfigurations;
+} __attribute__ ((packed));
+
+
+/* Endpoint descriptor */
+struct usb_endpoint_descriptor {
+ unsigned char bLength;
+ unsigned char bDescriptorType;
+ unsigned char bEndpointAddress;
+ unsigned char bmAttributes;
+ unsigned short wMaxPacketSize;
+ unsigned char bInterval;
+ unsigned char bRefresh;
+ unsigned char bSynchAddress;
+
+} __attribute__ ((packed));
+/* Interface descriptor */
+struct usb_interface_descriptor {
+ unsigned char bLength;
+ unsigned char bDescriptorType;
+ unsigned char bInterfaceNumber;
+ unsigned char bAlternateSetting;
+ unsigned char bNumEndpoints;
+ unsigned char bInterfaceClass;
+ unsigned char bInterfaceSubClass;
+ unsigned char bInterfaceProtocol;
+ unsigned char iInterface;
+
+ unsigned char no_of_ep;
+ unsigned char act_altsetting;
+ struct usb_endpoint_descriptor ep_desc[USB_MAXENDPOINTS];
+} __attribute__ ((packed));
+
+
+/* Configuration descriptor information.. */
+struct usb_config_descriptor {
+ unsigned char bLength;
+ unsigned char bDescriptorType;
+ unsigned short wTotalLength;
+ unsigned char bNumInterfaces;
+ unsigned char bConfigurationValue;
+ unsigned char iConfiguration;
+ unsigned char bmAttributes;
+ unsigned char MaxPower;
+
+ unsigned char no_of_if; /* number of interfaces */
+ struct usb_interface_descriptor if_desc[USB_MAXINTERFACES];
+} __attribute__ ((packed));
+
+
+struct usb_device {
+ int devnum; /* Device number on USB bus */
+ int slow; /* Slow device? */
+ char mf[32]; /* manufacturer */
+ char prod[32]; /* product */
+ char serial[32]; /* serial number */
+
+ int maxpacketsize; /* Maximum packet size; encoded as 0,1,2,3 = 8,16,32,64 */
+ unsigned int toggle[2]; /* one bit for each endpoint ([0] = IN, [1] = OUT) */
+ unsigned int halted[2]; /* endpoint halts; one bit per endpoint # & direction; */
+ /* [0] = IN, [1] = OUT */
+ int epmaxpacketin[16]; /* INput endpoint specific maximums */
+ int epmaxpacketout[16]; /* OUTput endpoint specific maximums */
+
+ int configno; /* selected config number */
+ struct usb_device_descriptor descriptor; /* Device Descriptor */
+ struct usb_config_descriptor config; /* config descriptor */
+
+ int have_langid; /* whether string_langid is valid yet */
+ int string_langid; /* language ID for strings */
+ int (*irq_handle)(struct usb_device *dev);
+ unsigned long irq_status;
+ int irq_act_len; /* transfered bytes */
+ void *privptr;
+ /*
+ * Child devices - if this is a hub device
+ * Each instance needs its own set of data structures.
+ */
+ unsigned long status;
+ int act_len; /* transfered bytes */
+ int maxchild; /* Number of ports if hub */
+ struct usb_device *parent;
+ struct usb_device *children[USB_MAXCHILDREN];
+};
+
+/**********************************************************************
+ * this is how the lowlevel part communicate with the outer world
+ */
+
+#ifdef CONFIG_USB_UHCI
+int usb_lowlevel_init(void);
+int usb_lowlevel_stop(void);
+int submit_bulk_msg(struct usb_device *dev, unsigned long pipe, void *buffer,int transfer_len);
+int submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
+ int transfer_len,struct devrequest *setup);
+int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
+ int transfer_len, int interval);
+
+/* Defines */
+#define USB_UHCI_VEND_ID 0x8086
+#define USB_UHCI_DEV_ID 0x7112
+
+#else
+#error USB Lowlevel not defined
+#endif
+
+#ifdef CONFIG_USB_STORAGE
+
+#define USB_MAX_STOR_DEV 5
+block_dev_desc_t *usb_stor_get_dev(int index);
+int usb_stor_scan(int mode);
+
+#endif
+
+#ifdef CONFIG_USB_KEYBOARD
+
+int drv_usb_kbd_init(void);
+int usb_kbd_deregister(void);
+
+#endif
+/* routines */
+int usb_init(void); /* initialize the USB Controller */
+int usb_stop(void); /* stop the USB Controller */
+
+
+int usb_set_protocol(struct usb_device *dev, int ifnum, int protocol);
+int usb_set_idle(struct usb_device *dev, int ifnum, int duration, int report_id);
+struct usb_device * usb_get_dev_index(int index);
+int usb_control_msg(struct usb_device *dev, unsigned int pipe,
+ unsigned char request, unsigned char requesttype,
+ unsigned short value, unsigned short index,
+ void *data, unsigned short size, int timeout);
+int usb_bulk_msg(struct usb_device *dev, unsigned int pipe,
+ void *data, int len, int *actual_length, int timeout);
+int usb_submit_int_msg(struct usb_device *dev, unsigned long pipe,
+ void *buffer,int transfer_len, int interval);
+void usb_disable_asynch(int disable);
+int usb_maxpacket(struct usb_device *dev,unsigned long pipe);
+void __inline__ wait_ms(unsigned long ms);
+int usb_get_configuration_no(struct usb_device *dev,unsigned char *buffer,int cfgno);
+int usb_get_report(struct usb_device *dev, int ifnum, unsigned char type, unsigned char id, void *buf, int size);
+int usb_get_class_descriptor(struct usb_device *dev, int ifnum,
+ unsigned char type, unsigned char id, void *buf, int size);
+int usb_clear_halt(struct usb_device *dev, int pipe);
+int usb_string(struct usb_device *dev, int index, char *buf, size_t size);
+int usb_set_interface(struct usb_device *dev, int interface, int alternate);
+
+/* big endian -> little endian conversion */
+#define swap_16(x) \
+ ((unsigned short)( \
+ (((unsigned short)(x) & (unsigned short)0x00ffU) << 8) | \
+ (((unsigned short)(x) & (unsigned short)0xff00U) >> 8) ))
+#define swap_32(x) \
+ ((unsigned long)( \
+ (((unsigned long)(x) & (unsigned long)0x000000ffUL) << 24) | \
+ (((unsigned long)(x) & (unsigned long)0x0000ff00UL) << 8) | \
+ (((unsigned long)(x) & (unsigned long)0x00ff0000UL) >> 8) | \
+ (((unsigned long)(x) & (unsigned long)0xff000000UL) >> 24) ))
+
+/*
+ * Calling this entity a "pipe" is glorifying it. A USB pipe
+ * is something embarrassingly simple: it basically consists
+ * of the following information:
+ * - device number (7 bits)
+ * - endpoint number (4 bits)
+ * - current Data0/1 state (1 bit)
+ * - direction (1 bit)
+ * - speed (1 bit)
+ * - max packet size (2 bits: 8, 16, 32 or 64)
+ * - pipe type (2 bits: control, interrupt, bulk, isochronous)
+ *
+ * That's 18 bits. Really. Nothing more. And the USB people have
+ * documented these eighteen bits as some kind of glorious
+ * virtual data structure.
+ *
+ * Let's not fall in that trap. We'll just encode it as a simple
+ * unsigned int. The encoding is:
+ *
+ * - max size: bits 0-1 (00 = 8, 01 = 16, 10 = 32, 11 = 64)
+ * - direction: bit 7 (0 = Host-to-Device [Out], 1 = Device-to-Host [In])
+ * - device: bits 8-14
+ * - endpoint: bits 15-18
+ * - Data0/1: bit 19
+ * - speed: bit 26 (0 = Full, 1 = Low Speed)
+ * - pipe type: bits 30-31 (00 = isochronous, 01 = interrupt, 10 = control, 11 = bulk)
+ *
+ * Why? Because it's arbitrary, and whatever encoding we select is really
+ * up to us. This one happens to share a lot of bit positions with the UHCI
+ * specification, so that much of the uhci driver can just mask the bits
+ * appropriately.
+ */
+/* Create various pipes... */
+#define create_pipe(dev,endpoint) \
+ (((dev)->devnum << 8) | (endpoint << 15) | ((dev)->slow << 26) | (dev)->maxpacketsize)
+#define default_pipe(dev) ((dev)->slow <<26)
+
+#define usb_sndctrlpipe(dev,endpoint) ((PIPE_CONTROL << 30) | create_pipe(dev,endpoint))
+#define usb_rcvctrlpipe(dev,endpoint) ((PIPE_CONTROL << 30) | create_pipe(dev,endpoint) | USB_DIR_IN)
+#define usb_sndisocpipe(dev,endpoint) ((PIPE_ISOCHRONOUS << 30) | create_pipe(dev,endpoint))
+#define usb_rcvisocpipe(dev,endpoint) ((PIPE_ISOCHRONOUS << 30) | create_pipe(dev,endpoint) | USB_DIR_IN)
+#define usb_sndbulkpipe(dev,endpoint) ((PIPE_BULK << 30) | create_pipe(dev,endpoint))
+#define usb_rcvbulkpipe(dev,endpoint) ((PIPE_BULK << 30) | create_pipe(dev,endpoint) | USB_DIR_IN)
+#define usb_sndintpipe(dev,endpoint) ((PIPE_INTERRUPT << 30) | create_pipe(dev,endpoint))
+#define usb_rcvintpipe(dev,endpoint) ((PIPE_INTERRUPT << 30) | create_pipe(dev,endpoint) | USB_DIR_IN)
+#define usb_snddefctrl(dev) ((PIPE_CONTROL << 30) | default_pipe(dev))
+#define usb_rcvdefctrl(dev) ((PIPE_CONTROL << 30) | default_pipe(dev) | USB_DIR_IN)
+
+/* The D0/D1 toggle bits */
+#define usb_gettoggle(dev, ep, out) (((dev)->toggle[out] >> ep) & 1)
+#define usb_dotoggle(dev, ep, out) ((dev)->toggle[out] ^= (1 << ep))
+#define usb_settoggle(dev, ep, out, bit) ((dev)->toggle[out] = ((dev)->toggle[out] & ~(1 << ep)) | ((bit) << ep))
+
+/* Endpoint halt control/status */
+#define usb_endpoint_out(ep_dir) (((ep_dir >> 7) & 1) ^ 1)
+#define usb_endpoint_halt(dev, ep, out) ((dev)->halted[out] |= (1 << (ep)))
+#define usb_endpoint_running(dev, ep, out) ((dev)->halted[out] &= ~(1 << (ep)))
+#define usb_endpoint_halted(dev, ep, out) ((dev)->halted[out] & (1 << (ep)))
+
+#define usb_packetid(pipe) (((pipe) & USB_DIR_IN) ? USB_PID_IN : USB_PID_OUT)
+
+#define usb_pipeout(pipe) ((((pipe) >> 7) & 1) ^ 1)
+#define usb_pipein(pipe) (((pipe) >> 7) & 1)
+#define usb_pipedevice(pipe) (((pipe) >> 8) & 0x7f)
+#define usb_pipe_endpdev(pipe) (((pipe) >> 8) & 0x7ff)
+#define usb_pipeendpoint(pipe) (((pipe) >> 15) & 0xf)
+#define usb_pipedata(pipe) (((pipe) >> 19) & 1)
+#define usb_pipeslow(pipe) (((pipe) >> 26) & 1)
+#define usb_pipetype(pipe) (((pipe) >> 30) & 3)
+#define usb_pipeisoc(pipe) (usb_pipetype((pipe)) == PIPE_ISOCHRONOUS)
+#define usb_pipeint(pipe) (usb_pipetype((pipe)) == PIPE_INTERRUPT)
+#define usb_pipecontrol(pipe) (usb_pipetype((pipe)) == PIPE_CONTROL)
+#define usb_pipebulk(pipe) (usb_pipetype((pipe)) == PIPE_BULK)
+
+
+/*************************************************************************
+ * Hub Stuff
+ */
+struct usb_port_status {
+ unsigned short wPortStatus;
+ unsigned short wPortChange;
+} __attribute__ ((packed));
+
+struct usb_hub_status {
+ unsigned short wHubStatus;
+ unsigned short wHubChange;
+} __attribute__ ((packed));
+
+
+/* Hub descriptor */
+struct usb_hub_descriptor {
+ unsigned char bLength;
+ unsigned char bDescriptorType;
+ unsigned char bNbrPorts;
+ unsigned short wHubCharacteristics;
+ unsigned char bPwrOn2PwrGood;
+ unsigned char bHubContrCurrent;
+ unsigned char DeviceRemovable[(USB_MAXCHILDREN+1+7)/8];
+ unsigned char PortPowerCtrlMask[(USB_MAXCHILDREN+1+7)/8];
+ /* DeviceRemovable and PortPwrCtrlMask want to be variable-length
+ bitmaps that hold max 255 entries. (bit0 is ignored) */
+} __attribute__ ((packed));
+
+
+struct usb_hub_device {
+ struct usb_device *pusb_dev;
+ struct usb_hub_descriptor desc;
+};
+
+#endif /*_USB_H_ */
--- /dev/null
+/*
+ * (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: Part of this code has been derived from linux
+ *
+ */
+#ifndef _USB_DEFS_H_
+#define _USB_DEFS_H_
+
+
+/* Everything is aribtrary */
+#define USB_ALTSETTINGALLOC 4
+#define USB_MAXALTSETTING 128 /* Hard limit */
+
+#define USB_MAX_DEVICE 32
+#define USB_MAXCONFIG 8
+#define USB_MAXINTERFACES 8
+#define USB_MAXENDPOINTS 16
+#define USB_MAXCHILDREN 8 /* This is arbitrary */
+#define USB_MAX_HUB 16
+
+#define USB_CNTL_TIMEOUT 100 /* 100ms timeout */
+
+/* USB constants */
+
+/* Device and/or Interface Class codes */
+#define USB_CLASS_PER_INTERFACE 0 /* for DeviceClass */
+#define USB_CLASS_AUDIO 1
+#define USB_CLASS_COMM 2
+#define USB_CLASS_HID 3
+#define USB_CLASS_PRINTER 7
+#define USB_CLASS_MASS_STORAGE 8
+#define USB_CLASS_HUB 9
+#define USB_CLASS_DATA 10
+#define USB_CLASS_VENDOR_SPEC 0xff
+
+/* some HID sub classes */
+#define USB_SUB_HID_NONE 0
+#define USB_SUB_HID_BOOT 1
+
+/* some UID Protocols */
+#define USB_PROT_HID_NONE 0
+#define USB_PROT_HID_KEYBOARD 1
+#define USB_PROT_HID_MOUSE 2
+
+
+/* Sub STORAGE Classes */
+#define US_SC_RBC 1 /* Typically, flash devices */
+#define US_SC_8020 2 /* CD-ROM */
+#define US_SC_QIC 3 /* QIC-157 Tapes */
+#define US_SC_UFI 4 /* Floppy */
+#define US_SC_8070 5 /* Removable media */
+#define US_SC_SCSI 6 /* Transparent */
+#define US_SC_MIN US_SC_RBC
+#define US_SC_MAX US_SC_SCSI
+
+/* STORAGE Protocols */
+#define US_PR_CB 1 /* Control/Bulk w/o interrupt */
+#define US_PR_CBI 0 /* Control/Bulk/Interrupt */
+#define US_PR_BULK 0x50 /* bulk only */
+
+/* USB types */
+#define USB_TYPE_STANDARD (0x00 << 5)
+#define USB_TYPE_CLASS (0x01 << 5)
+#define USB_TYPE_VENDOR (0x02 << 5)
+#define USB_TYPE_RESERVED (0x03 << 5)
+
+/* USB recipients */
+#define USB_RECIP_DEVICE 0x00
+#define USB_RECIP_INTERFACE 0x01
+#define USB_RECIP_ENDPOINT 0x02
+#define USB_RECIP_OTHER 0x03
+
+/* USB directions */
+#define USB_DIR_OUT 0
+#define USB_DIR_IN 0x80
+
+/* Descriptor types */
+#define USB_DT_DEVICE 0x01
+#define USB_DT_CONFIG 0x02
+#define USB_DT_STRING 0x03
+#define USB_DT_INTERFACE 0x04
+#define USB_DT_ENDPOINT 0x05
+
+#define USB_DT_HID (USB_TYPE_CLASS | 0x01)
+#define USB_DT_REPORT (USB_TYPE_CLASS | 0x02)
+#define USB_DT_PHYSICAL (USB_TYPE_CLASS | 0x03)
+#define USB_DT_HUB (USB_TYPE_CLASS | 0x09)
+
+/* Descriptor sizes per descriptor type */
+#define USB_DT_DEVICE_SIZE 18
+#define USB_DT_CONFIG_SIZE 9
+#define USB_DT_INTERFACE_SIZE 9
+#define USB_DT_ENDPOINT_SIZE 7
+#define USB_DT_ENDPOINT_AUDIO_SIZE 9 /* Audio extension */
+#define USB_DT_HUB_NONVAR_SIZE 7
+#define USB_DT_HID_SIZE 9
+
+/* Endpoints */
+#define USB_ENDPOINT_NUMBER_MASK 0x0f /* in bEndpointAddress */
+#define USB_ENDPOINT_DIR_MASK 0x80
+
+#define USB_ENDPOINT_XFERTYPE_MASK 0x03 /* in bmAttributes */
+#define USB_ENDPOINT_XFER_CONTROL 0
+#define USB_ENDPOINT_XFER_ISOC 1
+#define USB_ENDPOINT_XFER_BULK 2
+#define USB_ENDPOINT_XFER_INT 3
+
+/* USB Packet IDs (PIDs) */
+#define USB_PID_UNDEF_0 0xf0
+#define USB_PID_OUT 0xe1
+#define USB_PID_ACK 0xd2
+#define USB_PID_DATA0 0xc3
+#define USB_PID_UNDEF_4 0xb4
+#define USB_PID_SOF 0xa5
+#define USB_PID_UNDEF_6 0x96
+#define USB_PID_UNDEF_7 0x87
+#define USB_PID_UNDEF_8 0x78
+#define USB_PID_IN 0x69
+#define USB_PID_NAK 0x5a
+#define USB_PID_DATA1 0x4b
+#define USB_PID_PREAMBLE 0x3c
+#define USB_PID_SETUP 0x2d
+#define USB_PID_STALL 0x1e
+#define USB_PID_UNDEF_F 0x0f
+
+/* Standard requests */
+#define USB_REQ_GET_STATUS 0x00
+#define USB_REQ_CLEAR_FEATURE 0x01
+#define USB_REQ_SET_FEATURE 0x03
+#define USB_REQ_SET_ADDRESS 0x05
+#define USB_REQ_GET_DESCRIPTOR 0x06
+#define USB_REQ_SET_DESCRIPTOR 0x07
+#define USB_REQ_GET_CONFIGURATION 0x08
+#define USB_REQ_SET_CONFIGURATION 0x09
+#define USB_REQ_GET_INTERFACE 0x0A
+#define USB_REQ_SET_INTERFACE 0x0B
+#define USB_REQ_SYNCH_FRAME 0x0C
+
+/* HID requests */
+#define USB_REQ_GET_REPORT 0x01
+#define USB_REQ_GET_IDLE 0x02
+#define USB_REQ_GET_PROTOCOL 0x03
+#define USB_REQ_SET_REPORT 0x09
+#define USB_REQ_SET_IDLE 0x0A
+#define USB_REQ_SET_PROTOCOL 0x0B
+
+
+/* "pipe" definitions */
+
+#define PIPE_ISOCHRONOUS 0
+#define PIPE_INTERRUPT 1
+#define PIPE_CONTROL 2
+#define PIPE_BULK 3
+#define PIPE_DEVEP_MASK 0x0007ff00
+
+#define USB_ISOCHRONOUS 0
+#define USB_INTERRUPT 1
+#define USB_CONTROL 2
+#define USB_BULK 3
+
+/* USB-status codes: */
+#define USB_ST_ACTIVE 0x1 /* TD is active */
+#define USB_ST_STALLED 0x2 /* TD is stalled */
+#define USB_ST_BUF_ERR 0x4 /* buffer error */
+#define USB_ST_BABBLE_DET 0x8 /* Babble detected */
+#define USB_ST_NAK_REC 0x10 /* NAK Received*/
+#define USB_ST_CRC_ERR 0x20 /* CRC/timeout Error */
+#define USB_ST_BIT_ERR 0x40 /* Bitstuff error */
+#define USB_ST_NOT_PROC 0x80000000L /* Not yet processed */
+
+
+
+/*************************************************************************
+ * Hub defines
+ */
+
+/*
+ * Hub request types
+ */
+
+#define USB_RT_HUB (USB_TYPE_CLASS | USB_RECIP_DEVICE)
+#define USB_RT_PORT (USB_TYPE_CLASS | USB_RECIP_OTHER)
+
+/*
+ * Hub Class feature numbers
+ */
+#define C_HUB_LOCAL_POWER 0
+#define C_HUB_OVER_CURRENT 1
+
+/*
+ * Port feature numbers
+ */
+#define USB_PORT_FEAT_CONNECTION 0
+#define USB_PORT_FEAT_ENABLE 1
+#define USB_PORT_FEAT_SUSPEND 2
+#define USB_PORT_FEAT_OVER_CURRENT 3
+#define USB_PORT_FEAT_RESET 4
+#define USB_PORT_FEAT_POWER 8
+#define USB_PORT_FEAT_LOWSPEED 9
+#define USB_PORT_FEAT_C_CONNECTION 16
+#define USB_PORT_FEAT_C_ENABLE 17
+#define USB_PORT_FEAT_C_SUSPEND 18
+#define USB_PORT_FEAT_C_OVER_CURRENT 19
+#define USB_PORT_FEAT_C_RESET 20
+
+/* wPortStatus bits */
+#define USB_PORT_STAT_CONNECTION 0x0001
+#define USB_PORT_STAT_ENABLE 0x0002
+#define USB_PORT_STAT_SUSPEND 0x0004
+#define USB_PORT_STAT_OVERCURRENT 0x0008
+#define USB_PORT_STAT_RESET 0x0010
+#define USB_PORT_STAT_POWER 0x0100
+#define USB_PORT_STAT_LOW_SPEED 0x0200
+
+/* wPortChange bits */
+#define USB_PORT_STAT_C_CONNECTION 0x0001
+#define USB_PORT_STAT_C_ENABLE 0x0002
+#define USB_PORT_STAT_C_SUSPEND 0x0004
+#define USB_PORT_STAT_C_OVERCURRENT 0x0008
+#define USB_PORT_STAT_C_RESET 0x0010
+
+/* wHubCharacteristics (masks) */
+#define HUB_CHAR_LPSM 0x0003
+#define HUB_CHAR_COMPOUND 0x0004
+#define HUB_CHAR_OCPM 0x0018
+
+/*
+ *Hub Status & Hub Change bit masks
+ */
+#define HUB_STATUS_LOCAL_POWER 0x0001
+#define HUB_STATUS_OVERCURRENT 0x0002
+
+#define HUB_CHANGE_LOCAL_POWER 0x0001
+#define HUB_CHANGE_OVERCURRENT 0x0002
+
+#endif /*_USB_DEFS_H_ */