From: wdenk Date: Thu, 5 Jul 2001 14:47:06 +0000 (+0000) Subject: * Added support for PIP405 board, see "doc/README.PIP405". X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=d414bdd4b4c52ee516d2ab820e9ad3ca44ebeebf;p=users%2Frw%2Fppcboot.git * Added support for PIP405 board, see "doc/README.PIP405". Supplied by Denis Peter, 4 Jul 2001 This includes: - SCSI Support (so far only for Symbios SYM53C810A chip) - Floppy Disk Support - CD-ROM Support - ISO Parttion Support (boot from El-Torito bootable ISO CD-ROM) - MC146818 RTC support - Chips & Technologies 69000 Video Chip Support - Standard (PC-Style) Keyboard Support - Added IH_OS_PPCBOOT and IH_TYPE_FIRMWARE to the image definitions to allow PPCBoot updates with CRC check. --- diff --git a/CHANGELOG b/CHANGELOG index de84b22..d63c19d 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -56,6 +56,22 @@ To do: Modifications for 1.0.2: ====================================================================== +* Added support for PIP405 board, see "doc/README.PIP405". + Supplied by Denis Peter, 4 Jul 2001 + This includes: + +- SCSI Support (so far only for Symbios SYM53C810A chip) +- Floppy Disk Support +- CD-ROM Support +- ISO Partition Support (boot from El-Torito bootable ISO CD-ROM) +- MC146818 RTC support +- Chips & Technologies 69000 Video Chip Support +- Standard (PC-Style) Keyboard Support +- Added IH_OS_PPCBOOT and IH_TYPE_FIRMWARE to the image definitions + to allow PPCBoot updates with CRC check. + +* Added keyboard support to LWMON board (uses special I2C keyboard) + * Fix bug in calculation of initrd size Patch by Hannes Fertala, 2 Jul 2001 diff --git a/CREDITS b/CREDITS index b19027e..7a13d7d 100644 --- a/CREDITS +++ b/CREDITS @@ -113,8 +113,12 @@ N: Frank Morauf E: frank.morauf@salzbrenner.com D: Support for Embedded Planet RPX Super Board +N: Denis Peter +E: d.peter@mpl.ch +D: Port to PIP405 board, support for SCSI, floppy, CDROM, CT69000 video, ... + N: Bill Pitts -D: wlp@mindspring.com +E: wlp@mindspring.com D: BedBug embedded debugger code N: Stefan Roese diff --git a/MAKEALL b/MAKEALL index c570100..dd5a9e1 100755 --- a/MAKEALL +++ b/MAKEALL @@ -36,6 +36,7 @@ LIST="$LIST \ CPCI405 CPCIISER4 \ WALNUT405 \ AR405 CANBT ADCIOP \ + PIP405 \ ERIC \ " diff --git a/Makefile b/Makefile index 8141511..a54e38b 100644 --- a/Makefile +++ b/Makefile @@ -318,6 +318,15 @@ WALNUT405_config:unconfig echo "CPU = ppc4xx" >>config.mk ; \ echo "#include " >config.h +PIP405_config:unconfig + @echo "Configuring for $(@:_config=) Board..." ; \ + cd include ; \ + echo "ARCH = ppc" > config.mk ; \ + echo "BOARD = pip405">>config.mk ; \ + echo "CPU = ppc4xx" >>config.mk ; \ + echo "#include " >config.h + + AR405_config: unconfig @echo "Configuring for $(@:_config=) Board..." ; \ cd include ; \ diff --git a/README b/README index e5cc7ef..a0e8dc8 100644 --- a/README +++ b/README @@ -95,22 +95,25 @@ Directory Hierarchy: - board/cpciiser4 Files specific to CPCIISER4 boards - board/cu824 Files specific to CU824 boards +- board/eric Files specific to ERIC boards - board/esteem192e Files specific to ESTEEM192E boards - board/etx094 Files specific to ETX_094 boards - board/evb64260 Files specific to EVB64260 boards - board/fads Files specific to FADS boards +- board/flagadm Files specific to FLAGADM boards - board/genietv Files specific to GENIETV boards - board/gth Files specific to GTH boards - board/hermes Files specific to HERMES boards - board/hymod Files specific to HYMOD boards - board/ip860 Files specific to IP860 boards -- board/ivms8 Files specific to IVMS8 boards +- board/ivms8 Files specific to IVMS8/IVML24 boards - board/lantec Files specific to LANTEC boards - board/lwmon Files specific to LWMON boards - board/mbx8xx Files specific to MBX boards - board/pcu_e Files specific to PCU_E boards +- board/pip405 Files specific to PIP405 boards - board/RPXlite Files specific to RPXlite boards - board/rpxsuper Files specific to RPXsuper boards @@ -122,6 +125,7 @@ Directory Hierarchy: - board/sixnet Files specific to SIXNET boards - board/spd8xx Files specific to SPD8xxTS boards +- board/tqm8260 Files specific to TQM8260 boards - board/tqm8xx Files specific to TQM8xxL boards - board/walnut405 Files specific to Walnut405 boards @@ -188,15 +192,18 @@ The following options need to be configured: or CONFIG_MPC74xx - Board Type: Define exactly one of - CONFIG_ADCIOP, CONFIG_COGENT, CONFIG_CPCI405, CONFIG_ETX094, - CONFIG_FADS, CONFIG_FPS850L, CONFIG_HERMES, CONFIG_IP860, - CONFIG_IVMS8, CONFIG_MBX, CONFIG_SM850, CONFIG_SPD823TS, - CONFIG_TQM823L, CONFIG_TQM850L, CONFIG_TQM855L, CONFIG_TQM860L, - CONFIG_SXNI855T,CONFIG_EVB64260 ---- FIXME --- not tested yet: - CONFIG_TQM860, CONFIG_ADS, - CONFIG_RPXLITE, CONFIG_RPXCLASSIC, CONFIG_BSEIP, - CONFIG_HYMOD + + CONFIG_ADCIOP, CONFIG_FADS, CONFIG_RPXSUPER, + CONFIG_ADS, CONFIG_FPS850L, CONFIG_SANDPOINT, + CONFIG_BSEIP, CONFIG_HERMES, CONFIG_SBC8260, + CONFIG_COGENT, CONFIG_HYMOD, CONFIG_SM850, + CONFIG_COGENT, CONFIG_IP860, CONFIG_SPD823TS, + CONFIG_CPCI405, CONFIG_IVMS8, CONFIG_SXNI855T, + CONFIG_CU824, CONFIG_MBX, CONFIG_TQM823L, + CONFIG_ERIC, CONFIG_PIP405, CONFIG_TQM8260, + CONFIG_ETX094, CONFIG_RDSPROTO, CONFIG_TQM850L, + CONFIG_EVB64260, CONFIG_RPXCLASSIC, CONFIG_TQM855L, + CONFIG_EVB64260, CONFIG_RPXLITE, CONFIG_TQM860L - CPU Module Type: (if CONFIG_COGENT is defined) Define exactly one of @@ -308,6 +315,10 @@ The following options need to be configured: CFG_CMD_REGINFO * Register dump CFG_CMD_IMMAP * IMMR dump support CFG_CMD_DATE * support for RTC, date/time... + CFG_CMD_DHCP DHCP support + CFG_CMD_BEDBUG Include BedBug Debugger + CFG_CMD_FDC Floppy Disk Support + CFG_CMD_SCSI SCSI Support CFG_CMD_BSP * Board SPecific functions ----------------------------------------------- CFG_CMD_ALL all @@ -343,13 +354,53 @@ The following options need to be configured: CONFIG_RTC_MPC8xx - use internal RTC of MPC8xx CONFIG_RTC_PCF8563 - use Philips PCF8563 RTC + CONFIG_RTC_MC146818 - use MC146818 RTC - Partition Support: CONFIG_MAC_PARTITION and/or CONFIG_DOS_PARTITION + and/or CONFIG_ISO_PARTITION + + If IDE or SCSI support is enabled (CFG_CMD_IDE or + CFG_CMD_SCSI) you must configure support for at least + one partition type as well. + +- IDE Reset method: + CONFIG_IDE_RESET_ROUTINE + + Set this to define that instead of a reset Pin, the + routine ide_set_reset(int idereset) will be used. + +- ATAPI Support: + CONFIG_ATAPI + + Set this to enable ATAPI support. + +- SCSI Support: + At the moment only there is only support for the + SYM53C8XX SCSI controller; define + CONFIG_SCSI_SYM53C8XX to enable it. + + CFG_SCSI_MAX_LUN [8], CFG_SCSI_MAX_SCSI_ID [7] and + CFG_SCSI_MAX_DEVICE [CFG_SCSI_MAX_SCSI_ID * + CFG_SCSI_MAX_LUN] can be adjusted to define the + maximum numbers of LUNs, SCSI ID's and target + devices. + +- Keyboard Support: + CONFIG_ISA_KEYBOARD + + Define this to enable standard (PC-Style) keyboard + support - If IDE harddisk support is enabled (CFG_CMD_IDE) you - must configure support for at least one partition - type as well. +- Video support: + CONFIG_VIDEO + + Define this to enable video support (for instance + output to LCD). + + CONFIG_VIDEO_CT69000 + + Enable Chips & Technologies 69000 Video chip - BOOTP Recovery Mode: CONFIG_BOOTP_RANDOM_DELAY @@ -387,6 +438,19 @@ The following options need to be configured: on those systems that support this (optional) feature, like the TQM8xxL modules. +- I2C Support: CONFIG_I2C + + Enables I2C driver + + CONFIG_I2C_X + + Enables extended (16-bit) I2C addressing. + + CONFIG_SOFT_I2C + + Use software (aka bit-banging) driver instead of CPM + or similar hardware support for I2C + - SPI Support: CONFIG_SPI Enables SPI driver (so far only tested with @@ -397,6 +461,11 @@ The following options need to be configured: Enables extended (16-bit) SPI EEPROM addressing. (symmetrical to CONFIG_I2C_X) +- Configuration Management: + CONFIG_IDENT_STRING + + If defined, this string will be added to the PPCBoot + version information (PPCBOOT_VERSION) Configuration Settings: ----------------------- @@ -695,7 +764,7 @@ configurations; the following names are supported: FADS850SAR_config SPD823TS_config pcu_e_config FADS860T_config SXNI855T_config rsdproto_config FPS850L_config Sandpoint8240_config sbc8260_config - GENIETV_config TQM823L_config + GENIETV_config TQM823L_config PIP405_config Finally, type "make all", and you should get some working PPCBoot images ready for downlod to / installation on your system: diff --git a/board/lwmon/lwmon.c b/board/lwmon/lwmon.c index 16346e6..c12f7f8 100644 --- a/board/lwmon/lwmon.c +++ b/board/lwmon/lwmon.c @@ -271,6 +271,69 @@ void reset_phy(void) udelay(1000); } +/*----------------------------------------------------------------------- + * Keyboard Controller + */ +/* command codes */ +#define KEYBD_CMD_READ_KEYS 0x01 +#define KEYBD_CMD_READ_VERSION 0x02 +#define KEYBD_CMD_READ_STATUS 0x03 +#define KEYBD_CMD_RESET_ERRORS 0x10 + +/* Number of bytes returned from Keyboard Controller */ +#define KEYBD_VERSIONLEN 2 /* version information */ +#define KEYBD_DATALEN 9 /* normal key scan data */ + +static uchar kbd_addr = CFG_I2C_KEYBD_ADDR; +static uchar kbd_data[KEYBD_DATALEN]; +uchar keybd_env[2*KEYBD_DATALEN+1]; + +void misc_init_r (bd_t *bd) +{ + uchar val, errcd; + int i; + + i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE); + + /* Read initial keyboard error code */ + val = KEYBD_CMD_READ_STATUS; + i2c_write (&kbd_addr, 1, &val, 1); + i2c_read (&kbd_addr, 1, &errcd, 1); + if (errcd) { + printf (" KEYBD: Error %02X\n", errcd); + } + + /* Reset error code and verify */ + val = KEYBD_CMD_RESET_ERRORS; + i2c_write (&kbd_addr, 1, &val, 1); + val = KEYBD_CMD_READ_STATUS; + i2c_write (&kbd_addr, 1, &val, 1); + i2c_read (&kbd_addr, 1, &val, 1); + + if (val) { /* permanent error, report it */ + printf ("*** Keyboard error code %02X ***\n", val); + sprintf (keybd_env, "%02X", val); + setenv ("keybd", keybd_env); + return; + } + + /* Read Version */ + val = KEYBD_CMD_READ_VERSION; + i2c_write (&kbd_addr, 1, &val, 1); + i2c_read (&kbd_addr, 1, kbd_data, KEYBD_VERSIONLEN); + printf (" KEYBD: Version %d.%d\n", kbd_data[0], kbd_data[1]); + + /* Read keys */ + val = KEYBD_CMD_READ_KEYS; + i2c_write (&kbd_addr, 1, &val, 1); + i2c_read (&kbd_addr, 1, kbd_data, KEYBD_DATALEN); + + for (i=0; i $@ + +sinclude .depend + +######################################################################### diff --git a/board/pip405/cmd_pip405.c b/board/pip405/cmd_pip405.c new file mode 100644 index 0000000..3ff5eb9 --- /dev/null +++ b/board/pip405/cmd_pip405.c @@ -0,0 +1,218 @@ +/* + * (C) Copyright 2001 + * Denis Peter, MPL AG Switzerland, d.peter@mpl.ch + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * hacked for PIP405 + */ + +#include +#include +#include "pip405.h" +#include +#include "pip405_isa.h" +#include "video.h" +#include + +extern flash_info_t flash_info[]; /* info for FLASH chips */ + +int PCI_Write_CFG_Reg(int BusDevFunc, int Reg, unsigned int Value, int Width); +unsigned int PCI_Read_CFG_Reg(int BusDevFunc, int Reg, int Width); + + +#define TRUE 1 +#define FALSE 0 + +#define IMAGE_SIZE 0x80000 + +image_header_t header; + + + +int pip405_prg(unsigned long src,unsigned long size) +{ + unsigned long start; + flash_info_t *info; + int i,rc; + unsigned long *magic = (unsigned long *)src; + + info = &flash_info[0]; + start = 0 - size; + for(i=info->sector_count-1;i>0;i--) + { + info->protect[i] = 0; /* unprotect this sector */ + if(start>=info->start[i]) + break; + } + /* set-up flash location */ + rc=switch_cs(FALSE); + /* now erase flash */ + if(magic[0]!=IH_MAGIC) { + printf("Bad Magic number\n"); + switch_cs(rc); + return(0); + } + printf("Start erasing at %lx (sector %d) (start %lx)\n", + start,i,info->start[i]); + flash_erase (info, i, info->sector_count-1); + printf("flash erased, programming 0x%lx Bytes\n",size); + switch (rc = flash_write ((uchar *)src, start, size)) + { + case 0: printf ("programming done\n"); return(1); + case 1: printf ("Timeout writing to Flash\n"); return(0); + case 2: printf ("Flash not Erased\n"); return(0); + case 4: printf ("Can't write to protected Flash sectors\n"); return(0); + case 8: printf ("Outside available Flash\n"); return(0); + default: printf ("%s[%d] FIXME: rc=%d\n",__FILE__,__LINE__,rc); return(0); + } + return(0); +} + +int pip405_prg_image(unsigned long load_addr) +{ + unsigned long data,len,checksum; + image_header_t *hdr=&header; + /* Copy header so we can blank CRC field for re-calculation */ + memcpy (&header, (char *)load_addr, sizeof(image_header_t)); + + if (hdr->ih_magic != IH_MAGIC) { + printf ("Bad Magic Number\n"); + return(0); + } + if (hdr->ih_os != IH_OS_PPCBOOT) { + printf ("No PPCBOOT Image\n"); + return(0); + } + if (hdr->ih_type != IH_TYPE_FIRMWARE) { + printf ("No Firmware Image\n"); + return(0); + } + data = (ulong)&header; + len = sizeof(image_header_t); + checksum = hdr->ih_hcrc; + hdr->ih_hcrc = 0; + if (crc32 (0, (char *)data, len) != checksum) { + printf ("Bad Header Checksum\n"); + return(0); + } + data = load_addr + sizeof(image_header_t); + len = hdr->ih_size; + printf (" Verifying Checksum ... "); + if (crc32 (0, (char *)data, len) != hdr->ih_dcrc) { + printf ("Bad Data CRC\n"); + return(0); + } + printf ("OK\n"); + return(pip405_prg(data,len)); +} + + +/* ------------------------------------------------------------------------- */ + + +void do_pip405(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) +{ + + ulong size,src,device,function,load_addr; + unsigned char i2c[3]; + + src = MULTI_PURPOSE_SOCKET_ADDR; + size = IMAGE_SIZE; + + if (strcmp(argv[1], "flash") == 0) + { + + if (strcmp(argv[2], "floppy") == 0) { + char *local_args[3]; + extern void do_fdcboot (cmd_tbl_t *, bd_t *, int, int, char *[]); + printf ("\nupdating bootloader image from floppy\n"); + local_args[0] = argv[0]; + if(argc==4) { + local_args[1] = argv[3]; + local_args[2] = NULL; + load_addr=simple_strtoul(argv[3], NULL, 16); + do_fdcboot(cmdtp, bd, 0, 2, local_args); + } + else { + local_args[1] = NULL; + load_addr=CFG_LOAD_ADDR; + do_fdcboot(cmdtp, bd, 0, 1, local_args); + } + pip405_prg_image(load_addr); + return; + } + if (strcmp(argv[2], "mem") == 0) { + if(argc==4) { + load_addr=simple_strtoul(argv[3], NULL, 16); + } + else { + load_addr=CFG_LOAD_ADDR; + } + printf ("\nupdating bootloader image from memory at %lX\n",load_addr); + pip405_prg_image(load_addr); + return; + } + if (strcmp(argv[2], "mps") == 0) { + printf ("\nupdating bootloader image from MSP\n"); + pip405_prg(src,size); + return; + } + } + if (strcmp(argv[1], "prg") == 0) + { + if(argc==3) + { + size = (ulong)simple_strtoul(argv[2], NULL, 16); + printf("image size is 0x%lx\n",size); + } + pip405_prg(src,size); + return; + } + if (strcmp(argv[1], "info") == 0) + { + printf("argc %d\n",argc); + print_pip405_info(); + return; + } + if (strcmp(argv[1], "i2c") == 0) + { + printf("argc %d\n",argc); + i2c[0]=CFG_I2C_EEPROM_ADDR; + i2c[1]=0; + i2c[2]=0; + i2c_read(&i2c[0],3,(unsigned char *)CFG_LOAD_ADDR,512); + return; + } + if (strcmp(argv[1], "led") == 0) + { + printf("argc %d\n",argc); + device = (ulong)simple_strtoul(argv[2], NULL, 10); + function = (ulong)simple_strtoul(argv[3], NULL, 10); + if(device==0) + user_led0((function==1)); + else + user_led1((function==1)); + return; + } + printf("Usage:\n%s\n", cmdtp->usage); + return; +} + +/* ------------------------------------------------------------------------- */ diff --git a/board/pip405/config.mk b/board/pip405/config.mk new file mode 100644 index 0000000..9fe451d --- /dev/null +++ b/board/pip405/config.mk @@ -0,0 +1,29 @@ +# +# (C) Copyright 2001 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +# +# esd ADCIOP boards +# + +#TEXT_BASE = 0xFFFE0000 +TEXT_BASE = 0xFFF80000 diff --git a/board/pip405/flash.c b/board/pip405/flash.c new file mode 100644 index 0000000..bb16f4d --- /dev/null +++ b/board/pip405/flash.c @@ -0,0 +1,840 @@ +/* + * (C) Copyright 2001 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* + * Modified 4/5/2001 + * Wait for completion of each sector erase command issued + * 4/5/2001 + * Chris Hallinan - DS4.COM, Inc. - clh@net1plus.com + */ + +/* + * Modified 3/7/2001 + * - adopted for pip405, Denis Peter, MPL AG Switzerland + * TODO: + * clean-up + */ + +#include +#include +#include +#include "pip405.h" + +flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */ +/*----------------------------------------------------------------------- + * Functions + */ +static ulong flash_get_size (vu_long *addr, flash_info_t *info); +static int write_word (flash_info_t *info, ulong dest, ulong data); +static void flash_get_offsets (ulong base, flash_info_t *info); + +void unlock_intel_sectors(flash_info_t *info,ulong addr,ulong cnt); + + +#ifdef CONFIG_ADCIOP +#define ADDR0 0x0aa9 +#define ADDR1 0x0556 +#define FLASH_WORD_SIZE unsigned char +#endif + +#ifdef CONFIG_CPCI405 +#define ADDR0 0x5555 +#define ADDR1 0x2aaa +#define FLASH_WORD_SIZE unsigned short +#endif + +#ifdef CONFIG_PIP405 +#define ADDR0 0x5555 +#define ADDR1 0x2aaa +#define FLASH_WORD_SIZE unsigned short +#endif + +#define FALSE 0 +#define TRUE 1 + +/*----------------------------------------------------------------------- + */ + + +unsigned long flash_init (void) +{ + unsigned long size_b0, size_b1; + int i; + unsigned long pbcr; + unsigned long base_b0, base_b1; + + if(switch_cs(FALSE)==TRUE) /* map Flash High */ + printf("(MPS Boot) "); + else + printf("(Flash Boot) "); + /* Init: no FLASHes known */ + for (i=0; i= CFG_FLASH_BASE + flash_protect(FLAG_PROTECT_SET, + CFG_MONITOR_BASE, + CFG_MONITOR_BASE+CFG_MONITOR_LEN-1, + &flash_info[0]); +#endif + size_b1 = 0 ; + flash_info[0].size = size_b0; + } + + /* 2 banks */ + else + { + size_b1 = flash_get_size((vu_long *)FLASH_BASE1_PRELIM, &flash_info[1]); + + /* Re-do sizing to get full correct info */ + + if (size_b1) + { + mtdcr(ebccfga, pb0cr); + pbcr = mfdcr(ebccfgd); + mtdcr(ebccfga, pb0cr); + base_b1 = -size_b1; + pbcr = (pbcr & 0x0001ffff) | base_b1 | (((size_b1/1024/1024)-1)<<17); + mtdcr(ebccfgd, pbcr); + /* printf("pb1cr = %x\n", pbcr); */ + } + + if (size_b0) + { + mtdcr(ebccfga, pb1cr); + pbcr = mfdcr(ebccfgd); + mtdcr(ebccfga, pb1cr); + base_b0 = base_b1 - size_b0; + pbcr = (pbcr & 0x0001ffff) | base_b0 | (((size_b0/1024/1024)-1)<<17); + mtdcr(ebccfgd, pbcr); + /* printf("pb0cr = %x\n", pbcr); */ + } + + size_b0 = flash_get_size((vu_long *)base_b0, &flash_info[0]); + + flash_get_offsets (base_b0, &flash_info[0]); + + /* monitor protection ON by default */ + (void)flash_protect(FLAG_PROTECT_SET, + base_b0+size_b0-CFG_MONITOR_LEN, + base_b0+size_b0-1, + &flash_info[0]); + + if (size_b1) { + /* Re-do sizing to get full correct info */ + size_b1 = flash_get_size((vu_long *)base_b1, &flash_info[1]); + + flash_get_offsets (base_b1, &flash_info[1]); + + /* monitor protection ON by default */ + (void)flash_protect(FLAG_PROTECT_SET, + base_b1+size_b1-CFG_MONITOR_LEN, + base_b1+size_b1-1, + &flash_info[1]); + /* monitor protection OFF by default (one is enough) */ + (void)flash_protect(FLAG_PROTECT_CLEAR, + base_b0+size_b0-CFG_MONITOR_LEN, + base_b0+size_b0-1, + &flash_info[0]); + } else { + flash_info[1].flash_id = FLASH_UNKNOWN; + flash_info[1].sector_count = -1; + } + + flash_info[0].size = size_b0; + flash_info[1].size = size_b1; + }/* else 2 banks */ + switch_cs(TRUE); /* switch to boot mode */ + return (size_b0 + size_b1); +} + + +static void flash_get_offsets (ulong base, flash_info_t *info) +{ + return; +} +#if 0 +/*----------------------------------------------------------------------- + */ +static void flash_get_offsets (ulong base, flash_info_t *info) +{ + int i; + + /* set up sector start address table */ + if (((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) || + (info->flash_id == FLASH_AM040)){ + for (i = 0; i < info->sector_count; i++) + info->start[i] = base + (i * 0x00010000); + } + else { + if (info->flash_id & FLASH_BTYPE) { + /* set sector offsets for bottom boot block type */ + info->start[0] = base + 0x00000000; + info->start[1] = base + 0x00004000; + info->start[2] = base + 0x00006000; + info->start[3] = base + 0x00008000; + for (i = 4; i < info->sector_count; i++) { + info->start[i] = base + (i * 0x00010000) - 0x00030000; + } + } else { + /* set sector offsets for top boot block type */ + i = info->sector_count - 1; + info->start[i--] = base + info->size - 0x00004000; + info->start[i--] = base + info->size - 0x00006000; + info->start[i--] = base + info->size - 0x00008000; + for (; i >= 0; i--) { + info->start[i] = base + i * 0x00010000; + } + } + } +} + +#endif +/*----------------------------------------------------------------------- + */ +void flash_print_info (flash_info_t *info) +{ + int i; + int k; + int size; + int erased; + volatile unsigned long *flash; + + if (info->flash_id == FLASH_UNKNOWN) { + printf ("missing or unknown FLASH type\n"); + return; + } + + switch (info->flash_id & FLASH_VENDMASK) { + case FLASH_MAN_AMD: printf ("AMD "); break; + case FLASH_MAN_FUJ: printf ("FUJITSU "); break; + case FLASH_MAN_SST: printf ("SST "); break; + case FLASH_MAN_INTEL: printf ("Intel "); break; + default: printf ("Unknown Vendor "); break; + } + + switch (info->flash_id & FLASH_TYPEMASK) { + case FLASH_AM040: printf ("AM29F040 (512 Kbit, uniform sector size)\n"); + break; + case FLASH_AM400B: printf ("AM29LV400B (4 Mbit, bottom boot sect)\n"); + break; + case FLASH_AM400T: printf ("AM29LV400T (4 Mbit, top boot sector)\n"); + break; + case FLASH_AM800B: printf ("AM29LV800B (8 Mbit, bottom boot sect)\n"); + break; + case FLASH_AM800T: printf ("AM29LV800T (8 Mbit, top boot sector)\n"); + break; + case FLASH_AM160B: printf ("AM29LV160B (16 Mbit, bottom boot sect)\n"); + break; + case FLASH_AM160T: printf ("AM29LV160T (16 Mbit, top boot sector)\n"); + break; + case FLASH_AM320B: printf ("AM29LV320B (32 Mbit, bottom boot sect)\n"); + break; + case FLASH_AM320T: printf ("AM29LV320T (32 Mbit, top boot sector)\n"); + break; + case FLASH_SST800A: printf ("SST39LF/VF800 (8 Mbit, uniform sector size)\n"); + break; + case FLASH_SST160A: printf ("SST39LF/VF160 (16 Mbit, uniform sector size)\n"); + break; + case FLASH_INTEL320T: printf ("TE28F320C3 (32 Mbit, top sector size)\n"); + break; + default: printf ("Unknown Chip Type\n"); + break; + } + + printf (" Size: %ld KB in %d Sectors\n", + info->size >> 10, info->sector_count); + + printf (" Sector Start Addresses:"); + for (i=0; isector_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; kstart[i], + info->protect[i] ? " (RO)" : " " +#else + printf (" %08lX%s%s", + info->start[i], + erased ? " E" : " ", + info->protect[i] ? "RO " : " " +#endif + ); + } + printf ("\n"); +} + +/*----------------------------------------------------------------------- + */ + + +/*----------------------------------------------------------------------- + */ + +/* + * The following code cannot be run from FLASH! + */ +static ulong flash_get_size (vu_long *addr, flash_info_t *info) +{ + short i; + FLASH_WORD_SIZE value; + ulong base = (ulong)addr; + volatile FLASH_WORD_SIZE *addr2 = (FLASH_WORD_SIZE *)addr; + + /* Write auto select command: read Manufacturer ID */ + addr2[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA; + addr2[ADDR1] = (FLASH_WORD_SIZE)0x00550055; + addr2[ADDR0] = (FLASH_WORD_SIZE)0x00900090; + + value = addr2[0]; + /* printf("flash_get_size value: %x\n",value); */ + switch (value) { + case (FLASH_WORD_SIZE)AMD_MANUFACT: + info->flash_id = FLASH_MAN_AMD; + break; + case (FLASH_WORD_SIZE)FUJ_MANUFACT: + info->flash_id = FLASH_MAN_FUJ; + break; + case (FLASH_WORD_SIZE)INTEL_MANUFACT: + info->flash_id = FLASH_MAN_INTEL; + break; + case (FLASH_WORD_SIZE)SST_MANUFACT: + info->flash_id = FLASH_MAN_SST; + break; + default: + info->flash_id = FLASH_UNKNOWN; + info->sector_count = 0; + info->size = 0; + return (0); /* no or unknown flash */ + } + value = addr2[1]; /* device ID */ + /* printf("Device value %x\n",value); */ + switch (value) { + case (FLASH_WORD_SIZE)AMD_ID_F040B: + info->flash_id += FLASH_AM040; + info->sector_count = 8; + info->size = 0x0080000; /* => 512 ko */ + break; + case (FLASH_WORD_SIZE)AMD_ID_LV400T: + info->flash_id += FLASH_AM400T; + info->sector_count = 11; + info->size = 0x00080000; + break; /* => 0.5 MB */ + + case (FLASH_WORD_SIZE)AMD_ID_LV400B: + info->flash_id += FLASH_AM400B; + info->sector_count = 11; + info->size = 0x00080000; + break; /* => 0.5 MB */ + + case (FLASH_WORD_SIZE)AMD_ID_LV800T: + info->flash_id += FLASH_AM800T; + info->sector_count = 19; + info->size = 0x00100000; + break; /* => 1 MB */ + + case (FLASH_WORD_SIZE)AMD_ID_LV800B: + info->flash_id += FLASH_AM800B; + info->sector_count = 19; + info->size = 0x00100000; + break; /* => 1 MB */ + + case (FLASH_WORD_SIZE)AMD_ID_LV160T: + info->flash_id += FLASH_AM160T; + info->sector_count = 35; + info->size = 0x00200000; + break; /* => 2 MB */ + + case (FLASH_WORD_SIZE)AMD_ID_LV160B: + info->flash_id += FLASH_AM160B; + info->sector_count = 35; + info->size = 0x00200000; + break; /* => 2 MB */ +#if 0 /* enable when device IDs are available */ + case (FLASH_WORD_SIZE)AMD_ID_LV320T: + info->flash_id += FLASH_AM320T; + info->sector_count = 67; + info->size = 0x00400000; + break; /* => 4 MB */ + + case (FLASH_WORD_SIZE)AMD_ID_LV320B: + info->flash_id += FLASH_AM320B; + info->sector_count = 67; + info->size = 0x00400000; + break; /* => 4 MB */ +#endif + case (FLASH_WORD_SIZE)SST_ID_xF800A: + info->flash_id += FLASH_SST800A; + info->sector_count = 16; + info->size = 0x00100000; + break; /* => 1 MB */ + case (FLASH_WORD_SIZE)INTEL_ID_28F320C3T: + info->flash_id += FLASH_INTEL320T; + info->sector_count = 71; + info->size = 0x00400000; + break; /* => 4 MB */ + + + case (FLASH_WORD_SIZE)SST_ID_xF160A: + info->flash_id += FLASH_SST160A; + info->sector_count = 32; + info->size = 0x00200000; + break; /* => 2 MB */ + + default: + info->flash_id = FLASH_UNKNOWN; + return (0); /* => no or unknown flash */ + + } + + /* set up sector start address table */ + if (((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) || + (info->flash_id == FLASH_AM040)){ + for (i = 0; i < info->sector_count; i++) + info->start[i] = base + (i * 0x00010000); + } else { + if (info->flash_id & FLASH_BTYPE) { + /* set sector offsets for bottom boot block type */ + info->start[0] = base + 0x00000000; + info->start[1] = base + 0x00004000; + info->start[2] = base + 0x00006000; + info->start[3] = base + 0x00008000; + for (i = 4; i < info->sector_count; i++) + info->start[i] = base + (i * 0x00010000) - 0x00030000; + } + else { + /* set sector offsets for top boot block type */ + i = info->sector_count - 1; + if(info->sector_count==71) { + + info->start[i--] = base + info->size - 0x00002000; + info->start[i--] = base + info->size - 0x00004000; + info->start[i--] = base + info->size - 0x00006000; + info->start[i--] = base + info->size - 0x00008000; + info->start[i--] = base + info->size - 0x0000A000; + info->start[i--] = base + info->size - 0x0000C000; + info->start[i--] = base + info->size - 0x0000E000; + for (; i >= 0; i--) + info->start[i] = base + i * 0x000010000; + } + else { + info->start[i--] = base + info->size - 0x00004000; + info->start[i--] = base + info->size - 0x00006000; + info->start[i--] = base + info->size - 0x00008000; + for (; i >= 0; i--) + info->start[i] = base + i * 0x00010000; + } + } + } + + /* check for protected sectors */ + for (i = 0; i < info->sector_count; i++) { + /* read sector protection at sector address, (A7 .. A0) = 0x02 */ + /* D0 = 1 if protected */ + addr2 = (volatile FLASH_WORD_SIZE *)(info->start[i]); + if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL) + info->protect[i] = 0; + else + info->protect[i] = addr2[2] & 1; + } + + /* + * Prevent writes to uninitialized FLASH. + */ + if (info->flash_id != FLASH_UNKNOWN) { +#if 0 /* test-only */ +#ifdef CONFIG_ADCIOP + addr2 = (volatile unsigned char *)info->start[0]; + addr2[ADDR0] = 0xAA; + addr2[ADDR1] = 0x55; + addr2[ADDR0] = 0xF0; /* reset bank */ +#else + addr2 = (FLASH_WORD_SIZE *)info->start[0]; + *addr2 = (FLASH_WORD_SIZE)0x00F000F0; /* reset bank */ +#endif +#else /* test-only */ + addr2 = (FLASH_WORD_SIZE *)info->start[0]; + *addr2 = (FLASH_WORD_SIZE)0x00F000F0; /* reset bank */ +#endif /* test-only */ + } + + return (info->size); +} + +int wait_for_DQ7(flash_info_t *info, int sect) +{ + ulong start, now, last; + volatile FLASH_WORD_SIZE *addr = (FLASH_WORD_SIZE *)(info->start[sect]); + + start = get_timer (0); + last = start; + while ((addr[0] & (FLASH_WORD_SIZE)0x00800080) != (FLASH_WORD_SIZE)0x00800080) { + if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) { + printf ("Timeout\n"); + return -1; + } + /* show that we're waiting */ + if ((now - last) > 1000) { /* every second */ + putc ('.'); + last = now; + } + } + return 0; +} + +int intel_wait_for_DQ7(flash_info_t *info, int sect) +{ + ulong start, now, last; + volatile FLASH_WORD_SIZE *addr = (FLASH_WORD_SIZE *)(info->start[sect]); + + start = get_timer (0); + last = start; + while ((addr[0] & (FLASH_WORD_SIZE)0x00800080) != (FLASH_WORD_SIZE)0x00800080) { + if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) { + printf ("Timeout\n"); + return -1; + } + /* show that we're waiting */ + if ((now - last) > 1000) { /* every second */ + putc ('.'); + last = now; + } + } + addr[0]=(FLASH_WORD_SIZE)0x00500050; + return 0; +} + +/*----------------------------------------------------------------------- + */ + +void flash_erase (flash_info_t *info, int s_first, int s_last) +{ + volatile FLASH_WORD_SIZE *addr = (FLASH_WORD_SIZE *)(info->start[0]); + volatile FLASH_WORD_SIZE *addr2; + int flag, prot, sect, l_sect; + int i; + + if ((s_first < 0) || (s_first > s_last)) { + if (info->flash_id == FLASH_UNKNOWN) { + printf ("- missing\n"); + } else { + printf ("- no sectors to erase\n"); + } + return; + } + + if (info->flash_id == FLASH_UNKNOWN) { + printf ("Can't erase unknown flash type - aborted\n"); + return; + } + + prot = 0; + for (sect=s_first; sect<=s_last; ++sect) { + if (info->protect[sect]) { + prot++; + } + } + + if (prot) { + printf ("- Warning: %d protected sectors will not be erased!\n", + prot); + } else { + printf ("\n"); + } + + l_sect = -1; + + /* Disable interrupts which might cause a timeout here */ + flag = disable_interrupts(); + + /* Start erase on unprotected sectors */ + for (sect = s_first; sect<=s_last; sect++) { + if (info->protect[sect] == 0) { /* not protected */ + addr2 = (FLASH_WORD_SIZE *)(info->start[sect]); + /* printf("Erasing sector %p\n", addr2); */ /* CLH */ + if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) { + addr[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA; + addr[ADDR1] = (FLASH_WORD_SIZE)0x00550055; + addr[ADDR0] = (FLASH_WORD_SIZE)0x00800080; + addr[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA; + addr[ADDR1] = (FLASH_WORD_SIZE)0x00550055; + addr2[0] = (FLASH_WORD_SIZE)0x00500050; /* block erase */ + for (i=0; i<50; i++) + udelay(1000); /* wait 1 ms */ + wait_for_DQ7(info, sect); + } + else { + if((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL){ + addr2[0] = (FLASH_WORD_SIZE)0x00600060; /* unlock sector */ + addr2[0] = (FLASH_WORD_SIZE)0x00D000D0; /* sector erase */ + intel_wait_for_DQ7(info, sect); + addr2[0] = (FLASH_WORD_SIZE)0x00200020; /* sector erase */ + addr2[0] = (FLASH_WORD_SIZE)0x00D000D0; /* sector erase */ + intel_wait_for_DQ7(info, sect); + } + else { + addr[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA; + addr[ADDR1] = (FLASH_WORD_SIZE)0x00550055; + addr[ADDR0] = (FLASH_WORD_SIZE)0x00800080; + addr[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA; + addr[ADDR1] = (FLASH_WORD_SIZE)0x00550055; + addr2[0] = (FLASH_WORD_SIZE)0x00300030; /* sector erase */ + wait_for_DQ7(info, sect); + } + } + l_sect = sect; + /* + * Wait for each sector to complete, it's more + * reliable. According to AMD Spec, you must + * issue all erase commands within a specified + * timeout. This has been seen to fail, especially + * if printf()s are included (for debug)!! + */ + /* wait_for_DQ7(info, sect); */ + } + } + + /* re-enable interrupts if necessary */ + if (flag) + enable_interrupts(); + + /* wait at least 80us - let's wait 1 ms */ + udelay (1000); + +#if 0 + /* + * We wait for the last triggered sector + */ + if (l_sect < 0) + goto DONE; + wait_for_DQ7(info, l_sect); + +DONE: +#endif + /* reset to read mode */ + addr = (FLASH_WORD_SIZE *)info->start[0]; + addr[0] = (FLASH_WORD_SIZE)0x00F000F0; /* reset bank */ + + printf (" done\n"); +} + +void unlock_intel_sectors(flash_info_t *info,ulong addr,ulong cnt) +{ + int i; + volatile FLASH_WORD_SIZE *addr2; + long c; + c= (long)cnt; + for(i=info->sector_count-1;i>0;i--) + { + if(addr>=info->start[i]) + break; + } + do { + addr2 = (FLASH_WORD_SIZE *)(info->start[i]); + addr2[0] = (FLASH_WORD_SIZE)0x00600060; /* unlock sector setup */ + addr2[0] = (FLASH_WORD_SIZE)0x00D000D0; /* unlock sector */ + intel_wait_for_DQ7(info, i); + i++; + c-=(info->start[i]-info->start[i-1]); + }while(c>0); + + +} + + +/*----------------------------------------------------------------------- + * Copy memory to flash, returns: + * 0 - OK + * 1 - write timeout + * 2 - Flash not erased + */ + +int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt) +{ + ulong cp, wp, data; + int i, l, rc; + + + if((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL){ + unlock_intel_sectors(info,addr,cnt); + } + + wp = (addr & ~3); /* get lower word aligned address */ + /* + * handle unaligned start bytes + */ + if ((l = addr - wp) != 0) { + data = 0; + for (i=0, cp=wp; i0; ++i) { + data = (data << 8) | *src++; + --cnt; + ++cp; + } + for (; cnt==0 && i<4; ++i, ++cp) { + data = (data << 8) | (*(uchar *)cp); + } + + if ((rc = write_word(info, wp, data)) != 0) { + return (rc); + } + wp += 4; + } + + /* + * handle word aligned part + */ + while (cnt >= 4) { + data = 0; + for (i=0; i<4; ++i) { + data = (data << 8) | *src++; + } + if ((rc = write_word(info, wp, data)) != 0) { + return (rc); + } + wp += 4; + if((wp % 0x10000)==0) + printf("."); /* show Progress */ + cnt -= 4; + } + + if (cnt == 0) { + return (0); + } + + /* + * handle unaligned tail bytes + */ + data = 0; + for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) { + data = (data << 8) | *src++; + --cnt; + } + for (; i<4; ++i, ++cp) { + data = (data << 8) | (*(uchar *)cp); + } + + return (write_word(info, wp, data)); +} + +/*----------------------------------------------------------------------- + * Write a word to Flash, returns: + * 0 - OK + * 1 - write timeout + * 2 - Flash not erased + */ +static int write_word (flash_info_t *info, ulong dest, ulong data) +{ + volatile FLASH_WORD_SIZE *addr2 = (FLASH_WORD_SIZE *)(info->start[0]); + volatile FLASH_WORD_SIZE *dest2 = (FLASH_WORD_SIZE *)dest; + volatile FLASH_WORD_SIZE *data2 = (FLASH_WORD_SIZE *)&data; + ulong start; + int flag; + int i; + + /* Check if Flash is (sufficiently) erased */ + if ((*((volatile FLASH_WORD_SIZE *)dest) & + (FLASH_WORD_SIZE)data) != (FLASH_WORD_SIZE)data) { + return (2); + } + /* Disable interrupts which might cause a timeout here */ + flag = disable_interrupts(); + for (i=0; i<4/sizeof(FLASH_WORD_SIZE); i++) + { + if((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL){ + /* intel style writting */ + dest2[i] = (FLASH_WORD_SIZE)0x00400040; + dest2[i] = data2[i]; + if (flag) + enable_interrupts(); + /* data polling for D7 */ + start = get_timer (0); + while ((dest2[i] & (FLASH_WORD_SIZE)0x00800080) != (FLASH_WORD_SIZE)0x00800080) + { + if (get_timer(start) > CFG_FLASH_WRITE_TOUT) + return (1); + } + dest2[i] = (FLASH_WORD_SIZE)0xFFFFFFFF; /* return to read mode */ + + } + else { + addr2[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA; + addr2[ADDR1] = (FLASH_WORD_SIZE)0x00550055; + addr2[ADDR0] = (FLASH_WORD_SIZE)0x00A000A0; + + dest2[i] = data2[i]; + + /* re-enable interrupts if necessary */ + if (flag) + enable_interrupts(); + + /* data polling for D7 */ + start = get_timer (0); + while ((dest2[i] & (FLASH_WORD_SIZE)0x00800080) != + (data2[i] & (FLASH_WORD_SIZE)0x00800080)) { + if (get_timer(start) > CFG_FLASH_WRITE_TOUT) { + return (1); + } + } + } + } + return (0); +} + +/*----------------------------------------------------------------------- + */ diff --git a/board/pip405/init.S b/board/pip405/init.S new file mode 100644 index 0000000..1723d54 --- /dev/null +++ b/board/pip405/init.S @@ -0,0 +1,242 @@ +/*------------------------------------------------------------------------------+ + * + * This source code has been made available to you by IBM on an AS-IS + * basis. Anyone receiving this source is licensed under IBM + * copyrights to use it in any way he or she deems fit, including + * copying it, modifying it, compiling it, and redistributing it either + * with or without modifications. No license under IBM patents or + * patent applications is to be implied by the copyright license. + * + * Any user of this software should understand that IBM cannot provide + * technical support for this software and will not be responsible for + * any consequences resulting from the use of this software. + * + * Any person who transfers this source code or any derivative work + * must include the IBM copyright notice, this paragraph, and the + * preceding two paragraphs in the transferred software. + * + * COPYRIGHT I B M CORPORATION 1995 + * LICENSED MATERIAL - PROGRAM PROPERTY OF I B M + *-------------------------------------------------------------------------------*/ + +/*----------------------------------------------------------------------------- + * Function: ext_bus_cntlr_init + * Description: Initializes the External Bus Controller for the external + * peripherals. IMPORTANT: For pass1 this code must run from + * cache since you can not reliably change a peripheral banks + * timing register (pbxap) while running code from that bank. + * For ex., since we are running from ROM on bank 0, we can NOT + * execute the code that modifies bank 0 timings from ROM, so + * we run it from cache. + * Bank 0 - Flash or Multi Purpose Socket + * Bank 1 - Multi Purpose Socket or Flash + * Bank 2 - not used + * Bank 3 - not used + * Bank 4 - not used + * Bank 5 - not used + * Bank 6 - used to switch on the 12V for the Multipurpose socket + * Bank 7 - Config Register + *-----------------------------------------------------------------------------*/ +#include + +#define _LINUX_CONFIG_H 1 /* avoid reading Linux autoconf.h file */ + +#include "config_PIP405.h" +#include +#include + +#include +#include + + + .globl ext_bus_cntlr_init +ext_bus_cntlr_init: + mflr r4 /* save link register */ + bl ..getAddr +..getAddr: + mflr r3 /* get address of ..getAddr */ + mtlr r4 /* restore link register */ + addi r4,0,14 /* set ctr to 14; used to prefetch */ + mtctr r4 /* 14 cache lines to fit this function */ + /* in cache (gives us 8x14=112 instrctns) */ +..ebcloop: + icbt r0,r3 /* prefetch cache line for addr in r3 */ + addi r3,r3,32 /* move to next cache line */ + bdnz ..ebcloop /* continue for 14 cache lines */ + + /*------------------------------------------------------------------- + * Delay to ensure all accesses to ROM are complete before changing + * bank 0 timings. + *------------------------------------------------------------------- */ + addis r3,0,0x0 + ori r3,r3,0xA000 + mtctr r3 +..spinlp: + bdnz ..spinlp /* spin loop */ + + /*----------------------------------------------------------------------- + * decide boot up mode + *----------------------------------------------------------------------- */ + addi r4,0,pb0cr + mtdcr ebccfga,r4 + mfdcr r4,ebccfgd + + andi. r0, r4, 0x2000 /* mask out irrelevant bits */ + beq 0f /* jump if 8 bit bus width */ + + /* setup 16 bit things + *----------------------------------------------------------------------- + * Memory Bank 0 (16 Bit Flash) initialization + *---------------------------------------------------------------------- */ + + addi r4,0,pb0ap + mtdcr ebccfga,r4 + addis r4,0,0x9B01 + ori r4,r4,0x5480 + mtdcr ebccfgd,r4 + + addi r4,0,pb0cr + mtdcr ebccfga,r4 + /* BS=0x011(8MB),BU=0x3(R/W), */ + addis r4,0,((FLASH_BASE0_PRELIM & 0xFFF00000) | 0x00050000)@h + ori r4,r4,0xA000 /* BW=0x01(16 bits) */ + mtdcr ebccfgd,r4 + + /*----------------------------------------------------------------------- + * Memory Bank 1 (Multi Purpose Socket) initialization + *----------------------------------------------------------------------*/ + addi r4,0,pb1ap + mtdcr ebccfga,r4 + addis r4,0,0x0281 + ori r4,r4,0x5480 + mtdcr ebccfgd,r4 + + addi r4,0,pb1cr + mtdcr ebccfga,r4 + /* BS=0x011(8MB),BU=0x3(R/W), */ + addis r4,0,((MULTI_PURPOSE_SOCKET_ADDR & 0xFFF00000) | 0x00050000)@h + ori r4,r4,0x8000 /* BW=0x0( 8 bits) */ + mtdcr ebccfgd,r4 + b 1f + +0: + /* 8Bit boot mode: */ + /*----------------------------------------------------------------------- + * Memory Bank 0 Multi Purpose Socket initialization + *----------------------------------------------------------------------- */ + + addi r4,0,pb0ap + mtdcr ebccfga,r4 + addis r4,0,0x9B01 + ori r4,r4,0x5480 + mtdcr ebccfgd,r4 + + addi r4,0,pb0cr + mtdcr ebccfga,r4 + /* BS=0x011(4MB),BU=0x3(R/W), */ + addis r4,0,((FLASH_BASE0_PRELIM & 0xFFF00000) | 0x00050000)@h + ori r4,r4,0x8000 /* BW=0x0( 8 bits) */ + mtdcr ebccfgd,r4 + + /*----------------------------------------------------------------------- + * Memory Bank 1 (Flash) initialization + *-----------------------------------------------------------------------*/ + addi r4,0,pb1ap + mtdcr ebccfga,r4 + addis r4,0,0x0281 + ori r4,r4,0x5480 + mtdcr ebccfgd,r4 + + addi r4,0,pb1cr + mtdcr ebccfga,r4 + /* BS=0x011(8MB),BU=0x3(R/W), */ + addis r4,0,((MULTI_PURPOSE_SOCKET_ADDR & 0xFFF00000) | 0x00050000)@h + ori r4,r4,0xA000 /* BW=0x0( 8 bits) */ + mtdcr ebccfgd,r4 + +1: + /*----------------------------------------------------------------------- + * Memory Bank 2-3-4-5-6 (not used) initialization + *-----------------------------------------------------------------------*/ + addi r4,0,pb2cr + mtdcr ebccfga,r4 + addis r4,0,0x0000 + ori r4,r4,0x0000 + mtdcr ebccfgd,r4 + + addi r4,0,pb3cr + mtdcr ebccfga,r4 + addis r4,0,0x0000 + ori r4,r4,0x0000 + mtdcr ebccfgd,r4 + + addi r4,0,pb4cr + mtdcr ebccfga,r4 + addis r4,0,0x0000 + ori r4,r4,0x0000 + mtdcr ebccfgd,r4 + + addi r4,0,pb5cr + mtdcr ebccfga,r4 + addis r4,0,0x0000 + ori r4,r4,0x0000 + mtdcr ebccfgd,r4 + + addi r4,0,pb6cr + mtdcr ebccfga,r4 + addis r4,0,0x0000 + ori r4,r4,0x0000 + mtdcr ebccfgd,r4 + + /*----------------------------------------------------------------------- + * Memory Bank 7 (Config Register) initialization + *----------------------------------------------------------------------- */ + addi r4,0,pb7ap + mtdcr ebccfga,r4 + addis r4,0,0x0181 /* Doc says TWT=3 and Openios TWT=3!! */ + ori r4,r4,0x5280 /* disable Ready, BEM=0 */ + mtdcr ebccfgd,r4 + + addi r4,0,pb7cr + mtdcr ebccfga,r4 + /* BS=0x0(1MB),BU=0x3(R/W), */ + addis r4,0,((CONFIG_PORT_ADDR & 0xFFF00000) | 0x00010000)@h + ori r4,r4,0x8000 /* BW=0x0(8 bits) */ + mtdcr ebccfgd,r4 + nop /* pass2 DCR errata #8 */ + blr + +/*----------------------------------------------------------------------------- + * Function: sdram_init + * Description: Configures the internal SRAM memory. and setup the + * Stackpointer in it. + *----------------------------------------------------------------------------- */ + .globl sdram_init + +sdram_init: + + /*------------------------------------------------------------------- + * init OnChip Memory for a temporary stack + *------------------------------------------------------------------- */ + + lis r0, 0x7FFF + ori r0, r0, 0xFFFF + mfdcr r3, ocmiscntl /* get instr-side IRAM config */ + mfdcr r4, ocmdscntl /* get data-side IRAM config */ + and r3, r3, r0 /* disable data-side IRAM */ + and r4, r4, r0 /* disable data-side IRAM */ + mtdcr ocmiscntl, r3 /* set instr-side IRAM config */ + mtdcr ocmdscntl, r4 /* set data-side IRAM config */ + isync + lis r0, OCM_DATA_ADDR@h/* IRAM is mapped here */ + mtdcr ocmdsarc, r0 /* set data-side IRAM address */ + oris r4, r4, 0xC000 /* enable data-side IRAM */ + mtdcr ocmdscntl, r4 /* set data-side IRAM config */ + isync + + mfdcr r3, ocmdsarc /* set temp stackpointer (needed by CONS_Init) */ + andis. r3, r3, 0xFC00 + addi r1, r3, 0x1000-16 + + blr + diff --git a/board/pip405/kbd.c b/board/pip405/kbd.c new file mode 100644 index 0000000..1c538cb --- /dev/null +++ b/board/pip405/kbd.c @@ -0,0 +1,628 @@ +/* + * (C) Copyright 2001 + * Denis Peter, MPL AG Switzerland, d.peter@mpl.ch + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Source partly derived from: + * linux/drivers/char/pc_keyb.c + * + * + */ +#include +#include +#include +#include "pip405_isa.h" +#include "kbd.h" + + +unsigned char kbd_read_status(void); +unsigned char kbd_read_input(void); +void kbd_send_data(unsigned char data); +void disable_8259A_irq(unsigned int irq); +void enable_8259A_irq(unsigned int irq); + +/* used only by send_data - set by keyboard_interrupt */ + + +#undef KBG_DEBUG + +#ifdef KBG_DEBUG +#define PRINTF(fmt,args...) printf (fmt ,##args) +#else +#define PRINTF(fmt,args...) +#endif + +#define KBD_STAT_KOBF 0x01 +#define KBD_STAT_IBF 0x02 +#define KBD_STAT_SYS 0x04 +#define KBD_STAT_CD 0x08 +#define KBD_STAT_LOCK 0x10 +#define KBD_STAT_MOBF 0x20 +#define KBD_STAT_TI_OUT 0x40 +#define KBD_STAT_PARERR 0x80 + +#define KBD_INIT_TIMEOUT 1000 /* Timeout in ms for initializing the keyboard */ +#define KBC_TIMEOUT 250 /* Timeout in ms for sending to keyboard controller */ +#define KBD_TIMEOUT 1000 /* Timeout in ms for keyboard command acknowledge */ +/* + * Keyboard Controller Commands + */ + +#define KBD_CCMD_READ_MODE 0x20 /* Read mode bits */ +#define KBD_CCMD_WRITE_MODE 0x60 /* Write mode bits */ +#define KBD_CCMD_GET_VERSION 0xA1 /* Get controller version */ +#define KBD_CCMD_MOUSE_DISABLE 0xA7 /* Disable mouse interface */ +#define KBD_CCMD_MOUSE_ENABLE 0xA8 /* Enable mouse interface */ +#define KBD_CCMD_TEST_MOUSE 0xA9 /* Mouse interface test */ +#define KBD_CCMD_SELF_TEST 0xAA /* Controller self test */ +#define KBD_CCMD_KBD_TEST 0xAB /* Keyboard interface test */ +#define KBD_CCMD_KBD_DISABLE 0xAD /* Keyboard interface disable */ +#define KBD_CCMD_KBD_ENABLE 0xAE /* Keyboard interface enable */ +#define KBD_CCMD_WRITE_AUX_OBUF 0xD3 /* Write to output buffer as if + initiated by the auxiliary device */ +#define KBD_CCMD_WRITE_MOUSE 0xD4 /* Write the following byte to the mouse */ + +/* + * Keyboard Commands + */ + +#define KBD_CMD_SET_LEDS 0xED /* Set keyboard leds */ +#define KBD_CMD_SET_RATE 0xF3 /* Set typematic rate */ +#define KBD_CMD_ENABLE 0xF4 /* Enable scanning */ +#define KBD_CMD_DISABLE 0xF5 /* Disable scanning */ +#define KBD_CMD_RESET 0xFF /* Reset */ + +/* + * Keyboard Replies + */ + +#define KBD_REPLY_POR 0xAA /* Power on reset */ +#define KBD_REPLY_ACK 0xFA /* Command ACK */ +#define KBD_REPLY_RESEND 0xFE /* Command NACK, send the cmd again */ + +/* + * Status Register Bits + */ + +#define KBD_STAT_OBF 0x01 /* Keyboard output buffer full */ +#define KBD_STAT_IBF 0x02 /* Keyboard input buffer full */ +#define KBD_STAT_SELFTEST 0x04 /* Self test successful */ +#define KBD_STAT_CMD 0x08 /* Last write was a command write (0=data) */ +#define KBD_STAT_UNLOCKED 0x10 /* Zero if keyboard locked */ +#define KBD_STAT_MOUSE_OBF 0x20 /* Mouse output buffer full */ +#define KBD_STAT_GTO 0x40 /* General receive/xmit timeout */ +#define KBD_STAT_PERR 0x80 /* Parity error */ + +#define AUX_STAT_OBF (KBD_STAT_OBF | KBD_STAT_MOUSE_OBF) + +/* + * Controller Mode Register Bits + */ + +#define KBD_MODE_KBD_INT 0x01 /* Keyboard data generate IRQ1 */ +#define KBD_MODE_MOUSE_INT 0x02 /* Mouse data generate IRQ12 */ +#define KBD_MODE_SYS 0x04 /* The system flag (?) */ +#define KBD_MODE_NO_KEYLOCK 0x08 /* The keylock doesn't affect the keyboard if set */ +#define KBD_MODE_DISABLE_KBD 0x10 /* Disable keyboard interface */ +#define KBD_MODE_DISABLE_MOUSE 0x20 /* Disable mouse interface */ +#define KBD_MODE_KCC 0x40 /* Scan code conversion to PC format */ +#define KBD_MODE_RFU 0x80 + + +#define KDB_DATA_PORT 0x60 +#define KDB_COMMAND_PORT 0x64 + +#define LED_SCR 0x01 /* scroll lock led */ +#define LED_CAP 0x04 /* caps lock led */ +#define LED_NUM 0x02 /* num lock led */ + +#define KBD_BUFFER_LEN 0x20 /* size of the keyboardbuffer */ + + + + +static volatile char kbd_buffer[KBD_BUFFER_LEN]; +static volatile int in_pointer = 0; +static volatile int out_pointer = 0; + + +static unsigned char num_lock = 0; +static unsigned char caps_lock = 0; +static unsigned char scroll_lock = 0; +static unsigned char shift = 0; +static unsigned char ctrl = 0; +static unsigned char alt = 0; +static unsigned char e0 = 0; +static unsigned char leds = 0; + +/* Simple translation table for the keys */ + +static unsigned char kbd_plain_xlate[] = { + 0xff,0x1b, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=','\b','\t', /* 0x00 - 0x0f */ + 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']','\r',0xff, 'a', 's', /* 0x10 - 0x1f */ + 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';','\'', '`',0xff,'\\', 'z', 'x', 'c', 'v', /* 0x20 - 0x2f */ + 'b', 'n', 'm', ',', '.', '/',0xff,0xff,0xff, ' ',0xff,0xff,0xff,0xff,0xff,0xff, /* 0x30 - 0x3f */ + 0xff,0xff,0xff,0xff,0xff,0xff,0xff, '7', '8', '9', '-', '4', '5', '6', '+', '1', /* 0x40 - 0x4f */ + '2', '3', '0', '.',0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 0x50 - 0x5F */ + '\r',0xff,0xff + }; + +static unsigned char kbd_shift_xlate[] = { + 0xff,0x1b, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+','\b','\t', /* 0x00 - 0x0f */ + 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}','\r',0xff, 'A', 'S', /* 0x10 - 0x1f */ + 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '"', '~',0xff, '|', 'Z', 'X', 'C', 'V', /* 0x20 - 0x2f */ + 'B', 'N', 'M', '<', '>', '?',0xff,0xff,0xff, ' ',0xff,0xff,0xff,0xff,0xff,0xff, /* 0x30 - 0x3f */ + 0xff,0xff,0xff,0xff,0xff,0xff,0xff, '7', '8', '9', '-', '4', '5', '6', '+', '1', /* 0x40 - 0x4f */ + '2', '3', '0', '.',0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 0x50 - 0x5F */ + '\r',0xff,0xff + }; + +static unsigned char kbd_ctrl_xlate[] = { + 0xff,0x1b, '1',0x00, '3', '4', '5',0x1E, '7', '8', '9', '0',0x1F, '=','\b','\t', /* 0x00 - 0x0f */ + 0x11,0x17,0x05,0x12,0x14,0x18,0x15,0x09,0x0f,0x10,0x1b,0x1d,'\n',0xff,0x01,0x13, /* 0x10 - 0x1f */ + 0x04,0x06,0x08,0x09,0x0a,0x0b,0x0c, ';','\'', '~',0x00,0x1c,0x1a,0x18,0x03,0x16, /* 0x20 - 0x2f */ + 0x02,0x0e,0x0d, '<', '>', '?',0xff,0xff,0xff,0x00,0xff,0xff,0xff,0xff,0xff,0xff, /* 0x30 - 0x3f */ + 0xff,0xff,0xff,0xff,0xff,0xff,0xff, '7', '8', '9', '-', '4', '5', '6', '+', '1', /* 0x40 - 0x4f */ + '2', '3', '0', '.',0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 0x50 - 0x5F */ + '\r',0xff,0xff + }; + + + +/****************************************************************** + * Init + ******************************************************************/ +int isa_kbd_init(void) +{ + char* result; + result=kbd_initialize(); + if(result==NULL) { + PRINTF("AT Keyboard initialized\n"); + irq_install_handler(25, (interrupt_handler_t *)handle_isa_int, NULL); + isa_irq_install_handler(KBD_INTERRUPT, (interrupt_handler_t *)kbd_interrupt, NULL); + return (1); + } + else { + printf("%s\n",result); + return (-1); + } +} + +int drv_isa_kbd_init (void) +{ + int error, devices = 1 ; + device_t kbddev ; + + if(isa_kbd_init()==-1) + return -1; + memset (&kbddev, 0, sizeof(kbddev)); + strcpy(kbddev.name, "kbd"); + kbddev.flags = DEV_FLAGS_INPUT | DEV_FLAGS_SYSTEM; + kbddev.putc = NULL ; + kbddev.puts = NULL ; + kbddev.getc = kbd_getc ; + kbddev.tstc = kbd_testc ; + + error = device_register (&kbddev); + + return (error == 0) ? devices : error ; +} + +/****************************************************************** + * Queue handling + ******************************************************************/ +/* puts character in the queue and sets up the in and out pointer */ +void kbd_put_queue(char data) +{ + if((in_pointer+1)==KBD_BUFFER_LEN) { + if(out_pointer==0) { + return; /* buffer full */ + } else{ + in_pointer=0; + } + } else { + if((in_pointer+1)==out_pointer) + return; /* buffer full */ + in_pointer++; + } + kbd_buffer[in_pointer]=data; + return; +} + +/* test if a character is in the queue */ +int kbd_testc(void) +{ + if(in_pointer==out_pointer) + return(0); /* no data */ + else + return(1); +} +/* gets the character from the queue */ +int kbd_getc(void) +{ + char c; + while(in_pointer==out_pointer); + if((out_pointer+1)==KBD_BUFFER_LEN) + out_pointer=0; + else + out_pointer++; + c=kbd_buffer[out_pointer]; + return (int)c; + +} + + +/* set LEDs */ + +void kbd_set_leds(void) +{ + if(caps_lock==0) + leds&=~LED_CAP; /* switch caps_lock off */ + else + leds|=LED_CAP; /* switch on LED */ + if(num_lock==0) + leds&=~LED_NUM; /* switch LED off */ + else + leds|=LED_NUM; /* switch on LED */ + if(scroll_lock==0) + leds&=~LED_SCR; /* switch LED off */ + else + leds|=LED_SCR; /* switch on LED */ + kbd_send_data(KBD_CMD_SET_LEDS); + kbd_send_data(leds); +} + + +void handle_keyboard_event(unsigned char scancode) +{ + unsigned char keycode; + + /* Convert scancode to keycode */ + PRINTF("scancode %x\n",scancode); + if(scancode==0xe0) { + e0=1; /* special charakters */ + return; + } + if(e0==1) { + e0=0; /* delete flag */ + if(!( ((scancode&0x7F)==0x38)|| /* the right ctrl key */ + ((scancode&0x7F)==0x1D)|| /* the right alt key */ + ((scancode&0x7F)==0x35)|| /* the right '/' key */ + ((scancode&0x7F)==0x1C) )) /* the right enter key */ + /* we swallow unknown e0 codes */ + return; + } + /* special cntrl keys */ + switch(scancode) + { + case 0x2A: + case 0x36: /* shift pressed */ + shift=1; + return; /* do nothing else */ + case 0xAA: + case 0xB6: /* shift released */ + shift=0; + return; /* do nothing else */ + case 0x38: /* alt pressed */ + alt=1; + return; /* do nothing else */ + case 0xB8: /* alt released */ + alt=0; + return; /* do nothing else */ + case 0x1d: /* ctrl pressed */ + ctrl=1; + return; /* do nothing else */ + case 0x9d: /* ctrl released */ + ctrl=0; + return; /* do nothing else */ + case 0x46: /* scrollock pressed */ + scroll_lock=~scroll_lock; + kbd_set_leds(); + return; /* do nothing else */ + case 0x3A: /* capslock pressed */ + caps_lock=~caps_lock; + kbd_set_leds(); + return; + case 0x45: /* numlock pressed */ + num_lock=~num_lock; + kbd_set_leds(); + return; + case 0xC6: /* scroll lock released */ + case 0xC5: /* num lock released */ + case 0xBA: /* caps lock released */ + return; /* just swallow */ + } + if((scancode&0x80)==0x80) /* key released */ + return; + /* now, decide which table we need */ + if(scancode > (sizeof(kbd_plain_xlate)/sizeof(kbd_plain_xlate[0]))) { /* scancode not in list */ + PRINTF("unkown scancode %X\n",scancode); + return; /* swallow it */ + } + /* setup plain code first */ + keycode=kbd_plain_xlate[scancode]; + if(caps_lock==1) { /* caps_lock is pressed, overwrite plain code */ + if(scancode > (sizeof(kbd_shift_xlate)/sizeof(kbd_shift_xlate[0]))) { /* scancode not in list */ + PRINTF("unkown caps-locked scancode %X\n",scancode); + return; /* swallow it */ + } + keycode=kbd_shift_xlate[scancode]; + if(keycode<'A') { /* we only want the alphas capital */ + keycode=kbd_plain_xlate[scancode]; + } + } + if(shift==1) { /* shift overwrites caps_lock */ + if(scancode > (sizeof(kbd_shift_xlate)/sizeof(kbd_shift_xlate[0]))) { /* scancode not in list */ + PRINTF("unkown shifted scancode %X\n",scancode); + return; /* swallow it */ + } + keycode=kbd_shift_xlate[scancode]; + } + if(ctrl==1) { /* ctrl overwrites caps_lock and shift */ + if(scancode > (sizeof(kbd_ctrl_xlate)/sizeof(kbd_ctrl_xlate[0]))) { /* scancode not in list */ + PRINTF("unkown ctrl scancode %X\n",scancode); + return; /* swallow it */ + } + keycode=kbd_ctrl_xlate[scancode]; + } + /* check if valid keycode */ + if(keycode==0xff) { + PRINTF("unkown scancode %X\n",scancode); + return; /* swallow unknown codes */ + } + + kbd_put_queue(keycode); + PRINTF("%x\n",keycode); +} + +/* + * This reads the keyboard status port, and does the + * appropriate action. + * + */ +unsigned char handle_kbd_event(void) +{ + unsigned char status = kbd_read_status(); + unsigned int work = 10000; + + while ((--work > 0) && (status & KBD_STAT_OBF)) { + unsigned char scancode; + + scancode = kbd_read_input(); + + /* Error bytes must be ignored to make the + Synaptics touchpads compaq use work */ + /* Ignore error bytes */ + if (!(status & (KBD_STAT_GTO | KBD_STAT_PERR))) + { + if (status & KBD_STAT_MOUSE_OBF) + ; /* not supported: handle_mouse_event(scancode); */ + else + handle_keyboard_event(scancode); + } + status = kbd_read_status(); + } + if (!work) + PRINTF("pc_keyb: controller jammed (0x%02X).\n", status); + return status; +} + + + +/****************************************************************************** + * Lowlevel Part of keyboard section + */ +unsigned char kbd_read_status(void) +{ + return(in8(CFG_ISA_IO_BASE_ADDRESS + KDB_COMMAND_PORT)); +} + +unsigned char kbd_read_input(void) +{ + return(in8(CFG_ISA_IO_BASE_ADDRESS + KDB_DATA_PORT)); +} + +void kbd_write_command(unsigned char cmd) +{ + out8(CFG_ISA_IO_BASE_ADDRESS + KDB_COMMAND_PORT,cmd); +} + +void kbd_write_output(unsigned char data) +{ + out8(CFG_ISA_IO_BASE_ADDRESS + KDB_DATA_PORT, data); +} + +int kbd_read_data(void) +{ + int val; + unsigned char status; + + val=-1; + status = kbd_read_status(); + if (status & KBD_STAT_OBF) { + val = kbd_read_input(); + if (status & (KBD_STAT_GTO | KBD_STAT_PERR)) + val = -2; + } + return val; +} + +int kbd_wait_for_input(void) +{ + unsigned long timeout; + int val; + + timeout = KBD_TIMEOUT; + val=kbd_read_data(); + while(val < 0) + { + if(timeout--==0) + return -1; + udelay(1000); + val=kbd_read_data(); + } + return val; +} + + +void kb_wait(void) +{ + unsigned long timeout = KBC_TIMEOUT; + + do { + unsigned char status = handle_kbd_event(); + if (! (status & KBD_STAT_IBF)) + return; + udelay(50000); + timeout--; + } while (timeout); +} + +void kbd_write_command_w(int data) +{ + kb_wait(); + kbd_write_command(data); +} + +void kbd_write_output_w(int data) +{ + kb_wait(); + kbd_write_output(data); +} + +void kbd_send_data(unsigned char data) +{ + unsigned char status; + disable_8259A_irq(1); /* disable interrupt */ + kbd_write_output_w(data); + status = kbd_wait_for_input(); + if (status == KBD_REPLY_ACK) + enable_8259A_irq(1); /* enable interrupt */ +} + + +char * kbd_initialize(void) +{ + int status; + + in_pointer = 0; /* delete in Buffer */ + out_pointer = 0; + /* + * Test the keyboard interface. + * This seems to be the only way to get it going. + * If the test is successful a x55 is placed in the input buffer. + */ + kbd_write_command_w(KBD_CCMD_SELF_TEST); + if (kbd_wait_for_input() != 0x55) + return "Keyboard failed self test"; + /* + * Perform a keyboard interface test. This causes the controller + * to test the keyboard clock and data lines. The results of the + * test are placed in the input buffer. + */ + kbd_write_command_w(KBD_CCMD_KBD_TEST); + if (kbd_wait_for_input() != 0x00) + return "Keyboard interface failed self test"; + /* + * Enable the keyboard by allowing the keyboard clock to run. + */ + kbd_write_command_w(KBD_CCMD_KBD_ENABLE); + /* + * Reset keyboard. If the read times out + * then the assumption is that no keyboard is + * plugged into the machine. + * This defaults the keyboard to scan-code set 2. + * + * Set up to try again if the keyboard asks for RESEND. + */ + do { + kbd_write_output_w(KBD_CMD_RESET); + status = kbd_wait_for_input(); + if (status == KBD_REPLY_ACK) + break; + if (status != KBD_REPLY_RESEND) + { + PRINTF("status: %X\n",status); + return "Keyboard reset failed, no ACK"; + } + } while (1); + + if (kbd_wait_for_input() != KBD_REPLY_POR) + return "Keyboard reset failed, no POR"; + + /* + * Set keyboard controller mode. During this, the keyboard should be + * in the disabled state. + * + * Set up to try again if the keyboard asks for RESEND. + */ + do { + kbd_write_output_w(KBD_CMD_DISABLE); + status = kbd_wait_for_input(); + if (status == KBD_REPLY_ACK) + break; + if (status != KBD_REPLY_RESEND) + return "Disable keyboard: no ACK"; + } while (1); + + kbd_write_command_w(KBD_CCMD_WRITE_MODE); + kbd_write_output_w(KBD_MODE_KBD_INT + | KBD_MODE_SYS + | KBD_MODE_DISABLE_MOUSE + | KBD_MODE_KCC); + + /* ibm powerpc portables need this to use scan-code set 1 -- Cort */ + kbd_write_command_w(KBD_CCMD_READ_MODE); + if (!(kbd_wait_for_input() & KBD_MODE_KCC)) { + /* + * If the controller does not support conversion, + * Set the keyboard to scan-code set 1. + */ + kbd_write_output_w(0xF0); + kbd_wait_for_input(); + kbd_write_output_w(0x01); + kbd_wait_for_input(); + } + kbd_write_output_w(KBD_CMD_ENABLE); + if (kbd_wait_for_input() != KBD_REPLY_ACK) + return "Enable keyboard: no ACK"; + + /* + * Finally, set the typematic rate to maximum. + */ + kbd_write_output_w(KBD_CMD_SET_RATE); + if (kbd_wait_for_input() != KBD_REPLY_ACK) + return "Set rate: no ACK"; + kbd_write_output_w(0x00); + if (kbd_wait_for_input() != KBD_REPLY_ACK) + return "Set rate: no ACK"; + return NULL; +} + +void kbd_interrupt(void) +{ + handle_kbd_event(); +} + + + +/* eof */ + diff --git a/board/pip405/kbd.h b/board/pip405/kbd.h new file mode 100644 index 0000000..e2cdf37 --- /dev/null +++ b/board/pip405/kbd.h @@ -0,0 +1,35 @@ +/* + * (C) Copyright 2001 + * Denis Peter, MPL AG Switzerland, d.peter@mpl.ch + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +#ifndef _KBD_H_ +#define _KBD_H_ + +extern int kbd_testc(void); +extern int kbd_getc(void); +extern void kbd_interrupt(void); +extern char *kbd_initialize(void); + +unsigned char kbd_is_init(void); +#define KBD_INTERRUPT 1 +#endif diff --git a/board/pip405/pci_piix4.h b/board/pip405/pci_piix4.h new file mode 100644 index 0000000..2974fc2 --- /dev/null +++ b/board/pip405/pci_piix4.h @@ -0,0 +1,179 @@ +/* + * (C) Copyright 2001 + * Denis Peter, MPL AG Switzerland, d.peter@mpl.ch + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + */ +#ifndef _PCI_PIXX4_H +#define _PCI_PIXX4_H + +/*************************************************************************** +* Defines PIIX4 Config Registers +****************************************************************************/ + +/* Function 0 ISA Bridge */ +#define PCI_CFG_PIIX4_IORT 0x4C /* 8 bit ISA Recovery Timer Reg (default 0x4D) */ +#define PCI_CFG_PIIX4_XBCS 0x4E /* 16 bit XBus Chip select reg (default 0x0003) */ +#define PCI_CFG_PIIX4_PIRQC 0x60 /* PCI IRQ Route Register 4 x 8bit (default )*/ +#define PCI_CFG_PIIX4_SERIRQ 0x64 +#define PCI_CFG_PIIX4_TOM 0x69 +#define PCI_CFG_PIIX4_MSTAT 0x6A +#define PCI_CFG_PIIX4_MBDMA 0x76 +#define PCI_CFG_PIIX4_APICBS 0x80 +#define PCI_CFG_PIIX4_DLC 0x82 +#define PCI_CFG_PIIX4_PDMACFG 0x90 +#define PCI_CFG_PIIX4_DDMABS 0x92 +#define PCI_CFG_PIIX4_GENCFG 0xB0 +#define PCI_CFG_PIIX4_RTCCFG 0xCB + +/* IO Addresses */ +#define PIIX4_ISA_DMA1_CH0BA 0x00 +#define PIIX4_ISA_DMA1_CH0CA 0x01 +#define PIIX4_ISA_DMA1_CH1BA 0x02 +#define PIIX4_ISA_DMA1_CH1CA 0x03 +#define PIIX4_ISA_DMA1_CH2BA 0x04 +#define PIIX4_ISA_DMA1_CH2CA 0x05 +#define PIIX4_ISA_DMA1_CH3BA 0x06 +#define PIIX4_ISA_DMA1_CH3CA 0x07 +#define PIIX4_ISA_DMA1_CMDST 0x08 +#define PIIX4_ISA_DMA1_REQ 0x09 +#define PIIX4_ISA_DMA1_WSBM 0x0A +#define PIIX4_ISA_DMA1_CH_MOD 0x0B +#define PIIX4_ISA_DMA1_CLR_PT 0x0C +#define PIIX4_ISA_DMA1_M_CLR 0x0D +#define PIIX4_ISA_DMA1_CLR_M 0x0E +#define PIIX4_ISA_DMA1_RWAMB 0x0F + +#define PIIX4_ISA_DMA2_CH0BA 0xC0 +#define PIIX4_ISA_DMA2_CH0CA 0xC1 +#define PIIX4_ISA_DMA2_CH1BA 0xC2 +#define PIIX4_ISA_DMA2_CH1CA 0xC3 +#define PIIX4_ISA_DMA2_CH2BA 0xC4 +#define PIIX4_ISA_DMA2_CH2CA 0xC5 +#define PIIX4_ISA_DMA2_CH3BA 0xC6 +#define PIIX4_ISA_DMA2_CH3CA 0xC7 +#define PIIX4_ISA_DMA2_CMDST 0xD0 +#define PIIX4_ISA_DMA2_REQ 0xD2 +#define PIIX4_ISA_DMA2_WSBM 0xD4 +#define PIIX4_ISA_DMA2_CH_MOD 0xD6 +#define PIIX4_ISA_DMA2_CLR_PT 0xD8 +#define PIIX4_ISA_DMA2_M_CLR 0xDA +#define PIIX4_ISA_DMA2_CLR_M 0xDC +#define PIIX4_ISA_DMA2_RWAMB 0xDE + +#define PIIX4_ISA_INT1_ICW1 0x20 +#define PIIX4_ISA_INT1_OCW2 0x20 +#define PIIX4_ISA_INT1_OCW3 0x20 +#define PIIX4_ISA_INT1_ICW2 0x21 +#define PIIX4_ISA_INT1_ICW3 0x21 +#define PIIX4_ISA_INT1_ICW4 0x21 +#define PIIX4_ISA_INT1_OCW1 0x21 + +#define PIIX4_ISA_INT1_ELCR 0x4D0 + +#define PIIX4_ISA_INT2_ICW1 0xA0 +#define PIIX4_ISA_INT2_OCW2 0xA0 +#define PIIX4_ISA_INT2_OCW3 0xA0 +#define PIIX4_ISA_INT2_ICW2 0xA1 +#define PIIX4_ISA_INT2_ICW3 0xA1 +#define PIIX4_ISA_INT2_ICW4 0xA1 +#define PIIX4_ISA_INT2_OCW1 0xA1 +#define PIIX4_ISA_INT2_IMR 0xA1 /* read only */ + +#define PIIX4_ISA_INT2_ELCR 0x4D1 + +#define PIIX4_ISA_TMR0_CNT_ST 0x40 +#define PIIX4_ISA_TMR1_CNT_ST 0x41 +#define PIIX4_ISA_TMR2_CNT_ST 0x42 +#define PIIX4_ISA_TMR_TCW 0x43 + +#define PIIX4_ISA_RST_XBUS 0x60 + +#define PIIX4_ISA_NMI_CNT_ST 0x61 +#define PIIX4_ISA_NMI_ENABLE 0x70 + +#define PIIX4_ISA_RTC_INDEX 0x70 +#define PIIX4_ISA_RTC_DATA 0x71 +#define PIIX4_ISA_RTCEXT_IND 0x70 +#define PIIX4_ISA_RTCEXT_DATA 0x71 + +#define PIIX4_ISA_DMA1_CH2LPG 0x81 +#define PIIX4_ISA_DMA1_CH3LPG 0x82 +#define PIIX4_ISA_DMA1_CH1LPG 0x83 +#define PIIX4_ISA_DMA1_CH0LPG 0x87 +#define PIIX4_ISA_DMA2_CH2LPG 0x89 +#define PIIX4_ISA_DMA2_CH3LPG 0x8A +#define PIIX4_ISA_DMA2_CH1LPG 0x8B +#define PIIX4_ISA_DMA2_LPGRFR 0x8F + +#define PIIX4_ISA_PORT_92 0x92 + +#define PIIX4_ISA_APM_CONTRL 0xB2 +#define PIIX4_ISA_APM_STATUS 0xB3 + +#define PIIX4_ISA_COCPU_ERROR 0xF0 + +/* Function 1 IDE Controller */ +#define PCI_CFG_PIIX4_BMIBA 0x20 +#define PCI_CFG_PIIX4_IDETIM 0x40 +#define PCI_CFG_PIIX4_SIDETIM 0x44 +#define PCI_CFG_PIIX4_UDMACTL 0x48 +#define PCI_CFG_PIIX4_UDMATIM 0x4A + +/* Function 2 USB Controller */ +#define PCI_CFG_PIIX4_SBRNUM 0x60 +#define PCI_CFG_PIIX4_LEGSUP 0xC0 + +/* Function 3 Power Management */ +#define PCI_CFG_PIIX4_PMAB 0x40 +#define PCI_CFG_PIIX4_CNTA 0x44 +#define PCI_CFG_PIIX4_CNTB 0x48 +#define PCI_CFG_PIIX4_GPICTL 0x4C +#define PCI_CFG_PIIX4_DEVRESD 0x50 +#define PCI_CFG_PIIX4_DEVACTA 0x54 +#define PCI_CFG_PIIX4_DEVACTB 0x58 +#define PCI_CFG_PIIX4_DEVRESA 0x5C +#define PCI_CFG_PIIX4_DEVRESB 0x60 +#define PCI_CFG_PIIX4_DEVRESC 0x64 +#define PCI_CFG_PIIX4_DEVRESE 0x68 +#define PCI_CFG_PIIX4_DEVRESF 0x6C +#define PCI_CFG_PIIX4_DEVRESG 0x70 +#define PCI_CFG_PIIX4_DEVRESH 0x74 +#define PCI_CFG_PIIX4_DEVRESI 0x78 + + + + + + + + + + + + + + + + + +#endif + diff --git a/board/pip405/pci_pip405.c b/board/pip405/pci_pip405.c new file mode 100644 index 0000000..e4dbd33 --- /dev/null +++ b/board/pip405/pci_pip405.c @@ -0,0 +1,1505 @@ +/*-----------------------------------------------------------------------------+ +| +| This source code has been made available to you by IBM on an AS-IS +| basis. Anyone receiving this source is licensed under IBM +| copyrights to use it in any way he or she deems fit, including +| copying it, modifying it, compiling it, and redistributing it either +| with or without modifications. No license under IBM patents or +| patent applications is to be implied by the copyright license. +| +| Any user of this software should understand that IBM cannot provide +| technical support for this software and will not be responsible for +| any consequences resulting from the use of this software. +| +| Any person who transfers this source code or any derivative work +| must include the IBM copyright notice, this paragraph, and the +| preceding two paragraphs in the transferred software. +| +| COPYRIGHT I B M CORPORATION 1995 +| LICENSED MATERIAL - PROGRAM PROPERTY OF I B M ++-----------------------------------------------------------------------------*/ +/* + * Adopted for PIP405 03.07.01 + * Denis Peter, MPL AG Switzerland, d.peter@mpl.ch + * + * TODO: Clean-up + */ + +#include +#include +#include +#include "pci_pip405.h" +#include +#include "pci_piix4.h" +#include "pip405_isa.h" +#include "pip405.h" +#include +#include "video.h" + + +void pciinfo(int bus_no); +#ifdef CONFIG_PPC405GP + +#ifdef CONFIG_PCI + +#undef PCI_DEBUG + +/*------------------------------------------------------------------------ +| These are the lowest addresses allowed for PCI configuration. +| They correspond to lowest available I/O and Memory addresses. +| In the case where where multiple PMM regs are being used to map +| different PLB to PCI regions, each region should have it's own +| minimum address. ++-----------------------------------------------------------------------*/ +unsigned long LowestMemAddr1 = MIN_PCI_MEMADDR1; +unsigned long LowestMemAddr2 = MIN_PCI_MEMADDR2; +unsigned long LowestIOAddr = MIN_PCI_PCI_IOADDR1; + +unsigned long MaxBusNum = 0; + + + +void PCI_Config_SCSI_contrl(int BusDevFunc); /* forward declaration */ + + +/*-----------------------------------------------------------------------------+ +| pci_init. Initializes the 405GP PCI Configuration regs. ++-----------------------------------------------------------------------------*/ +void pci_init(void) +{ + unsigned short temp_short; + +#ifdef CONFIG_PCI_HOST + /*--------------------------------------------------------------------------+ + | 405GP PCI Master configuration. + | Map one 512 MB range of PLB/processor addresses to PCI memory space. + | PLB address 0x80000000-0x9FFFFFFF ==> PCI address 0x80000000-0x9FFFFFFF + | Use byte reversed out routines to handle endianess. + +--------------------------------------------------------------------------*/ + out32r(PMM0MA, 0x00000000); /* ensure disabled b4 setting PMM0LA */ + out32r(PMM0LA, PCI_M0_LOCAL_ADDR); + out32r(PMM0PCILA, PCI_M0_PCI_LOW_ADDR); + out32r(PMM0PCIHA, PCI_M0_PCI_HIGH_ADDR); + out32r(PMM0MA, PCI_M0_MASK_ATTRIB); /* no prefetching, and enable region */ + /*--------------------------------------------------------------------------+ + | Map one 512 MB range of PLB/processor addresses to PCI memory space. + | PLB address 0xA0000000-0xBFFFFFFF ==> PCI address 0x00000000-0x1FFFFFFF + | Use byte reversed out routines to handle endianess. + | This space is for the VGA card. + +--------------------------------------------------------------------------*/ + out32r(PMM1MA, 0x00000000); /* ensure disabled b4 setting PMM1LA */ + out32r(PMM1LA, PCI_M1_LOCAL_ADDR); + out32r(PMM1PCILA, PCI_M1_PCI_LOW_ADDR); + out32r(PMM1PCIHA, PCI_M1_PCI_HIGH_ADDR); + out32r(PMM1MA, PCI_M1_MASK_ATTRIB); /* no prefetching, and enable region */ + /*--------------------------------------------------------------------------+ + | PMM2 is not used. Initialize them to zero. + +--------------------------------------------------------------------------*/ + out32r(PMM2MA, 0x00000000); /* ensure disabled b4 setting PMM2LA */ + out32r(PMM2LA, PCI_M2_LOCAL_ADDR); + out32r(PMM2PCILA, PCI_M2_PCI_LOW_ADDR); + out32r(PMM2PCIHA, PCI_M2_PCI_HIGH_ADDR); + out32r(PMM2MA, PCI_M2_MASK_ATTRIB); /* not enabled */ +#endif + + /*--------------------------------------------------------------------------+ + | 405GP PCI Target configuration. (PTM1) + | Note: PTM1MS is hardwire enabled but we set the enable bit anyway. + +--------------------------------------------------------------------------*/ + out32r(PTM1LA, CFG_PCI_PTM1LA); /* insert address */ + out32r(PTM1MS, CFG_PCI_PTM1MS); /* insert size, enable bit is 1 */ + + /*--------------------------------------------------------------------------+ + | 405GP PCI Target configuration. (PTM2) + +--------------------------------------------------------------------------*/ + out32r(PTM2LA, CFG_PCI_PTM2LA); /* insert address */ + if (CFG_PCI_PTM2MS == 0) + { + out32r(PTM2MS, 0x00000001); /* set enable bit */ + PCI_Write_CFG_Reg(PCIDEVID_405GP, PCIBASEADDR2, 0x00000000, 4); + out32r(PTM2MS, 0x00000000); /* disable */ + } + else + out32r(PTM2MS, CFG_PCI_PTM2MS); /* insert size, enable bit is 1 */ + + /* + * Insert Subsystem Vendor and Device ID + */ + PCI_Write_CFG_Reg(PCIDEVID_405GP, PCISSVENDORID, CFG_PCI_SUBSYS_VENDORID, 2); + PCI_Write_CFG_Reg(PCIDEVID_405GP, PCISSDEVICEID, CFG_PCI_SUBSYS_DEVICEID, 2); + +#ifdef CONFIG_PCI_HOST + /*--------------------------------------------------------------------------+ + | Write the 405GP PCI Configuration regs. + | Enable 405GP to be a master on the PCI bus (PMM). + | Enable 405GP to act as a PCI memory target (PTM). + +--------------------------------------------------------------------------*/ + temp_short = PCI_Read_CFG_Reg(PCIDEVID_405GP, PCICMD, 2); + PCI_Write_CFG_Reg(PCIDEVID_405GP, PCICMD, temp_short | BM_EN | MEM_EN, 2); +#endif + +#if 0 /* test-only: no need yet! */ + /*--------------------------------------------------------------------------+ + | If PCI speed = 66Mhz, set 66Mhz capable bit. + +--------------------------------------------------------------------------*/ + if (board_cfg.pci_speed==66666666) { + temp_short = PCI_Read_CFG_Reg(PCIDEVID_405GP, PCISTATUS, 2); + PCI_Write_CFG_Reg(PCIDEVID_405GP,PCISTATUS,(temp_short|CAPABLE_66MHZ), 2); + } +#endif + + /* + * Set HCE bit (Host Configuration Enabled) + */ + temp_short = PCI_Read_CFG_Reg(PCIDEVID_405GP, PCIBRDGOPT2, 2); + PCI_Write_CFG_Reg(PCIDEVID_405GP, PCIBRDGOPT2,(temp_short | 0x0001), 2); + +#ifdef CONFIG_PCI_PNP + /*--------------------------------------------------------------------------+ + | Scan the PCI bus and configure devices found. + +--------------------------------------------------------------------------*/ +#if 0 + pciScanForDevices(0); +#endif + PCI_Scan(0); + isa_sio_setup(); + +#endif /* CONFIG_PCI_PNP */ + +} + +/*-----------------------------------------------------------------------------+ +| Subroutine: PCI_Read_CFG_Reg +| Description: Read a PCI configuration register +| Inputs: +| BusDevFunc PCI Bus+Device+Function number +| Reg Configuration register number +| Width Number of bytes to read (1, 2, or 4) +| Return value: +| (unsigned int) Value of the configuration register read. +| For reads shorter than 4 bytes, return value +| is LSB-justified ++-----------------------------------------------------------------------------*/ +unsigned long PCI_Read_CFG_Reg(int BusDevFunc, int Reg, int Width) +{ + unsigned int RegAddr; + + /*--------------------------------------------------------------------------+ + | bit 31 must be 1 and bits 1:0 must be 0 (note Little Endian bit notation) + +--------------------------------------------------------------------------*/ + RegAddr = 0x80000000 | ((Reg|BusDevFunc) & 0xFFFFFFFC); + + /*--------------------------------------------------------------------------+ + | Write reg to PCI Config Address + +--------------------------------------------------------------------------*/ + out32r(PCICFGADR, RegAddr); + + /*--------------------------------------------------------------------------+ + | Read reg value from PCI Config Data + +--------------------------------------------------------------------------*/ + switch (Width) + { + case 1: return ((unsigned int) in8(PCICFGDATA | (Reg & 0x3))); + case 2: return ((unsigned int) in16r(PCICFGDATA | (Reg & 0x3))); + case 4: return (in32r(PCICFGDATA | (Reg & 0x3))); + } + + return 0; /* not reached: just to satisfy the compiler */ +} + +/*-----------------------------------------------------------------------------+ +| Subroutine: PCI_Write_CFG_Reg +| Description: Write a PCI configuration register. +| Inputs: +| BusDevFunc PCI Bus+Device+Function number +| Reg Configuration register number +| Value Configuration register value +| Width Number of bytes to write (1, 2, or 4) +| Return value: +| 0 Successful +| Updated for pass2 errata #6. Need to disable interrupts and clear the +| PCICFGADR reg after writing the PCICFGDATA reg. ++-----------------------------------------------------------------------------*/ +int PCI_Write_CFG_Reg(int BusDevFunc, int Reg, unsigned long Value, int Width) +{ + unsigned int RegAddr; + unsigned int msr; + + /*--------------------------------------------------------------------------+ + | Ensure interrupts disabled for pass2 errata #6. + +--------------------------------------------------------------------------*/ + msr = mfmsr(); + mtmsr(msr & ~(MSR_EE|MSR_CE)); + + /*--------------------------------------------------------------------------+ + | bit 31 must be 1 and bits 1:0 must be 0 (note Little Endian bit notation) + +--------------------------------------------------------------------------*/ + RegAddr = 0x80000000 | ((Reg|BusDevFunc) & 0xFFFFFFFC); + + /*--------------------------------------------------------------------------+ + | Write reg to PCI Config Address + +--------------------------------------------------------------------------*/ + out32r(PCICFGADR, RegAddr); + + /*--------------------------------------------------------------------------+ + | Write reg value to PCI Config Data + +--------------------------------------------------------------------------*/ + switch (Width) + { + case 1: out8(PCICFGDATA | (Reg & 0x3), (unsigned char)(Value & 0xFF)); + break; + case 2: out16r(PCICFGDATA | (Reg & 0x3),(unsigned short)(Value & 0xFFFF)); + break; + case 4: out32r(PCICFGDATA | (Reg & 0x3), Value); + break; + } + + /*--------------------------------------------------------------------------+ + | Write PCI Config Address after writing PCICFGDATA for pass2 errata #6. + +--------------------------------------------------------------------------*/ + out32r(PCICFGADR, 0x00000000); + + /*--------------------------------------------------------------------------+ + | Restore msr (for pass2 errata #6). + +--------------------------------------------------------------------------*/ + mtmsr(msr); + + return (0); +} + +/*----------------------------------------------------------------------- +| +| Subroutine: PCI_Scan +| +| Prototype: void PCI_Scan(int BusNum) +| +| Description: Scan through all 16 allowable PCI IDs and configure +| those for which the vendor ID indicates there is a +| device present. +| +| Inputs: +| BusNum Bus number where scanning begins +| +| Return value: +| None +| ++----------------------------------------------------------------------*/ +void PCI_Scan(int BusNum) +{ + int Device; + int BusDevFunc; + int isabridgeDev; + /*--------------------------------------------------------------------------+ + | Start with device 1, the 405GP is device 0. MCG 01/04/99 + +--------------------------------------------------------------------------*/ + /*************************************************************************** + * Since the IO and Memory Area of the ISA Bridge is not relocable, config it + * first. + ****************************************************************************/ + isabridgeDev=0; + for (Device = 1; Device < MAX_PCI_DEVICES; Device++) + { + BusDevFunc = (BusNum << 16) | (Device << 11); + + if (PCI_Read_CFG_Reg(BusDevFunc, PCIVENDORID,2) != 0xFFFF) + { + if(PCI_Read_CFG_Reg(BusDevFunc, PCICLASSCODE,2) == 0x0601) + { + isabridgeDev=Device; + PCI_Config_ISABridge(BusDevFunc); + break; /* do not scan further */ + } + } + } + /*--------------------------------------------------------------------------+ + | Start with device 1, the 405GP is device 0. MCG 01/04/99 + +--------------------------------------------------------------------------*/ + for (Device = 1; Device < MAX_PCI_DEVICES; Device++) + { + if(Device==isabridgeDev) + continue; /* skip ISA Bridge */ + BusDevFunc = (BusNum << 16) | (Device << 11); + + if (PCI_Read_CFG_Reg(BusDevFunc, PCIVENDORID,2) != 0xFFFF) + { +#ifdef PCI_DEBUG + printf("Device %d is present\n",Device); +#endif + switch( PCI_Read_CFG_Reg(BusDevFunc, PCICLASSCODE, 2) ) + { + case 0x0604: /* PCI-PCI Bridge */ +#ifdef PCI_DEBUG + printf("Device %d is PCI Bridge\n",Device); +#endif + PCI_Config_Device(BusDevFunc, 2); + PCI_Config_Bridge(BusDevFunc); + break; + case 0x0100: /* PCI-PCI Bridge */ +#ifdef PCI_DEBUG + printf("Device %d is SCSI Controller\n",Device); +#endif + PCI_Config_SCSI_contrl(BusDevFunc); + break; + + case 0x0300: /* VGA Display controller */ + case 0x0001: /* VGA Display controller (pre PCI rev 2.0)*/ +#ifdef PCI_DEBUG + printf("Device %d is VGA\n",Device); +#endif + PCI_Config_VGA_contrl(BusDevFunc); + break; + + default: +#ifdef PCI_DEBUG + printf("Device %d is a 0x%04X\n",Device,PCI_Read_CFG_Reg(BusDevFunc, PCICLASSCODE, 2)); +#endif +/* PCI_Config_Device(BusDevFunc, 6); */ + } + } + else + { +#ifdef DEBUG + printf("Device %d not present\n",Device); +#endif + } + } +} + +/* ISA Bus (logical device 0) */ +static PCI_CFG_TABLE piix4_fn0[] = { + {PCI_CFG_PIIX4_SERIRQ, 0xD0, 1},/* enable Continous SERIRQ Pin */ + {PCI_CFG_PIIX4_GENCFG, 0x00010000, 4},/* enable SERIRQs */ + {PCI_CFG_PIIX4_XBCS, 0x0000, 2}, /* disable all peri CS */ + {PCI_CFG_PIIX4_RTCCFG, 0x21, 1}, /* enable RTC */ + {0xFFFF, 0,0} /* end of device table */ +}; +/* IDE Controller (logical device 1) */ +static PCI_CFG_TABLE piix4_fn1[] = { + {PCI_CFG_COMMAND, 0x0001, 2},/* enable IO access */ + {PCI_CFG_PIIX4_IDETIM, 0x80008000, 4},/* enable Both IDE channels */ + {0xFFFF, 0,0} /* end of device table */ +}; + + + +/*----------------------------------------------------------------------- +| Subroutine: PCI_Config_ISABridge +| +| Description: Configure a PCI to ISA Bridge +| Since there address space is not relocable, we have +| to set it up manually +| +| Inputs: +| BusDevFunc Bus+Device+Function number +| Return value: +| None ++----------------------------------------------------------------------*/ +void PCI_Config_ISABridge(int BusDevFunc) +{ + + PCI_CFG_TABLE *pCT; + + if(PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_DEVICE_ID, 2)==0x7110) { + /* OK this is a PIIX4 + Memory size is 16M (ISA Memory) */ + LowestMemAddr1+=0x1000000; + /* IOSize is 64Kb (ISA IO) */ + LowestIOAddr+=0x10000; + if(LowestIOAddr>=MAX_PCI_PCI_IOADDR1) + LowestIOAddr=MIN_PCI_PCI_IOADDR2; + /* Fill in Function 0 Config */ + pCT = piix4_fn0; + while (pCT->with>0) + { + PCI_Write_CFG_Reg(BusDevFunc,pCT->index,pCT->val,pCT->with); /* Config Func 0 */ + pCT++; + } + /* init Function 1 */ + BusDevFunc|= (1<<8); + pCT = piix4_fn1; + while (pCT->with>0) + { + PCI_Write_CFG_Reg(BusDevFunc,pCT->index,pCT->val,pCT->with); /* Config Func 1 */ + pCT++; + } + printf(" Rev: PCB Rev: %c PLD%d Rev %d PLD%d Rev %d\n\n",(in8(PLD_BOARD_CFG_REG)&0xf)+'A', + in8(PLD_PART_REG)&0xf,in8(PLD_VERS_REG)&0xf, + (in8(PLD_PART_REG)>>4)&0xf,(in8(PLD_VERS_REG)>>4)&0xf); + + + } +} + +/* VGA Controller (logical device 0) */ +static PCI_CFG_TABLE ct69000_fn0[] = { + {PCI_CFG_BASE_ADDRESS_0, 0x80000000, 4},/* Frame buffer access */ + {PCI_CFG_EXPANSION_ROM, 0x00000000, 4},/* disable ROM */ + {PCI_CFG_DEV_INT_LINE, 29, 1},/* Int vector = 29 */ + {PCI_CFG_COMMAND, 0x0003, 2},/* enable IO access */ + {0xFFFF, 0,0} /* end of device table */ +}; + +/*----------------------------------------------------------------------- +| Subroutine: PCI_Config_VGA_contrl +| +| Description: Configure a PCI to ISA Bridge +| Since there address space is not relocable, we have +| to set it up manually +| +| Inputs: +| BusDevFunc Bus+Device+Function number +| Return value: +| None ++----------------------------------------------------------------------*/ +void PCI_Config_VGA_contrl(int BusDevFunc) +{ + PCI_CFG_TABLE *pCT; + + /*printf(" VGA ID %04X, busdecfunc %x\n",(short)PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_DEVICE_ID, 2),(int)BusDevFunc);*/ + if(PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_DEVICE_ID, 2)==0x00C0) { + /* OK this is the ct69000 + * Memory size is 16M (ISA Memory) */ + /* printf("C&T69000 found\n"); */ + /* configuration: + LOW_Memory: PCI Address 0x000A0000..0x000CFFFF Loc Addr. 0x800A0000..0x800CFFFF + FB_Memory: PCI Address 0x20000000..0x21000000 Loc Addr. 0xA0000000..0xA1000000 + IO_Addresses: 3B0..3DF + */ + + /* Fill in Function 0 Config */ + pCT = ct69000_fn0; + while (pCT->with>0) { + PCI_Write_CFG_Reg(BusDevFunc,pCT->index,pCT->val,pCT->with); /* Config Func 0 */ + pCT++; + } + /*printf("configured\n"); */ + /*video_init(BusDevFunc); */ + } +} + +static PCI_CFG_TABLE sym810_fn0[] = { + {PCI_CFG_BASE_ADDRESS_0, 0x00001001, 4},/* IO Base address */ + {PCI_CFG_BASE_ADDRESS_1, 0x81000000, 4},/* Memory Base address */ + {PCI_CFG_DEV_INT_LINE, 30, 1},/* Int vector = 30 */ + {PCI_CFG_COMMAND, 0x0006, 2},/* enable Memory access and busmaster */ + {0xFFFF, 0,0} /* end of device table */ +}; + +/*----------------------------------------------------------------------- +| Subroutine: PCI_Config_VGA_contrl +| +| Description: Configure a PCI to ISA Bridge +| Since there address space is not relocable, we have +| to set it up manually +| +| Inputs: +| BusDevFunc Bus+Device+Function number +| Return value: +| None ++----------------------------------------------------------------------*/ +void PCI_Config_SCSI_contrl(int BusDevFunc) +{ + PCI_CFG_TABLE *pCT; + + /*printf(" SCSI ID %04X, busdecfunc %x\n",(short)PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_DEVICE_ID, 2),(int)BusDevFunc);*/ + if((unsigned short)PCI_Read_CFG_Reg(BusDevFunc, PCI_CFG_DEVICE_ID, 2)==0x0001) { + /* OK this is a Symbois 810 + * Fill in Function 0 Config */ + pCT = sym810_fn0; + while (pCT->with>0) + { + PCI_Write_CFG_Reg(BusDevFunc,pCT->index,pCT->val,pCT->with); /* Config Func 0 */ + pCT++; + } + /*scsi_init(BusDevFunc);*/ + } +} + +/*----------------------------------------------------------------------- +| Subroutine: PCI_Config_Device +| +| Description: Configure a PCI device by examining its I/O and memory +| address space needs and allocating address space to it by +| programming the address decoders in the Base Address Registers. +| +| Inputs: +| BusDevFunc Bus+Device+Function number +| NumBaseAddr Number of base address registers to +| configure +| Return value: +| None ++----------------------------------------------------------------------*/ +void PCI_Config_Device(int BusDevFunc, int NumBaseAddr) +{ + int AddrSlot, i; + unsigned long AddrDesc, AddrProg, Min_Gnt_Val, int_line; + + for (AddrSlot = 0; AddrSlot < NumBaseAddr; AddrSlot++) + { + PCI_Write_CFG_Reg(BusDevFunc, PCIBASEADDR0 + (4*AddrSlot), 0xFFFFFFFF,4); + + AddrDesc = PCI_Read_CFG_Reg(BusDevFunc, PCIBASEADDR0 + (4*AddrSlot), 4); + + if (AddrDesc == 0) /* unimplemented, stop looking */ + continue; /* 01/04/99 MCG */ + +#ifdef PCI_DEBUG + printf("Read Base Addr Reg %d = 0x%08x\n",AddrSlot,AddrDesc); +#endif + + if ((AddrDesc & 1) == 0) /* Memory */ + { + AddrDesc &= 0xFFFFFFF0; + + for (i = 0; (AddrDesc & 1) != 1; i++) + AddrDesc = AddrDesc >> 1; + + AddrDesc = 1 << i; + + if ((unsigned long)AddrDesc < 4096) + AddrDesc = 4096; +#ifdef PCI_DEBUG + printf(" PCI Memory space = 0x%x bytes \n",AddrDesc); +#endif + for (AddrProg = MIN_PCI_MEMADDR1; AddrProg < LowestMemAddr1; AddrProg += AddrDesc); + + PCI_Write_CFG_Reg(BusDevFunc, PCIBASEADDR0 + (4*AddrSlot),AddrProg,4); + LowestMemAddr1 = AddrProg + AddrDesc; + } + else /* I/O */ + { + AddrDesc &= 0xFFFFFFFC; + + for (i = 0; (AddrDesc & 1) != 1; i++) + AddrDesc = AddrDesc >> 1; + + AddrDesc = 1 << i; +#ifdef PCI_DEBUG + printf(" PCI I/O space = 0x%x bytes \n",AddrDesc); +#endif + for (AddrProg = MIN_PCI_PCI_IOADDR2; AddrProg < LowestIOAddr; AddrProg += AddrDesc); + + PCI_Write_CFG_Reg(BusDevFunc, PCIBASEADDR0 + (4*AddrSlot),AddrProg,4); + LowestIOAddr = AddrProg + AddrDesc; + } + + } + + Min_Gnt_Val = 0x80; + PCI_Write_CFG_Reg(BusDevFunc, PCILATENCYTIM, Min_Gnt_Val, 1); + + /* + * Write pci interrupt line register (cpci405 specific) + */ + switch ((BusDevFunc >> 11) & 0x03) + { + case 0: + int_line = 27 + 2; + break; + case 1: + int_line = 27 + 3; + break; + case 2: + int_line = 27 + 0; + break; + case 3: + int_line = 27 + 1; + break; + } + PCI_Write_CFG_Reg(BusDevFunc, PCIINTLINE, int_line, 1); + + /* + * Enable i/o space, memory space and master on this device + */ + PCI_Write_CFG_Reg(BusDevFunc, PCICMD, 7, 2); + +} + +/*----------------------------------------------------------------------- +| Subroutine: PCI_Config_VGA_Device +| +| Description: Configure a PCI VGA device by examining its I/O and memory +| address space needs and allocating address space to it by +| programming the address decoders in the Base Address Registers. +| +| Inputs: +| BusDevFunc Bus+Device+Function number +| NumBaseAddr Number of base address registers to +| configure +| Return value: +| None ++----------------------------------------------------------------------*/ +void PCI_Config_VGA_Device(int BusDevFunc, int NumBaseAddr) +{ + int AddrSlot, i; + unsigned long AddrDesc, AddrProg, Min_Gnt_Val; + + for (AddrSlot = 0; AddrSlot < NumBaseAddr; AddrSlot++) + { + PCI_Write_CFG_Reg(BusDevFunc, PCIBASEADDR0 + (4*AddrSlot), 0xFFFFFFFF,4); + + AddrDesc = PCI_Read_CFG_Reg(BusDevFunc, PCIBASEADDR0 + (4*AddrSlot), 4); + + if (AddrDesc == 0) /* unimplemented, stop looking */ + continue; /* 01/04/99 MCG */ + +#ifdef PCI_DEBUG + printf("VGA Device Read Base Addr Reg %d = 0x%08x\n",AddrSlot,AddrDesc); +#endif + + if ((AddrDesc & 1) == 0) /* Memory */ + { + AddrDesc &= 0xFFFFFFF0; + + for (i = 0; (AddrDesc & 1) != 1; i++) + AddrDesc = AddrDesc >> 1; + + AddrDesc = 1 << i; + + if ((unsigned long)AddrDesc < 4096) + AddrDesc = 4096; +#ifdef PCI_DEBUG + printf(" PCI Memory space = 0x%x bytes \n",AddrDesc); +#endif + for (AddrProg = MIN_PCI_MEMADDR2; AddrProg < LowestMemAddr2; AddrProg += AddrDesc); + + PCI_Write_CFG_Reg(BusDevFunc, PCIBASEADDR0 + (4*AddrSlot),AddrProg,4); + LowestMemAddr2 = AddrProg + AddrDesc; + } + else /* I/O */ + { + AddrDesc &= 0xFFFFFFFC; + + for (i = 0; (AddrDesc & 1) != 1; i++) + AddrDesc = AddrDesc >> 1; + + AddrDesc = 1 << i; +#ifdef PCI_DEBUG + printf(" PCI I/O space = 0x%x bytes \n",AddrDesc); +#endif + for (AddrProg = MIN_PCI_PCI_IOADDR2; AddrProg < LowestIOAddr; AddrProg ++= AddrDesc); + + PCI_Write_CFG_Reg(BusDevFunc, PCIBASEADDR0 + (4*AddrSlot),AddrProg,4); + LowestIOAddr = AddrProg + AddrDesc; + } + + } + + Min_Gnt_Val = 0x80; + PCI_Write_CFG_Reg(BusDevFunc, PCILATENCYTIM, Min_Gnt_Val, 1); +} + +/*----------------------------------------------------------------------- +| +| Subroutine: PCI_Config_Bridge +| +| Prototype: void PCI_Config_Bridge(int BusDevFunc) +| +| Description: Configure a PCI-PCI bridge +| +| Inputs: +| BusDevFunc Bus+Device+Function number +| +| Return value: +| None +| ++----------------------------------------------------------------------*/ +void PCI_Config_Bridge(int BusDevFunc) +{ + int SecondaryBus; + int PrimaryBus; + int CommandReg_Val; + int InitialLowestIOAddr, InitialLowestMemAddr; + int IOBase, MemBase; + int IOLimit, MemLimit; + + InitialLowestIOAddr = LowestIOAddr; + InitialLowestMemAddr = LowestMemAddr1; + + CommandReg_Val = (unsigned short)PCI_Read_CFG_Reg(BusDevFunc, PCICMD, 2); + + /* Configure bridge's base address registers */ + + PCI_Config_Device(BusDevFunc, 2); + + if ( LowestIOAddr > InitialLowestIOAddr ) /* bridge uses IO space? */ + CommandReg_Val |= 0x01; /* enable I/O Space */ + + if ( LowestMemAddr1 > InitialLowestMemAddr ) /* bridge uses memory space? */ + CommandReg_Val |= 0x02; /* enable Memory Space */ + + PrimaryBus = (BusDevFunc >> 16) & 0xFF; + PCI_Write_CFG_Reg(BusDevFunc, PCIPCI_PRIMARYBUS, PrimaryBus, 1); + + SecondaryBus = ++MaxBusNum; + PCI_Write_CFG_Reg(BusDevFunc, PCIPCI_SECONDARYBUS, SecondaryBus, 1); + + /* Start with max. possible value for subordinate bus number */ + /* Later, after any additional child busses are found, we'll update this */ + + PCI_Write_CFG_Reg(BusDevFunc, PCIPCI_SUBORDINATEBUS, 0xFF, 1); + + /* IO Base must be on 4Kb boundary. Adjust if needed */ + + if ((LowestIOAddr % 4096) != 0) + LowestIOAddr += 4096 - (LowestIOAddr % 4096); + + PCI_Write_CFG_Reg(BusDevFunc, PCIPCI_IOBASE, (LowestIOAddr>>8) & 0xF0, 1); + PCI_Write_CFG_Reg(BusDevFunc, PCIPCI_IOBASEUPPER16, (LowestIOAddr>>16) & 0xFFFF, 2); + + IOBase = LowestIOAddr; + + /* Mem Base must be on 1 MB boundary. adjust if needed */ + if ((LowestMemAddr1 % 0x100000) != 0) + LowestMemAddr1 += 0x100000 - (LowestMemAddr1 % 0x100000); + + PCI_Write_CFG_Reg(BusDevFunc, PCIPCI_MEMBASE, (LowestMemAddr1>>16) & 0xFFF0, 2); + MemBase = LowestMemAddr1; + + PCI_Scan(SecondaryBus); + + PCI_Write_CFG_Reg(BusDevFunc, PCIPCI_SUBORDINATEBUS, MaxBusNum, 1); + + IOLimit = LowestIOAddr; + if (LowestIOAddr > IOBase) /* IO space used on secondary bus? */ + { + CommandReg_Val |= 0x01; /* enable IO Space */ + IOLimit--; /* IOLimit is highest used address */ + } + + PCI_Write_CFG_Reg(BusDevFunc, PCIPCI_IOLIMIT, ((IOLimit)>>8) & 0xF0, 1); + PCI_Write_CFG_Reg(BusDevFunc, PCIPCI_IOLIMITUPPER16, ((IOLimit)>>16) & 0xFFFF, 2); + + /* IOLIMIT is the starting address of a 4K block forwarded by the bridge. */ + /* Round LowestIOAddr up to the next 4K boundary if IO space is enabled. */ + + if ((CommandReg_Val & 0x01) == 0x01) + LowestIOAddr = (IOLimit | 0xFFF) + 1; + + MemLimit = LowestMemAddr1; + if ( LowestMemAddr1 > MemBase ) /* mem. space is used on secondary bus? */ + { + CommandReg_Val |= 0x02; /* enable Memory Space */ + MemLimit--; /* MemLimit is highest used address */ + } + + PCI_Write_CFG_Reg(BusDevFunc, PCIPCI_MEMLIMIT, ((MemLimit)>>16) & 0xFFF0, 2); + + /* MEMLIMIT is the starting address of a 1M block forwarded by the bridge. */ + /* Round LowestMemAddr up to the next 1M boundary if Memory space is enabled. */ + + if ( (CommandReg_Val & 0x02) == 0x02 ) + LowestMemAddr1 = (MemLimit | 0xFFFFF) + 1; + + /* Enable Bus Master on secondary bus */ + CommandReg_Val |= 0x04; + + PCI_Write_CFG_Reg(BusDevFunc, PCICMD, CommandReg_Val, 2); + +} + +/*----------------------------------------------------------------------- +| Subroutine: PCI_Find_Device +| +| Prototype: int PCI_Find_Device(hword VendorID, hword DeviceID); +| +| Description: +| Locate a PCI device by vendor and device number +| +| Inputs: +| VendorID Value of the device's Vendor ID field +| DeviceID Value of the device's Device ID field +| +| Return value: +| < 0 Device not found +| (int) PCI Bus+Device+Function number ++----------------------------------------------------------------------*/ +int PCI_Find_Device(unsigned short VendorID, unsigned short DeviceID) +{ + int Device; + int BusDevFunc; + int BusNum; + int Funct; + + for (BusNum = MaxBusNum; BusNum >= 0; BusNum--) + for (Device = 0; Device < MAX_PCI_DEVICES; Device++) + { + for(Funct=0;FunctheaderType = 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(baseregsize[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;iattr[i]&DESC_IS_IO)==DESC_IS_IO) + { + printf("%4lX ",pD->size[i]); + match=1; + } + } + if(match==0) + printf(" "); + match=0; + for(i=0;iattr[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 PCI address 0x80000000-0x9FFFFFFF + * Use byte reversed out routines to handle endianess. + ***********************************************************************/ +#define PCI_M0_LOCAL_ADDR 0x80000000 +#define PCI_M0_PCI_LOW_ADDR 0x80000000 +#define PCI_M0_PCI_HIGH_ADDR 0x00000000 +#define PCI_M0_MASK_ATTRIB 0xE0000001 /* no prefetching, and enable region */ +/************************************************************************** + * Map one 512 MB range of PLB/processor addresses to PCI memory space. + * PLB address 0xA0000000-0xBFFFFFFF ==> PCI address 0x00000000-0x1FFFFFFF + * This space is for the VGA card. + **************************************************************************/ +#define PCI_M1_LOCAL_ADDR 0xA0000000 +#define PCI_M1_PCI_LOW_ADDR 0x00000000 +#define PCI_M1_PCI_HIGH_ADDR 0x00000000 +#define PCI_M1_MASK_ATTRIB 0xE0000001 /* no prefetching, and enable region */ +/*************************************************************************** + * PMM2 is not used. Initialize them to zero. + *****************************************************************************/ +#define PCI_M2_LOCAL_ADDR 0x00000000 +#define PCI_M2_PCI_LOW_ADDR 0x00000000 +#define PCI_M2_PCI_HIGH_ADDR 0x00000000 +#define PCI_M2_MASK_ATTRIB 0x00000000 /* not enabled */ + +typedef struct pciHeaderDevice + { + short vendorId; /* vendor ID */ + short deviceId; /* device ID */ + short command; /* command register */ + short status; /* status register */ + char revisionId; /* revision ID */ + char classCode; /* class code */ + char subClass; /* sub class code */ + char progIf; /* programming interface */ + char cacheLine; /* cache line */ + char latency; /* latency time */ + char headerType; /* header type */ + char bist; /* BIST */ + int base0; /* base address 0 */ + int base1; /* base address 1 */ + int base2; /* base address 2 */ + int base3; /* base address 3 */ + int base4; /* base address 4 */ + int base5; /* base address 5 */ + int cis; /* cardBus CIS pointer */ + short subVendorId; /* sub system vendor ID */ + short subSystemId; /* sub system ID */ + int romBase; /* expansion ROM base address */ + int reserved0; /* reserved */ + int reserved1; /* reserved */ + char intLine; /* interrupt line */ + char intPin; /* interrupt pin */ + char minGrant; /* min Grant */ + char maxLatency; /* max Latency */ + } PCI_HEADER_DEVICE; + +typedef struct pciHeaderBridge + { + short vendorId; /* vendor ID */ + short deviceId; /* device ID */ + short command; /* command register */ + short status; /* status register */ + char revisionId; /* revision ID */ + char classCode; /* class code */ + char subClass; /* sub class code */ + char progIf; /* programming interface */ + char cacheLine; /* cache line */ + char latency; /* latency time */ + char headerType; /* header type */ + char bist; /* BIST */ + int base0; /* base address 0 */ + int base1; /* base address 1 */ + char priBus; /* primary bus number */ + char secBus; /* secondary bus number */ + char subBus; /* subordinate bus number */ + char secLatency; /* secondary latency timer */ + char ioBase; /* IO base */ + char ioLimit; /* IO limit */ + short secStatus; /* secondary status */ + short memBase; /* memory base */ + short memLimit; /* memory limit */ + short preBase; /* prefetchable memory base */ + short preLimit; /* prefetchable memory limit */ + int preBaseUpper; /* prefetchable memory base upper 32 bits */ + int preLimitUpper; /* prefetchable memory base upper 32 bits */ + short ioBaseUpper; /* IO base upper 16 bits */ + short ioLimitUpper; /* IO limit upper 16 bits */ + int reserved; /* reserved */ + int romBase; /* expansion ROM base address */ + char intLine; /* interrupt line */ + char intPin; /* interrupt pin */ + short control; /* bridge control */ + } PCI_HEADER_BRIDGE; + + +typedef struct pciRecourceDesc + { + unsigned long BusDevFunc; /* location of the device */ + short vendorId; /* vendor ID */ + short deviceId; /* device ID */ + char revisionId; /* revision ID */ + char classCode; /* class code */ + char subClass; /* sub class code */ + char progIf; /* programming interface */ + char headerType; /* header type */ + unsigned long size[MAX_PCI_BASE_REG]; /* memory sizes */ + char attr[MAX_PCI_BASE_REG]; /* memory attributes */ + char intLine; /* interrupt line */ + char intPin; /* interrupt pin */ + char pciInt; /* Pci Interrupt Line ( 0 = no, 1 = A...)*/ + } PCI_RESOURCE_DESC; + + +/* table fore PCI Initialization */ +typedef struct { + const int index; + const unsigned long val; + const int with; +} PCI_CFG_TABLE; + + + +unsigned long PCI_Read_CFG_Reg(int BusDevFunc, int Reg, int Width); +int PCI_Write_CFG_Reg(int BusDevFunc, int Reg, unsigned long Value, int Width); +void PCI_Scan(int BusNum); +void PCI_Config_Device(int BusDevFunc, int NumBaseAddr); +void PCI_Config_VGA_Device(int BusDevFunc, int NumBaseAddr); +void PCI_Config_Bridge(int BusDevFunc); +void PCI_Dump_Device(int BusDevFunc); +int PCI_Find_Device(unsigned short VendorID, unsigned short DeviceID); +void pciHeaderShow(int BusDevFunc); +void pciDheaderPrint(PCI_HEADER_DEVICE * pD); +void pciBheaderPrint(PCI_HEADER_BRIDGE * pB); +void PCI_Config_ISABridge(int BusDevFunc); +void PCI_Config_VGA_contrl(int BusDevFunc); + +void pciScanForDevices(int BusNum); +void pciShowRes(PCI_RESOURCE_DESC *pd); +int pciGetResource(PCI_RESOURCE_DESC * pR); +int pciGetHeader0(PCI_HEADER_DEVICE * pD,int BusDevFunc); + + +#endif diff --git a/board/pip405/pip405.c b/board/pip405/pip405.c new file mode 100644 index 0000000..6a8268a --- /dev/null +++ b/board/pip405/pip405.c @@ -0,0 +1,889 @@ +/* + * (C) Copyright 2001 + * Denis Peter, MPL AG Switzerland, d.peter@mpl.ch + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * TODO: clean-up + */ + +#include +#include "pip405.h" +#include +#include <405gp_i2c.h> +#include "pip405_isa.h" +#include "video.h" + + +extern block_dev_desc_t * scsi_get_dev(int dev); +extern block_dev_desc_t * ide_get_dev(int dev); + +#undef SDRAM_DEBUG + +#define FALSE 0 +#define TRUE 1 + +/* stdlib.h causes some compatibility problems; should fixe these! -- wd */ +#ifndef __ldiv_t_defined +typedef struct { + long int quot; /* Quotient */ + long int rem; /* Remainder */ +} ldiv_t; +extern ldiv_t ldiv (long int __numer, long int __denom); +# define __ldiv_t_defined 1 +#endif + + + + +typedef enum { + SDRAM_NO_ERR, + SDRAM_SPD_COMM_ERR, + SDRAM_SPD_CHKSUM_ERR, + SDRAM_UNSUPPORTED_ERR, + SDRAM_UNKNOWN_ERR +} SDRAM_ERR; + +typedef struct { + const unsigned char mode; + const unsigned char row; + const unsigned char col; + const unsigned char bank; +} SDRAM_SETUP; + +static const SDRAM_SETUP sdram_setup_table[] = { + {1, 11, 9, 2}, + {1, 11, 10, 2}, + {2, 12, 9, 4}, + {2, 12, 10, 4}, + {3, 13, 9, 4}, + {3, 13, 10, 4}, + {3, 13, 11, 4}, + {4, 12, 8, 2}, + {4, 12, 8, 4}, + {5, 11, 8, 2}, + {5, 11, 8, 4}, + {6, 13, 8, 2}, + {6, 13, 8, 4}, + {7, 13, 9, 2}, + {7, 13, 10, 2}, + {0, 0, 0, 0} +}; + +static const unsigned char cal_indextable[] = { + 9, 23, 25 +}; + + +/* + * translate ns.ns/10 coding of SPD timing values + * into 10 ps unit values + */ + +unsigned short NS10to10PS(unsigned char spd_byte, unsigned char spd_version) +{ + unsigned short ns, ns10; + + /* isolate upper nibble */ + ns = (spd_byte >> 4) & 0x0F; + /* isolate lower nibble */ + ns10 = (spd_byte & 0x0F); + + return(ns*100 + ns10*10); +} + +/* + * translate ns.ns/4 coding of SPD timing values + * into 10 ps unit values + */ + +unsigned short NS4to10PS(unsigned char spd_byte, unsigned char spd_version) +{ + unsigned short ns, ns4; + + /* isolate upper 6 bits */ + ns = (spd_byte >> 2) & 0x3F; + /* isloate lower 2 bits */ + ns4 = (spd_byte & 0x03); + + return(ns*100 + ns4*25); +} + +/* + * translate ns coding of SPD timing values + * into 10 ps unit values + */ + +unsigned short NSto10PS(unsigned char spd_byte) +{ + return(spd_byte*100); +} + +#ifdef SDRAM_DEBUG + +void write_hex(unsigned char i) +{ + char cc; + cc=i>>4; + cc&=0xf; + if(cc>9) + serial_putc(cc+55); + else + serial_putc(cc+48); + cc=i&0xf; + if(cc>9) + serial_putc(cc+55); + else + serial_putc(cc+48); +} +#endif + +int board_pre_init (void) +{ + unsigned char dataout[1]; + unsigned char datain[128]; + unsigned long sdram_size; + SDRAM_SETUP *t = (SDRAM_SETUP *)sdram_setup_table; + unsigned long memclk; + unsigned long tmemclk; + unsigned long tmp, bank, baseaddr, bank_size; + unsigned short i; + unsigned char rows, cols, banks, sdram_banks, density; + unsigned char supported_cal, trp_clocks, trcd_clocks, tras_clocks, trc_clocks; + unsigned char cal_index, cal_val, spd_version, spd_chksum; + unsigned char buf[8]; + + memclk = get_bus_freq(tmemclk); + tmemclk = 1000000000 / (memclk / 100); /* in 10 ps units */ + +#ifdef SDRAM_DEBUG + serial_init(198000000,9600); + serial_puts("\nstart SDRAM Setup\n"); +#endif + + /* Read Serial Presence Detect Information */ + dataout[0] = 0; + for (i=0; i<128;i++) + datain[i] = 127; + i2c_send(SDRAM_EEPROM_WRITE_ADDRESS,1,dataout); + i2c_receive(SDRAM_EEPROM_READ_ADDRESS,128,datain); +#if 0 + for (i=0;i<128;i++) + { + write_hex(datain[i]); + serial_puts(" "); + if (((i+1)%16) == 0) + serial_puts("\n"); + } + serial_puts("\n"); +#endif + spd_chksum = 0; + for (i = 0; i < 63; i++) { + spd_chksum += datain[i]; + } /* endfor */ + if (datain[63] != spd_chksum) { +#ifdef SDRAM_DEBUG + serial_puts("SPD chksum: 0x"); + write_hex(datain[63]); + serial_puts(" != calc. chksum: 0x"); + write_hex(spd_chksum); + serial_puts("\n"); +#endif + } + /* SPD seems to be ok, use it */ + + /* get SPD version */ + spd_version = datain[62]; + + /* do some sanity checks on the kind of RAM */ + if ((datain[0] < 0x80) || /* less than 128 valid bytes in SPD */ + (datain[2] != 0x04) || /* if not SDRAM */ + (!((datain[6] == 0x40) || + (datain[6] == 0x48))) || /* or not (64 Bit or 72 Bit) */ + (datain[7] != 0x00) || + (datain[8] != 0x01) || /* or not LVTTL signal levels */ + (datain[126] == 0x66)) /* or a 66Mhz modules */ + serial_puts("\nunsupported SDRAM\n"); +#ifdef SDRAM_DEBUG + serial_puts("SDRAM sanity ok\n"); +#endif + + /* get number of rows/cols/banks out of byte 3+4+5 */ + rows = datain[3]; cols = datain[4]; banks = datain[5]; + + /* get number of SDRAM banks out of byte 17 and + supported CAS latencies out of byte 18 */ + sdram_banks = datain[17]; supported_cal = datain[18] & ~0x81; + + while (t->mode != 0) { + if ((t->row == rows) && (t->col == cols) && (t->bank == sdram_banks)) + break; + t++; + } /* endwhile */ + +#ifdef SDRAM_DEBUG + serial_puts("mode: "); + write_hex(t->mode); + serial_puts("\n"); +#endif + if (t->mode == 0) + puts("\nunsupported SDRAM\n"); + /* get tRP, tRCD, tRAS and density from byte 27+29+30+31 */ +#ifdef SDRAM_DEBUG + serial_puts("tRP: "); + write_hex(datain[27]); + serial_puts("\ntRCD: "); + write_hex(datain[29]); + serial_puts("\ntRAS: "); + write_hex(datain[30]); + serial_puts("\n"); +#endif + + trp_clocks = (NSto10PS(datain[27])+(tmemclk-1)) / tmemclk; + trcd_clocks = (NSto10PS(datain[29])+(tmemclk-1)) / tmemclk; + tras_clocks = (NSto10PS(datain[30])+(tmemclk-1)) / tmemclk; + density = datain[31]; + + /* trc_clocks is sum of trp_clocks + tras_clocks */ + trc_clocks = trp_clocks + tras_clocks; + + cal_val = 255; + for (i = 6, cal_index = 0; (i > 0) && (cal_index < 3); i--) { + /* is this CAS latency supported ? */ + if ((supported_cal >> i) & 0x01) { + buf[0]=datain[cal_indextable[cal_index]]; + if (cal_index < 2) { + if (NS10to10PS(buf[0], spd_version) <= tmemclk) + cal_val = i; + } + else { + /* SPD bytes 25+26 have another format */ + if (NS4to10PS(buf[0], spd_version) <= tmemclk) + cal_val = i; + } /* endif */ + cal_index++; + } /* endif */ + } /* endfor */ +#ifdef SDRAM_DEBUG + serial_puts("CAL: "); + write_hex(cal_val+1); + serial_puts("\n"); +#endif + + if (cal_val == 255) + puts("\nunsupported SDRAM\n"); + + /* get SDRAM timing register */ + mtdcr(memcfga,mem_sdtr1); + tmp=mfdcr(memcfgd) & ~0x018FC01F; + /* insert CASL value */ + tmp |= ((unsigned long)cal_val) << 23; + /* insert PTA value */ + tmp |= ((unsigned long)(trp_clocks - 1)) << 18; + /* insert CTP value */ + tmp |= ((unsigned long)(trc_clocks - trp_clocks - trcd_clocks - 1)) << 16; + /* insert LDF (always 01) */ + tmp |= ((unsigned long)0x01) << 14; + /* insert RFTA value */ + tmp |= ((unsigned long)(trc_clocks - 4)) << 2; + /* insert RCD value */ + tmp |= ((unsigned long)(trcd_clocks - 1)) << 0; + + /* write SDRAM timing register */ + mtdcr(memcfga,mem_sdtr1); + mtdcr(memcfgd,tmp); + baseaddr=CFG_SDRAM_BASE; + bank_size = (((unsigned long)density) << 22) / 2; + /* insert AM value */ + tmp = ((unsigned long)t->mode-1) << 13; + /* insert SZ value; */ + switch (bank_size) { + case 0x00400000: tmp |= ((unsigned long)0x00) << 17; break; + case 0x00800000: tmp |= ((unsigned long)0x01) << 17; break; + case 0x01000000: tmp |= ((unsigned long)0x02) << 17; break; + case 0x02000000: tmp |= ((unsigned long)0x03) << 17; break; + case 0x04000000: tmp |= ((unsigned long)0x04) << 17; break; + case 0x08000000: tmp |= ((unsigned long)0x05) << 17; break; + case 0x10000000: tmp |= ((unsigned long)0x06) << 17; break; + default: serial_puts("unsupported SDRAM\n"); + } /* endswitch */ + + /* get SDRAM bank 0 register */ + mtdcr(memcfga,mem_mb0cf); + bank = mfdcr(memcfgd) & ~0xFFCEE001; + bank |= (baseaddr | tmp | 0x01); + baseaddr += bank_size; + sdram_size += bank_size; + + /* write SDRAM bank 0 register */ + mtdcr(memcfga,mem_mb0cf); + mtdcr(memcfgd,bank); + + /* get SDRAM bank 1 register */ + mtdcr(memcfga,mem_mb1cf); + bank = mfdcr(memcfgd) & ~0xFFCEE001; + sdram_size=0; + if (banks == 2) { + bank |= (baseaddr | tmp | 0x01); + baseaddr += bank_size; + sdram_size += bank_size; + } /* endif */ + + /* write SDRAM bank 1 register */ + mtdcr(memcfga,mem_mb1cf); + mtdcr(memcfgd,bank); + + + /* get SDRAM bank 2 register */ + mtdcr(memcfga,mem_mb2cf); + bank = mfdcr(memcfgd) & ~0xFFCEE001; + + bank |= (baseaddr | tmp | 0x01); + baseaddr += bank_size; + sdram_size += bank_size; + + /* write SDRAM bank 2 register */ + mtdcr(memcfga,mem_mb2cf); + mtdcr(memcfgd,bank); + + + /* get SDRAM bank 3 register */ + mtdcr(memcfga,mem_mb3cf); + bank = mfdcr(memcfgd) & ~0xFFCEE001; + + if (banks == 2) { + bank |= (baseaddr | tmp | 0x01); + baseaddr += bank_size; + sdram_size += bank_size; + } /* endif */ + + /* write SDRAM bank 3 register */ + mtdcr(memcfga,mem_mb3cf); + mtdcr(memcfgd,bank); + + + /* get SDRAM refresh interval register */ + mtdcr(memcfga,mem_rtr); + tmp = mfdcr(memcfgd) & ~0x3FF80000; + + if (tmemclk < NSto10PS(16)) + tmp |= 0x05F00000; + else + tmp |= 0x03F80000; + + /* write SDRAM refresh interval register */ + mtdcr(memcfga,mem_rtr); + mtdcr(memcfgd,tmp); + + /* enable SDRAM controller with no ECC, 32-bit SDRAM width, 16 byte burst */ + mtdcr(memcfga,mem_mcopt1); + tmp = (mfdcr(memcfgd) & ~0xFFE00000) | 0x80C00000; + mtdcr(memcfga,mem_mcopt1); + mtdcr(memcfgd,tmp); + + + + /*-------------------------------------------------------------------------+ + | Interrupt controller setup for the PIP405 board. + | Note: IRQ 0-15 405GP internally generated; active high; level sensitive + | IRQ 16 405GP internally generated; active low; level sensitive + | IRQ 17-24 RESERVED + | IRQ 25 (EXT IRQ 0) SouthBridg; active low; level sensitive + | IRQ 26 (EXT IRQ 1) NMI: active low; level sensitive + | IRQ 27 (EXT IRQ 2) SMI: active Low; level sensitive + | IRQ 28 (EXT IRQ 3) PCI SLOT 3; active low; level sensitive + | IRQ 29 (EXT IRQ 4) PCI SLOT 2; active low; level sensitive + | IRQ 30 (EXT IRQ 5) PCI SLOT 1; active low; level sensitive + | IRQ 31 (EXT IRQ 6) PCI SLOT 0; active low; level sensitive + | Note for PIP405 board: + | An interrupt taken for the SouthBridge (IRQ 25) indicates that + | the Interrupt Controller in the South Bridge has caused the + | interrupt. The IC must be read to determine which device + | caused the interrupt. + | + +-------------------------------------------------------------------------*/ + mtdcr(uicsr, 0xFFFFFFFF); /* clear all ints */ + mtdcr(uicer, 0x00000000); /* disable all ints */ + mtdcr(uiccr, 0x00000000); /* set all to be non-critical (for now)*/ + mtdcr(uicpr, 0xFFFFFF80); /* set int polarities */ + mtdcr(uictr, 0x10000000); /* set int trigger levels */ + mtdcr(uicvcr, 0x00000001); /* set vect base=0,INT0 highest priority*/ + mtdcr(uicsr, 0xFFFFFFFF); /* clear all ints */ + + return 0; +} + + +/* ------------------------------------------------------------------------- */ + +/* + * Check Board Identity: + */ + +int checkboard (void) +{ + unsigned char s[32]; + unsigned char bc; + int i; + i=getenv_r("serial#",s,32); + if ((i==0) || strncmp(s, "PIP405", 6)) { + printf ("### No HW ID - assuming PIP405 "); + } + else { + s[6]=0; + printf("%s SN: %s",s,&s[7]); + } + bc=in8(CONFIG_PORT_ADDR); + printf(" Boot Config: 0x%x\n",bc); + return (0); +} + + +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ +/* + initdram(int board_type) reads EEPROM via I2c. EEPROM contains all of + the necessary info for SDRAM controller configuration +*/ +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ +long int initdram (int board_type) +{ + unsigned long bank_reg[4],tmp,bank_size; + int i,ds; + unsigned long TotalSize; + + ds=0; + /* since the DRAM controller is allready set up, calculate the size with the + bank registers */ + mtdcr(memcfga,mem_mb0cf); + bank_reg[0] = mfdcr(memcfgd); + mtdcr(memcfga,mem_mb1cf); + bank_reg[1] = mfdcr(memcfgd); + mtdcr(memcfga,mem_mb2cf); + bank_reg[2] = mfdcr(memcfgd); + mtdcr(memcfga,mem_mb3cf); + bank_reg[3] = mfdcr(memcfgd); + TotalSize=0; + for(i=0;i<4;i++) + { + if((bank_reg[i]&0x1)==0x1) + { + tmp=(bank_reg[i]>>17)&0x7; + bank_size=4< *(1024*1024) */ + return (TotalSize*1024*1024); +} + +/* ------------------------------------------------------------------------- */ + +int testdram (void) +{ + /* TODO: XXX XXX XXX */ + printf ("test: xxx MB - ok\n"); + + return (0); +} + +/* ------------------------------------------------------------------------- */ + + /* switches the cs0 and the cs1 to the locations. + When boot is TRUE, the the mapping is switched + to the boot configuration, If it is FALSE, the + flash will be switched in the boot area */ + + +int switch_cs(unsigned char boot) +{ + unsigned long pbcr; + mtdcr(ebccfga, pb0cr); /* get cs0 config reg */ + pbcr = mfdcr(ebccfgd); + if((pbcr&0x00002000)==0) { + /* we need only to switch if boot from MPS */ + /*printf(" MPS boot mode detected. ");*/ + /* printf("cs0 cfg: %lx\n",pbcr); */ + if(boot==TRUE) { + /* switch to boot configuration */ + /* this is a 8bit boot, switch cs0 to flash location */ + /* printf("switch to boot mode (MPS on High address\n"); */ + pbcr&=0x000FFFFF; /*mask base address of the cs0 */ + pbcr|=(FLASH_BASE0_PRELIM & 0xFFF00000); + mtdcr(ebccfga, pb0cr); + mtdcr(ebccfgd, pbcr); + /* printf(" new cs0 cfg: %lx\n",pbcr); */ + mtdcr(ebccfga, pb1cr); /* get cs1 config reg (flash) */ + pbcr = mfdcr(ebccfgd); + /* printf(" old cs1 cfg: %lx\n",pbcr); */ + pbcr&=0x000FFFFF; /*mask base address of the cs1 */ + pbcr|=(MULTI_PURPOSE_SOCKET_ADDR & 0xFFF00000); + mtdcr(ebccfga, pb1cr); + mtdcr(ebccfgd, pbcr); + /* printf(" new cs1 cfg: %lx, MPS is on High Address\n",pbcr); */ + } + else + { + /* map flash to boot area, */ + /*printf("map Flash to boot area\n"); */ + pbcr&=0x000FFFFF; /*mask base address of the cs0 */ + pbcr|=(MULTI_PURPOSE_SOCKET_ADDR & 0xFFF00000); + mtdcr(ebccfga, pb0cr); + mtdcr(ebccfgd, pbcr); +/* printf(" new cs0 cfg: %lx\n",pbcr); */ + mtdcr(ebccfga, pb1cr); /* get cs1 config reg (flash) */ + pbcr = mfdcr(ebccfgd); +/* printf(" cs1 cfg: %lx\n",pbcr); */ + pbcr&=0x000FFFFF; /*mask base address of the cs1 */ + pbcr|=(FLASH_BASE0_PRELIM & 0xFFF00000); + mtdcr(ebccfga, pb1cr); + mtdcr(ebccfgd, pbcr); +/* printf(" new cs1 cfg: %lx Flash is on High Address\n",pbcr); */ + } + return TRUE; + } + else + return FALSE; +/* printf("Normal boot, no switching necessary\n"); */ +} + +/************************************************************************ +* Print PIP405 Info +************************************************************************/ +void print_pip405_info(void) +{ + unsigned char part,vers,cfg,ledu,sysman,flashcom,can,serpwr,compwr,nicvga,scsirst; + + part=in8(PLD_PART_REG); + vers=in8(PLD_VERS_REG); + cfg=in8(PLD_BOARD_CFG_REG); + ledu=in8(PLD_LED_USER_REG); + sysman=in8(PLD_SYS_MAN_REG); + flashcom=in8(PLD_FLASH_COM_REG); + can=in8(PLD_CAN_REG); + serpwr=in8(PLD_SER_PWR_REG); + compwr=in8(PLD_COM_PWR_REG); + nicvga=in8(PLD_NIC_VGA_REG); + scsirst=in8(PLD_SCSI_RST_REG); + printf("PLD Part %d version %d\n",part&0xf,vers&0xf); + printf("PLD Part %d version %d\n",(part>>4)&0xf,(vers>>4)&0xf); + printf("Board Revision %c\n",(cfg&0xf)+'A'); + printf("Population Options %d %d %d %d\n",(cfg>>4)&0x1,(cfg>>5)&0x1,(cfg>>6)&0x1,(cfg>>7)&0x1); + printf("User LED0 %s User LED1 %s\n",((ledu&0x1)==0x1) ? "on" : "off",((ledu&0x2)==0x2) ? "on" : "off"); + printf("Additionally Options %d %d\n",(ledu>>2)&0x1,(ledu>>3)&0x1); + printf("User Config Switch %d %d %d %d\n",(ledu>>4)&0x1,(ledu>>5)&0x1,(ledu>>6)&0x1,(ledu>>7)&0x1); + switch(sysman&0x3) + { + case 0: printf("PCI Clocks are running\n"); break; + case 1: printf("PCI Clocks are stopped in POS State\n"); break; + case 2: printf("PCI Clocks are stopped when PCI_STP# is asserted\n"); break; + case 3: printf("PCI Clocks are stopped\n"); break; + } + switch((sysman>>2)&0x3) + { + case 0: printf("Main Clocks are running\n"); break; + case 1: printf("Main Clocks are stopped in POS State\n"); break; + case 2: + case 3: printf("PCI Clocks are stopped\n"); break; + } + printf("INIT asserts %sINT2# (SMI)\n",((sysman&0x10)==0x10) ? "" : "not "); + printf("INIT asserts %sINT1# (NMI)\n",((sysman&0x20)==0x20) ? "" : "not "); + printf("INIT occured %d\n",(sysman>>6)&0x1); + printf("SER1 is routed to %s\n",((flashcom&0x1)==0x1) ? "RS485" : "RS232"); + printf("COM2 is routed to %s\n",((flashcom&0x2)==0x2) ? "RS485" : "RS232"); + printf("RS485 is configured as %s duplex\n",((flashcom&0x4)==0x4) ? "full" : "half"); + printf("RS485 is connected to %s\n",((flashcom&0x8)==0x8) ? "COM1" : "COM2"); + printf("SER1 uses handshakes %s\n",((flashcom&0x10)==0x10) ? "DTR/DSR" : "RTS/CTS"); + printf("Bootflash is %swriteprotected\n",((flashcom&0x20)==0x20) ? "not " : ""); + printf("Bootflash VPP is %s\n",((flashcom&0x40)==0x40) ? "on" : "off"); + printf("Bootsector is %swriteprotected\n",((flashcom&0x80)==0x80) ? "not " : ""); + switch((can)&0x3) + { + case 0: printf("CAN Controller is on address 0x1000..0x10FF\n"); break; + case 1: printf("CAN Controller is on address 0x8000..0x80FF\n"); break; + case 2: printf("CAN Controller is on address 0xE000..0xE0FF\n"); break; + case 3: printf("CAN Controller is disabled\n"); break; + } + switch((can>>2)&0x3) + { + case 0: printf("CAN Controller Reset is ISA Reset\n"); break; + case 1: printf("CAN Controller Reset is ISA Reset and POS State\n"); break; + case 2: + case 3: printf("CAN Controller is in reset\n"); break; + } + if(((can>>4)<3)||((can>>4)==8)||((can>>4)==13)) + printf("CAN Interrupt is disabled\n"); + else + printf("CAN Interrupt is ISA INT%d\n",(can>>4)&0xf); + switch(serpwr&0x3) + { + case 0: printf("SER0 Drivers are enabled\n"); break; + case 1: printf("SER0 Drivers are disabled in the POS state\n"); break; + case 2: + case 3: printf("SER0 Drivers are disabled\n"); break; + } + switch((serpwr>>2)&0x3) + { + case 0: printf("SER1 Drivers are enabled\n"); break; + case 1: printf("SER1 Drivers are disabled in the POS state\n"); break; + case 2: + case 3: printf("SER1 Drivers are disabled\n"); break; + } + switch(compwr&0x3) + { + case 0: printf("COM1 Drivers are enabled\n"); break; + case 1: printf("COM1 Drivers are disabled in the POS state\n"); break; + case 2: + case 3: printf("COM1 Drivers are disabled\n"); break; + } + switch((compwr>>2)&0x3) + { + case 0: printf("COM2 Drivers are enabled\n"); break; + case 1: printf("COM2 Drivers are disabled in the POS state\n"); break; + case 2: + case 3: printf("COM2 Drivers are disabled\n"); break; + } + switch((nicvga)&0x3) + { + case 0: printf("PHY is running\n"); break; + case 1: printf("PHY is in Power save mode in POS state\n"); break; + case 2: + case 3: printf("PHY is in Power save mode\n"); break; + } + switch((nicvga>>2)&0x3) + { + case 0: printf("VGA is running\n"); break; + case 1: printf("VGA is in Power save mode in POS state\n"); break; + case 2: + case 3: printf("VGA is in Power save mode\n"); break; + } + printf("PHY is %sreseted\n",((nicvga&0x10)==0x10)?"":"not "); + printf("VGA is %sreseted\n",((nicvga&0x20)==0x20)?"":"not "); + printf("Reserved Configuration is %d %d\n",(nicvga>>6)&0x1,(nicvga>>7)&0x1); + switch((scsirst)&0x3) + { + case 0: printf("SCSI Controller is running\n"); break; + case 1: printf("SCSI Controller is in Power save mode in POS state\n"); break; + case 2: + case 3: printf("SCSI Controller is in Power save mode\n"); break; + } + printf("SCSI termination is %s\n",((scsirst&0x4)==0x4)?"disabled":"enabled"); + printf("SCSI Controller is %sreseted\n",((scsirst&0x10)==0x10)?"":"not "); + printf("IDE disks are %sreseted\n",((scsirst&0x20)==0x20)?"":"not "); + printf("ISA Bus is %sreseted\n",((scsirst&0x40)==0x40)?"":"not "); + printf("Super IO is %sreseted\n",((scsirst&0x80)==0x80)?"":"not "); +} + +void user_led0(unsigned char on) +{ + if(on==TRUE) + out8(PLD_LED_USER_REG,(in8(PLD_LED_USER_REG)|0x1)); + else + out8(PLD_LED_USER_REG,(in8(PLD_LED_USER_REG)&0xfe)); +} + +void user_led1(unsigned char on) +{ + if(on==TRUE) + out8(PLD_LED_USER_REG,(in8(PLD_LED_USER_REG)|0x2)); + else + out8(PLD_LED_USER_REG,(in8(PLD_LED_USER_REG)&0xfd)); +} + +void ide_set_reset(int idereset) +{ + /* if reset = 1 IDE reset will be asserted */ + unsigned char resreg; + resreg=in8(PLD_SCSI_RST_REG); + if(idereset==1) + resreg|=0x20; + else + resreg&=0xdf; + out8(PLD_SCSI_RST_REG,resreg); +} + + +/****************************************************** + * Routines to display the Board information + * to the screen (since the VGA will be initialized as last, + * we must resend the infos) + */ + +void video_put_dev_string(block_dev_desc_t *dev_desc) +{ + char buf[80]; + ldiv_t mb; + unsigned long lba512; /* number of blocks if 512bytes block size */ + + if(dev_desc->type!=DEV_TYPE_UNKNOWN) { + if(dev_desc->if_type==IF_TYPE_SCSI) + sprintf(buf,"SCSI %d: (%d:%d) ",dev_desc->dev,dev_desc->target,dev_desc->lun); + else + sprintf(buf,"IDE %d: ",dev_desc->dev); + video_puts(buf); + switch(dev_desc->type & 0x1F) { + case DEV_TYPE_HARDDISK: video_puts("Hard Disk"); break; + case DEV_TYPE_CDROM: video_puts("CD ROM"); break; + case DEV_TYPE_OPDISK: video_puts("Optical Device"); break; + case DEV_TYPE_TAPE: video_puts("Tape"); break; + default: video_puts("unknown"); break; + } + video_puts(" "); + video_puts(dev_desc->vendor); + video_puts(" "); + if(dev_desc->if_type!=IF_TYPE_IDE) + video_puts(dev_desc->product); + + if((dev_desc->lba * dev_desc->blksz)>0L) { + lba512=dev_desc->lba * (dev_desc->blksz/512); + mb = ldiv(lba512, 2048); /* (1024 *1024 / 512 MB */ + /* round to 1 digit */ + mb.rem *= 10 * 512; + mb.rem += 512 * 1024; + mb.rem /= 1024 * 1024; + sprintf (buf," %ld x %ld Bytes = %ld.%ld MB\n",dev_desc->lba,dev_desc->blksz,mb.quot, mb.rem); + } + else { + sprintf (buf," Capacity: not available\n"); + } + video_puts(buf); + } +} + +void video_write_board_info(void) +{ + extern char version_string[]; + unsigned long pvr = get_pvr(); + char buf[32],tmpbuf[80]; + PPC405_SYS_INFO sys_info; + init_data_t *idata = (init_data_t *)(CFG_INIT_RAM_ADDR + CFG_INIT_DATA_OFFSET); + unsigned char *s = getenv("serial#"); + unsigned char *e; + unsigned char bc; + block_dev_desc_t *dev_desc; + int i; + + /* first write PPCBOOT Info */ + video_puts("\n"); + video_puts(version_string); + video_puts("\n\n"); + /* then CPU and board infos */ + get_sys_info(&sys_info); + video_puts("CPU: IBM PowerPC 405GP Rev. "); + switch (pvr) { + case PVR_405GP_RB: video_putc('B'); break; + case PVR_405GP_RC: video_putc('C'); break; + case PVR_405GP_RD: video_putc('D'); break; + default: video_puts("unknown"); break; + } + sprintf(tmpbuf," at %s MHz (PLB=%lu, OPB=%lu, EBC=%lu MHz)\n", strmhz(buf,idata->cpu_clk), + sys_info.freqPLB / 1000000, + sys_info.freqPLB / sys_info.pllOpbDiv / 1000000, + sys_info.freqPLB / sys_info.pllExtBusDiv / 1000000); + video_puts(tmpbuf); + if (mfdcr(strap) & PSR_PCI_ASYNC_EN) + video_puts(" PCI async ext clock used, "); + else { + sprintf(buf," PCI sync clock at %lu MHz, ", sys_info.freqPLB / sys_info.pllPciDiv / 1000000); + video_puts(buf); + } + if (mfdcr(strap) & PSR_PCI_ARBIT_EN) + video_puts("internal PCI arbiter enabled\n"); + else + video_puts("external PCI arbiter enabled\n"); + video_puts(" 16 kB I-Cache 8 kB D-Cache\n"); + /* now some board infos */ + video_puts("Board: "); + if (!s || strncmp(s, "PIP405", 6)) { + bc=video_set_attr(VGA_ATTR_CLR_RED | VGA_ATTR_ITN); + video_puts("### No HW ID - assuming PIP405"); + } + else { + bc=video_set_attr(VGA_ATTR_CLR_GRN); + for (e=s; *e; ++e) { + if (*e == ' ') + break; + } + for ( ; sbi_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 +#include +#include +#include "pip405.h" +#include "pip405_isa.h" +#include "pci_piix4.h" +#include "kbd.h" +#include "video.h" + + +#undef ISA_DEBUG + +#ifdef ISA_DEBUG +#define PRINTF(fmt,args...) printf (fmt ,##args) +#else +#define PRINTF(fmt,args...) +#endif + +#ifndef TRUE +#define TRUE 1 +#endif +#ifndef FALSE +#define FALSE 0 +#endif + + + +/* fdc (logical device 0) */ +const SIO_LOGDEV_TABLE sio_fdc[] = { + {0x60, 3}, /* set IO to FDPort (3F0) */ + {0x61, 0xF0}, /* set IO to FDPort (3F0) */ + {0x70, 06}, /* set IRQ 6 for FDPort */ + {0x74, 02}, /* set DMA 2 for FDPort */ + {0xF0, 0x05}, /* set to PS2 type */ + {0xF1, 0x00}, /* default value */ + {0x30, 1}, /* and activate the device */ + {0xFF, 0} /* end of device table */ +}; +/* paralell port (logical device 3) */ +const SIO_LOGDEV_TABLE sio_pport[] = { + {0x60, 3}, /* set IO to PPort (378) */ + {0x61, 0x78}, /* set IO to PPort (378) */ + {0x70, 07}, /* set IRQ 7 for PPort */ + {0x30, 1}, /* and activate the device */ + {0xFF, 0} /* end of device table */ +}; +/* uart 1 (logical device 4) */ +const SIO_LOGDEV_TABLE sio_com1[] = { + {0x60, 3}, /* set IO to COM1 (3F8) */ + {0x61, 0xF8}, /* set IO to COM1 (3F8) */ + {0x70, 04}, /* set IRQ 4 for COM1 */ + {0x30, 1}, /* and activate the device */ + {0xFF, 0} /* end of device table */ +}; +/* uart 2 (logical device 5) */ +const SIO_LOGDEV_TABLE sio_com2[] = { + {0x60, 2}, /* set IO to COM2 (2F8) */ + {0x61, 0xF8}, /* set IO to COM2 (2F8) */ + {0x70, 03}, /* set IRQ 3 for COM2 */ + {0x30, 1}, /* and activate the device */ + {0xFF, 0} /* end of device table */ +}; + +/* keyboard controller (logical device 7) */ +const SIO_LOGDEV_TABLE sio_keyboard[] = { + {0x70, 1}, /* set IRQ 1 for keyboard */ + {0x72, 12}, /* set IRQ 12 for mouse */ + {0xF0, 0}, /* disable Port92 (this is a PowerPC!!) */ + {0x30, 1}, /* and activate the device */ + {0xFF, 0} /* end of device table */ +}; + +/* SIO initialization table */ +const SIO_TABLE sio_table[] = { + {0, sio_fdc}, /* init table for floppy disk controller */ + {3, sio_pport}, /* init table for paralell port */ + {4, sio_com1}, /* init table for COM1 */ + {5, sio_com2}, /* init table for COM2 */ + {7, sio_keyboard}, /* init table for keyboard controller */ + {0, NULL} /* end of SIO table */ +}; + +/******************************************************************************* +* Config SuperIO FDC37C672 +********************************************************************************/ +unsigned char open_cfg_super_IO(int address) +{ + out8(CFG_ISA_IO_BASE_ADDRESS | address,0x55); /* open config */ + out8(CFG_ISA_IO_BASE_ADDRESS | address,0x20); /* set address to DEV ID */ + if(in8(CFG_ISA_IO_BASE_ADDRESS | address | 0x1)==0x40) /* ok Device ID is correct */ + return TRUE; + else + return FALSE; +} + +void close_cfg_super_IO(int address) +{ + out8(CFG_ISA_IO_BASE_ADDRESS | address,0xAA); /* close config */ +} + + +unsigned char read_cfg_super_IO(int address, unsigned char function, unsigned char regaddr) +{ + /* assuming config reg is open */ + out8(CFG_ISA_IO_BASE_ADDRESS | address,0x7); /* points to the function reg */ + out8(CFG_ISA_IO_BASE_ADDRESS | address | 1,function); /* set the function no */ + out8(CFG_ISA_IO_BASE_ADDRESS | address,regaddr); /* sets the address in the function */ + return in8(CFG_ISA_IO_BASE_ADDRESS | address | 1); +} + +void write_cfg_super_IO(int address, unsigned char function, unsigned char regaddr, unsigned char data) +{ + /* assuming config reg is open */ + out8(CFG_ISA_IO_BASE_ADDRESS | address,0x7); /* points to the function reg */ + out8(CFG_ISA_IO_BASE_ADDRESS | address | 1,function); /* set the function no */ + out8(CFG_ISA_IO_BASE_ADDRESS | address,regaddr); /* sets the address in the function */ + out8(CFG_ISA_IO_BASE_ADDRESS | address | 1,data); /* writes the data */ +} + +void isa_sio_loadtable(void) +{ + SIO_TABLE *t = (SIO_TABLE *)sio_table; + SIO_LOGDEV_TABLE *ldt; + + while (t->ldev_table != NULL) { + /* as long as their are logical device */ + ldt = (SIO_LOGDEV_TABLE *)t->ldev_table; + + while (ldt->index != 0xFF) { + /* as long as their are register to be programmed for this device, do it */ + write_cfg_super_IO(SIO_CFG_PORT, t->ldev, ldt->index, ldt->val); + ldt++; + } /* endwhile */ + t++; + } /* endwhile */ +} + + +void isa_sio_setup() +{ + if(open_cfg_super_IO(SIO_CFG_PORT)==TRUE) + { + + isa_sio_loadtable(); + close_cfg_super_IO(0x3F0); + } +} + + + +/****************************************************************************** + * IRQ Controller + * we use the Vector mode + */ + +struct isa_irq_action { + interrupt_handler_t *handler; + void *arg; + int count; +}; + +static struct isa_irq_action isa_irqs[16]; + + +/* + * This contains the irq mask for both 8259A irq controllers, + */ +static unsigned int cached_irq_mask = 0xffff; + +#define cached_imr1 (unsigned char)cached_irq_mask +#define cached_imr2 (unsigned char)(cached_irq_mask>>8) +#define IMR_1 CFG_ISA_IO_BASE_ADDRESS + PIIX4_ISA_INT1_OCW1 +#define IMR_2 CFG_ISA_IO_BASE_ADDRESS + PIIX4_ISA_INT2_OCW1 +#define ICW1_1 CFG_ISA_IO_BASE_ADDRESS + PIIX4_ISA_INT1_ICW1 +#define ICW1_2 CFG_ISA_IO_BASE_ADDRESS + PIIX4_ISA_INT2_ICW1 +#define ICW2_1 CFG_ISA_IO_BASE_ADDRESS + PIIX4_ISA_INT1_ICW2 +#define ICW2_2 CFG_ISA_IO_BASE_ADDRESS + PIIX4_ISA_INT2_ICW2 +#define ICW3_1 ICW2_1 +#define ICW3_2 ICW2_2 +#define ICW4_1 ICW2_1 +#define ICW4_2 ICW2_2 +#define ISR_1 ICW1_1 +#define ISR_2 ICW1_2 + + +void disable_8259A_irq(unsigned int irq) +{ + unsigned int mask = 1 << irq; + + cached_irq_mask |= mask; + if (irq & 8) + out8(IMR_2,cached_imr2); + else + out8(IMR_1,cached_imr1); +} + +void enable_8259A_irq(unsigned int irq) +{ + unsigned int mask = ~(1 << irq); + + cached_irq_mask &= mask; + if (irq & 8) + out8(IMR_2,cached_imr2); + else + out8(IMR_1,cached_imr1); +} +/* +int i8259A_irq_pending(unsigned int irq) +{ + unsigned int mask = 1<> 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<> 8); + out8(ISR_2,0x0A); /* back to the IRR register */ + return value; +} + +/* + * Careful! The 8259A is a fragile beast, it pretty + * much _has_ to be done exactly like this (mask it + * first, _then_ send the EOI, and the order of EOI + * to the two 8259s is important! + */ +void mask_and_ack_8259A(unsigned int irq) +{ + unsigned int irqmask = 1 << irq; + unsigned int temp_irqmask = cached_irq_mask; + /* + * Lightweight spurious IRQ detection. We do not want + * to overdo spurious IRQ handling - it's usually a sign + * of hardware problems, so we only do the checks we can + * do without slowing down good hardware unnecesserily. + * + * Note that IRQ7 and IRQ15 (the two spurious IRQs + * usually resulting from the 8259A-1|2 PICs) occur + * even if the IRQ is masked in the 8259A. Thus we + * can check spurious 8259A IRQs without doing the + * quite slow i8259A_irq_real() call for every IRQ. + * This does not cover 100% of spurious interrupts, + * but should be enough to warn the user that there + * is something bad going on ... + */ + if (temp_irqmask & irqmask) + goto spurious_8259A_irq; + temp_irqmask |= irqmask; + +handle_real_irq: + if (irq & 8) { + in8(IMR_2); /* DUMMY - (do we need this?) */ + out8(IMR_2,(unsigned char)(temp_irqmask>>8)); + out8(ISR_2,0x60+(irq&7));/* 'Specific EOI' to slave */ + out8(ISR_1,0x62); /* 'Specific EOI' to master-IRQ2 */ + out8(IMR_2,cached_imr2); /* turn it on again */ + } else { + in8(IMR_1); /* DUMMY - (do we need this?) */ + out8(IMR_1,(unsigned char)temp_irqmask); + out8(ISR_1,0x60+irq); /* 'Specific EOI' to master */ + out8(IMR_1,cached_imr1); /* turn it on again */ + } + + return; + +spurious_8259A_irq: + /* + * this is the slow path - should happen rarely. + */ + if (i8259A_irq_real(irq)) + /* + * oops, the IRQ _is_ in service according to the + * 8259A - not spurious, go handle it. + */ + goto handle_real_irq; + + { + static int spurious_irq_mask; + /* + * At this point we can be sure the IRQ is spurious, + * lets ACK and report it. [once per IRQ] + */ + if (!(spurious_irq_mask & irqmask)) { + PRINTF("spurious 8259A interrupt: IRQ%d.\n", irq); + spurious_irq_mask |= irqmask; + } + /* irq_err_count++; */ + /* + * Theoretically we do not have to handle this IRQ, + * but in Linux this does not cause problems and is + * simpler for us. + */ + goto handle_real_irq; + } +} + +void init_8259A(void) +{ + out8(IMR_1,0xff); /* mask all of 8259A-1 */ + out8(IMR_2,0xff); /* mask all of 8259A-2 */ + + out8(ICW1_1,0x11); /* ICW1: select 8259A-1 init */ + out8(ICW2_1,0x20 + 0); /* ICW2: 8259A-1 IR0-7 mapped to 0x20-0x27 */ + out8(ICW3_1,0x04); /* 8259A-1 (the master) has a slave on IR2 */ + out8(ICW4_1,0x01); /* master expects normal EOI */ + out8(ICW1_2,0x11); /* ICW2: select 8259A-2 init */ + out8(ICW2_2,0x20 + 8); /* ICW2: 8259A-2 IR0-7 mapped to 0x28-0x2f */ + out8(ICW3_2,0x02); /* 8259A-2 is a slave on master's IR2 */ + out8(ICW4_2,0x01); /* (slave's support for AEOI in flat mode + is to be investigated) */ + udelay(10000); /* wait for 8259A to initialize */ + out8(IMR_1,cached_imr1); /* restore master IRQ mask */ + udelay(10000); /* wait for 8259A to initialize */ + out8(IMR_2,cached_imr2); /* restore slave IRQ mask */ +} + + +#define PCI_INT_ACK_ADDR 0xEED00000 + +int handle_isa_int(void) +{ + unsigned long irqack; + unsigned char isr1,isr2,irq; + /* first we acknokledge the int via the PCI bus */ + irqack=in32(PCI_INT_ACK_ADDR); + /* now we get the ISRs */ + isr2=in8(ISR_2); + isr1=in8(ISR_1); + irq=(unsigned char)irqack; + if((irq==7)&&((isr1&0x80)==0)) { + PRINTF("IRQ7 detected but not in ISR\n"); + } + else { + /* we should handle cascaded interrupts here also */ + /* printf("ISA Irq %d\n",irq); */ + isa_irqs[irq].count++; + if (isa_irqs[irq].handler != NULL) + (*isa_irqs[irq].handler)(isa_irqs[irq].arg); /* call isr */ + else + { + PRINTF ("bogus interrupt vector 0x%x\n", irq); + } + } + /* issue EOI instruction to clear the IRQ */ + mask_and_ack_8259A(irq); + return 0; +} + + + +/****************************************************************** + * Install and free an ISA interrupt handler. + */ + +void isa_irq_install_handler(int vec, interrupt_handler_t *handler, void *arg) +{ + if (isa_irqs[vec].handler != NULL) { + printf ("ISA Interrupt vector %d: handler 0x%x replacing 0x%x\n", + vec, (uint)handler, (uint)isa_irqs[vec].handler); + } + isa_irqs[vec].handler = handler; + isa_irqs[vec].arg = arg; + enable_8259A_irq(vec); + PRINTF ("Install ISA IRQ %d ==> %p, @ %p mask=%04x\n", vec, handler, &isa_irqs[vec].handler,cached_irq_mask); + +} + +void isa_irq_free_handler(int vec) +{ + disable_8259A_irq(vec); + isa_irqs[vec].handler = NULL; + isa_irqs[vec].arg = NULL; + printf ("Free ISA IRQ %d mask=%04x\n", vec, cached_irq_mask); + +} + +/****************************************************************************/ + + + + +void isa_init_irq_contr(void) +{ + int i; + /* disable all Interrupts */ + /* first write icws controller 1 */ + for(i=0;i<16;i++) + { + isa_irqs[i].handler=NULL; + isa_irqs[i].arg=NULL; + isa_irqs[i].count=0; + } + init_8259A(); + out8(IMR_2,0xFF); +} + +/*************************************************************************** + * some helping routines + */ + +int overwrite_console(void) +{ + return(in8(CONFIG_PORT_ADDR) & 0x1); /* return TRUE if console should be overwritten */ +} + diff --git a/board/pip405/pip405_isa.h b/board/pip405/pip405_isa.h new file mode 100644 index 0000000..1b775fb --- /dev/null +++ b/board/pip405/pip405_isa.h @@ -0,0 +1,56 @@ +/* + * (C) Copyright 2001 + * Denis Peter, MPL AG Switzerland, d.peter@mpl.ch + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef _PIP405_ISA_H_ +#define _PIP405_ISA_H_ +/* Super IO */ +#define SIO_CFG_PORT 0x3F0 /* Config Port Address */ + + + +/* table fore SIO initialization */ +typedef struct { + const uchar index; + const uchar val; +} SIO_LOGDEV_TABLE; + +typedef struct { + const uchar ldev; + const SIO_LOGDEV_TABLE *ldev_table; +} SIO_TABLE; + + + + +unsigned char open_cfg_super_IO(int address); +unsigned char read_cfg_super_IO(int address, unsigned char function, unsigned char regaddr); +void write_cfg_super_IO(int address, unsigned char function, unsigned char regaddr, unsigned char data); +void close_cfg_super_IO(int address); +void isa_sio_setup(void); +void isa_sio_setup(void); +void isa_irq_install_handler(int vec, interrupt_handler_t *handler, void *arg); +void isa_irq_free_handler(int vec); +int handle_isa_int(void); + + +#endif diff --git a/board/pip405/ppcboot.lds b/board/pip405/ppcboot.lds new file mode 100644 index 0000000..01cdff5 --- /dev/null +++ b/board/pip405/ppcboot.lds @@ -0,0 +1,144 @@ +/* + * (C) Copyright 2001 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +OUTPUT_ARCH(powerpc) +SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib); +/* Do we need any of these for elf? + __DYNAMIC = 0; */ +SECTIONS +{ + .resetvec 0xFFFFFFFC : + { + *(.resetvec) + } = 0xffff + + /* Read-only sections, merged into text segment: */ + . = + SIZEOF_HEADERS; + .interp : { *(.interp) } + .hash : { *(.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .rel.text : { *(.rel.text) } + .rela.text : { *(.rela.text) } + .rel.data : { *(.rel.data) } + .rela.data : { *(.rela.data) } + .rel.rodata : { *(.rel.rodata) } + .rela.rodata : { *(.rela.rodata) } + .rel.got : { *(.rel.got) } + .rela.got : { *(.rela.got) } + .rel.ctors : { *(.rel.ctors) } + .rela.ctors : { *(.rela.ctors) } + .rel.dtors : { *(.rel.dtors) } + .rela.dtors : { *(.rela.dtors) } + .rel.bss : { *(.rel.bss) } + .rela.bss : { *(.rela.bss) } + .rel.plt : { *(.rel.plt) } + .rela.plt : { *(.rela.plt) } + .init : { *(.init) } + .plt : { *(.plt) } + .text : + { + /* WARNING - the following is hand-optimized to fit within */ + /* the sector layout of our flash chips! XXX FIXME XXX */ + + cpu/ppc4xx/start.o (.text) + board/pip405/init.o (.text) + cpu/ppc4xx/kgdb.o (.text) + cpu/ppc4xx/traps.o (.text) + cpu/ppc4xx/interrupts.o (.text) + cpu/ppc4xx/serial.o (.text) + cpu/ppc4xx/cpu_init.o (.text) + cpu/ppc4xx/speed.o (.text) + cpu/ppc4xx/405gp_enet.o (.text) + common/dlmalloc.o (.text) + ppc/crc32.o (.text) + ppc/extable.o (.text) + ppc/zlib.o (.text) + +/* . = env_offset;*/ +/* common/environment.o(.text)*/ + + *(.text) + *(.fixup) + *(.got1) + } + _etext = .; + PROVIDE (etext = .); + .rodata : + { + *(.rodata) + *(.rodata1) + } + .fini : { *(.fini) } =0 + .ctors : { *(.ctors) } + .dtors : { *(.dtors) } + + /* Read-write section, merged into data segment: */ + . = (. + 0x00FF) & 0xFFFFFF00; + _erotext = .; + PROVIDE (erotext = .); + .reloc : + { + *(.got) + _GOT2_TABLE_ = .; + *(.got2) + _FIXUP_TABLE_ = .; + *(.fixup) + } + __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2; + __fixup_entries = (. - _FIXUP_TABLE_)>>2; + + .data : + { + *(.data) + *(.data1) + *(.sdata) + *(.sdata2) + *(.dynamic) + CONSTRUCTORS + } + _edata = .; + PROVIDE (edata = .); + + __start___ex_table = .; + __ex_table : { *(__ex_table) } + __stop___ex_table = .; + + . = ALIGN(256); + __init_begin = .; + .text.init : { *(.text.init) } + .data.init : { *(.data.init) } + . = ALIGN(256); + __init_end = .; + + __bss_start = .; + .bss : + { + *(.sbss) *(.scommon) + *(.dynbss) + *(.bss) + *(COMMON) + } + _end = . ; + PROVIDE (end = .); +} diff --git a/board/pip405/ppcboot.lds.debug b/board/pip405/ppcboot.lds.debug new file mode 100644 index 0000000..266238e --- /dev/null +++ b/board/pip405/ppcboot.lds.debug @@ -0,0 +1,131 @@ +/* + * (C) Copyright 2001 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +OUTPUT_ARCH(powerpc) +SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib); +/* Do we need any of these for elf? + __DYNAMIC = 0; */ +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + . = + SIZEOF_HEADERS; + .interp : { *(.interp) } + .hash : { *(.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .rel.text : { *(.rel.text) } + .rela.text : { *(.rela.text) } + .rel.data : { *(.rel.data) } + .rela.data : { *(.rela.data) } + .rel.rodata : { *(.rel.rodata) } + .rela.rodata : { *(.rela.rodata) } + .rel.got : { *(.rel.got) } + .rela.got : { *(.rela.got) } + .rel.ctors : { *(.rel.ctors) } + .rela.ctors : { *(.rela.ctors) } + .rel.dtors : { *(.rel.dtors) } + .rela.dtors : { *(.rela.dtors) } + .rel.bss : { *(.rel.bss) } + .rela.bss : { *(.rela.bss) } + .rel.plt : { *(.rel.plt) } + .rela.plt : { *(.rela.plt) } + .init : { *(.init) } + .plt : { *(.plt) } + .text : + { + /* WARNING - the following is hand-optimized to fit within */ + /* the sector layout of our flash chips! XXX FIXME XXX */ + + mpc8xx/start.o (.text) + common/dlmalloc.o (.text) + ppc/vsprintf.o (.text) + ppc/crc32.o (.text) + ppc/extable.o (.text) + + common/environment.o(.text) + + *(.text) + *(.fixup) + *(.got1) + } + _etext = .; + PROVIDE (etext = .); + .rodata : + { + *(.rodata) + *(.rodata1) + } + .fini : { *(.fini) } =0 + .ctors : { *(.ctors) } + .dtors : { *(.dtors) } + + /* Read-write section, merged into data segment: */ + . = (. + 0x0FFF) & 0xFFFFF000; + _erotext = .; + PROVIDE (erotext = .); + .reloc : + { + *(.got) + _GOT2_TABLE_ = .; + *(.got2) + _FIXUP_TABLE_ = .; + *(.fixup) + } + __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2; + __fixup_entries = (. - _FIXUP_TABLE_)>>2; + + .data : + { + *(.data) + *(.data1) + *(.sdata) + *(.sdata2) + *(.dynamic) + CONSTRUCTORS + } + _edata = .; + PROVIDE (edata = .); + + __start___ex_table = .; + __ex_table : { *(__ex_table) } + __stop___ex_table = .; + + . = ALIGN(4096); + __init_begin = .; + .text.init : { *(.text.init) } + .data.init : { *(.data.init) } + . = ALIGN(4096); + __init_end = .; + + __bss_start = .; + .bss : + { + *(.sbss) *(.scommon) + *(.dynbss) + *(.bss) + *(COMMON) + } + _end = . ; + PROVIDE (end = .); +} + diff --git a/board/pip405/sym53c8xx.c b/board/pip405/sym53c8xx.c new file mode 100644 index 0000000..6e2ed33 --- /dev/null +++ b/board/pip405/sym53c8xx.c @@ -0,0 +1,751 @@ +/* + * (C) Copyright 2001 + * Denis Peter, MPL AG Switzerland, d.peter@mpl.ch. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * partly derived from + * linux/drivers/scsi/sym53c8xx.c + * + */ + +/* + * SCSI support based on the chip sym53C810. + */ + +#include +#include +#include +#include "pci_pip405.h" +#include +#include "sym53c8xx_defs.h" +#include + +#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;icmdlen;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(retrycnttrans_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(retrycnttarget,retrycnt); + for(t=0;ttarget,retrycnt); + return FALSE; + default: + return FALSE; + } + } + PRINTF("Status = %X\n",pccb->status); + return FALSE; +} + + + + +void scsi_chip_init(void) +{ + /* first we issue a soft reset */ + scsi_write_byte(ISTAT,SRST); + udelay(1000); + scsi_write_byte(ISTAT,0); + /* setup chip */ + scsi_write_byte(SCNTL0,0xC0); /* full arbitration no start, no message, parity disabled, master */ + scsi_write_byte(SCNTL1,0x00); + scsi_write_byte(SCNTL2,0x00); + scsi_write_byte(SCNTL3,0x13); /* synchronous clock 40/4=10MHz, asynchronous 40MHz */ + scsi_write_byte(SCID,0x47); /* ID=7, enable reselection */ + scsi_write_byte(SXFER,0x00); /* synchronous transfer period 10MHz, asynchronous */ + scsi_write_byte(SDID,0x00); /* targed SCSI ID = 0 */ + scsi_int_mask=0x0000; /* no Interrupt is enabled */ + script_int_mask=0x00; + scsi_int_enable(); + scsi_write_byte(GPREG,0x01); /* GPIO0 is LED (off) */ + scsi_write_byte(GPCNTL,0x0E); /* GPIO0 is Output */ + scsi_write_byte(STIME0,0x08); /* handshake timer disabled, selection timeout 512msec */ + scsi_write_byte(RESPID,0x80); /* repond only to the own ID (reselection) */ + scsi_write_byte(STEST1,0x00); /* not isolated, SCLK is used */ + scsi_write_byte(STEST2,0x00); /* no Lowlevel Mode? */ + scsi_write_byte(STEST3,0x80); /* enable tolerANT */ + scsi_write_byte(CTEST3,0x04); /* clear FIFO */ + scsi_write_byte(CTEST4,0x00); + scsi_write_byte(CTEST5,0x00); +#ifdef SCSI_SINGLE_STEP + scsi_write_byte(DCNTL,IRQM | SSM); + scsi_write_byte(DMODE,MAN); +#else + scsi_write_byte(DCNTL,IRQM); + scsi_write_byte(DMODE,0x00); +#endif +} +#endif /* (CONFIG_COMMANDS & CFG_CMD_SCSI) */ + + diff --git a/board/pip405/sym53c8xx_defs.h b/board/pip405/sym53c8xx_defs.h new file mode 100644 index 0000000..d1bc3cf --- /dev/null +++ b/board/pip405/sym53c8xx_defs.h @@ -0,0 +1,582 @@ +/* + * (C) Copyright 2001 + * Denis Peter, MPL AG Switzerland + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Most of these definitions are derived from + * linux/drivers/scsi/sym53c8xx_defs.h + * + */ + +#ifndef _SYM53C8XX_DEFS_H +#define _SYM53C8XX_DEFS_H + + +#define SCNTL0 0x00 /* full arb., ena parity, par->ATN */ + +#define SCNTL1 0x01 /* no reset */ + #define ISCON 0x10 /* connected to scsi */ + #define CRST 0x08 /* force reset */ + #define IARB 0x02 /* immediate arbitration */ + +#define SCNTL2 0x02 /* no disconnect expected */ + #define SDU 0x80 /* cmd: disconnect will raise error */ + #define CHM 0x40 /* sta: chained mode */ + #define WSS 0x08 /* sta: wide scsi send [W]*/ + #define WSR 0x01 /* sta: wide scsi received [W]*/ + +#define SCNTL3 0x03 /* cnf system clock dependent */ + #define EWS 0x08 /* cmd: enable wide scsi [W]*/ + #define ULTRA 0x80 /* cmd: ULTRA enable */ + /* bits 0-2, 7 rsvd for C1010 */ + +#define SCID 0x04 /* cnf host adapter scsi address */ + #define RRE 0x40 /* r/w:e enable response to resel. */ + #define SRE 0x20 /* r/w:e enable response to select */ + +#define SXFER 0x05 /* ### Sync speed and count */ + /* bits 6-7 rsvd for C1010 */ + +#define SDID 0x06 /* ### Destination-ID */ + +#define GPREG 0x07 /* ??? IO-Pins */ + +#define SFBR 0x08 /* ### First byte in phase */ + +#define SOCL 0x09 + #define CREQ 0x80 /* r/w: SCSI-REQ */ + #define CACK 0x40 /* r/w: SCSI-ACK */ + #define CBSY 0x20 /* r/w: SCSI-BSY */ + #define CSEL 0x10 /* r/w: SCSI-SEL */ + #define CATN 0x08 /* r/w: SCSI-ATN */ + #define CMSG 0x04 /* r/w: SCSI-MSG */ + #define CC_D 0x02 /* r/w: SCSI-C_D */ + #define CI_O 0x01 /* r/w: SCSI-I_O */ + +#define SSID 0x0a + +#define SBCL 0x0b + +#define DSTAT 0x0c + #define DFE 0x80 /* sta: dma fifo empty */ + #define MDPE 0x40 /* int: master data parity error */ + #define BF 0x20 /* int: script: bus fault */ + #define ABRT 0x10 /* int: script: command aborted */ + #define SSI 0x08 /* int: script: single step */ + #define SIR 0x04 /* int: script: interrupt instruct. */ + #define IID 0x01 /* int: script: illegal instruct. */ + +#define SSTAT0 0x0d + #define ILF 0x80 /* sta: data in SIDL register lsb */ + #define ORF 0x40 /* sta: data in SODR register lsb */ + #define OLF 0x20 /* sta: data in SODL register lsb */ + #define AIP 0x10 /* sta: arbitration in progress */ + #define LOA 0x08 /* sta: arbitration lost */ + #define WOA 0x04 /* sta: arbitration won */ + #define IRST 0x02 /* sta: scsi reset signal */ + #define SDP 0x01 /* sta: scsi parity signal */ + +#define SSTAT1 0x0e + #define FF3210 0xf0 /* sta: bytes in the scsi fifo */ + +#define SSTAT2 0x0f + #define ILF1 0x80 /* sta: data in SIDL register msb[W]*/ + #define ORF1 0x40 /* sta: data in SODR register msb[W]*/ + #define OLF1 0x20 /* sta: data in SODL register msb[W]*/ + #define DM 0x04 /* sta: DIFFSENS mismatch (895/6 only) */ + #define LDSC 0x02 /* sta: disconnect & reconnect */ + +#define DSA 0x10 /* --> Base page */ +#define DSA1 0x11 +#define DSA2 0x12 +#define DSA3 0x13 + +#define ISTAT 0x14 /* --> Main Command and status */ + #define CABRT 0x80 /* cmd: abort current operation */ + #define SRST 0x40 /* mod: reset chip */ + #define SIGP 0x20 /* r/w: message from host to ncr */ + #define SEM 0x10 /* r/w: message between host + ncr */ + #define CON 0x08 /* sta: connected to scsi */ + #define INTF 0x04 /* sta: int on the fly (reset by wr)*/ + #define SIP 0x02 /* sta: scsi-interrupt */ + #define DIP 0x01 /* sta: host/script interrupt */ + + +#define CTEST0 0x18 +#define CTEST1 0x19 +#define CTEST2 0x1a + #define CSIGP 0x40 + /* bits 0-2,7 rsvd for C1010 */ + +#define CTEST3 0x1b + #define FLF 0x08 /* cmd: flush dma fifo */ + #define CLF 0x04 /* cmd: clear dma fifo */ + #define FM 0x02 /* mod: fetch pin mode */ + #define WRIE 0x01 /* mod: write and invalidate enable */ + /* bits 4-7 rsvd for C1010 */ + +#define DFIFO 0x20 +#define CTEST4 0x21 + #define BDIS 0x80 /* mod: burst disable */ + #define MPEE 0x08 /* mod: master parity error enable */ + +#define CTEST5 0x22 + #define DFS 0x20 /* mod: dma fifo size */ + /* bits 0-1, 3-7 rsvd for C1010 */ +#define CTEST6 0x23 + +#define DBC 0x24 /* ### Byte count and command */ +#define DNAD 0x28 /* ### Next command register */ +#define DSP 0x2c /* --> Script Pointer */ +#define DSPS 0x30 /* --> Script pointer save/opcode#2 */ + +#define SCRATCHA 0x34 /* Temporary register a */ +#define SCRATCHA1 0x35 +#define SCRATCHA2 0x36 +#define SCRATCHA3 0x37 + +#define DMODE 0x38 + #define BL_2 0x80 /* mod: burst length shift value +2 */ + #define BL_1 0x40 /* mod: burst length shift value +1 */ + #define ERL 0x08 /* mod: enable read line */ + #define ERMP 0x04 /* mod: enable read multiple */ + #define BOF 0x02 /* mod: burst op code fetch */ + #define MAN 0x01 /* mod: manual start */ + +#define DIEN 0x39 +#define SBR 0x3a + +#define DCNTL 0x3b /* --> Script execution control */ + #define CLSE 0x80 /* mod: cache line size enable */ + #define PFF 0x40 /* cmd: pre-fetch flush */ + #define PFEN 0x20 /* mod: pre-fetch enable */ + #define SSM 0x10 /* mod: single step mode */ + #define IRQM 0x08 /* mod: irq mode (1 = totem pole !) */ + #define STD 0x04 /* cmd: start dma mode */ + #define IRQD 0x02 /* mod: irq disable */ + #define NOCOM 0x01 /* cmd: protect sfbr while reselect */ + /* bits 0-1 rsvd for C1010 */ + +#define ADDER 0x3c + +#define SIEN 0x40 /* -->: interrupt enable */ +#define SIST 0x42 /* <--: interrupt status */ + #define SBMC 0x1000/* sta: SCSI Bus Mode Change (895/6 only) */ + #define STO 0x0400/* sta: timeout (select) */ + #define GEN 0x0200/* sta: timeout (general) */ + #define HTH 0x0100/* sta: timeout (handshake) */ + #define MA 0x80 /* sta: phase mismatch */ + #define CMP 0x40 /* sta: arbitration complete */ + #define SEL 0x20 /* sta: selected by another device */ + #define RSL 0x10 /* sta: reselected by another device*/ + #define SGE 0x08 /* sta: gross error (over/underflow)*/ + #define UDC 0x04 /* sta: unexpected disconnect */ + #define RST 0x02 /* sta: scsi bus reset detected */ + #define PAR 0x01 /* sta: scsi parity error */ + +#define SLPAR 0x44 +#define SWIDE 0x45 +#define MACNTL 0x46 +#define GPCNTL 0x47 +#define STIME0 0x48 /* cmd: timeout for select&handshake*/ +#define STIME1 0x49 /* cmd: timeout user defined */ +#define RESPID 0x4a /* sta: Reselect-IDs */ + +#define STEST0 0x4c + +#define STEST1 0x4d + #define SCLK 0x80 /* Use the PCI clock as SCSI clock */ + #define DBLEN 0x08 /* clock doubler running */ + #define DBLSEL 0x04 /* clock doubler selected */ + + +#define STEST2 0x4e + #define ROF 0x40 /* reset scsi offset (after gross error!) */ + #define EXT 0x02 /* extended filtering */ + +#define STEST3 0x4f + #define TE 0x80 /* c: tolerAnt enable */ + #define HSC 0x20 /* c: Halt SCSI Clock */ + #define CSF 0x02 /* c: clear scsi fifo */ + +#define SIDL 0x50 /* Lowlevel: latched from scsi data */ +#define STEST4 0x52 + #define SMODE 0xc0 /* SCSI bus mode (895/6 only) */ + #define SMODE_HVD 0x40 /* High Voltage Differential */ + #define SMODE_SE 0x80 /* Single Ended */ + #define SMODE_LVD 0xc0 /* Low Voltage Differential */ + #define LCKFRQ 0x20 /* Frequency Lock (895/6 only) */ + /* bits 0-5 rsvd for C1010 */ + +#define SODL 0x54 /* Lowlevel: data out to scsi data */ + +#define SBDL 0x58 /* Lowlevel: data from scsi data */ + + + + +/*----------------------------------------------------------- +** +** Utility macros for the script. +** +**----------------------------------------------------------- +*/ + +#define REG(r) (r) + +/*----------------------------------------------------------- +** +** SCSI phases +** +** DT phases illegal for ncr driver. +** +**----------------------------------------------------------- +*/ + +#define SCR_DATA_OUT 0x00000000 +#define SCR_DATA_IN 0x01000000 +#define SCR_COMMAND 0x02000000 +#define SCR_STATUS 0x03000000 +#define SCR_DT_DATA_OUT 0x04000000 +#define SCR_DT_DATA_IN 0x05000000 +#define SCR_MSG_OUT 0x06000000 +#define SCR_MSG_IN 0x07000000 + +#define SCR_ILG_OUT 0x04000000 +#define SCR_ILG_IN 0x05000000 + +/*----------------------------------------------------------- +** +** Data transfer via SCSI. +** +**----------------------------------------------------------- +** +** MOVE_ABS (LEN) +** <> +** +** MOVE_IND (LEN) +** <> +** +** MOVE_TBL +** <> +** +**----------------------------------------------------------- +*/ + +#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] +** <> +** +** SEL_TBL | << dnad_offset>> [ | REL_JMP] +** <> +** +**----------------------------------------------------------- +*/ + +#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: <> +** +** WAIT_RESEL +** <> +** +**----------------------------------------------------------- +*/ + +#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 = +** << 0 >> +** +** LOAD_SFBR(data) SFBR = +** << 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) +** <> +** +** LOAD_REL (LEN) (DSA relative) +** <> +** +**----------------------------------------------------------- +*/ + +#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 ( ... ) ] +** <
> +** +** JUMPR [ | IFTRUE/IFFALSE ( ... ) ] +** <> +** +** CALL [ | IFTRUE/IFFALSE ( ... ) ] +** <
> +** +** CALLR [ | IFTRUE/IFFALSE ( ... ) ] +** <> +** +** RETURN [ | IFTRUE/IFFALSE ( ... ) ] +** <> +** +** INT [ | IFTRUE/IFFALSE ( ... ) ] +** <> +** +** INT_FLY [ | IFTRUE/IFFALSE ( ... ) ] +** <> +** +** Conditions: +** WHEN (phase) +** IF (phase) +** CARRYSET +** DATA (data, mask) +** +**----------------------------------------------------------- +*/ + +#define SCR_NO_OP 0x80000000 +#define SCR_JUMP 0x80080000 +#define SCR_JUMP64 0x80480000 +#define SCR_JUMPR 0x80880000 +#define SCR_CALL 0x88080000 +#define SCR_CALLR 0x88880000 +#define SCR_RETURN 0x90080000 +#define SCR_INT 0x98080000 +#define SCR_INT_FLY 0x98180000 + +#define IFFALSE(arg) (0x00080000 | (arg)) +#define IFTRUE(arg) (0x00000000 | (arg)) + +#define WHEN(phase) (0x00030000 | (phase)) +#define IF(phase) (0x00020000 | (phase)) + +#define DATA(D) (0x00040000 | ((D) & 0xff)) +#define MASK(D,M) (0x00040000 | (((M ^ 0xff) & 0xff) << 8ul)|((D) & 0xff)) + +#define CARRYSET (0x00200000) + + + +#define SIR_COMPLETE 0x10000000 +/* script errors */ +#define SIR_SEL_ATN_NO_MSG_OUT 0x00000001 +#define SIR_CMD_OUT_ILL_PH 0x00000002 +#define SIR_STATUS_ILL_PH 0x00000003 +#define SIR_MSG_RECEIVED 0x00000004 +#define SIR_DATA_IN_ERR 0x00000005 +#define SIR_DATA_OUT_ERR 0x00000006 +#define SIR_SCRIPT_ERROR 0x00000007 +#define SIR_MSG_OUT_NO_CMD 0x00000008 +#define SIR_MSG_OVER7 0x00000009 +/* Fly interrupt */ +#define INT_ON_FY 0x00000080 +/* Hardware errors are defined in scsi.h */ + +#define SCSI_IDENTIFY 0xC0 + +#ifndef TRUE +#define TRUE 1 +#endif +#ifndef FALSE +#define FALSE 0 +#endif + +#endif diff --git a/board/pip405/vga_table.h b/board/pip405/vga_table.h new file mode 100644 index 0000000..d1cf5a6 --- /dev/null +++ b/board/pip405/vga_table.h @@ -0,0 +1,5115 @@ +/* + * (C) Copyright 2001 + * Denis Peter, MPL AG, d.peter@mpl.ch. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * Note: Parts of these software are imported from + * - UBL, The Universal Talkware Boot Loader + * Copyright (C) 2000 Universal Talkware Inc. + * - Linux + * + * File: vga_table.c + * + * contains all tables (include fonts) for the vga controller. + * + **********************************************/ +#ifndef _VGA_TABLE_H +#define _VGA_TABLE_H + +/* table for VGA Initialization */ +typedef struct { + const unsigned char reg; + const unsigned char val; +} VIDEO_CFG_TABLE; + +/* Attribute table */ +static VIDEO_CFG_TABLE attr[] = { + { 0x00, 0x00 }, /* black */ + { 0x01, 0x01 }, /* blue */ + { 0x02, 0x02 }, /* green */ + { 0x03, 0x03 }, /* cyan */ + { 0x04, 0x04 }, /* red */ + { 0x05, 0x05 }, /* magenta */ + { 0x06, 0x14 }, /* brown */ + { 0x07, 0x07 }, /* white */ + { 0x08, 0x38 }, /* dark gray */ + { 0x09, 0x39 }, /* light blue */ + { 0x0A, 0x3A }, /* light green */ + { 0x0B, 0x3B }, /* light Cyan */ + { 0x0C, 0x3C }, /* light red */ + { 0x0D, 0x3D }, /* light magenta */ + { 0x0E, 0x3E }, /* yellow */ + { 0x0F, 0x3F }, /* intense white */ + { 0x10, 0x0C }, /* mode control */ + { 0x11, 0x00 }, /* overscan color */ + { 0x12, 0x0f }, /* color plane enable */ + { 0x13, 0x08 }, /* horizontal Pel Panning */ + { 0x14, 0x00 }, /* color select */ + { 0xFF, 0xFF} /* end of table */ +}; + +/* Values for VGA 80 x 25 Text mode */ +static VIDEO_CFG_TABLE crtc[] = { + {0x00,0x5F}, /* horizontal total */ + {0x01,0x4F}, /* horizontal displayed */ + {0x02,0x50}, /* horizontal blank start */ + {0x03,0x82}, /* horizontal blank end MIP520 BIOS*/ + {0x04,0x55}, /* horizontal synch pos MIP520 */ + {0x05,0x9F}, /* horizontal synch width BIOS Source */ + {0x06,0xBF}, /* vertical total BIOS MIP520*/ + {0x07,0x1F}, /* overflow */ + {0x08,0x00}, /* prescan */ + {0x09,0x4F}, /* maximum scanline */ + {0x0A,0x0D}, /* cursor start */ + {0x0B,0x0E}, /* cursor end */ + {0x0C,0x00}, /* start address high byte */ + {0x0D,0x00}, /* start address low byte */ + {0x0E,0x07}, /* cursor location high byte */ + {0x0F,0x80}, /* cursor location low byte */ + {0x10,0x9C}, /* vertical synch start BIOS MIP520*/ + {0x11,0x8E}, /* vertical synch end */ + {0x12,0x8F}, /* vertical display enable end BIOS MIP520 */ + {0x13,0x28}, /* offset */ + {0x14,0x1F}, /* underline row */ + {0x15,0x96}, /* verical blank start */ + {0x16,0xB9}, /* verical blank end */ + {0x17,0xA3}, /* crt Mode Control */ + {0x18,0xFF}, /* line compare */ + /* added for 69000 */ + {0x22,0x20}, /* Memory Latch */ + {0x30,0x00}, /* ext. total vertical register */ + {0x31,0x00}, /* ext. vertical display end */ + {0x32,0x00}, /* ext. vertical synch */ + {0x33,0x00}, /* ext. vertical blanking start */ + {0x38,0x00}, /* ext. total horizontal register */ + {0x3C,0x00}, /* ext. horizontal blanking end */ + {0x40,0x00}, /* ext. start address */ + {0x41,0x00}, /* ext. offset */ + {0x70,0x4F}, /* interlace control register */ + {0x71,0x00}, /* NTSC/PAL Video Output Control */ + {0x72,0x00}, /* NTSC/PAL horizontal serration 1 start */ + {0x73,0x00}, /* NTSC/PAL horizontal serration 2 start */ + {0x74,0x00}, /* NTSC/PAL horizontal pulse width */ + {0x75,0x00}, /* NTSC/PAL filtering burst read length */ + {0x76,0x00}, /* NTSC/PAL filtering burst read quantity */ + {0x77,0x00}, /* NTSC/PAL Filtering Control */ + {0x78,0x00}, /* NTSC/PAL Vertical reduction */ + {0x79,0x00}, /* NTSC/PAL horizontal total fine adjust */ + {0xFF,0xFF} /* end of table */ +}; + +static VIDEO_CFG_TABLE grmr[] = { + {0x00,0x00}, /* all planes are reset */ + {0x01,0x00}, /* no special altering of plane */ + {0x02,0x00}, /* color compare */ + {0x03,0x00}, /* data rotate */ + {0x04,0x00}, /* read plane 0 */ + {0x05,0x10}, /* Mode */ + {0x06,0x0E}, /* misc */ + {0x07,0x00}, /* Color */ + {0x08,0xFF}, /* Bitmask */ + {0xFF,0xFF} /* end of table */ +}; + + +static VIDEO_CFG_TABLE seq[] = { + {0x00,0x03}, /* release the resets */ + {0x01,0x00}, /* clocking mode */ + {0x02,0x03}, /* enable plane 0,1 access */ + {0x03,0x00}, /* character map */ + {0x04,0x02}, /* Memory mode */ + {0x07,0x00}, /* Reset Counter */ + {0xFF,0xFF} /* end of table */ +}; + +static VIDEO_CFG_TABLE xreg[] = { + + { 0x0A, 0x00 }, /* Frame Buffer Mapping */ + { 0x0B, 0x01 }, /* PCI Write Burst support */ + { 0x0E, 0x00 }, /* Frame buffer Page select */ + { 0x20, 0x00 }, /* BitBLT Configuration */ + /* { 0x40, 0x03 }, */ /* Memory Access Control */ + { 0x40, 0x00 }, /* Memory Access Control */ + { 0x60, 0x00 }, /* Video Pin Control */ + { 0x61, 0x00 }, /* DPMS Synch control */ + { 0x62, 0x00 }, /* GPIO Pin Control */ + { 0x63, 0xBD }, /* GPIO Pin Data*/ + { 0x67, 0x00 }, /* Pin Tri-State */ + { 0x80, 0x00 }, /* Pixel Pipeline Config 0 register */ + { 0x81, 0x00 }, /* Pixel Pipeline Config 1 register */ + { 0x82, 0x00 }, /* Pixel Pipeline Config 2 register */ + { 0xA0, 0x00 }, /* Cursor 1 Control Reg */ + { 0xA1, 0x00 }, /* Cursor 1 Vertical Extension Reg */ + { 0xA2, 0x00 }, /* Cursor 1 Base Address Low */ + { 0xA3, 0x00 }, /* Cursor 1 Base Address High */ + { 0xA4, 0x00 }, /* Cursor 1 X-Position Low */ + { 0xA5, 0x00 }, /* Cursor 1 X-Position High */ + { 0xA6, 0x00 }, /* Cursor 1 Y-Position Low */ + { 0xA7, 0x00 }, /* Cursor 1 Y-Position High */ + { 0xA8, 0x00 }, /* Cursor 2 Control Reg */ + { 0xA9, 0x00 }, /* Cursor 2 Vertical Extension Reg */ + { 0xAA, 0x00 }, /* Cursor 2 Base Address Low */ + { 0xAB, 0x00 }, /* Cursor 2 Base Address High */ + { 0xAC, 0x00 }, /* Cursor 2 X-Position Low */ + { 0xAD, 0x00 }, /* Cursor 2 X-Position High */ + { 0xAE, 0x00 }, /* Cursor 2 Y-Position Low */ + { 0xAF, 0x00 }, /* Cursor 2 Y-Position High */ + { 0xC0, 0x7D }, /* Dot Clock 0 VCO M-Divisor */ + { 0xC1, 0x07 }, /* Dot Clock 0 VCO N-Divisor */ + { 0xC3, 0x34 }, /* Dot Clock 0 Divisor select */ + { 0xC4, 0x55 }, /* Dot Clock 1 VCO M-Divisor */ + { 0xC5, 0x09 }, /* Dot Clock 1 VCO N-Divisor */ + { 0xC7, 0x24 }, /* Dot Clock 1 Divisor select */ + { 0xC8, 0x7D }, /* Dot Clock 2 VCO M-Divisor */ + { 0xC9, 0x07 }, /* Dot Clock 2 VCO N-Divisor */ + { 0xCB, 0x34 }, /* Dot Clock 2 Divisor select */ + { 0xCC, 0x38 }, /* Memory Clock 0 VCO M-Divisor */ + { 0xCD, 0x03 }, /* Memory Clock 0 VCO N-Divisor */ + { 0xCE, 0x90 }, /* Memory Clock 0 Divisor select */ + { 0xCF, 0x06 }, /* Clock Config */ + { 0xD0, 0x0F }, /* Power Down */ + { 0xD1, 0x01 }, /* Power Down BitBLT */ + /* { 0xD2, 0x0F }, */ /* 2KHz Counter Power Down */ + { 0xFF, 0xFF} /* end of table */ +}; +/* Clock Config: + * If Loop Divisor = 1 + * Fvco = (Fref * M/N) + * Fout = Fvco / Post Divisor + * Dot Clk0: + * --------- + * M = (M Div + 2) = 127 + * N = (N Div + 2) = 9 + * Post Divisor = 8 + * Loop Divisor = 1 + * Fref = 14.31818MHz => Fvco 202.045MHz => Dot Clock 0 = 25.25MHz + * + * Dot Clk1: + * --------- + * M = (M Div + 2) = 57 + * N = (N Div + 2) = 11 + * Post Divisor = 4 + * Loop Divisor = 1 + * Fref = 14.31818MHz => Fvco 113.24MHz => Dot Clock 1 = 28.31MHz + * + * Dot Clk2: + * --------- + * M = (M Div + 2) = 127 + * N = (N Div + 2) = 9 + * Post Divisor = 8 + * Loop Divisor = 1 + * Fref = 14.31818MHz => Fvco 202.045MHz => Dot Clock 2 = 25.25MHz + * + * Memory Clk: + * ----------- + * M = (M Div + 2) = 58 + * N = (N Div + 2) = 5 + * Post Divisor = 2 + * Fref = 14.31818MHz => Fvco 166MHz => Dot Clock 1 = 83MHz + * + */ + + + +/* DAC datas */ +static unsigned char dac[][3] = { + {0x00, 0x00, 0x00}, /* Index 0 (00) */ + {0x00, 0x00, 0x2A}, /* Index 1 (01) */ + {0x00, 0x2A, 0x00}, /* Index 2 (02) */ + {0x00, 0x2A, 0x2A}, /* Index 3 (03) */ + {0x2A, 0x00, 0x00}, /* Index 4 (04) */ + {0x2A, 0x00, 0x2A}, /* Index 5 (05) */ + {0x2A, 0x2A, 0x00}, /* Index 6 (06) */ + {0x2A, 0x2A, 0x2A}, /* Index 7 (07) */ + {0x00, 0x00, 0x15}, /* Index 8 (08) */ + {0x00, 0x00, 0x3F}, /* Index 9 (09) */ + {0x00, 0x2A, 0x15}, /* Index 10 (0A) */ + {0x00, 0x2A, 0x3F}, /* Index 11 (0B) */ + {0x2A, 0x00, 0x15}, /* Index 12 (0C) */ + {0x2A, 0x00, 0x3F}, /* Index 13 (0D) */ + {0x2A, 0x2A, 0x15}, /* Index 14 (0E) */ + {0x2A, 0x2A, 0x3F}, /* Index 15 (0F) */ + {0x00, 0x15, 0x00}, /* Index 16 (10) */ + {0x00, 0x15, 0x2A}, /* Index 17 (11) */ + {0x00, 0x3F, 0x00}, /* Index 18 (12) */ + {0x00, 0x3F, 0x2A}, /* Index 19 (13) */ + {0x2A, 0x15, 0x00}, /* Index 20 (14) */ + {0x2A, 0x15, 0x2A}, /* Index 21 (15) */ + {0x2A, 0x3F, 0x00}, /* Index 22 (16) */ + {0x2A, 0x3F, 0x2A}, /* Index 23 (17) */ + {0x00, 0x15, 0x15}, /* Index 24 (18) */ + {0x00, 0x15, 0x3F}, /* Index 25 (19) */ + {0x00, 0x3F, 0x15}, /* Index 26 (1A) */ + {0x00, 0x3F, 0x3F}, /* Index 27 (1B) */ + {0x2A, 0x15, 0x15}, /* Index 28 (1C) */ + {0x2A, 0x15, 0x3F}, /* Index 29 (1D) */ + {0x2A, 0x3F, 0x15}, /* Index 30 (1E) */ + {0x2A, 0x3F, 0x3F}, /* Index 31 (1F) */ + {0x15, 0x00, 0x00}, /* Index 32 (20) */ + {0x15, 0x00, 0x2A}, /* Index 33 (21) */ + {0x15, 0x2A, 0x00}, /* Index 34 (22) */ + {0x15, 0x2A, 0x2A}, /* Index 35 (23) */ + {0x3F, 0x00, 0x00}, /* Index 36 (24) */ + {0x3F, 0x00, 0x2A}, /* Index 37 (25) */ + {0x3F, 0x2A, 0x00}, /* Index 38 (26) */ + {0x3F, 0x2A, 0x2A}, /* Index 39 (27) */ + {0x15, 0x00, 0x15}, /* Index 40 (28) */ + {0x15, 0x00, 0x3F}, /* Index 41 (29) */ + {0x15, 0x2A, 0x15}, /* Index 42 (2A) */ + {0x15, 0x2A, 0x3F}, /* Index 43 (2B) */ + {0x3F, 0x00, 0x15}, /* Index 44 (2C) */ + {0x3F, 0x00, 0x3F}, /* Index 45 (2D) */ + {0x3F, 0x2A, 0x15}, /* Index 46 (2E) */ + {0x3F, 0x2A, 0x3F}, /* Index 47 (2F) */ + {0x15, 0x15, 0x00}, /* Index 48 (30) */ + {0x15, 0x15, 0x2A}, /* Index 49 (31) */ + {0x15, 0x3F, 0x00}, /* Index 50 (32) */ + {0x15, 0x3F, 0x2A}, /* Index 51 (33) */ + {0x3F, 0x15, 0x00}, /* Index 52 (34) */ + {0x3F, 0x15, 0x2A}, /* Index 53 (35) */ + {0x3F, 0x3F, 0x00}, /* Index 54 (36) */ + {0x3F, 0x3F, 0x2A}, /* Index 55 (37) */ + {0x15, 0x15, 0x15}, /* Index 56 (38) */ + {0x15, 0x15, 0x3F}, /* Index 57 (39) */ + {0x15, 0x3F, 0x15}, /* Index 58 (3A) */ + {0x15, 0x3F, 0x3F}, /* Index 59 (3B) */ + {0x3F, 0x15, 0x15}, /* Index 60 (3C) */ + {0x3F, 0x15, 0x3F}, /* Index 61 (3D) */ + {0x3F, 0x3F, 0x15}, /* Index 62 (3E) */ + {0x3F, 0x3F, 0x3F}, /* Index 63 (3F) */ + {0x16, 0x1E, 0x17}, /* Index 64 (40) */ + {0x27, 0x2F, 0x00}, /* Index 65 (41) */ + {0x1E, 0x20, 0x18}, /* Index 66 (42) */ + {0x30, 0x04, 0x06}, /* Index 67 (43) */ + {0x08, 0x05, 0x12}, /* Index 68 (44) */ + {0x30, 0x0A, 0x31}, /* Index 69 (45) */ + {0x08, 0x16, 0x07}, /* Index 70 (46) */ + {0x1B, 0x33, 0x21}, /* Index 71 (47) */ + {0x02, 0x2C, 0x16}, /* Index 72 (48) */ + {0x3D, 0x1C, 0x11}, /* Index 73 (49) */ + {0x07, 0x22, 0x33}, /* Index 74 (4A) */ + {0x1D, 0x2B, 0x0A}, /* Index 75 (4B) */ + {0x1A, 0x15, 0x16}, /* Index 76 (4C) */ + {0x15, 0x26, 0x24}, /* Index 77 (4D) */ + {0x05, 0x2B, 0x1E}, /* Index 78 (4E) */ + {0x11, 0x18, 0x01}, /* Index 79 (4F) */ + {0x3A, 0x2C, 0x27}, /* Index 80 (50) */ + {0x25, 0x23, 0x00}, /* Index 81 (51) */ + {0x2A, 0x16, 0x2A}, /* Index 82 (52) */ + {0x18, 0x19, 0x17}, /* Index 83 (53) */ + {0x0B, 0x0F, 0x06}, /* Index 84 (54) */ + {0x00, 0x34, 0x08}, /* Index 85 (55) */ + {0x00, 0x19, 0x12}, /* Index 86 (56) */ + {0x01, 0x06, 0x3B}, /* Index 87 (57) */ + {0x29, 0x0E, 0x25}, /* Index 88 (58) */ + {0x20, 0x10, 0x28}, /* Index 89 (59) */ + {0x02, 0x37, 0x24}, /* Index 90 (5A) */ + {0x08, 0x2A, 0x2E}, /* Index 91 (5B) */ + {0x26, 0x2A, 0x22}, /* Index 92 (5C) */ + {0x0C, 0x0C, 0x2A}, /* Index 93 (5D) */ + {0x28, 0x07, 0x02}, /* Index 94 (5E) */ + {0x34, 0x05, 0x2B}, /* Index 95 (5F) */ + {0x0C, 0x31, 0x33}, /* Index 96 (60) */ + {0x22, 0x08, 0x30}, /* Index 97 (61) */ + {0x00, 0x25, 0x01}, /* Index 98 (62) */ + {0x06, 0x15, 0x01}, /* Index 99 (63) */ + {0x0D, 0x2A, 0x0A}, /* Index 100 (64) */ + {0x08, 0x25, 0x16}, /* Index 101 (65) */ + {0x2A, 0x0A, 0x01}, /* Index 102 (66) */ + {0x08, 0x3B, 0x28}, /* Index 103 (67) */ + {0x00, 0x09, 0x04}, /* Index 104 (68) */ + {0x16, 0x0F, 0x05}, /* Index 105 (69) */ + {0x02, 0x2F, 0x1D}, /* Index 106 (6A) */ + {0x06, 0x3E, 0x02}, /* Index 107 (6B) */ + {0x09, 0x30, 0x07}, /* Index 108 (6C) */ + {0x34, 0x03, 0x06}, /* Index 109 (6D) */ + {0x00, 0x15, 0x2A}, /* Index 110 (6E) */ + {0x39, 0x23, 0x20}, /* Index 111 (6F) */ + {0x2A, 0x32, 0x0C}, /* Index 112 (70) */ + {0x09, 0x31, 0x26}, /* Index 113 (71) */ + {0x27, 0x23, 0x28}, /* Index 114 (72) */ + {0x20, 0x13, 0x0C}, /* Index 115 (73) */ + {0x2C, 0x1E, 0x26}, /* Index 116 (74) */ + {0x20, 0x2F, 0x05}, /* Index 117 (75) */ + {0x22, 0x1B, 0x22}, /* Index 118 (76) */ + {0x09, 0x1C, 0x06}, /* Index 119 (77) */ + {0x16, 0x38, 0x0E}, /* Index 120 (78) */ + {0x22, 0x16, 0x20}, /* Index 121 (79) */ + {0x10, 0x17, 0x25}, /* Index 122 (7A) */ + {0x04, 0x32, 0x22}, /* Index 123 (7B) */ + {0x20, 0x00, 0x37}, /* Index 124 (7C) */ + {0x21, 0x15, 0x1A}, /* Index 125 (7D) */ + {0x01, 0x04, 0x20}, /* Index 126 (7E) */ + {0x02, 0x0C, 0x1E}, /* Index 127 (7F) */ + {0x15, 0x15, 0x29}, /* Index 128 (80) */ + {0x24, 0x3B, 0x00}, /* Index 129 (81) */ + {0x24, 0x28, 0x01}, /* Index 130 (82) */ + {0x20, 0x19, 0x07}, /* Index 131 (83) */ + {0x1A, 0x13, 0x02}, /* Index 132 (84) */ + {0x04, 0x24, 0x1F}, /* Index 133 (85) */ + {0x32, 0x30, 0x08}, /* Index 134 (86) */ + {0x23, 0x12, 0x0B}, /* Index 135 (87) */ + {0x21, 0x38, 0x00}, /* Index 136 (88) */ + {0x04, 0x13, 0x09}, /* Index 137 (89) */ + {0x06, 0x3E, 0x14}, /* Index 138 (8A) */ + {0x23, 0x22, 0x2D}, /* Index 139 (8B) */ + {0x3D, 0x35, 0x30}, /* Index 140 (8C) */ + {0x24, 0x38, 0x05}, /* Index 141 (8D) */ + {0x18, 0x01, 0x26}, /* Index 142 (8E) */ + {0x27, 0x11, 0x38}, /* Index 143 (8F) */ + {0x08, 0x1A, 0x08}, /* Index 144 (90) */ + {0x00, 0x1A, 0x07}, /* Index 145 (91) */ + {0x16, 0x0C, 0x30}, /* Index 146 (92) */ + {0x1B, 0x0A, 0x0B}, /* Index 147 (93) */ + {0x01, 0x0C, 0x09}, /* Index 148 (94) */ + {0x00, 0x33, 0x03}, /* Index 149 (95) */ + {0x13, 0x0A, 0x06}, /* Index 150 (96) */ + {0x22, 0x19, 0x23}, /* Index 151 (97) */ + {0x07, 0x30, 0x39}, /* Index 152 (98) */ + {0x20, 0x07, 0x0D}, /* Index 153 (99) */ + {0x39, 0x18, 0x20}, /* Index 154 (9A) */ + {0x32, 0x31, 0x29}, /* Index 155 (9B) */ + {0x28, 0x3F, 0x02}, /* Index 156 (9C) */ + {0x02, 0x15, 0x3E}, /* Index 157 (9D) */ + {0x27, 0x33, 0x0E}, /* Index 158 (9E) */ + {0x39, 0x2E, 0x1D}, /* Index 159 (9F) */ + {0x1E, 0x38, 0x10}, /* Index 160 (A0) */ + {0x01, 0x33, 0x19}, /* Index 161 (A1) */ + {0x2B, 0x20, 0x0B}, /* Index 162 (A2) */ + {0x29, 0x0B, 0x23}, /* Index 163 (A3) */ + {0x25, 0x04, 0x19}, /* Index 164 (A4) */ + {0x34, 0x36, 0x08}, /* Index 165 (A5) */ + {0x17, 0x1D, 0x01}, /* Index 166 (A6) */ + {0x0A, 0x29, 0x10}, /* Index 167 (A7) */ + {0x14, 0x1C, 0x2B}, /* Index 168 (A8) */ + {0x02, 0x2C, 0x13}, /* Index 169 (A9) */ + {0x14, 0x16, 0x3A}, /* Index 170 (AA) */ + {0x2B, 0x22, 0x28}, /* Index 171 (AB) */ + {0x2E, 0x0A, 0x22}, /* Index 172 (AC) */ + {0x00, 0x20, 0x28}, /* Index 173 (AD) */ + {0x08, 0x22, 0x2D}, /* Index 174 (AE) */ + {0x2C, 0x17, 0x1D}, /* Index 175 (AF) */ + {0x02, 0x0D, 0x20}, /* Index 176 (B0) */ + {0x00, 0x18, 0x2C}, /* Index 177 (B1) */ + {0x19, 0x19, 0x3C}, /* Index 178 (B2) */ + {0x20, 0x32, 0x10}, /* Index 179 (B3) */ + {0x38, 0x1C, 0x21}, /* Index 180 (B4) */ + {0x36, 0x10, 0x00}, /* Index 181 (B5) */ + {0x20, 0x08, 0x19}, /* Index 182 (B6) */ + {0x09, 0x12, 0x01}, /* Index 183 (B7) */ + {0x1D, 0x39, 0x03}, /* Index 184 (B8) */ + {0x20, 0x28, 0x11}, /* Index 185 (B9) */ + {0x35, 0x17, 0x01}, /* Index 186 (BA) */ + {0x0C, 0x02, 0x08}, /* Index 187 (BB) */ + {0x39, 0x0D, 0x10}, /* Index 188 (BC) */ + {0x38, 0x21, 0x16}, /* Index 189 (BD) */ + {0x29, 0x3E, 0x14}, /* Index 190 (BE) */ + {0x0A, 0x1C, 0x28}, /* Index 191 (BF) */ + {0x2F, 0x03, 0x08}, /* Index 192 (C0) */ + {0x02, 0x18, 0x39}, /* Index 193 (C1) */ + {0x0F, 0x31, 0x1E}, /* Index 194 (C2) */ + {0x24, 0x0C, 0x03}, /* Index 195 (C3) */ + {0x04, 0x1A, 0x04}, /* Index 196 (C4) */ + {0x30, 0x33, 0x04}, /* Index 197 (C5) */ + {0x2C, 0x18, 0x36}, /* Index 198 (C6) */ + {0x18, 0x2F, 0x09}, /* Index 199 (C7) */ + {0x03, 0x04, 0x03}, /* Index 200 (C8) */ + {0x22, 0x05, 0x10}, /* Index 201 (C9) */ + {0x03, 0x24, 0x0A}, /* Index 202 (CA) */ + {0x00, 0x1E, 0x1A}, /* Index 203 (CB) */ + {0x00, 0x0A, 0x11}, /* Index 204 (CC) */ + {0x0E, 0x1F, 0x09}, /* Index 205 (CD) */ + {0x1B, 0x3A, 0x3B}, /* Index 206 (CE) */ + {0x22, 0x39, 0x36}, /* Index 207 (CF) */ + {0x22, 0x10, 0x23}, /* Index 208 (D0) */ + {0x31, 0x14, 0x2B}, /* Index 209 (D1) */ + {0x0C, 0x33, 0x35}, /* Index 210 (D2) */ + {0x27, 0x3E, 0x10}, /* Index 211 (D3) */ + {0x10, 0x04, 0x30}, /* Index 212 (D4) */ + {0x05, 0x21, 0x0A}, /* Index 213 (D5) */ + {0x09, 0x11, 0x24}, /* Index 214 (D6) */ + {0x02, 0x2B, 0x00}, /* Index 215 (D7) */ + {0x02, 0x05, 0x15}, /* Index 216 (D8) */ + {0x11, 0x32, 0x1A}, /* Index 217 (D9) */ + {0x2E, 0x1B, 0x08}, /* Index 218 (DA) */ + {0x0D, 0x2F, 0x11}, /* Index 219 (DB) */ + {0x03, 0x30, 0x28}, /* Index 220 (DC) */ + {0x15, 0x38, 0x0A}, /* Index 221 (DD) */ + {0x07, 0x00, 0x00}, /* Index 222 (DE) */ + {0x1D, 0x1C, 0x20}, /* Index 223 (DF) */ + {0x35, 0x11, 0x35}, /* Index 224 (E0) */ + {0x24, 0x29, 0x03}, /* Index 225 (E1) */ + {0x22, 0x37, 0x39}, /* Index 226 (E2) */ + {0x11, 0x1B, 0x10}, /* Index 227 (E3) */ + {0x2D, 0x18, 0x00}, /* Index 228 (E4) */ + {0x20, 0x2F, 0x10}, /* Index 229 (E5) */ + {0x21, 0x26, 0x32}, /* Index 230 (E6) */ + {0x24, 0x10, 0x3D}, /* Index 231 (E7) */ + {0x27, 0x0E, 0x03}, /* Index 232 (E8) */ + {0x31, 0x1F, 0x11}, /* Index 233 (E9) */ + {0x16, 0x0D, 0x02}, /* Index 234 (EA) */ + {0x24, 0x12, 0x16}, /* Index 235 (EB) */ + {0x0F, 0x27, 0x18}, /* Index 236 (EC) */ + {0x10, 0x0E, 0x20}, /* Index 237 (ED) */ + {0x12, 0x0C, 0x0D}, /* Index 238 (EE) */ + {0x14, 0x38, 0x0B}, /* Index 239 (EF) */ + {0x23, 0x0C, 0x09}, /* Index 240 (F0) */ + {0x13, 0x21, 0x0E}, /* Index 241 (F1) */ + {0x2C, 0x05, 0x2C}, /* Index 242 (F2) */ + {0x08, 0x29, 0x01}, /* Index 243 (F3) */ + {0x36, 0x0A, 0x13}, /* Index 244 (F4) */ + {0x08, 0x2D, 0x26}, /* Index 245 (F5) */ + {0x23, 0x30, 0x3E}, /* Index 246 (F6) */ + {0x33, 0x00, 0x04}, /* Index 247 (F7) */ + {0x25, 0x1E, 0x3A}, /* Index 248 (F8) */ + {0x11, 0x2C, 0x26}, /* Index 249 (F9) */ + {0x20, 0x32, 0x27}, /* Index 250 (FA) */ + {0x23, 0x21, 0x13}, /* Index 251 (FB) */ + {0x22, 0x23, 0x1F}, /* Index 252 (FC) */ + {0x31, 0x08, 0x0A}, /* Index 253 (FD) */ + {0x00, 0x01, 0x09}, /* Index 254 (FE) */ + {0x17, 0x07, 0x38} /* Index 255 (FF) */ +}; + + +/*********************************************** + * 8x16 Font + * + * copied from file + * drivers/video/font_8x16.c (LINUX) + **********************************************/ +/**********************************************/ +/* */ +/* Font file generated by cpi2fnt */ +/* */ +/**********************************************/ + +#define FONTDATAMAX 4096 + +unsigned char fontdata_8x16[FONTDATAMAX] = { + + /* 0 0x00 '^@' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 1 0x01 '^A' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x81, /* 10000001 */ + 0xa5, /* 10100101 */ + 0x81, /* 10000001 */ + 0x81, /* 10000001 */ + 0xbd, /* 10111101 */ + 0x99, /* 10011001 */ + 0x81, /* 10000001 */ + 0x81, /* 10000001 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 2 0x02 '^B' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0xff, /* 11111111 */ + 0xdb, /* 11011011 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xc3, /* 11000011 */ + 0xe7, /* 11100111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 3 0x03 '^C' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x6c, /* 01101100 */ + 0xfe, /* 11111110 */ + 0xfe, /* 11111110 */ + 0xfe, /* 11111110 */ + 0xfe, /* 11111110 */ + 0x7c, /* 01111100 */ + 0x38, /* 00111000 */ + 0x10, /* 00010000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 4 0x04 '^D' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x10, /* 00010000 */ + 0x38, /* 00111000 */ + 0x7c, /* 01111100 */ + 0xfe, /* 11111110 */ + 0x7c, /* 01111100 */ + 0x38, /* 00111000 */ + 0x10, /* 00010000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 5 0x05 '^E' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x3c, /* 00111100 */ + 0xe7, /* 11100111 */ + 0xe7, /* 11100111 */ + 0xe7, /* 11100111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 6 0x06 '^F' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x7e, /* 01111110 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 7 0x07 '^G' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 8 0x08 '^H' */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xe7, /* 11100111 */ + 0xc3, /* 11000011 */ + 0xc3, /* 11000011 */ + 0xe7, /* 11100111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + + /* 9 0x09 '^I' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0x42, /* 01000010 */ + 0x42, /* 01000010 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 10 0x0a '^J' */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xc3, /* 11000011 */ + 0x99, /* 10011001 */ + 0xbd, /* 10111101 */ + 0xbd, /* 10111101 */ + 0x99, /* 10011001 */ + 0xc3, /* 11000011 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + + /* 11 0x0b '^K' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x1e, /* 00011110 */ + 0x0e, /* 00001110 */ + 0x1a, /* 00011010 */ + 0x32, /* 00110010 */ + 0x78, /* 01111000 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x78, /* 01111000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 12 0x0c '^L' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 13 0x0d '^M' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x3f, /* 00111111 */ + 0x33, /* 00110011 */ + 0x3f, /* 00111111 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x70, /* 01110000 */ + 0xf0, /* 11110000 */ + 0xe0, /* 11100000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 14 0x0e '^N' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7f, /* 01111111 */ + 0x63, /* 01100011 */ + 0x7f, /* 01111111 */ + 0x63, /* 01100011 */ + 0x63, /* 01100011 */ + 0x63, /* 01100011 */ + 0x63, /* 01100011 */ + 0x67, /* 01100111 */ + 0xe7, /* 11100111 */ + 0xe6, /* 11100110 */ + 0xc0, /* 11000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 15 0x0f '^O' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xdb, /* 11011011 */ + 0x3c, /* 00111100 */ + 0xe7, /* 11100111 */ + 0x3c, /* 00111100 */ + 0xdb, /* 11011011 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 16 0x10 '^P' */ + 0x00, /* 00000000 */ + 0x80, /* 10000000 */ + 0xc0, /* 11000000 */ + 0xe0, /* 11100000 */ + 0xf0, /* 11110000 */ + 0xf8, /* 11111000 */ + 0xfe, /* 11111110 */ + 0xf8, /* 11111000 */ + 0xf0, /* 11110000 */ + 0xe0, /* 11100000 */ + 0xc0, /* 11000000 */ + 0x80, /* 10000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 17 0x11 '^Q' */ + 0x00, /* 00000000 */ + 0x02, /* 00000010 */ + 0x06, /* 00000110 */ + 0x0e, /* 00001110 */ + 0x1e, /* 00011110 */ + 0x3e, /* 00111110 */ + 0xfe, /* 11111110 */ + 0x3e, /* 00111110 */ + 0x1e, /* 00011110 */ + 0x0e, /* 00001110 */ + 0x06, /* 00000110 */ + 0x02, /* 00000010 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 18 0x12 '^R' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 19 0x13 '^S' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x00, /* 00000000 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 20 0x14 '^T' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7f, /* 01111111 */ + 0xdb, /* 11011011 */ + 0xdb, /* 11011011 */ + 0xdb, /* 11011011 */ + 0x7b, /* 01111011 */ + 0x1b, /* 00011011 */ + 0x1b, /* 00011011 */ + 0x1b, /* 00011011 */ + 0x1b, /* 00011011 */ + 0x1b, /* 00011011 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 21 0x15 '^U' */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0x60, /* 01100000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x0c, /* 00001100 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 22 0x16 '^V' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0xfe, /* 11111110 */ + 0xfe, /* 11111110 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 23 0x17 '^W' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 24 0x18 '^X' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 25 0x19 '^Y' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 26 0x1a '^Z' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0xfe, /* 11111110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 27 0x1b '^[' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0xfe, /* 11111110 */ + 0x60, /* 01100000 */ + 0x30, /* 00110000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 28 0x1c '^\' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 29 0x1d '^]' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x28, /* 00101000 */ + 0x6c, /* 01101100 */ + 0xfe, /* 11111110 */ + 0x6c, /* 01101100 */ + 0x28, /* 00101000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 30 0x1e '^^' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x10, /* 00010000 */ + 0x38, /* 00111000 */ + 0x38, /* 00111000 */ + 0x7c, /* 01111100 */ + 0x7c, /* 01111100 */ + 0xfe, /* 11111110 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 31 0x1f '^_' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0xfe, /* 11111110 */ + 0x7c, /* 01111100 */ + 0x7c, /* 01111100 */ + 0x38, /* 00111000 */ + 0x38, /* 00111000 */ + 0x10, /* 00010000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 32 0x20 ' ' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 33 0x21 '!' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x3c, /* 00111100 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 34 0x22 '"' */ + 0x00, /* 00000000 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x24, /* 00100100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 35 0x23 '#' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0xfe, /* 11111110 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0xfe, /* 11111110 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 36 0x24 '$' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc2, /* 11000010 */ + 0xc0, /* 11000000 */ + 0x7c, /* 01111100 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x86, /* 10000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 37 0x25 '%' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc2, /* 11000010 */ + 0xc6, /* 11000110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0xc6, /* 11000110 */ + 0x86, /* 10000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 38 0x26 '&' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x76, /* 01110110 */ + 0xdc, /* 11011100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 39 0x27 ''' */ + 0x00, /* 00000000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 40 0x28 '(' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 41 0x29 ')' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 42 0x2a '*' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0xff, /* 11111111 */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 43 0x2b '+' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 44 0x2c ',' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 45 0x2d '-' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 46 0x2e '.' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 47 0x2f '/' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x02, /* 00000010 */ + 0x06, /* 00000110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0xc0, /* 11000000 */ + 0x80, /* 10000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 48 0x30 '0' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xd6, /* 11010110 */ + 0xd6, /* 11010110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 49 0x31 '1' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x38, /* 00111000 */ + 0x78, /* 01111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 50 0x32 '2' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0x06, /* 00000110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0xc0, /* 11000000 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 51 0x33 '3' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x3c, /* 00111100 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 52 0x34 '4' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x0c, /* 00001100 */ + 0x1c, /* 00011100 */ + 0x3c, /* 00111100 */ + 0x6c, /* 01101100 */ + 0xcc, /* 11001100 */ + 0xfe, /* 11111110 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x1e, /* 00011110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 53 0x35 '5' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xfc, /* 11111100 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 54 0x36 '6' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x60, /* 01100000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xfc, /* 11111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 55 0x37 '7' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 56 0x38 '8' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 57 0x39 '9' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7e, /* 01111110 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x0c, /* 00001100 */ + 0x78, /* 01111000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 58 0x3a ':' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 59 0x3b ';' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 60 0x3c '<' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x06, /* 00000110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x06, /* 00000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 61 0x3d '=' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 62 0x3e '>' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x60, /* 01100000 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x06, /* 00000110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 63 0x3f '?' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 64 0x40 '@' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xde, /* 11011110 */ + 0xde, /* 11011110 */ + 0xde, /* 11011110 */ + 0xdc, /* 11011100 */ + 0xc0, /* 11000000 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 65 0x41 'A' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x10, /* 00010000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 66 0x42 'B' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfc, /* 11111100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x7c, /* 01111100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0xfc, /* 11111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 67 0x43 'C' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0xc2, /* 11000010 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc2, /* 11000010 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 68 0x44 'D' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xf8, /* 11111000 */ + 0x6c, /* 01101100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x6c, /* 01101100 */ + 0xf8, /* 11111000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 69 0x45 'E' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x66, /* 01100110 */ + 0x62, /* 01100010 */ + 0x68, /* 01101000 */ + 0x78, /* 01111000 */ + 0x68, /* 01101000 */ + 0x60, /* 01100000 */ + 0x62, /* 01100010 */ + 0x66, /* 01100110 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 70 0x46 'F' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x66, /* 01100110 */ + 0x62, /* 01100010 */ + 0x68, /* 01101000 */ + 0x78, /* 01111000 */ + 0x68, /* 01101000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0xf0, /* 11110000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 71 0x47 'G' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0xc2, /* 11000010 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xde, /* 11011110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x66, /* 01100110 */ + 0x3a, /* 00111010 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 72 0x48 'H' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 73 0x49 'I' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 74 0x4a 'J' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x1e, /* 00011110 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x78, /* 01111000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 75 0x4b 'K' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xe6, /* 11100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x6c, /* 01101100 */ + 0x78, /* 01111000 */ + 0x78, /* 01111000 */ + 0x6c, /* 01101100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0xe6, /* 11100110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 76 0x4c 'L' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xf0, /* 11110000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x62, /* 01100010 */ + 0x66, /* 01100110 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 77 0x4d 'M' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xee, /* 11101110 */ + 0xfe, /* 11111110 */ + 0xfe, /* 11111110 */ + 0xd6, /* 11010110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 78 0x4e 'N' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xe6, /* 11100110 */ + 0xf6, /* 11110110 */ + 0xfe, /* 11111110 */ + 0xde, /* 11011110 */ + 0xce, /* 11001110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 79 0x4f 'O' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 80 0x50 'P' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfc, /* 11111100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x7c, /* 01111100 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0xf0, /* 11110000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 81 0x51 'Q' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xd6, /* 11010110 */ + 0xde, /* 11011110 */ + 0x7c, /* 01111100 */ + 0x0c, /* 00001100 */ + 0x0e, /* 00001110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 82 0x52 'R' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfc, /* 11111100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x7c, /* 01111100 */ + 0x6c, /* 01101100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0xe6, /* 11100110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 83 0x53 'S' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x60, /* 01100000 */ + 0x38, /* 00111000 */ + 0x0c, /* 00001100 */ + 0x06, /* 00000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 84 0x54 'T' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x7e, /* 01111110 */ + 0x5a, /* 01011010 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 85 0x55 'U' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 86 0x56 'V' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x10, /* 00010000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 87 0x57 'W' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xd6, /* 11010110 */ + 0xd6, /* 11010110 */ + 0xd6, /* 11010110 */ + 0xfe, /* 11111110 */ + 0xee, /* 11101110 */ + 0x6c, /* 01101100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 88 0x58 'X' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x6c, /* 01101100 */ + 0x7c, /* 01111100 */ + 0x38, /* 00111000 */ + 0x38, /* 00111000 */ + 0x7c, /* 01111100 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 89 0x59 'Y' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 90 0x5a 'Z' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0x86, /* 10000110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0xc2, /* 11000010 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 91 0x5b '[' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x3c, /* 00111100 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 92 0x5c '\' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x80, /* 10000000 */ + 0xc0, /* 11000000 */ + 0xe0, /* 11100000 */ + 0x70, /* 01110000 */ + 0x38, /* 00111000 */ + 0x1c, /* 00011100 */ + 0x0e, /* 00001110 */ + 0x06, /* 00000110 */ + 0x02, /* 00000010 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 93 0x5d ']' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x3c, /* 00111100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 94 0x5e '^' */ + 0x10, /* 00010000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 95 0x5f '_' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 96 0x60 '`' */ + 0x00, /* 00000000 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 97 0x61 'a' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x78, /* 01111000 */ + 0x0c, /* 00001100 */ + 0x7c, /* 01111100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 98 0x62 'b' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xe0, /* 11100000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x78, /* 01111000 */ + 0x6c, /* 01101100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 99 0x63 'c' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 100 0x64 'd' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x1c, /* 00011100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x3c, /* 00111100 */ + 0x6c, /* 01101100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 101 0x65 'e' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 102 0x66 'f' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x1c, /* 00011100 */ + 0x36, /* 00110110 */ + 0x32, /* 00110010 */ + 0x30, /* 00110000 */ + 0x78, /* 01111000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x78, /* 01111000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 103 0x67 'g' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x76, /* 01110110 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x7c, /* 01111100 */ + 0x0c, /* 00001100 */ + 0xcc, /* 11001100 */ + 0x78, /* 01111000 */ + 0x00, /* 00000000 */ + + /* 104 0x68 'h' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xe0, /* 11100000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x6c, /* 01101100 */ + 0x76, /* 01110110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0xe6, /* 11100110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 105 0x69 'i' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 106 0x6a 'j' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x00, /* 00000000 */ + 0x0e, /* 00001110 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + + /* 107 0x6b 'k' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xe0, /* 11100000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x66, /* 01100110 */ + 0x6c, /* 01101100 */ + 0x78, /* 01111000 */ + 0x78, /* 01111000 */ + 0x6c, /* 01101100 */ + 0x66, /* 01100110 */ + 0xe6, /* 11100110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 108 0x6c 'l' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 109 0x6d 'm' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xec, /* 11101100 */ + 0xfe, /* 11111110 */ + 0xd6, /* 11010110 */ + 0xd6, /* 11010110 */ + 0xd6, /* 11010110 */ + 0xd6, /* 11010110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 110 0x6e 'n' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xdc, /* 11011100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 111 0x6f 'o' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 112 0x70 'p' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xdc, /* 11011100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x7c, /* 01111100 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0xf0, /* 11110000 */ + 0x00, /* 00000000 */ + + /* 113 0x71 'q' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x76, /* 01110110 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x7c, /* 01111100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x1e, /* 00011110 */ + 0x00, /* 00000000 */ + + /* 114 0x72 'r' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xdc, /* 11011100 */ + 0x76, /* 01110110 */ + 0x66, /* 01100110 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0xf0, /* 11110000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 115 0x73 's' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0x60, /* 01100000 */ + 0x38, /* 00111000 */ + 0x0c, /* 00001100 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 116 0x74 't' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x10, /* 00010000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0xfc, /* 11111100 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x36, /* 00110110 */ + 0x1c, /* 00011100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 117 0x75 'u' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 118 0x76 'v' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 119 0x77 'w' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xd6, /* 11010110 */ + 0xd6, /* 11010110 */ + 0xd6, /* 11010110 */ + 0xfe, /* 11111110 */ + 0x6c, /* 01101100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 120 0x78 'x' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x38, /* 00111000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 121 0x79 'y' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7e, /* 01111110 */ + 0x06, /* 00000110 */ + 0x0c, /* 00001100 */ + 0xf8, /* 11111000 */ + 0x00, /* 00000000 */ + + /* 122 0x7a 'z' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0xcc, /* 11001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 123 0x7b '{' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x0e, /* 00001110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x70, /* 01110000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x0e, /* 00001110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 124 0x7c '|' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 125 0x7d '}' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x70, /* 01110000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x0e, /* 00001110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x70, /* 01110000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 126 0x7e '~' */ + 0x00, /* 00000000 */ + 0x76, /* 01110110 */ + 0xdc, /* 11011100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 127 0x7f '' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x10, /* 00010000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 128 0x80 '' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0xc2, /* 11000010 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc2, /* 11000010 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x70, /* 01110000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 129 0x81 '' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xcc, /* 11001100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 130 0x82 '' */ + 0x00, /* 00000000 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 131 0x83 '' */ + 0x00, /* 00000000 */ + 0x10, /* 00010000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0x00, /* 00000000 */ + 0x78, /* 01111000 */ + 0x0c, /* 00001100 */ + 0x7c, /* 01111100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 132 0x84 '' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xcc, /* 11001100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x78, /* 01111000 */ + 0x0c, /* 00001100 */ + 0x7c, /* 01111100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 133 0x85 '' */ + 0x00, /* 00000000 */ + 0x60, /* 01100000 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x78, /* 01111000 */ + 0x0c, /* 00001100 */ + 0x7c, /* 01111100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 134 0x86 '' */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x00, /* 00000000 */ + 0x78, /* 01111000 */ + 0x0c, /* 00001100 */ + 0x7c, /* 01111100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 135 0x87 '' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x18, /* 00011000 */ + 0x70, /* 01110000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 136 0x88 '' */ + 0x00, /* 00000000 */ + 0x10, /* 00010000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 137 0x89 '' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 138 0x8a '' */ + 0x00, /* 00000000 */ + 0x60, /* 01100000 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 139 0x8b '' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x66, /* 01100110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 140 0x8c '' */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 141 0x8d '' */ + 0x00, /* 00000000 */ + 0x60, /* 01100000 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 142 0x8e '' */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x10, /* 00010000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 143 0x8f '' */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x10, /* 00010000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 144 0x90 '' */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x66, /* 01100110 */ + 0x62, /* 01100010 */ + 0x68, /* 01101000 */ + 0x78, /* 01111000 */ + 0x68, /* 01101000 */ + 0x62, /* 01100010 */ + 0x66, /* 01100110 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 145 0x91 '' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xec, /* 11101100 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x7e, /* 01111110 */ + 0xd8, /* 11011000 */ + 0xd8, /* 11011000 */ + 0x6e, /* 01101110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 146 0x92 '' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x3e, /* 00111110 */ + 0x6c, /* 01101100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xfe, /* 11111110 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xce, /* 11001110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 147 0x93 '' */ + 0x00, /* 00000000 */ + 0x10, /* 00010000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 148 0x94 '' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 149 0x95 '' */ + 0x00, /* 00000000 */ + 0x60, /* 01100000 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 150 0x96 '' */ + 0x00, /* 00000000 */ + 0x30, /* 00110000 */ + 0x78, /* 01111000 */ + 0xcc, /* 11001100 */ + 0x00, /* 00000000 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 151 0x97 '' */ + 0x00, /* 00000000 */ + 0x60, /* 01100000 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 152 0x98 '' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7e, /* 01111110 */ + 0x06, /* 00000110 */ + 0x0c, /* 00001100 */ + 0x78, /* 01111000 */ + 0x00, /* 00000000 */ + + /* 153 0x99 '' */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 154 0x9a '' */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 155 0x9b '' */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 156 0x9c '' */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0x64, /* 01100100 */ + 0x60, /* 01100000 */ + 0xf0, /* 11110000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0xe6, /* 11100110 */ + 0xfc, /* 11111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 157 0x9d '' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 158 0x9e '' */ + 0x00, /* 00000000 */ + 0xf8, /* 11111000 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xf8, /* 11111000 */ + 0xc4, /* 11000100 */ + 0xcc, /* 11001100 */ + 0xde, /* 11011110 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 159 0x9f '' */ + 0x00, /* 00000000 */ + 0x0e, /* 00001110 */ + 0x1b, /* 00011011 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xd8, /* 11011000 */ + 0x70, /* 01110000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 160 0xa0 ' ' */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0x00, /* 00000000 */ + 0x78, /* 01111000 */ + 0x0c, /* 00001100 */ + 0x7c, /* 01111100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 161 0xa1 '¡' */ + 0x00, /* 00000000 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 162 0xa2 '¢' */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 163 0xa3 '£' */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0x00, /* 00000000 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 164 0xa4 '¤' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x76, /* 01110110 */ + 0xdc, /* 11011100 */ + 0x00, /* 00000000 */ + 0xdc, /* 11011100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 165 0xa5 '¥' */ + 0x76, /* 01110110 */ + 0xdc, /* 11011100 */ + 0x00, /* 00000000 */ + 0xc6, /* 11000110 */ + 0xe6, /* 11100110 */ + 0xf6, /* 11110110 */ + 0xfe, /* 11111110 */ + 0xde, /* 11011110 */ + 0xce, /* 11001110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 166 0xa6 '¦' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x3c, /* 00111100 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x3e, /* 00111110 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 167 0xa7 '§' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 168 0xa8 '¨' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x00, /* 00000000 */ + 0x30, /* 00110000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0xc0, /* 11000000 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x7c, /* 01111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 169 0xa9 '©' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 170 0xaa 'ª' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 171 0xab '«' */ + 0x00, /* 00000000 */ + 0x60, /* 01100000 */ + 0xe0, /* 11100000 */ + 0x62, /* 01100010 */ + 0x66, /* 01100110 */ + 0x6c, /* 01101100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0xdc, /* 11011100 */ + 0x86, /* 10000110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x3e, /* 00111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 172 0xac '¬' */ + 0x00, /* 00000000 */ + 0x60, /* 01100000 */ + 0xe0, /* 11100000 */ + 0x62, /* 01100010 */ + 0x66, /* 01100110 */ + 0x6c, /* 01101100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x66, /* 01100110 */ + 0xce, /* 11001110 */ + 0x9a, /* 10011010 */ + 0x3f, /* 00111111 */ + 0x06, /* 00000110 */ + 0x06, /* 00000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 173 0xad '­' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x3c, /* 00111100 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 174 0xae '®' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x36, /* 00110110 */ + 0x6c, /* 01101100 */ + 0xd8, /* 11011000 */ + 0x6c, /* 01101100 */ + 0x36, /* 00110110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 175 0xaf '¯' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xd8, /* 11011000 */ + 0x6c, /* 01101100 */ + 0x36, /* 00110110 */ + 0x6c, /* 01101100 */ + 0xd8, /* 11011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 176 0xb0 '°' */ + 0x11, /* 00010001 */ + 0x44, /* 01000100 */ + 0x11, /* 00010001 */ + 0x44, /* 01000100 */ + 0x11, /* 00010001 */ + 0x44, /* 01000100 */ + 0x11, /* 00010001 */ + 0x44, /* 01000100 */ + 0x11, /* 00010001 */ + 0x44, /* 01000100 */ + 0x11, /* 00010001 */ + 0x44, /* 01000100 */ + 0x11, /* 00010001 */ + 0x44, /* 01000100 */ + 0x11, /* 00010001 */ + 0x44, /* 01000100 */ + + /* 177 0xb1 '±' */ + 0x55, /* 01010101 */ + 0xaa, /* 10101010 */ + 0x55, /* 01010101 */ + 0xaa, /* 10101010 */ + 0x55, /* 01010101 */ + 0xaa, /* 10101010 */ + 0x55, /* 01010101 */ + 0xaa, /* 10101010 */ + 0x55, /* 01010101 */ + 0xaa, /* 10101010 */ + 0x55, /* 01010101 */ + 0xaa, /* 10101010 */ + 0x55, /* 01010101 */ + 0xaa, /* 10101010 */ + 0x55, /* 01010101 */ + 0xaa, /* 10101010 */ + + /* 178 0xb2 '²' */ + 0xdd, /* 11011101 */ + 0x77, /* 01110111 */ + 0xdd, /* 11011101 */ + 0x77, /* 01110111 */ + 0xdd, /* 11011101 */ + 0x77, /* 01110111 */ + 0xdd, /* 11011101 */ + 0x77, /* 01110111 */ + 0xdd, /* 11011101 */ + 0x77, /* 01110111 */ + 0xdd, /* 11011101 */ + 0x77, /* 01110111 */ + 0xdd, /* 11011101 */ + 0x77, /* 01110111 */ + 0xdd, /* 11011101 */ + 0x77, /* 01110111 */ + + /* 179 0xb3 '³' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 180 0xb4 '´' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xf8, /* 11111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 181 0xb5 'µ' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xf8, /* 11111000 */ + 0x18, /* 00011000 */ + 0xf8, /* 11111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 182 0xb6 '¶' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0xf6, /* 11110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 183 0xb7 '·' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 184 0xb8 '¸' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xf8, /* 11111000 */ + 0x18, /* 00011000 */ + 0xf8, /* 11111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 185 0xb9 '¹' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0xf6, /* 11110110 */ + 0x06, /* 00000110 */ + 0xf6, /* 11110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 186 0xba 'º' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 187 0xbb '»' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x06, /* 00000110 */ + 0xf6, /* 11110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 188 0xbc '¼' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0xf6, /* 11110110 */ + 0x06, /* 00000110 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 189 0xbd '½' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 190 0xbe '¾' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xf8, /* 11111000 */ + 0x18, /* 00011000 */ + 0xf8, /* 11111000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 191 0xbf '¿' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xf8, /* 11111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 192 0xc0 'À' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x1f, /* 00011111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 193 0xc1 'Á' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 194 0xc2 'Â' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 195 0xc3 'Ã' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x1f, /* 00011111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 196 0xc4 'Ä' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 197 0xc5 'Å' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xff, /* 11111111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 198 0xc6 'Æ' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x1f, /* 00011111 */ + 0x18, /* 00011000 */ + 0x1f, /* 00011111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 199 0xc7 'Ç' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x37, /* 00110111 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 200 0xc8 'È' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x37, /* 00110111 */ + 0x30, /* 00110000 */ + 0x3f, /* 00111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 201 0xc9 'É' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x3f, /* 00111111 */ + 0x30, /* 00110000 */ + 0x37, /* 00110111 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 202 0xca 'Ê' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0xf7, /* 11110111 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 203 0xcb 'Ë' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0xf7, /* 11110111 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 204 0xcc 'Ì' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x37, /* 00110111 */ + 0x30, /* 00110000 */ + 0x37, /* 00110111 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 205 0xcd 'Í' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 206 0xce 'Î' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0xf7, /* 11110111 */ + 0x00, /* 00000000 */ + 0xf7, /* 11110111 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 207 0xcf 'Ï' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 208 0xd0 'Ð' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 209 0xd1 'Ñ' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 210 0xd2 'Ò' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 211 0xd3 'Ó' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x3f, /* 00111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 212 0xd4 'Ô' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x1f, /* 00011111 */ + 0x18, /* 00011000 */ + 0x1f, /* 00011111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 213 0xd5 'Õ' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x1f, /* 00011111 */ + 0x18, /* 00011000 */ + 0x1f, /* 00011111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 214 0xd6 'Ö' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x3f, /* 00111111 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 215 0xd7 '×' */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0xff, /* 11111111 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + + /* 216 0xd8 'Ø' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xff, /* 11111111 */ + 0x18, /* 00011000 */ + 0xff, /* 11111111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 217 0xd9 'Ù' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xf8, /* 11111000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 218 0xda 'Ú' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x1f, /* 00011111 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 219 0xdb 'Û' */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + + /* 220 0xdc 'Ü' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + + /* 221 0xdd 'Ý' */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + 0xf0, /* 11110000 */ + + /* 222 0xde 'Þ' */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + 0x0f, /* 00001111 */ + + /* 223 0xdf 'ß' */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0xff, /* 11111111 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 224 0xe0 'à' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x76, /* 01110110 */ + 0xdc, /* 11011100 */ + 0xd8, /* 11011000 */ + 0xd8, /* 11011000 */ + 0xd8, /* 11011000 */ + 0xdc, /* 11011100 */ + 0x76, /* 01110110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 225 0xe1 'á' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x78, /* 01111000 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xcc, /* 11001100 */ + 0xd8, /* 11011000 */ + 0xcc, /* 11001100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xcc, /* 11001100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 226 0xe2 'â' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0xc0, /* 11000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 227 0xe3 'ã' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 228 0xe4 'ä' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0x60, /* 01100000 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 229 0xe5 'å' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0xd8, /* 11011000 */ + 0xd8, /* 11011000 */ + 0xd8, /* 11011000 */ + 0xd8, /* 11011000 */ + 0xd8, /* 11011000 */ + 0x70, /* 01110000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 230 0xe6 'æ' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x7c, /* 01111100 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0xc0, /* 11000000 */ + 0x00, /* 00000000 */ + + /* 231 0xe7 'ç' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x76, /* 01110110 */ + 0xdc, /* 11011100 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 232 0xe8 'è' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 233 0xe9 'é' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xfe, /* 11111110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 234 0xea 'ê' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0xee, /* 11101110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 235 0xeb 'ë' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x1e, /* 00011110 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x3e, /* 00111110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 236 0xec 'ì' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0xdb, /* 11011011 */ + 0xdb, /* 11011011 */ + 0xdb, /* 11011011 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 237 0xed 'í' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x03, /* 00000011 */ + 0x06, /* 00000110 */ + 0x7e, /* 01111110 */ + 0xdb, /* 11011011 */ + 0xdb, /* 11011011 */ + 0xf3, /* 11110011 */ + 0x7e, /* 01111110 */ + 0x60, /* 01100000 */ + 0xc0, /* 11000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 238 0xee 'î' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x1c, /* 00011100 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x7c, /* 01111100 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x60, /* 01100000 */ + 0x30, /* 00110000 */ + 0x1c, /* 00011100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 239 0xef 'ï' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 01111100 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0xc6, /* 11000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 240 0xf0 'ð' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 11111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 241 0xf1 'ñ' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 242 0xf2 'ò' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x06, /* 00000110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 243 0xf3 'ó' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00110000 */ + 0x60, /* 01100000 */ + 0x30, /* 00110000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00001100 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 244 0xf4 'ô' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x0e, /* 00001110 */ + 0x1b, /* 00011011 */ + 0x1b, /* 00011011 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* 245 0xf5 'õ' */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0xd8, /* 11011000 */ + 0xd8, /* 11011000 */ + 0xd8, /* 11011000 */ + 0x70, /* 01110000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 246 0xf6 'ö' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 247 0xf7 '÷' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x76, /* 01110110 */ + 0xdc, /* 11011100 */ + 0x00, /* 00000000 */ + 0x76, /* 01110110 */ + 0xdc, /* 11011100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 248 0xf8 'ø' */ + 0x00, /* 00000000 */ + 0x38, /* 00111000 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x38, /* 00111000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 249 0xf9 'ù' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 250 0xfa 'ú' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 251 0xfb 'û' */ + 0x00, /* 00000000 */ + 0x0f, /* 00001111 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0x0c, /* 00001100 */ + 0xec, /* 11101100 */ + 0x6c, /* 01101100 */ + 0x6c, /* 01101100 */ + 0x3c, /* 00111100 */ + 0x1c, /* 00011100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 252 0xfc 'ü' */ + 0x00, /* 00000000 */ + 0x6c, /* 01101100 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x36, /* 00110110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 253 0xfd 'ý' */ + 0x00, /* 00000000 */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0x0c, /* 00001100 */ + 0x18, /* 00011000 */ + 0x32, /* 00110010 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 254 0xfe 'þ' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x7e, /* 01111110 */ + 0x7e, /* 01111110 */ + 0x7e, /* 01111110 */ + 0x7e, /* 01111110 */ + 0x7e, /* 01111110 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 255 0xff 'ÿ' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + +}; + +#endif /* #ifndef _VGA_TABLE_H */ diff --git a/board/pip405/video.c b/board/pip405/video.c new file mode 100644 index 0000000..199e235 --- /dev/null +++ b/board/pip405/video.c @@ -0,0 +1,741 @@ +/* + * (C) Copyright 2001 + * Denis Peter, MPL AG Switzerland + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * Note: Parts of these software are imported from + * - UBL, The Universal Talkware Boot Loader + * Copyright (C) 2000 Universal Talkware Inc. + * - Linux + * + * + */ + +#include +#include +#include +#include +#include "video.h" +#ifdef CONFIG_PPC405 +#include <405gp_pci.h> +#endif +#include "vga_table.h" + + +#ifdef CONFIG_VIDEO_CT69000 +#define VIDEO_VEND_ID 0x102C +#define VIDEO_DEV_ID 0x00C0 +#else +#error CONFIG_VIDEO_CT69000 must be defined +#endif + +/* + * Routine for resent board info to video + * resides in pip405.c + */ +extern void video_write_board_info(void); + +#undef VGA_DEBUG + +#ifdef VGA_DEBUG +#define PRINTF(fmt,args...) printf (fmt ,##args) +#else +#define PRINTF(fmt,args...) +#endif + +#define VGA_MAXROWS 25 +#define VGA_MAXCOLS 80 + +#define CRTC_CURSH 14 /* cursor high pos */ +#define CRTC_CURSL 15 /* cursor low pos */ + +/* description of the hardware layout */ + +#define ATTRI_INDEX CFG_ISA_IO_BASE_ADDRESS | 0x3c0 /* Index and Data write port of the attribute Registers */ +#define ATTRI_DATA CFG_ISA_IO_BASE_ADDRESS | 0x3c1 /* Data port of the attribute Registers */ +#define STATUS_REG0 CFG_ISA_IO_BASE_ADDRESS | 0x3c2 /* Status Register 0 (read only) */ +#define MSR_REG_W CFG_ISA_IO_BASE_ADDRESS | 0x3c2 /* Misc. Output Register (write only) */ +#define SEQ_INDEX CFG_ISA_IO_BASE_ADDRESS | 0x3c4 /* Index port of the Sequencer Controller */ +#define SEQ_DATA CFG_ISA_IO_BASE_ADDRESS | 0x3c5 /* Data port of the Sequencer Controller */ +#define COL_PAL_MASK CFG_ISA_IO_BASE_ADDRESS | 0x3c6 /* Color Palette Mask */ +#define COL_PAL_STAT CFG_ISA_IO_BASE_ADDRESS | 0x3c7 /* Color Palette Status (read only) */ +#define COL_PAL_IND_R CFG_ISA_IO_BASE_ADDRESS | 0x3c7 /* Color Palette Read Mode Index (write only) */ +#define COL_PAL_IND_W CFG_ISA_IO_BASE_ADDRESS | 0x3c8 /* Color Palette Write Mode Index */ +#define COL_PAL_DATA CFG_ISA_IO_BASE_ADDRESS | 0x3c9 /* Color Palette Data Port */ +#define FCR_REG_R CFG_ISA_IO_BASE_ADDRESS | 0x3ca /* Feature Control Register (read only) */ +#define MSR_REG_R CFG_ISA_IO_BASE_ADDRESS | 0x3cc /* Misc. Output Register (read only) */ +#define GR_INDEX CFG_ISA_IO_BASE_ADDRESS | 0x3ce /* Index port of the Graphic Controller Registers */ +#define GR_DATA CFG_ISA_IO_BASE_ADDRESS | 0x3cf /* Data port of the Graphic Controller Registers */ +#define FP_INDEX CFG_ISA_IO_BASE_ADDRESS | 0x3d0 /* Index port of the Flat panel Registers */ +#define FP_DATA CFG_ISA_IO_BASE_ADDRESS | 0x3d1 /* Data port of the Flat panel Registers */ +#define MR_INDEX CFG_ISA_IO_BASE_ADDRESS | 0x3d2 /* Index Port of the Multimedia Extension */ +#define MR_DATA CFG_ISA_IO_BASE_ADDRESS | 0x3d3 /* Data Port of the Multimedia Extension */ +#define CRT_INDEX CFG_ISA_IO_BASE_ADDRESS | 0x3d4 /* Index port of the CRT Controller */ +#define CRT_DATA CFG_ISA_IO_BASE_ADDRESS | 0x3d5 /* Data port of the CRT Controller */ +#define XREG_INDEX CFG_ISA_IO_BASE_ADDRESS | 0x3d6 /* Extended Register index */ +#define XREG_DATA CFG_ISA_IO_BASE_ADDRESS | 0x3d7 /* Extended Register data */ +#define STATUS_REG1 CFG_ISA_IO_BASE_ADDRESS | 0x3da /* Input Status Register 1 (read only) */ +#define FCR_REG_W CFG_ISA_IO_BASE_ADDRESS | 0x3da /* Feature Control Register (write only) */ + + +static unsigned char * video_fb; /* Frame buffer */ + +/* current hardware state */ + +static int video_row; +static int video_col; +static unsigned char video_attr; + +static unsigned long font_base_addr; +/********************************************************************** + * some forward declerations... + */ +int video_init(int busdevfunc); +void vga_set_attrib(void); +void vga_set_crt(void); +void vga_set_dac(void); +void vga_set_gr(void); +void vga_set_seq(void); +void vga_set_xreg(void); +void vga_write_sr(unsigned char reg,unsigned char val); +void vga_write_gr(unsigned char reg,unsigned char val); +void vga_write_cr(unsigned char reg,unsigned char val); +void vga_set_font(void); + +/*************************************************************************** + * Init VGA Device + */ + +int drv_video_init(void) +{ + int error, devices = 1 ; + device_t vgadev ; + int busdevfunc; + + busdevfunc=PCI_Find_Device(VIDEO_VEND_ID,VIDEO_DEV_ID); /* get PCI Device ID */ + if(busdevfunc==-1) { + printf("Error VGA Controller (%04X,%04X) not found\n",VIDEO_VEND_ID,VIDEO_DEV_ID); + return -1; + } + video_init(busdevfunc); + video_write_board_info(); + memset (&vgadev, 0, sizeof(vgadev)); + + strcpy(vgadev.name, "vga"); + vgadev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_SYSTEM; + vgadev.putc = video_putc; + vgadev.puts = video_puts; + vgadev.getc = NULL; + vgadev.tstc = NULL; + + error = device_register (&vgadev); + + return (error == 0) ? devices : error ; +} + + +/*********************************************************** + * VGA Initializing + */ + +int video_init(int busdevfunc) +{ + font_base_addr = PCI_Read_CFG_Reg(busdevfunc, PCI_CFG_BASE_ADDRESS_0, 4); + + video_fb = (char*)font_base_addr; /* we look into the big linaer memory area */ + + /* set the extended Registers */ + vga_set_xreg(); + + /* set IO Addresses to 0x3Dx (color mode ) */ + out8(MSR_REG_W,0x01); + + /* Feature Control Register: + Bits 7-4 Reserved = 0 + Bit 3 Vertical Sync select = 1 = Enabled + Bits 2-0 Reserved = 010 = as read from memory. + */ + out8(FCR_REG_W,0x02); + + + /* Miscelaneous output Register: + Bits 7-6 (num lines) = 01 = VGA 400 lines, + Bit 5 (Odd/Even Page) = 1 = Sleect high page of memory, + Bit 4 reserved = 0, + Bits 3-2 (Clocl Select) = 01 = 28.322Mhz + Bit 1 = Display Ram Enable = 1 = Enable processor access. + Bit 0 = Io Address Select = 1 = Color Graphics Enulation. + */ + out8(MSR_REG_W,0x67); + /* set the palette */ + vga_set_dac(); + /* set the attributes (before we bring up the engine + then we dont have to wait for refresh). + */ + vga_set_attrib(); + + /* set the crontroller register. */ + vga_set_crt(); + + vga_write_sr(0x00,0x01); /* synchronous reset */ + vga_write_sr(0x01,0x00); /* clocking mode */ + vga_write_sr(0x02,0x03); /* write to map 0, 1 */ + vga_write_sr(0x03,0x00); /* select character map 0 */ + vga_write_sr(0x04,0x03); /* even-odd addressing */ + vga_write_sr(0x00,0x03); /* clear synchronous reset */ + + vga_set_seq(); /* Set the extended sr's. */ + + vga_set_gr(); /* Set the graphic registers. */ + + /* load the font */ + vga_set_font(); + + /* initialize the rol/col counts and the text attribute. */ + video_row=0; + video_col=0; + video_attr = VGA_ATTR_CLR_WHT; + + /* Clear the video ram */ + video_clear(); + + return 1; +} + +void vga_set_font(void) +{ + int i,j; + char *fontmap; + fontmap = (char *)font_base_addr; + + vga_write_sr(0x00,0x01); /* synchronous reset */ + vga_write_sr(0x04,0x06); /* sequential addressing */ + vga_write_sr(0x02,0x04); /* write to map 2 */ + vga_write_sr(0x00,0x03); /* clear synchronous reset */ + + vga_write_gr(0x04,0x02); /* select map 2 */ + vga_write_gr(0x05,0x00); /* disable odd-even addressing */ + vga_write_gr(0x06,0x00); /* map start at 0xa0000 */ + + for(i=0;i<0x100;i++) { + for(j=0;j<0x10;j++) { + *((char *)fontmap+i*32+j)=(char)fontdata_8x16[i*16+j]; + } + } + vga_write_sr(0x00,0x01); /* synchronous reset */ + vga_write_sr(0x02,0x03); /* write to map 0 and 1 */ + vga_write_sr(0x04,0x03); /* odd-even addressing */ + vga_write_sr(0x03,0x00); /* Character map 0 & 1 */ + vga_write_sr(0x00,0x03); /* clear synchronous reset */ + + vga_write_gr(0x04,0x00); /* select map 0 for CPU */ + vga_write_gr(0x05,0x10); /* enable odd-even addressing */ + vga_write_gr(0x06,0x0E); /* map start at 0xb8000 */ +} + + +/* since we are BIG endian, swap attributes and char */ +unsigned short vga_swap_short(unsigned short val) +{ + unsigned short swapped; + swapped = ((val & 0xff)<<8) | ((val & 0xff00)>>8); + return swapped; +} + +/**************************************************** + * Routines usable Outside world + */ + +/* scolls the text up row rows */ +void video_scroll(int row) +{ + unsigned short clear = ((unsigned short)video_attr << 8) | (' '); + unsigned short* addr16 = &((unsigned short *)video_fb)[(VGA_MAXROWS-row)*VGA_MAXCOLS]; + int i; + + clear=vga_swap_short(clear); + memcpy(video_fb, video_fb+row*(VGA_MAXCOLS*2), (VGA_MAXROWS-row)*(VGA_MAXCOLS*2)); + for (i = 0 ; i < row * VGA_MAXCOLS ; i++) + addr16[i] = clear; + video_row-=row; + video_col=0; +} + + +unsigned long video_cursor(int col, int row) +{ + unsigned short off = row * VGA_MAXCOLS + col ; + unsigned long saved = (video_col << 16) | (video_row & 0xFFFF); + video_col = col; + video_row = row; + + vga_write_cr(CRTC_CURSH,(unsigned char)((off & 0xff00)>>8)); /* Cursor pos. high */ + vga_write_cr(CRTC_CURSL,(unsigned char)(off & 0xff)); /* Cursor pos. low */ + return saved; +} + +void video_set_lxy(unsigned long lxy) +{ + int col = (lxy >> 16) & 0xFFFF; + int row = lxy & 0xFFFF; + video_cursor(col,row); +} + +unsigned long video_get_lxy(void) +{ + return (video_col << 16) | (video_row & 0xFFFF); +} + +void video_clear(void) +{ + int i; + unsigned short clear = ((unsigned short)video_attr << 8) | (' '); + unsigned short * addr16 = (unsigned short * )video_fb; + clear=vga_swap_short(clear); + video_row = video_col = 0; + for (i = 0 ; i < 2000 ; i++) { + addr16[i] = clear; + } +} + +void video_copy(unsigned short *buffer) +{ + int i; + unsigned short * addr16 = (unsigned short * )video_fb; + for (i = 0 ; i < 2000 ; i++) { + buffer[i] = addr16[i]; + } +} + +void video_write(unsigned short *buffer) +{ + int i; + unsigned short * addr16 = (unsigned short *)video_fb; + for (i = 0 ; i < 2000 ; i++) { + addr16[i] = buffer[i]; + } +} + +void video_putc(char ch) +{ + char* addr; + + switch (ch) { + case '\n': + video_col=0; + video_row++; + break; + case '\r': + video_col=0; + break; + case '\t': + video_col += 8 - video_col % 8; + break; + case '\a': +/* beep(); */ + break; + case '\b': + if(video_col) + video_col--; + else + return; + break; + default: + addr = video_fb + 2 * video_row * 80 + 2 * video_col; + + *((char *)addr+1) = (char) video_attr; + *((char *)addr) = (char) ch; + video_col++; + if (video_col > (VGA_MAXCOLS-1)) { + video_row++; + video_col=0; + } + } + + /* If we're on the bottom of the secreen, wrap one row */ + if (video_row > (VGA_MAXROWS-1)) + video_scroll(1); + video_cursor(video_col, video_row); +} + + +unsigned char video_set_attr(unsigned char attr) +{ + unsigned char saved_attr = video_attr; + video_attr = attr; + return saved_attr; +} + +unsigned char video_set_attr_xy(unsigned char attr, int x, int y) +{ + unsigned char *addr = video_fb + (x * 80 + y) * 2 + 1; + unsigned char saved_attr = *addr; + *addr = attr; + return saved_attr; +} + +/* put char at xy */ +void video_putc_xy(char ch, int x, int y) +{ + video_col = x; + video_row = y; + video_putc(ch); +} + +/* put char at xy relative to the position */ +void video_putc_rxy(char ch, int x, int y) +{ + video_col += x; + video_row += y; + video_putc(ch); +} + +/* put char with attribute at xy */ +void video_putc_axy(char ch, char attr, int x, int y) +{ + unsigned char saved_attr = video_set_attr(attr); + video_col = x; + video_row = y; + video_putc(ch); + video_set_attr(saved_attr); +} + +void video_puts(const char *s) +{ + while(*s) { + video_putc(*s); + s++; + } +} + +void video_puts_a(const char *s, char attr) +{ + unsigned char saved_attr = video_set_attr(attr); + video_puts(s); + video_set_attr(saved_attr); +} + +void video_puts_xy(const char *s, int x, int y) +{ + video_cursor(x,y); + video_puts(s); +} + +void video_puts_axy(const char *s, char attr, int x, int y) +{ + unsigned char saved_attr = video_set_attr(attr); + video_puts_xy(s, x, y); + video_set_attr(saved_attr); +} + +void video_wipe_ca_area(unsigned char ch, char attr, int x, int y, int w, int h) +{ + int r, c; + /* better to do this as word writes */ + unsigned short * addr16 = (unsigned short *)video_fb + (y * 80 + x); + unsigned short charattr = (unsigned short)ch << 8 | attr; + charattr=vga_swap_short(charattr); + for (r = 0 ; r < h ; r++, addr16 += 80) { + for (c = 0 ; c < w ; c++) { + addr16[c] = charattr; + } + } +} + +void video_wipe_a_area(unsigned char attr, int x, int y, int w, int h) +{ + int r, c; + /* better to do this as word writes */ + unsigned short * addr16 = (unsigned short *)video_fb + (y * 80 + x); + for (r = 0 ; r < h ; r++, addr16 += 80) { + for (c = 0 ; c < w ; c++) { + ((char*)addr16)[c*2+1] = attr; + } + } +} + +void video_wipe_c_area(unsigned char ch, int x, int y, int w, int h) +{ + int r, c; + /* better to do this as word writes */ + unsigned short * addr16 = (unsigned short *)video_fb + (y * 80 + x); + for (r = 0 ; r < h ; r++, addr16 += 80) { + for (c = 0 ; c < w ; c++) { + ((char*)addr16)[c*2] = ch; + } + } +} + + +/* +tl t tr +l l +bl b br +*/ +typedef struct { + unsigned char tl; /* top left corner */ + unsigned char t; /* top edge */ + unsigned char tr; /* top right corner */ + unsigned char l; /* left edge */ + unsigned char r; /* right edge */ + unsigned char bl; /* bottom left corner */ + unsigned char b; /* bottom edge */ + unsigned char br; /* bottom right corner */ +} box_chars_t; + +box_chars_t sbox_chars = { + 0xDA, 0xC4, 0xBF, + 0xB3, 0xB3, + 0xC0, 0xC4, 0xD9 +}; + +box_chars_t dbox_chars = { + 0xC9, 0xCD, 0xBB, + 0xBA, 0xBA, + 0xC8, 0xCD, 0xBC +}; + +static char cmap[] = "0123456789ABCDEF"; +void video_putchex(char c) +{ + video_putc(cmap[(c >> 4 ) & 0xF]); + video_putc(cmap[c & 0xF]); +} + +void video_putchexl(char c) +{ + video_putc(cmap[c & 0xF]); +} + +void video_putchexh(char c) +{ + video_putc(cmap[(c >> 4) & 0xF]); +} + +#define VGA_CELL_CA(a,c) (((unsigned short)c<<8)|a) /* for BIG endians */ + +void video_gbox_area(box_chars_t *box_chars_p, int x, int y, int w, int h) +{ + int r, c; + /* better to do this as word writes */ + unsigned short* addr16 = (unsigned short *)video_fb + (y * VGA_MAXCOLS + x); + for (r = 0 ; r < h ; r++, addr16 += VGA_MAXCOLS) { + if (r == 0) { + addr16[0] = VGA_CELL_CA(video_attr, box_chars_p->tl); + addr16[w-1] = VGA_CELL_CA(video_attr, box_chars_p->tr); + for (c = 1 ; c < w - 1 ; c++) + addr16[c] = VGA_CELL_CA(video_attr, box_chars_p->t); + } else if (r == h - 1) { + addr16[0] = VGA_CELL_CA(video_attr, box_chars_p->bl); + addr16[w-1] = VGA_CELL_CA(video_attr, box_chars_p->br); + for (c = 1 ; c < w - 1 ; c++) + addr16[c] = VGA_CELL_CA(video_attr, box_chars_p->b); + } else { + addr16[0] = VGA_CELL_CA(video_attr, box_chars_p->l); + addr16[w-1] = VGA_CELL_CA(video_attr, box_chars_p->r); + } + } +} + +/* Writes a box on the screen */ +void video_box_area(int x, int y, int w, int h) { + video_gbox_area(&sbox_chars, x, y, w, h); +} +/*writes a box with double lines on the screen */ +void video_dbox_area(int x, int y, int w, int h) { + video_gbox_area(&dbox_chars, x, y, w, h); +} + +/* routines to set the VGA registers */ + +/* set attributes */ +void vga_set_attrib(void) +{ + int i; + unsigned char status; + + status=in8(STATUS_REG1); + i=0; + + while(attr[i].reg!=0xFF) { + out8(ATTRI_INDEX,attr[i].reg); + out8(ATTRI_INDEX,attr[i].val); /* Attribute uses index for index and data */ + i++; + } + out8(ATTRI_INDEX,0x20); /* unblank the screen */ +} + +/* set CRT Controller Registers */ +void vga_set_crt(void) +{ + int i; + i=0; + while(crtc[i].reg!=0xFF) { + out8(CRT_INDEX,crtc[i].reg); + out8(CRT_DATA,crtc[i].val); + i++; + } +} +/* Set Palette Registers (DAC) */ +void vga_set_dac(void) +{ + int i; + for(i=0;i<256;i++) { + out8(COL_PAL_IND_W,(unsigned char)i); + out8(COL_PAL_DATA,dac[i][0]); /* red */ + out8(COL_PAL_DATA,dac[i][1]); /* green */ + out8(COL_PAL_DATA,dac[i][2]); /* blue */ + } + out8(COL_PAL_MASK,0xff); /* set mask */ +} +/* set Graphic Controller Register */ +void vga_set_gr(void) +{ + int i; + i=0; + while(grmr[i].reg!=0xFF) { + out8(GR_INDEX,grmr[i].reg); + out8(GR_DATA,grmr[i].val); + i++; + } +} + +/* Set Sequencer Registers */ +void vga_set_seq(void) +{ + int i; + i=0; + while(seq[i].reg!=0xFF) { + out8(SEQ_INDEX,seq[i].reg); + out8(SEQ_DATA,seq[i].val); + i++; + } +} + + +/* Set Extension Registers */ +void vga_set_xreg(void) +{ + int i; + i=0; + while(xreg[i].reg!=0xFF) { + out8(XREG_INDEX,xreg[i].reg); + out8(XREG_DATA,xreg[i].val); + i++; + } +} + +/************************************************************ + * some helping routines + */ + +void vga_write_sr(unsigned char reg,unsigned char val) +{ + out8(SEQ_INDEX,reg); + out8(SEQ_DATA,val); +} + + +void vga_write_gr(unsigned char reg,unsigned char val) +{ + out8(GR_INDEX,reg); + out8(GR_DATA,val); +} + +void vga_write_cr(unsigned char reg,unsigned char val) +{ + out8(CRT_INDEX,reg); + out8(CRT_DATA,val); +} + + +#if 0 +void video_dump_reg(void) +{ + /* first dump attributes */ + int i; + unsigned char status; + + + printf("Extended Regs:\n"); + i=0; + while(xreg[i].reg!=0xFF) { + out8(XREG_INDEX,xreg[i].reg); + status=in8(XREG_DATA); + printf("XR%02X is %02X, should be %02X\n",xreg[i].reg,status,xreg[i].val); + i++; + } + printf("Sequencer Regs:\n"); + i=0; + while(seq[i].reg!=0xFF) { + out8(SEQ_INDEX,seq[i].reg); + status=in8(SEQ_DATA); + printf("SR%02X is %02X, should be %02X\n",seq[i].reg,status,seq[i].val); + i++; + } + printf("Graphic Regs:\n"); + i=0; + while(grmr[i].reg!=0xFF) { + out8(GR_INDEX,grmr[i].reg); + status=in8(GR_DATA); + printf("GR%02X is %02X, should be %02X\n",grmr[i].reg,status,grmr[i].val); + i++; + } + printf("CRT Regs:\n"); + i=0; + while(crtc[i].reg!=0xFF) { + out8(CRT_INDEX,crtc[i].reg); + status=in8(CRT_DATA); + printf("CR%02X is %02X, should be %02X\n",crtc[i].reg,status,crtc[i].val); + i++; + } + printf("Attributes:\n"); + status=in8(STATUS_REG1); + i=0; + while(attr[i].reg!=0xFF) { + out8(ATTRI_INDEX,attr[i].reg); + status=in8(ATTRI_DATA); + out8(ATTRI_INDEX,attr[i].val); /* Attribute uses index for index and data */ + printf("AR%02X is %02X, should be %02X\n",attr[i].reg,status,attr[i].val); + i++; + } +} +#endif + + + + + + + + + + + + + + + + + + + + + diff --git a/board/pip405/video.h b/board/pip405/video.h new file mode 100644 index 0000000..3c6f513 --- /dev/null +++ b/board/pip405/video.h @@ -0,0 +1,73 @@ +/* + * (C) Copyright 2001 + * Denis Peter, MPL AG Switzerland + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +#ifndef _VIDEO_H +#define _VIDEO_H + +int video_init(int busdevfunc); +void video_clear(void); +void video_putc(char ch); +void video_puts(const char *s); +void video_puts_a(const char *s, char attr); +unsigned char video_set_attr(unsigned char attr); + +void video_box_area(int x, int y, int w, int h); +void video_dbox_area(int x, int y, int w, int h); +void video_wipe_c_area(unsigned char ch, int x, int y, int w, int h); + +void video_wipe_a_area(unsigned char attr, int x, int y, int w, int h); +void video_wipe_ca_area(unsigned char ch, char attr, int x, int y, int w, int h); +void video_puts_axy(const char *s, char attr, int x, int y); +void video_putc_rxy(char ch, int x, int y); +void video_putc_xy(char ch, int x, int y); +unsigned char video_set_attr_xy(unsigned char attr, int x, int y); +void video_copy(unsigned short *buffer); +void video_write(unsigned short *buffer); + +#define VGA_ATTR_CLR_RED 0x4 +#define VGA_ATTR_CLR_GRN 0x2 +#define VGA_ATTR_CLR_BLU 0x1 +#define VGA_ATTR_CLR_YEL (VGA_ATTR_CLR_RED | VGA_ATTR_CLR_GRN) +#define VGA_ATTR_CLR_CYN (VGA_ATTR_CLR_GRN | VGA_ATTR_CLR_BLU) +#define VGA_ATTR_CLR_MAG (VGA_ATTR_CLR_BLU | VGA_ATTR_CLR_RED) +#define VGA_ATTR_CLR_BLK 0 +#define VGA_ATTR_CLR_WHT (VGA_ATTR_CLR_RED | VGA_ATTR_CLR_GRN | VGA_ATTR_CLR_BLU) + +#define VGA_ATTR_BNK 0x80 +#define VGA_ATTR_ITN 0x08 + +#define VGA_ATTR_BG_MSK 0x70 +#define VGA_ATTR_FG_MSK 0x07 + +#define VGA_ATTR_BG_GET(v) (((v) & VGA_ATTR_BG_MSK)>>4) +#define VGA_ATTR_BG_SET(v, c) (((c) & VGA_ATTR_FG_MSK)<<4) | (v & ~VGA_ATTR_BG_MSK)) + +#define VGA_ATTR_FG_GET(v) ((v) & VGA_ATTR_FG_MSK) +#define VGA_ATTR_FG_SET(v, c) ((c) & VGA_ATTR_FG_MSK) | (v & ~VGA_ATTR_FG_MSK)) + +#define VGA_ATTR_FG_BG_SET(v, b, f) (VGA_ATTR_BG_SET(v, b) | VGA_ATTR_FG_SET(v, cf)) + +#define VGA_ATTR_INVERT(A) ((((A)&0x7)<<4)|(((A)&0x70)>>4) |((A)&0x88)) + +#endif diff --git a/common/Makefile b/common/Makefile index e8f8015..814fa24 100644 --- a/common/Makefile +++ b/common/Makefile @@ -33,6 +33,7 @@ COBJS = board.o main.o command.o \ cmd_console.o cmd_date.o cmd_eeprom.o \ cmd_flash.o cmd_ide.o cmd_mem.o cmd_net.o \ cmd_nvedit.o cmd_pcmcia.o cmd_reginfo.o \ + cmd_fdc.o cmd_scsi.o \ cmd_bedbug.o bedbug.o s_record.o dlmalloc.o \ kgdb.o console.o lists.o devices.o flash.o cmd_i2c.o cmd_immap.o diff --git a/common/board.c b/common/board.c index 25b44c0..c47ae26 100644 --- a/common/board.c +++ b/common/board.c @@ -31,6 +31,9 @@ #if (CONFIG_COMMANDS & CFG_CMD_IDE) #include #endif +#if (CONFIG_COMMANDS & CFG_CMD_SCSI) +#include +#endif #if (CONFIG_COMMANDS & CFG_CMD_KGDB) #include #endif @@ -156,6 +159,7 @@ board_init_f (ulong bootflag) defined(CONFIG_AR405) || \ defined(CONFIG_CANBT) || \ defined(CONFIG_WALNUT405) || \ + defined(CONFIG_PIP405) || \ defined(CONFIG_CPCIISER4) || \ defined(CONFIG_ADCIOP) || \ defined(CONFIG_LWMON) || \ @@ -259,6 +263,7 @@ board_init_f (ulong bootflag) * First reserve memory for monitor code at end of DRAM. */ len = get_endaddr() - CFG_MONITOR_BASE; + if (len > CFG_MONITOR_LEN) { printf ("*** PPCBoot size %ld > reserved memory (%d)\n", len, CFG_MONITOR_LEN); @@ -400,7 +405,11 @@ board_init_f (ulong bootflag) bd->bi_procfreq = idata->cpu_clk; /* Processor Speed, In Hz */ bd->bi_plb_busfreq = bd->bi_busfreq; +#ifdef CONFIG_PPC405 + bd->bi_pci_busfreq = get_PCI_freq(); +#else bd->bi_pci_busfreq = bd->bi_busfreq; +#endif #endif /* Function pointers must be added after code relocation */ @@ -545,11 +554,12 @@ void board_init_r (bd_t *bd, ulong dest_addr) /* relocate environment function pointers etc. */ env_relocate (reloc_off); -#if defined(CONFIG_COGENT) || \ - defined(CONFIG_HYMOD) || \ - defined(CONFIG_CPCI405) || \ - defined(CONFIG_PCU_E) || \ - defined(CONFIG_EVB64260) +#if defined(CONFIG_COGENT) || \ + defined(CONFIG_CPCI405) || \ + defined(CONFIG_EVB64260) || \ + defined(CONFIG_HYMOD) || \ + defined(CONFIG_LWMON) || \ + defined(CONFIG_PCU_E) /* miscellaneous platform dependent initialisations */ misc_init_r(bd); #endif @@ -565,8 +575,8 @@ void board_init_r (bd_t *bd, ulong dest_addr) defined(CONFIG_IVML24) || \ defined(CONFIG_IP860) || \ defined(CONFIG_LWMON) || \ - defined(CONFIG_RPXSUPER) || \ - defined(CONFIG_PCU_E) ) + defined(CONFIG_PCU_E) || \ + defined(CONFIG_RPXSUPER) ) # ifdef DEBUG puts (" Reset Ethernet PHY\n"); # endif @@ -631,6 +641,10 @@ void board_init_r (bd_t *bd, ulong dest_addr) ide_init(bd); #endif /* CFG_CMD_IDE */ +#if (CONFIG_COMMANDS & CFG_CMD_SCSI) + scsi_init(); +#endif + #if (CONFIG_COMMANDS & CFG_CMD_BEDBUG) bedbug_init(); #endif diff --git a/common/cmd_boot.c b/common/cmd_boot.c index e7ae548..6f70f1e 100644 --- a/common/cmd_boot.c +++ b/common/cmd_boot.c @@ -59,6 +59,11 @@ void do_bdinfo (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) print_num ("immr_base", bd->bi_immr_base ); #endif print_num ("bootflags", bd->bi_bootflags ); +#if defined(CONFIG_PPC405) + print_str ("procfreq", strmhz(buf, bd->bi_procfreq)); + print_str ("plb_busfreq", strmhz(buf, bd->bi_plb_busfreq)); + print_str ("pci_busfreq", strmhz(buf, bd->bi_pci_busfreq)); +#else #if defined(CFG_CLKS_IN_HZ) print_str ("intfreq", strmhz(buf, bd->bi_intfreq)); print_str ("busfreq", strmhz(buf, bd->bi_busfreq)); @@ -66,6 +71,7 @@ void do_bdinfo (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) print_str ("intfreq", strmhz(buf, bd->bi_intfreq*1000000L)); print_str ("busfreq", strmhz(buf, bd->bi_busfreq*1000000L)); #endif /* CFG_CLKS_IN_HZ */ +#endif /* CONFIG_PPC405) */ printf (" ethaddr ="); for (i=0; i<6; ++i) { printf ("%c%02X", i ? ':' : ' ', bd->bi_enetaddr[i]); diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index f38f6f5..51aa4c9 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -674,6 +674,7 @@ print_type (image_header_t *hdr) case IH_OS_INVALID: os = "Invalid OS"; break; case IH_OS_NETBSD: os = "NetBSD"; break; case IH_OS_LINUX: os = "Linux"; break; + case IH_OS_PPCBOOT: os = "PPCBoot"; break; default: os = "Unknown OS"; break; } @@ -699,6 +700,7 @@ print_type (image_header_t *hdr) case IH_TYPE_KERNEL: type = "Kernel Image"; break; case IH_TYPE_RAMDISK: type = "RAMDisk Image"; break; case IH_TYPE_MULTI: type = "Multi-File Image"; break; + case IH_TYPE_FIRMWARE: type = "Firmware"; break; default: type = "Unknown Image"; break; } diff --git a/common/cmd_date.c b/common/cmd_date.c index 6c4fe60..84ac1a2 100644 --- a/common/cmd_date.c +++ b/common/cmd_date.c @@ -65,6 +65,7 @@ void do_date (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) (tm.tm_wday<0 || tm.tm_wday>6) ? "unknown " : weekdays[tm.tm_wday], tm.tm_hour, tm.tm_min, tm.tm_sec); + return; default: printf ("Usage:\n%s\n", cmdtp->usage); diff --git a/common/cmd_fdc.c b/common/cmd_fdc.c new file mode 100644 index 0000000..e854885 --- /dev/null +++ b/common/cmd_fdc.c @@ -0,0 +1,731 @@ +/* + * (C) Copyright 2001 + * Denis Peter, MPL AG, d.peter@mpl.ch. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ +/* + * Floppy Disk support + */ + +#include +#include +#include +#include + + +#undef FDC_DEBUG + +#ifdef FDC_DEBUG +#define PRINTF(fmt,args...) printf (fmt ,##args) +#else +#define PRINTF(fmt,args...) +#endif + +#ifndef TRUE +#define TRUE 1 +#endif +#ifndef FALSE +#define FALSE 0 +#endif + + +#if (CONFIG_COMMANDS & CFG_CMD_DATE) +#include +#endif + +#if (CONFIG_COMMANDS & CFG_CMD_FDC) + + +typedef struct { + int flags; /* connected drives ect */ + unsigned long blnr; /* Logical block nr */ + uchar drive; /* drive no */ + uchar cmdlen; /* cmd length */ + uchar cmd[16]; /* cmd desc */ + uchar dma; /* if > 0 dma enabled */ + uchar result[11];/* status information */ + uchar resultlen; /* lenght of result */ +} FDC_COMMAND_STRUCT; +/* flags: only the lower 8bit used: + * bit 0 if set drive 0 is present + * bit 1 if set drive 1 is present + * bit 2 if set drive 2 is present + * bit 3 if set drive 3 is present + * bit 4 if set disk in drive 0 is inserted + * bit 5 if set disk in drive 1 is inserted + * bit 6 if set disk in drive 2 is inserted + * bit 7 if set disk in drive 4 is inserted + */ + + +/* cmd indexes */ +#define COMMAND 0 +#define DRIVE 1 +#define CONFIG0 1 +#define SPEC_HUTSRT 1 +#define TRACK 2 +#define CONFIG1 2 +#define SPEC_HLT 2 +#define HEAD 3 +#define CONFIG2 3 +#define SECTOR 4 +#define SECTOR_SIZE 5 +#define LAST_TRACK 6 +#define GAP 7 +#define DTL 8 +/* result indexes */ +#define STATUS_0 0 +#define STATUS_PCN 1 +#define STATUS_1 1 +#define STATUS_2 2 +#define STATUS_TRACK 3 +#define STATUS_HEAD 4 +#define STATUS_SECT 5 +#define STATUS_SECT_SIZE 6 + + +/* Register addresses */ +#define FDC_BASE 0x3F0 +#define FDC_SRA FDC_BASE + 0 /* Status Register A */ +#define FDC_SRB FDC_BASE + 1 /* Status Register B */ +#define FDC_DOR FDC_BASE + 2 /* Digital Output Register */ +#define FDC_TDR FDC_BASE + 3 /* Tape Drive Register */ +#define FDC_DSR FDC_BASE + 4 /* Data rate Register */ +#define FDC_MSR FDC_BASE + 4 /* Main Status Register */ +#define FDC_FIFO FDC_BASE + 5 /* FIFO */ +#define FDC_DIR FDC_BASE + 6 /* Digital Input Register */ +#define FDC_CCR FDC_BASE + 7 /* Configuration Control */ +/* Commands */ +#define FDC_CMD_SENSE_INT 0x08 +#define FDC_CMD_CONFIGURE 0x13 +#define FDC_CMD_SPECIFY 0x03 +#define FDC_CMD_RECALIBRATE 0x07 +#define FDC_CMD_READ 0x06 +#define FDC_CMD_READ_TRACK 0x02 +#define FDC_CMD_READ_ID 0x0A +#define FDC_CMD_DUMP_REG 0x0E +#define FDC_CMD_SEEK 0x0F + +#define FDC_CMD_SENSE_INT_LEN 0x01 +#define FDC_CMD_CONFIGURE_LEN 0x04 +#define FDC_CMD_SPECIFY_LEN 0x03 +#define FDC_CMD_RECALIBRATE_LEN 0x02 +#define FDC_CMD_READ_LEN 0x09 +#define FDC_CMD_READ_TRACK_LEN 0x09 +#define FDC_CMD_READ_ID_LEN 0x02 +#define FDC_CMD_DUMP_REG_LEN 0x01 +#define FDC_CMD_SEEK_LEN 0x03 + +#define FDC_FIFO_THR 0x0C +#define FDC_FIFO_DIS 0x00 +#define FDC_IMPLIED_SEEK 0x01 +#define FDC_POLL_DIS 0x00 +#define FDC_PRE_TRK 0x00 +#define FDC_CONFIGURE FDC_FIFO_THR | (FDC_POLL_DIS<<4) | (FDC_FIFO_DIS<<5) | (FDC_IMPLIED_SEEK << 6) +#define FDC_MFM_MODE 0x01 /* MFM enable */ +#define FDC_SKIP_MODE 0x00 /* skip enable */ + +#define FDC_TIME_OUT 100000 /* time out */ +#define FDC_RW_RETRIES 3 /* read write retries */ +#define FDC_CAL_RETRIES 3 /* calibration and seek retries */ + + +/* Disk structure */ +typedef struct { + unsigned int size; /* nr of sectors total */ + unsigned int sect; /* sectors per track */ + unsigned int head; /* nr of heads */ + unsigned int track; /* nr of tracks */ + unsigned int stretch; /* !=0 means double track steps */ + unsigned char gap; /* gap1 size */ + unsigned char rate; /* data rate. |= 0x40 for perpendicular */ + unsigned char spec1; /* stepping rate, head unload time */ + unsigned char fmt_gap; /* gap2 size */ + unsigned char hlt; /* head load time */ + unsigned char sect_code; /* Sector Size code */ + const char * name; /* used only for predefined formats */ +} FD_GEO_STRUCT; + + +/* supported Floppy types (currently only one) */ +const static FD_GEO_STRUCT floppy_type[2] = { + { 2880,18,2,80,0,0x1B,0x00,0xCF,0x6C,16,2,"H1440" }, /* 7 1.44MB 3.5" */ + { 0, 0,0, 0,0,0x00,0x00,0x00,0x00, 0,0,NULL }, /* end of table */ +}; + +static FDC_COMMAND_STRUCT cmd; /* global command struct */ + +/* Supporting Functions */ +/* reads a Register of the FDC */ +unsigned char read_fdc_reg(unsigned int addr) +{ + volatile unsigned char *val = (volatile unsigned char *)(CFG_ISA_IO_BASE_ADDRESS | addr); + return val[0]; +} + +/* writes a Register of the FDC */ +void write_fdc_reg(unsigned int addr, unsigned char val) +{ + volatile unsigned char *tmp = (volatile unsigned char *)(CFG_ISA_IO_BASE_ADDRESS | addr); + tmp[0]=val; +} + +/* waits for an interrupt (polling) */ +int wait_for_fdc_int(void) +{ + unsigned long timeout; + timeout = FDC_TIME_OUT; + while((read_fdc_reg(FDC_SRA)&0x80)==0) { + timeout--; + udelay(10); + if(timeout==0) /* timeout occured */ + return FALSE; + } + return TRUE; +} + + +/* reads a byte from the FIFO of the FDC and checks direction and RQM bit + of the MSR. returns -1 if timeout, or byte if ok */ +int read_fdc_byte(void) +{ + unsigned long timeout; + timeout = FDC_TIME_OUT; + while((read_fdc_reg(FDC_MSR)&0xC0)!=0xC0) { + /* direction out and ready */ + udelay(10); + timeout--; + if(timeout==0) /* timeout occured */ + return -1; + } + return read_fdc_reg(FDC_FIFO); +} + +/* if the direction of the FIFO is wrong, this routine is used to + empty the FIFO. Should _not_ be used */ +int fdc_need_more_output(void) +{ + unsigned char c; + while((read_fdc_reg(FDC_MSR)&0xC0)==0xC0) { + c=(unsigned char)read_fdc_byte(); + printf("Error: more output: %x\n",c); + } + return TRUE; +} + + +/* writes a byte to the FIFO of the FDC and checks direction and RQM bit + of the MSR */ +int write_fdc_byte(unsigned char val) +{ + unsigned long timeout; + timeout = FDC_TIME_OUT; + while((read_fdc_reg(FDC_MSR)&0xC0)!=0x80) { + /* direction in and ready for byte */ + timeout--; + udelay(10); + fdc_need_more_output(); + if(timeout==0) /* timeout occured */ + return FALSE; + } + write_fdc_reg(FDC_FIFO,val); + return TRUE; +} + +/* sets up all FDC commands and issues it to the FDC. If + the command causes direct results (no Execution Phase) + the result is be read as well. */ + +int fdc_issue_cmd(FDC_COMMAND_STRUCT *pCMD,FD_GEO_STRUCT *pFG) +{ + int i; + unsigned long head,track,sect,timeout; + track = pCMD->blnr / (pFG->sect * pFG->head); /* track nr */ + sect = pCMD->blnr % (pFG->sect * pFG->head); /* remaining blocks */ + head = sect / pFG->sect; /* head nr */ + sect = sect % pFG->sect; /* remaining blocks */ + sect++; /* sectors are 1 based */ + PRINTF("Track %ld, Head %ld, Sector %ld, Drive %d (blnr %ld)\n",track,head,sect,pCMD->drive,pCMD->blnr); + if(head|=0) { /* max heads = 2 */ + pCMD->cmd[DRIVE]=pCMD->drive | 0x04; /* head 1 */ + pCMD->cmd[HEAD]=(unsigned char) head; /* head register */ + } + else { + pCMD->cmd[DRIVE]=pCMD->drive; /* head 0 */ + pCMD->cmd[HEAD]=(unsigned char) head; /* head register */ + } + pCMD->cmd[TRACK]=(unsigned char) track; /* track */ + switch (pCMD->cmd[COMMAND]) { + case FDC_CMD_READ: + pCMD->cmd[SECTOR]=(unsigned char) sect; /* sector */ + pCMD->cmd[SECTOR_SIZE]=pFG->sect_code; /* sector size code */ + pCMD->cmd[LAST_TRACK]=pFG->sect; /* End of track */ + pCMD->cmd[GAP]=pFG->gap; /* gap */ + pCMD->cmd[DTL]=0xFF; /* DTL */ + pCMD->cmdlen=FDC_CMD_READ_LEN; + pCMD->cmd[COMMAND]|=(FDC_MFM_MODE<<6); /* set MFM bit */ + pCMD->cmd[COMMAND]|=(FDC_SKIP_MODE<<5); /* set Skip bit */ + pCMD->resultlen=0; /* result only after execution */ + break; + case FDC_CMD_SEEK: + pCMD->cmdlen=FDC_CMD_SEEK_LEN; + pCMD->resultlen=0; /* no result */ + break; + case FDC_CMD_CONFIGURE: + pCMD->cmd[CONFIG0]=0; + pCMD->cmd[CONFIG1]=FDC_CONFIGURE; /* FIFO Threshold, Poll, Enable FIFO */ + pCMD->cmd[CONFIG2]=FDC_PRE_TRK; /* Precompensation Track */ + pCMD->cmdlen=FDC_CMD_CONFIGURE_LEN; + pCMD->resultlen=0; /* no result */ + break; + case FDC_CMD_SPECIFY: + pCMD->cmd[SPEC_HUTSRT]=pFG->spec1; + pCMD->cmd[SPEC_HLT]=(pFG->hlt)<<1; /* head load time */ + if(pCMD->dma==0) + pCMD->cmd[SPEC_HLT]|=0x1; /* no dma */ + pCMD->cmdlen=FDC_CMD_SPECIFY_LEN; + pCMD->resultlen=0; /* no result */ + break; + case FDC_CMD_DUMP_REG: + pCMD->cmdlen=FDC_CMD_DUMP_REG_LEN; + pCMD->resultlen=10; /* 10 byte result */ + break; + case FDC_CMD_READ_ID: + pCMD->cmd[COMMAND]|=(FDC_MFM_MODE<<6); /* set MFM bit */ + pCMD->cmdlen=FDC_CMD_READ_ID_LEN; + pCMD->resultlen=7; /* 7 byte result */ + break; + case FDC_CMD_RECALIBRATE: + pCMD->cmd[DRIVE]&=0x03; /* don't set the head bit */ + pCMD->cmdlen=FDC_CMD_RECALIBRATE_LEN; + pCMD->resultlen=0; /* no result */ + break; + break; + case FDC_CMD_SENSE_INT: + pCMD->cmdlen=FDC_CMD_SENSE_INT_LEN; + pCMD->resultlen=2; + break; + } + for(i=0;icmdlen;i++) { + /* PRINTF("write cmd%d = 0x%02X\n",i,pCMD->cmd[i]); */ + if(write_fdc_byte(pCMD->cmd[i])==FALSE) { + PRINTF("Error: timeout while issue cmd%d\n",i); + return FALSE; + } + } + timeout=FDC_TIME_OUT; + for(i=0;iresultlen;i++) { + while((read_fdc_reg(FDC_MSR)&0xC0)!=0xC0) { + timeout--; + if(timeout==0) { + PRINTF(" timeout while reading result%d MSR=0x%02X\n",i,read_fdc_reg(FDC_MSR)); + return FALSE; + } + } + pCMD->result[i]=(unsigned char)read_fdc_byte(); + } + return TRUE; +} + +/* selects the drive assigned in the cmd structur and + switches on the Motor */ +void select_fdc_drive(FDC_COMMAND_STRUCT *pCMD) +{ + unsigned char val; + + val=(1<<(4+pCMD->drive))|pCMD->drive|0xC; /* set reset, dma gate and motor bits */ + if((read_fdc_reg(FDC_DOR)&val)!=val) { + write_fdc_reg(FDC_DOR,val); + for(val=0;val<255;val++) + udelay(500); /* wait some time to start motor */ + } +} + +/* switches off the Motor of the specified drive */ +void stop_fdc_drive(FDC_COMMAND_STRUCT *pCMD) +{ + unsigned char val; + + val=(1<<(4+pCMD->drive))|pCMD->drive; /* sets motor bits */ + write_fdc_reg(FDC_DOR,(read_fdc_reg(FDC_DOR)&~val)); +} + +/* issues a recalibrate command, waits for interrupt and + * issues a sense_interrupt */ +int fdc_recalibrate(FDC_COMMAND_STRUCT *pCMD,FD_GEO_STRUCT *pFG) +{ + pCMD->cmd[COMMAND]=FDC_CMD_RECALIBRATE; + if(fdc_issue_cmd(pCMD,pFG)==FALSE) + return FALSE; + while(wait_for_fdc_int()!=TRUE); + pCMD->cmd[COMMAND]=FDC_CMD_SENSE_INT; + return(fdc_issue_cmd(pCMD,pFG)); +} + +/* issues a recalibrate command, waits for interrupt and + * issues a sense_interrupt */ +int fdc_seek(FDC_COMMAND_STRUCT *pCMD,FD_GEO_STRUCT *pFG) +{ + pCMD->cmd[COMMAND]=FDC_CMD_SEEK; + if(fdc_issue_cmd(pCMD,pFG)==FALSE) + return FALSE; + while(wait_for_fdc_int()!=TRUE); + pCMD->cmd[COMMAND]=FDC_CMD_SENSE_INT; + return(fdc_issue_cmd(pCMD,pFG)); +} + + +/* terminates current command, by not servicing the FIFO + * waits for interrupt and fills in the result bytes */ +int fdc_terminate(FDC_COMMAND_STRUCT *pCMD) +{ + int i; + for(i=0;i<100;i++) + udelay(500); /* wait 500usec for fifo overrun */ + while((read_fdc_reg(FDC_SRA)&0x80)==0x00); /* wait as long as no int has occured */ + for(i=0;i<7;i++) { + pCMD->result[i]=(unsigned char)read_fdc_byte(); + } + return TRUE; +} + +/* reads data from FDC, seek commands are issued automatic */ +int fdc_read_data(unsigned char *buffer, unsigned long blocks,FDC_COMMAND_STRUCT *pCMD, FD_GEO_STRUCT *pFG) +{ + /* first seek to start address */ + unsigned long len,lastblk,readblk,i,timeout,ii,offset; + unsigned char pcn,c,retriesrw,retriescal; + unsigned char *bufferw; /* working buffer */ + int sect_size; + int flags; + + flags=disable_interrupts(); /* switch off all Interrupts */ + select_fdc_drive(pCMD); /* switch on drive */ + sect_size=0x080<sect_code; + retriesrw=0; + retriescal=0; + offset=0; + if(fdc_seek(pCMD,pFG)==FALSE) { + stop_fdc_drive(pCMD); + enable_interrupts(); + return FALSE; + } + if((pCMD->result[STATUS_0]&0x20)!=0x20) { + printf("Seek error Status: %02X\n",pCMD->result[STATUS_0]); + stop_fdc_drive(pCMD); + enable_interrupts(); + return FALSE; + } + pcn=pCMD->result[STATUS_PCN]; /* current track */ + /* now determine the next seek point */ + lastblk=pCMD->blnr + blocks; + /* readblk=(pFG->head*pFG->sect)-(pCMD->blnr%(pFG->head*pFG->sect)); */ + readblk=pFG->sect-(pCMD->blnr%pFG->sect); + PRINTF("1st nr of block possible read %ld start %ld\n",readblk,pCMD->blnr); + if(readblk>blocks) /* is end within 1st track */ + readblk=blocks; /* yes, correct it */ + PRINTF("we read %ld blocks start %ld\n",readblk,pCMD->blnr); + bufferw=&buffer[0]; /* setup working buffer */ + do { +retryrw: + len=sect_size * readblk; + pCMD->cmd[COMMAND]=FDC_CMD_READ; + if(fdc_issue_cmd(pCMD,pFG)==FALSE) { + stop_fdc_drive(pCMD); + enable_interrupts(); + return FALSE; + } + for (i=0;i6) { + for(ii=0;ii<7;ii++) { + pCMD->result[ii]=bufferw[(i-7+ii)]; + } /* for */ + } + if(retriesrw++>FDC_RW_RETRIES) { + if (retriescal++>FDC_CAL_RETRIES) { + stop_fdc_drive(pCMD); + enable_interrupts(); + return FALSE; + } + else { + PRINTF(" trying to recalibrate Try %d\n",retriescal); + if(fdc_recalibrate(pCMD,pFG)==FALSE) { + stop_fdc_drive(pCMD); + enable_interrupts(); + return FALSE; + } + retriesrw=0; + goto retrycal; + } /* else >FDC_CAL_RETRIES */ + } + else { + PRINTF("Read retry %d\n",retriesrw); + goto retryrw; + } /* else >FDC_RW_RETRIES */ + }/* if output */ + timeout--; + }while(TRUE); + } /* for len */ + /* the last sector of a track or all data has been read, + * we need to get the results */ + fdc_terminate(pCMD); + offset+=(sect_size*readblk); /* set up buffer pointer */ + bufferw=&buffer[offset]; + pCMD->blnr+=readblk; /* update current block nr */ + blocks-=readblk; /* update blocks */ + if(blocks==0) + break; /* we are finish */ + /* setup new read blocks */ + /* readblk=pFG->head*pFG->sect; */ + readblk=pFG->sect; + if(readblk>blocks) + readblk=blocks; +retrycal: + /* a seek is necessary */ + if(fdc_seek(pCMD,pFG)==FALSE) { + stop_fdc_drive(pCMD); + enable_interrupts(); + return FALSE; + } + if((pCMD->result[STATUS_0]&0x20)!=0x20) { + PRINTF("Seek error Status: %02X\n",pCMD->result[STATUS_0]); + stop_fdc_drive(pCMD); + return FALSE; + } + pcn=pCMD->result[STATUS_PCN]; /* current track */ + }while(TRUE); /* start over */ + stop_fdc_drive(pCMD); /* switch off drive */ + enable_interrupts(); + return TRUE; +} + +/* Scan all drives and check if drive is present and disk is inserted */ +int fdc_check_drive(FDC_COMMAND_STRUCT *pCMD, FD_GEO_STRUCT *pFG) +{ + int i,drives,state; + /* OK procedure of data book is satisfied. + * trying to get some information over the drives */ + state=0; /* no drives, no disks */ + for(drives=0;drives<4;drives++) { + pCMD->drive=drives; + select_fdc_drive(pCMD); + pCMD->blnr=0; /* set to the 1st block */ + if(fdc_recalibrate(pCMD,pFG)==FALSE) + break; + if((pCMD->result[STATUS_0]&0x10)==0x10) + break; + /* ok drive connected check for disk */ + state|=(1<blnr=pFG->size; /* set to the last block */ + if(fdc_seek(pCMD,pFG)==FALSE) + break; + pCMD->blnr=0; /* set to the 1st block */ + if(fdc_recalibrate(pCMD,pFG)==FALSE) + break; + pCMD->cmd[COMMAND]=FDC_CMD_READ_ID; + if(fdc_issue_cmd(pCMD,pFG)==FALSE) + break; + state|=(0x10<name : ""); + } + pCMD->flags=state; + return TRUE; +} + + +/************************************************************************** +* int fdc_setup +* setup the fdc according the datasheet +* assuming in PS2 Mode +*/ +int fdc_setup(FDC_COMMAND_STRUCT *pCMD, FD_GEO_STRUCT *pFG) +{ + + int i; + /* first, we reset the FDC via the DOR */ + write_fdc_reg(FDC_DOR,0x00); + for(i=0; i<255; i++) /* then we wait some time */ + udelay(500); + /* then, we clear the reset in the DOR */ + pCMD->drive=0; + select_fdc_drive(pCMD); + /* initialize the CCR */ + write_fdc_reg(FDC_CCR,pFG->rate); + /* then initialize the DSR */ + write_fdc_reg(FDC_DSR,pFG->rate); + if(wait_for_fdc_int()==FALSE) { + PRINTF("Time Out after writing CCR\n"); + return FALSE; + } + /* now issue sense Interrupt and status command + * assuming only one drive present (drive 0) */ + pCMD->dma=0; /* we don't use any dma at all */ + for(i=0;i<4;i++) { + /* issue sense interrupt for all 4 possible drives */ + pCMD->cmd[COMMAND]=FDC_CMD_SENSE_INT; + if(fdc_issue_cmd(pCMD,pFG)==FALSE) { + PRINTF("Sense Interrupt for drive %d failed\n",i); + } + } + /* assuming drive 0 for rest of configuration + * issue the configure command */ + pCMD->drive=0; + select_fdc_drive(pCMD); + pCMD->cmd[COMMAND]=FDC_CMD_CONFIGURE; + if(fdc_issue_cmd(pCMD,pFG)==FALSE) { + PRINTF(" configure timeout\n"); + stop_fdc_drive(pCMD); + return FALSE; + } + /* issue specify command */ + pCMD->cmd[COMMAND]=FDC_CMD_SPECIFY; + if(fdc_issue_cmd(pCMD,pFG)==FALSE) { + PRINTF(" specify timeout\n"); + stop_fdc_drive(pCMD); + return FALSE; + + } + /* then, we clear the reset in the DOR */ + /* fdc_check_drive(pCMD,pFG); */ + /* write_fdc_reg(FDC_DOR,0x04); */ + return TRUE; +} + +/**************************************************************************** + * main routine do_fdcboot + */ + +void do_fdcboot(cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) +{ + FD_GEO_STRUCT *pFG = (FD_GEO_STRUCT *)floppy_type; + FDC_COMMAND_STRUCT *pCMD = &cmd; + unsigned long addr,imsize; + image_header_t *hdr; /* used for fdc boot */ + unsigned char boot_drive; + int i,nrofblk; + char *ep; + + switch (argc) { + case 1: + addr = CFG_LOAD_ADDR; + boot_drive=0; /* default boot from drive 0 */ + break; + case 2: + addr = simple_strtoul(argv[1], NULL, 16); + boot_drive=0; /* default boot from drive 0 */ + break; + case 3: + addr = simple_strtoul(argv[1], NULL, 16); + boot_drive=simple_strtoul(argv[2], NULL, 10); + break; + default: + printf ("Usage:\n%s\n", cmdtp->usage); + return; + } + /* setup FDC and scan for drives */ + if(fdc_setup(pCMD,pFG)==FALSE) { + printf("\n** Error in setup FDC **\n"); + return; + } + if(fdc_check_drive(pCMD,pFG)==FALSE) { + printf("\n** Error in check_drives **\n"); + return; + } + if((pCMD->flags&(1<flags&(0x10<drive=boot_drive; + /* read first block */ + pCMD->blnr=0; + if(fdc_read_data((unsigned char *)addr,1,pCMD,pFG)==FALSE) { + printf("\nRead error:"); + for(i=0;i<7;i++) + printf("result%d: 0x%02X\n",i,pCMD->result[i]); + return; + } + hdr = (image_header_t *)addr; + if (hdr->ih_magic != IH_MAGIC) { + printf ("Bad Magic Number\n"); + return; + } + print_image_hdr(hdr); + + imsize= hdr->ih_size+sizeof(image_header_t); + nrofblk=imsize/512; + if((imsize%512)>0) + nrofblk++; + printf("Loading %ld Bytes (%d blocks) at 0x%08lx..\n",imsize,nrofblk,addr); + pCMD->blnr=0; + if(fdc_read_data((unsigned char *)addr,nrofblk,pCMD,pFG)==FALSE) { + /* read image block */ + printf("\nRead error:"); + for(i=0;i<7;i++) + printf("result%d: 0x%02X\n",i,pCMD->result[i]); + return; + } + printf("OK %ld Bytes loaded.\n",imsize); + /* Loading ok, update default load address */ + + load_addr = addr; + if(hdr->ih_type == IH_TYPE_KERNEL) { + /* Check if we should attempt an auto-start */ + if (((ep = getenv("autostart")) != NULL) && (strcmp(ep,"yes") == 0)) { + char *local_args[2]; + extern void do_bootm (cmd_tbl_t *, bd_t *, int, int, char *[]); + + local_args[0] = argv[0]; + local_args[1] = NULL; + + printf ("Automatic boot of image at addr 0x%08lX ...\n", addr); + + do_bootm (cmdtp, bd, 0, 1, local_args); + } + } +} + + + +#endif /* CONFIG_COMMANDS & CFG_CMD_FDC */ + + diff --git a/common/cmd_i2c.c b/common/cmd_i2c.c index 7826066..c9b273f 100644 --- a/common/cmd_i2c.c +++ b/common/cmd_i2c.c @@ -53,6 +53,7 @@ do_i2c (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) #if !defined(CONFIG_CPCI405) && !defined(CONFIG_AR405) && \ + !defined(CONFIG_PIP405) && \ !defined (CONFIG_WALNUT405) && !defined (CONFIG_ERIC) i2c_state_t state; @@ -70,6 +71,7 @@ do_i2c (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) if (strncmp (argv[1], "res", 3) == 0) { printf ("I2C reset 50kHz ... "); #if defined(CONFIG_CPCI405) || defined(CONFIG_AR405) || \ + defined(CONFIG_PIP405) || \ defined (CONFIG_WALNUT405) || defined (CONFIG_ERIC) i2c_init (); #else @@ -88,6 +90,7 @@ do_i2c (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) else printf ("I2C reset %dkHz ... ", speed/1000); #if defined(CONFIG_CPCI405) || defined(CONFIG_AR405) || \ + defined(CONFIG_PIP405) || \ defined (CONFIG_WALNUT405) || defined (CONFIG_ERIC) i2c_init (); #else @@ -115,6 +118,7 @@ do_i2c (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) , i2c_addr, (ulong)data_addr, size); #if defined(CONFIG_CPCI405) || defined(CONFIG_AR405) || \ + defined(CONFIG_PIP405) || \ defined (CONFIG_WALNUT405) || defined (CONFIG_ERIC) #else @@ -123,6 +127,7 @@ do_i2c (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) #if defined(CONFIG_CPCI405) || defined(CONFIG_AR405) || \ + defined(CONFIG_PIP405) || \ defined (CONFIG_WALNUT405) || defined (CONFIG_ERIC) rc = i2c_receive (i2c_addr, size, data_addr); @@ -140,6 +145,7 @@ do_i2c (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) } #if defined(CONFIG_CPCI405) || defined(CONFIG_AR405) || \ + defined(CONFIG_PIP405) || \ defined (CONFIG_WALNUT405) || defined (CONFIG_ERIC) #else @@ -164,6 +170,7 @@ do_i2c (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) #if defined(CONFIG_CPCI405) || defined(CONFIG_AR405) || \ + defined(CONFIG_PIP405) || \ defined (CONFIG_WALNUT405) || defined (CONFIG_ERIC) #else @@ -171,6 +178,7 @@ do_i2c (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) #endif #if defined(CONFIG_CPCI405) || defined(CONFIG_AR405) || \ + defined(CONFIG_PIP405) || \ defined (CONFIG_WALNUT405) || defined (CONFIG_ERIC) rc = i2c_send (i2c_addr, size, data_addr); @@ -185,6 +193,7 @@ do_i2c (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) } #if defined(CONFIG_CPCI405) || defined(CONFIG_AR405) || \ + defined(CONFIG_PIP405) || \ defined (CONFIG_WALNUT405) || defined (CONFIG_ERIC) #else @@ -214,6 +223,7 @@ do_i2c (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) i2c_addr, sec_addr, (ulong)data_addr, size); #if defined(CONFIG_CPCI405) || defined(CONFIG_AR405) || \ + defined(CONFIG_PIP405) || \ defined (CONFIG_WALNUT405) || defined (CONFIG_ERIC) #else @@ -221,6 +231,7 @@ do_i2c (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) #endif #if defined(CONFIG_CPCI405) || defined(CONFIG_AR405) || \ + defined(CONFIG_PIP405) || \ defined (CONFIG_WALNUT405) || defined (CONFIG_ERIC) rc = i2c_receive (i2c_addr, size, data_addr); @@ -237,6 +248,7 @@ do_i2c (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) } #if defined(CONFIG_CPCI405) || defined(CONFIG_AR405) || \ + defined(CONFIG_PIP405) || \ defined (CONFIG_WALNUT405) || defined (CONFIG_ERIC) #else @@ -263,6 +275,7 @@ do_i2c (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) i2c_addr, sec_addr, (ulong)data_addr, size); #if defined(CONFIG_CPCI405) || defined(CONFIG_AR405) || \ + defined(CONFIG_PIP405) || \ defined (CONFIG_WALNUT405) || defined (CONFIG_ERIC) #else @@ -270,6 +283,7 @@ do_i2c (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) #endif #if defined(CONFIG_CPCI405) || defined(CONFIG_AR405) || \ + defined(CONFIG_PIP405) || \ defined (CONFIG_WALNUT405) || defined (CONFIG_ERIC) rc = i2c_send (i2c_addr, size, data_addr); @@ -285,6 +299,7 @@ do_i2c (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) } #if defined(CONFIG_CPCI405) || defined(CONFIG_AR405) || \ + defined(CONFIG_PIP405) || \ defined (CONFIG_WALNUT405) || defined (CONFIG_ERIC) #else diff --git a/common/cmd_ide.c b/common/cmd_ide.c index 8265010..6f64a1b 100644 --- a/common/cmd_ide.c +++ b/common/cmd_ide.c @@ -1,5 +1,5 @@ /* - * (C) Copyright 2000 + * (C) Copyright 2000, 2001 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * * See file CREDITS for list of people who contributed to this @@ -44,15 +44,6 @@ # include #endif -/* stdlib.h causes some compatibility problems; should fixe these! -- wd */ -#ifndef __ldiv_t_defined -typedef struct { - long int quot; /* Quotient */ - long int rem; /* Remainder */ -} ldiv_t; -extern ldiv_t ldiv (long int __numer, long int __denom); -# define __ldiv_t_defined 1 -#endif #undef IDE_DEBUG @@ -115,15 +106,9 @@ static ulong bus_offset[CFG_IDE_MAXBUS] = { #define ATA_CURR_BASE(dev) (CFG_ATA_BASE_ADDR+bus_offset[IDE_BUS(dev)]) -typedef struct ide_dev_id { - ulong size; - uchar model[40]; - uchar serial_no[20]; -} ide_dev_id_t; - static int ide_bus_ok[CFG_IDE_MAXBUS]; -static ide_dev_id_t ide_device[CFG_IDE_MAXDEVICE]; +static block_dev_desc_t ide_dev_desc[CFG_IDE_MAXDEVICE]; /* ------------------------------------------------------------------------- */ #ifdef CONFIG_IDE_LED @@ -138,16 +123,31 @@ static void ide_reset (void); #define ide_reset() /* dummy */ #endif -static void ide_ident (int device); -static void ide_print (int device); +static void ide_ident (block_dev_desc_t *dev_desc); static uchar ide_wait (int dev, ulong t); +#ifdef CONFIG_PIP405 +#define IDE_TIME_OUT 2000 /* 2 sec timeout */ +#else +#define IDE_TIME_OUT 500 /* 500ms timeout */ +#endif + +#define ATAPI_TIME_OUT 7000 /* 7 sec timeout (5 sec seems to work...) */ + + static void __inline__ outb(int dev, int port, unsigned char val); static unsigned char __inline__ inb(int dev, int port); static void input_swap_data(int dev, ulong *sect_buf, int words); static void input_data(int dev, ulong *sect_buf, int words); static void output_data(int dev, ulong *sect_buf, int words); -static void trim_trail (unsigned char *str, unsigned int len); +static void ident_cpy (unsigned char *dest, unsigned char *src, unsigned int len); + + +#ifdef CONFIG_ATAPI +static void atapi_inquiry(block_dev_desc_t *dev_desc); +ulong atapi_read (int device, ulong blknr, ulong blkcnt, ulong *buffer); +#endif + #ifdef CONFIG_IDE_PCMCIA static void set_pcmcia_timing (int pmode); @@ -180,8 +180,10 @@ void do_ide (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) putc ('\n'); for (i=0; i 0) && (curr_device < 0)) { - curr_device = i; + dev_print(&ide_dev_desc[i]); +/* ide_print (i); */ +/* if((ide_device[i].size > 0) && (ide_dev_desc[i].if_type==IF_TYPE_IDE)) */ + if((ide_dev_desc[i].lba > 0) && (ide_dev_desc[i].blksz > 0)) { + init_part (&ide_dev_desc[i]); /* initialize partition type */ + if(curr_device < 0) + curr_device = i; } } #if defined(CONFIG_WATCHDOG) @@ -556,6 +565,12 @@ void ide_init (bd_t *bd) /* ------------------------------------------------------------------------- */ +block_dev_desc_t * ide_get_dev(int dev) +{ + return((block_dev_desc_t *)&ide_dev_desc[dev]); +} + + #ifdef CONFIG_IDE_PCMCIA static void @@ -722,44 +737,68 @@ input_data(int dev, ulong *sect_buf, int words) /* ------------------------------------------------------------------------- */ -static void ide_ident (int device) +static void ide_ident (block_dev_desc_t *dev_desc) { ulong iobuf[ATA_SECTORWORDS]; unsigned char c; hd_driveid_t *iop = (hd_driveid_t *)iobuf; - ide_dev_id_t *idp = &(ide_device[device]); + #if 0 int mode, cycle_time; #endif - + int device; + device=dev_desc->dev; printf (" Device %d: ", device); ide_led (DEVICE_LED(device), 1); /* LED on */ /* Select device */ outb (device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device)); + dev_desc->if_type=IF_TYPE_IDE; +#ifdef CONFIG_ATAPI + /* check signature */ + if((inb(device,ATA_SECT_CNT)==0x01) && + (inb(device,ATA_SECT_NUM)==0x01) && + (inb(device,ATA_CYL_LOW)==0x14) && + (inb(device,ATA_CYL_HIGH)==0xEB)) { + /* ATAPI Signature found */ + dev_desc->if_type=IF_TYPE_ATAPI; + /* Start Ident Command + */ + outb (device, ATA_COMMAND, ATAPI_CMD_IDENT); + /* Wait for completion ATAPI devices need more time to become ready + */ + c = ide_wait (device, ATAPI_TIME_OUT); + } + else +#endif + { + /* Start Ident Command + */ + outb (device, ATA_COMMAND, ATA_CMD_IDENT); - /* Start Ident Command - */ - outb (device, ATA_COMMAND, ATA_CMD_IDENT); - - /* Wait for completion - */ - c = ide_wait (device, 100); - + /* Wait for completion + */ + c = ide_wait (device, IDE_TIME_OUT); + } ide_led (DEVICE_LED(device), 0); /* LED off */ if (((c & ATA_STAT_READY) == 0) || ((c & (ATA_STAT_FAULT|ATA_STAT_ERR)) != 0) ) { - idp->size = 0; - idp->model[0] = idp->serial_no[0] = '\0'; + dev_desc->type=DEV_TYPE_UNKNOWN; return; } input_swap_data (device, iobuf, ATA_SECTORWORDS); + + ident_cpy (dev_desc->revision, iop->fw_rev, sizeof(dev_desc->revision)); + ident_cpy (dev_desc->vendor, iop->model, sizeof(dev_desc->vendor)); + ident_cpy (dev_desc->product, iop->serial_no, sizeof(dev_desc->product)); - trim_trail (iop->model, sizeof(iop->model)); - trim_trail (iop->serial_no, sizeof(iop->serial_no)); + if((iop->config & 0x0080)==0x0080) + dev_desc->removable = 1; + else + dev_desc->removable = 0; #if 0 /* @@ -789,43 +828,21 @@ static void ide_ident (int device) printf ("PIO mode to use: PIO %d\n", mode); #endif +#ifdef CONFIG_ATAPI + if(dev_desc->if_type==IF_TYPE_ATAPI) { + atapi_inquiry(dev_desc); + return; + } +#endif /* swap shorts */ - idp->size = (iop->lba_capacity << 16) | (iop->lba_capacity >> 16); - - strncpy (idp->model, iop->model, sizeof(idp->model)); - strncpy (idp->serial_no, iop->serial_no, sizeof(idp->serial_no)); + dev_desc->lba = (iop->lba_capacity << 16) | (iop->lba_capacity >> 16); + /* assuming HD */ + dev_desc->type=DEV_TYPE_HARDDISK; + dev_desc->blksz=ATA_BLOCKSIZE; + dev_desc->lun=0; /* just to fill something in... */ + } -/* ------------------------------------------------------------------------- */ - -static void ide_print (int device) -{ - ldiv_t mb, gb; - ide_dev_id_t *idp = &(ide_device[device]); - char *mod, *ser; - - if (idp->size == 0) { - puts ("not available\n"); - return; - } - - mb = ldiv(idp->size, ((1024 * 1024) / 512)); /* MB */ - /* round to 1 digit */ - mb.rem *= 10 * 512; - mb.rem += 512 * 1024; - mb.rem /= 1024 * 1024; - - gb = ldiv(10 * mb.quot + mb.rem, 10240); - gb.rem += 512; - gb.rem /= 1024; - - mod = idp->model; while (*mod && (*mod==' ')) ++mod; - ser = idp->serial_no; while (*ser && (*ser==' ')) ++ser; - - printf ("Model: %s Serial #: %s ", mod, ser); - printf ("Capacity: %ld.%ld MB = %ld.%ld GB\n", - mb.quot, mb.rem, gb.quot, gb.rem); -} /* ------------------------------------------------------------------------- */ @@ -834,6 +851,7 @@ ulong ide_read (int device, ulong blknr, ulong blkcnt, ulong *buffer) ulong n = 0; unsigned char c; + PRINTF("ide_read dev %d start %lX, blocks %lX buffer at %lX\n",device,blknr,blkcnt,(ulong)buffer); ide_led (DEVICE_LED(device), 1); /* LED on */ /* Select device @@ -842,7 +860,7 @@ ulong ide_read (int device, ulong blknr, ulong blkcnt, ulong *buffer) while (blkcnt-- > 0) { - c = ide_wait (device, 500); + c = ide_wait (device, IDE_TIME_OUT); if (c & ATA_STAT_BUSY) { printf ("IDE read: device %d not ready\n", device); @@ -860,7 +878,7 @@ ulong ide_read (int device, ulong blknr, ulong blkcnt, ulong *buffer) udelay (50); - c = ide_wait (device, 500); /* can't take over 500 ms */ + c = ide_wait (device, IDE_TIME_OUT); /* can't take over 500 ms */ if ((c&(ATA_STAT_DRQ|ATA_STAT_BUSY|ATA_STAT_ERR)) != ATA_STAT_DRQ) { printf ("Error (no IRQ) dev %d blk %ld: status 0x%02x\n", @@ -896,7 +914,7 @@ ulong ide_write (int device, ulong blknr, ulong blkcnt, ulong *buffer) while (blkcnt-- > 0) { - c = ide_wait (device, 500); + c = ide_wait (device, IDE_TIME_OUT); if (c & ATA_STAT_BUSY) { printf ("IDE read: device %d not ready\n", device); @@ -914,7 +932,7 @@ ulong ide_write (int device, ulong blknr, ulong blkcnt, ulong *buffer) udelay (50); - c = ide_wait (device, 500); /* can't take over 500 ms */ + c = ide_wait (device, IDE_TIME_OUT); /* can't take over 500 ms */ if ((c&(ATA_STAT_DRQ|ATA_STAT_BUSY|ATA_STAT_ERR)) != ATA_STAT_DRQ) { printf ("Error (no IRQ) dev %d blk %ld: status 0x%02x\n", @@ -935,18 +953,28 @@ WR_OUT: /* ------------------------------------------------------------------------- */ -/* Trim trailing blanks, and NUL-terminate string +/* copy src to dest, skipping leading and trailing blanks and null terminate the string */ -static void trim_trail (unsigned char *str, unsigned int len) +static void ident_cpy (unsigned char *dest, unsigned char *src, unsigned int len) { - unsigned char *p = str + len - 1; + int start,end; - while (len-- > 0) { - *p-- = '\0'; - if (*p != ' ') { - return; - } + start=0; + while(startstart) { + if(src[end]!=' ') + break; + end--; } + for( ; start<=end; start++) { + *dest++=src[start]; + } + *dest='\0'; } /* ------------------------------------------------------------------------- */ @@ -972,19 +1000,23 @@ static uchar ide_wait (int dev, ulong t) /* ------------------------------------------------------------------------- */ #ifdef CONFIG_IDE_RESET +#ifdef CONFIG_IDE_RESET_ROUTINE +extern void ide_set_reset(int idereset); +#endif static void ide_reset (void) { int i; +#if defined(CFG_PC_IDE_RESET) volatile immap_t *immr = (immap_t *)CFG_IMMR; - +#endif curr_device = -1; for (i=0; iim_ioport.iop_pcdat &= ~(CFG_PC_IDE_RESET); /* Set reset bit */ @@ -998,7 +1030,14 @@ static void ide_reset (void) /* de-assert RESET signal of IDE */ immr->im_ioport.iop_pcdat |= CFG_PC_IDE_RESET; #else +#ifdef CONFIG_IDE_RESET_ROUTINE + ide_set_reset(1); /* assert reset */ + udelay (20000); + /* de-assert RESET signal of IDE */ + ide_set_reset(0); +#else #error IDE reset pin not configured +#endif /* CONFIG_IDE_RESET_ROUTINE */ #endif /* CFG_PC_IDE_RESET */ #if defined(CONFIG_WATCHDOG) @@ -1076,4 +1115,247 @@ static void ide_led (uchar led, uchar status) /* ------------------------------------------------------------------------- */ +#ifdef CONFIG_ATAPI +/**************************************************************************** + * ATAPI Support + */ + + + +#undef ATAPI_DEBUG + +#ifdef ATAPI_DEBUG +#define AT_PRINTF(fmt,args...) printf (fmt ,##args) +#else +#define AT_PRINTF(fmt,args...) +#endif + +/* + * issue an atapi command + */ +unsigned char atapi_issue(int device,unsigned char* ccb,int ccblen, unsigned char * buffer,int buflen) +{ + unsigned char c,err; + int n; + ide_led (DEVICE_LED(device), 1); /* LED on */ + + /* Select device + */ + outb (device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device)); + c = ide_wait (device, ATAPI_TIME_OUT); + + if (c & ATA_STAT_BUSY) { + printf ("ATAPI_ISSUE: device %d not ready\n", device); + err=0xff; + goto AI_OUT; + } + outb (device, ATA_ERROR_REG, 0); /* no DMA, no overlaped */ + outb (device, ATA_CYL_LOW, (unsigned char)(buflen & 0xff)); + outb (device, ATA_CYL_HIGH, (unsigned char)((buflen<<8) & 0xff)); + outb (device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device)); + + outb (device, ATA_COMMAND, ATAPI_CMD_PACKET); + udelay (50); + c = ide_wait (device, ATAPI_TIME_OUT); /* can't take over 500 ms */ + + if ((c&(ATA_STAT_DRQ|ATA_STAT_BUSY|ATA_STAT_ERR)) != ATA_STAT_DRQ) { /* DRQ must be 1, BSY 0 */ + printf ("ATTAPI_ISSUE: Error (no IRQ) before sending ccb dev %d status 0x%02x\n",device,c); + err=0xff; + goto AI_OUT; + } + output_data (device, (unsigned long *)ccb,ccblen/2); /* write command block */ + /*while((inb(device,ATA_STATUS) & ATA_STAT_BUSY)==0) */ + udelay (50); /* device must set bsy */ + /*c = inb (device, ATA_STATUS);*/ /* clear IRQ */ + c = ide_wait (device, ATAPI_TIME_OUT); /* wait until BSY=0, DRQ=1 */ + if ((c&(ATA_STAT_DRQ|ATA_STAT_BUSY|ATA_STAT_ERR)) != ATA_STAT_DRQ) { + if((c&ATA_STAT_ERR) == ATA_STAT_ERR) { + err=(inb(device,ATA_ERROR_REG)); + AT_PRINTF("atapi_issue returned sense key %X\n",err); + } + else { + /* maybe no data command ? */ + if(buflen==0) + err=0; + else { + printf ("ATTAPI_ISSUE: (no IRQ) after sending ccb (%x) status 0x%02x\n", ccb[0],c); + err=0xff; + } + } + goto AI_OUT; + } + n=inb(device, ATA_CYL_HIGH); + n<<=8; + n+=inb(device, ATA_CYL_LOW); + AT_PRINTF("ATAPI_ISSUE: %d Bytes to transfer\n",n); + /* ok now decide if it is an in or output */ + if((inb(device, ATA_SECT_CNT)&0x02)==0) { + AT_PRINTF("Write to device\n"); + output_data(device,(unsigned long *)buffer,n>>2); + } + else { + AT_PRINTF("Read from device @ %p words %d\n",buffer,n>>2); + input_data(device,(unsigned long *)buffer,n>>2); + } + c = inb (device, ATA_STATUS); /* clear IRQ */ + if((c & ATA_STAT_ERR) == ATA_STAT_ERR) { + err=(inb(device,ATA_ERROR_REG) >> 8) &0x0f; + AT_PRINTF("atapi_issue returned sense key %X\n",err); + } + else + err = 0; +AI_OUT: + ide_led (DEVICE_LED(device), 0); /* LED off */ + return(err); +} + +/* + * sending the command to atapi_issue. If an status other than good returns, an request_sense + * will be issued + */ +unsigned char atapi_issue_autoreq(int device,unsigned char* ccb,int ccblen, unsigned char * buffer,int buflen) +{ + unsigned char sense_data[16],sense_ccb[12]; + unsigned char res; + int i,retrycnt; + + retrycnt=0; +retry: + res= atapi_issue(device,ccb,ccblen,buffer,buflen); + if(res==0) + return (0); /* Ok */ + if(res==0xff) + return (0xff); /* error */ + AT_PRINTF("(auto_req)atapi_issue returned sense key %X\n",res); + for(i=0;i<12;i++) + sense_ccb[i]=0; /* initialize it to zero */ + sense_ccb[0]=ATAPI_CMD_REQ_SENSE; + sense_ccb[4]=16; /* allocation Legnth */ + res=atapi_issue(device,sense_ccb,12,sense_data,14); + AT_PRINTF("ATAPI_CMD_REQ_SENSE returned %x\n",res); + AT_PRINTF(" Sense page: %02X key %02X ASC %02X ASCQ %02X\n",sense_data[0],sense_data[2]&0xf,sense_data[12],sense_data[13]); + if(((sense_data[2]&0xf)==0) && (sense_data[12]==0) && (sense_data[13]==0)) + return(0); /* ok device ready */ + if(((sense_data[2]&0xf)==0x02) && (sense_data[12]==0x04) && (sense_data[13]!=0x01)) { + printf("Error\n"); + return (0xff); + } + if(((sense_data[2]&0xf)==0x02) && (sense_data[12]==0x3A)) { + AT_PRINTF("Media not present\n"); + return (0xff); + } + if((sense_data[2]&0xf)==0x06) { + AT_PRINTF("Unit attention...retry\n"); + if(retrycnt++<4) + goto retry; + return (0xff); + } + printf("unknown sense_key\n"); + return(0xff); +} + + + +static void atapi_inquiry(block_dev_desc_t * dev_desc) +{ + unsigned char ccb[12]; /* Command descriptor block */ + unsigned char iobuf[64]; /* temp buf */ + unsigned char c; + int i,device; + + device=dev_desc->dev; + dev_desc->type=DEV_TYPE_UNKNOWN; /* not yet valid */ + dev_desc->block_read=atapi_read; + for(i=0;i<12;i++) + ccb[i]=0; /* initialize it to zero */ + ccb[0]=ATAPI_CMD_INQUIRY; + ccb[4]=40; /* allocation Legnth */ + c=atapi_issue_autoreq(device,ccb,12,(unsigned char *)iobuf,40); + AT_PRINTF("ATAPI_CMD_INQUIRY returned %x\n",c); + if(c!=0) + return; + /* copy device ident strings */ + ident_cpy(dev_desc->vendor,&iobuf[8],8); + ident_cpy(dev_desc->product,&iobuf[16],16); + ident_cpy(dev_desc->revision,&iobuf[32],5); + dev_desc->lun=0; + dev_desc->lba=0; + dev_desc->blksz=0; + dev_desc->type=iobuf[0] & 0x1f; + if((iobuf[1]&0x80)==0x80) + dev_desc->removable = 1; + else + dev_desc->removable = 0; + for(i=0;i<12;i++) + ccb[i]=0; /* initialize it to zero */ + ccb[0]=ATAPI_CMD_START_STOP; + ccb[4]=0x01; /* start */ + c=atapi_issue_autoreq(device,ccb,12,(unsigned char *)iobuf,0); + AT_PRINTF("ATAPI_CMD_START_STOP returned %x\n",c); + if(c!=0) + return; + for(i=0;i<12;i++) + ccb[i]=0; /* initialize it to zero */ + ccb[0]=ATAPI_CMD_READ_CAP; + c=atapi_issue_autoreq(device,ccb,12,(unsigned char *)iobuf,8); + AT_PRINTF("ATAPI_CMD_READ_CAP returned %x\n",c); + if(c!=0) + return; + AT_PRINTF("Read Cap: LBA %02X%02X%02X%02X blksize %02X%02X%02X%02X\n",iobuf[0],iobuf[1],iobuf[2],iobuf[3], + iobuf[4],iobuf[5],iobuf[6],iobuf[7]); + dev_desc->lba=((unsigned long)iobuf[0]<<24)+((unsigned long)iobuf[1]<<16)+((unsigned long)iobuf[2]<<8)+((unsigned long)iobuf[3]); + dev_desc->blksz=((unsigned long)iobuf[4]<<24)+((unsigned long)iobuf[5]<<16)+((unsigned long)iobuf[6]<<8)+((unsigned long)iobuf[7]); + return; +} + + +/* + * atapi_read: + * we transfer only one block per command, since the multiple DRQ per command is not yet implemented + */ +#define ATAPI_READ_MAX_BYTES 2048 /* we read max 32kbytes */ +#define ATAPI_READ_BLOCK_SIZE 2048 /* assuming CD part */ +#define ATAPI_READ_MAX_BLOCK ATAPI_READ_MAX_BYTES/ATAPI_READ_BLOCK_SIZE /* max blocks */ + +ulong atapi_read (int device, ulong blknr, ulong blkcnt, ulong *buffer) +{ + ulong n = 0; + unsigned char ccb[12]; /* Command descriptor block */ + ulong cnt; + + AT_PRINTF("atapi_read dev %d start %lX, blocks %lX buffer at %lX\n",device,blknr,blkcnt,(ulong)buffer); + do { + if(blkcnt>ATAPI_READ_MAX_BLOCK) { + cnt=ATAPI_READ_MAX_BLOCK; + } + else { + cnt=blkcnt; + } + ccb[0]=ATAPI_CMD_READ_12; + ccb[1]=0; /* reserved */ + ccb[2]=(unsigned char) (blknr>>24) & 0xff; /* MSB Block */ + ccb[3]=(unsigned char) (blknr>>16) & 0xff; /* */ + ccb[4]=(unsigned char) (blknr>>8) & 0xff; + ccb[5]=(unsigned char) blknr & 0xff; /* LSB Block */ + ccb[6]=(unsigned char) (cnt>>24) & 0xff; /* MSB Block count */ + ccb[7]=(unsigned char) (cnt>>16) & 0xff; + ccb[8]=(unsigned char) (cnt>>8) & 0xff; + ccb[9]=(unsigned char) cnt & 0xff; /* LSB Block */ + ccb[10]=0; /* reserved */ + ccb[11]=0; /* reserved */ + if(atapi_issue_autoreq(device,ccb,12,(unsigned char *)buffer,cnt*ATAPI_READ_BLOCK_SIZE)==0xff) + return(n); + n+=cnt; + blkcnt-=cnt; + blknr+=cnt; + buffer+=cnt*(ATAPI_READ_BLOCK_SIZE/4); /* ulong blocksize in ulong */ + } while(blkcnt>0); + return(n); +} + +/* ------------------------------------------------------------------------- */ + + +#endif /* CONFIG_ATAPI */ + #endif /* CONFIG_COMMANDS & CFG_CMD_IDE */ diff --git a/common/cmd_scsi.c b/common/cmd_scsi.c new file mode 100644 index 0000000..1c2fe19 --- /dev/null +++ b/common/cmd_scsi.c @@ -0,0 +1,585 @@ +/* + * (C) Copyright 2001 + * Denis Peter, MPL AG Switzerland + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * + */ + +/* + * SCSI support. + */ + +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_PPC405 +#include <405gp_pci.h> +#endif + + + + +#undef SCSI_DEBUG + +#ifdef SCSI_DEBUG +#define PRINTF(fmt,args...) printf (fmt ,##args) +#else +#define PRINTF(fmt,args...) +#endif + +#if (CONFIG_COMMANDS & CFG_CMD_SCSI) + +#ifdef CONFIG_SCSI_SYM53C8XX +#define SCSI_VEND_ID 0x1000 +#define SCSI_DEV_ID 0x0001 +#else +#error CONFIG_SCSI_SYM53C8XX must be defined +#endif + + +static ccb tempccb; /* temporary scsi command buffer */ + +static unsigned char tempbuff[512]; /* temporary data buffer */ + +static int scsi_max_devs; /* number of highest available scsi device */ + +static int scsi_curr_dev; /* current device */ + +static block_dev_desc_t scsi_dev_desc[CFG_SCSI_MAX_DEVICE]; + +/******************************************************************************** + * forward declerations of some Setup Routines + */ +void scsi_setup_test_unit_ready(ccb * pccb); +void scsi_setup_read_capacity(ccb * pccb); +void scsi_setup_read6(ccb * pccb, unsigned long start, unsigned short blocks); +void scsi_setup_read_ext(ccb * pccb, unsigned long start, unsigned short blocks); +void scsi_setup_inquiry(ccb * pccb); +void scsi_ident_cpy (unsigned char *dest, unsigned char *src, unsigned int len); + + +ulong scsi_read(int device, ulong blknr, ulong blkcnt, ulong *buffer); + + +/********************************************************************************* + * (re)-scan the scsi bus and reports scsi device info + * to the user if mode = 1 + */ +void scsi_scan(int mode) +{ + unsigned char i,perq,modi,lun; + unsigned long capacity,blksz; + ccb* pccb=(ccb *)&tempccb; + + if(mode==1) { + printf(" SCSI: scanning bus for devices...\n"); + } + for(i=0;itarget=i; + for(lun=0;lunlun=lun; + pccb->pdata=(unsigned char *)&tempbuff; + pccb->datalen=512; + scsi_setup_inquiry(pccb); + if(scsi_exec(pccb)!=TRUE) { + if(pccb->contr_stat==SCSI_SEL_TIME_OUT) { + PRINTF("Selection timeout ID %d\n",pccb->target); + continue; /* selection timeout => assuming no device present */ + } + scsi_print_error(pccb); + continue; + } + perq=tempbuff[0]; + modi=tempbuff[1]; + if((perq & 0x1f)==0x1f) { + continue; /* skip unknown devices */ + } + if((modi&0x80)==0x80) /* drive is removable */ + scsi_dev_desc[scsi_max_devs].removable=TRUE; + /* get info for this device */ + scsi_ident_cpy(&scsi_dev_desc[scsi_max_devs].vendor[0],&tempbuff[8],8); + scsi_ident_cpy(&scsi_dev_desc[scsi_max_devs].product[0],&tempbuff[16],16); + scsi_ident_cpy(&scsi_dev_desc[scsi_max_devs].revision[0],&tempbuff[32],4); + scsi_dev_desc[scsi_max_devs].target=pccb->target; + scsi_dev_desc[scsi_max_devs].lun=pccb->lun; + + pccb->datalen=0; + scsi_setup_test_unit_ready(pccb); + if(scsi_exec(pccb)!=TRUE) { + if(scsi_dev_desc[scsi_max_devs].removable==TRUE) { + scsi_dev_desc[scsi_max_devs].type=perq; + goto removable; + } + scsi_print_error(pccb); + continue; + } + pccb->datalen=8; + scsi_setup_read_capacity(pccb); + if(scsi_exec(pccb)!=TRUE) { + scsi_print_error(pccb); + continue; + } + capacity=((unsigned long)tempbuff[0]<<24)|((unsigned long)tempbuff[1]<<16)| + ((unsigned long)tempbuff[2]<<8)|((unsigned long)tempbuff[3]); + blksz=((unsigned long)tempbuff[4]<<24)|((unsigned long)tempbuff[5]<<16)| + ((unsigned long)tempbuff[6]<<8)|((unsigned long)tempbuff[7]); + scsi_dev_desc[scsi_max_devs].lba=capacity; + scsi_dev_desc[scsi_max_devs].blksz=blksz; + scsi_dev_desc[scsi_max_devs].type=perq; + init_part(&scsi_dev_desc[scsi_max_devs]); +removable: + if(mode==1) { + printf (" Device %d: ", scsi_max_devs); + dev_print(&scsi_dev_desc[scsi_max_devs]); + } /* if mode */ + scsi_max_devs++; + } /* next LUN */ + } + if(scsi_max_devs>0) + scsi_curr_dev=0; + else + scsi_curr_dev=-1; +} + + + +void scsi_init(void) +{ + int busdevfunc; + + busdevfunc=PCI_Find_Device(SCSI_VEND_ID,SCSI_DEV_ID); /* get PCI Device ID */ + if(busdevfunc==-1) { + printf("Error SCSI Controller (%04X,%04X) not found\n",SCSI_VEND_ID,SCSI_DEV_ID); + return; + } + scsi_low_level_init(busdevfunc); + scsi_scan(1); +} + +block_dev_desc_t * scsi_get_dev(int dev) +{ + return((block_dev_desc_t *)&scsi_dev_desc[dev]); +} + + + +/****************************************************************************** + * scsi boot command intepreter. Derived from diskboot + */ +void do_scsiboot (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) +{ + char *boot_device = NULL; + char *ep; + int dev, part; + ulong cnt; + ulong addr; + disk_partition_t info; + image_header_t *hdr; + + switch (argc) { + case 1: + addr = CFG_LOAD_ADDR; + boot_device = getenv ("bootdevice"); + break; + case 2: + addr = simple_strtoul(argv[1], NULL, 16); + boot_device = getenv ("bootdevice"); + break; + case 3: + addr = simple_strtoul(argv[1], NULL, 16); + boot_device = argv[2]; + break; + default: + printf ("Usage:\n%s\n", cmdtp->usage); + return; + } + + if (!boot_device) { + puts ("\n** No boot device **\n"); + return; + } + + dev = simple_strtoul(boot_device, &ep, 16); + printf("booting from dev %d\n",dev); + if (scsi_dev_desc[dev].type == DEV_TYPE_UNKNOWN) { + printf ("\n** Device %d not available\n", dev); + return; + } + + if (*ep) { + if (*ep != ':') { + puts ("\n** Invalid boot device, use `dev[:part]' **\n"); + return; + } + part = simple_strtoul(++ep, NULL, 16); + } + if (get_partition_info (&scsi_dev_desc[dev], part, &info)) { + printf("error reading partinfo\n"); + return; + } + if (strncmp(info.type, BOOT_PART_TYPE, sizeof(info.type)) != 0) { + printf ("\n** Invalid partition type \"%.32s\"" + " (expect \"" BOOT_PART_TYPE "\")\n", + info.type); + return; + } + + printf ("\nLoading from SCSI device %d, partition %d: " + "Name: %.32s Type: %.32s\n", + dev, part, info.name, info.type); + + PRINTF ("First Block: %ld, # of blocks: %ld, Block Size: %ld\n", + info.start, info.size, info.blksz); + + if (scsi_read (dev, info.start, 1, (ulong *)addr) != 1) { + printf ("** Read error on %d:%d\n", dev, part); + return; + } + + hdr = (image_header_t *)addr; + + if (hdr->ih_magic == IH_MAGIC) { + + print_image_hdr (hdr); + cnt = (hdr->ih_size + sizeof(image_header_t)); + cnt += info.blksz - 1; + cnt /= info.blksz; + cnt -= 1; + } else { + cnt = info.size - 1; + } + + if (scsi_read (dev, info.start+1, cnt, + (ulong *)(addr+info.blksz)) != cnt) { + printf ("** Read error on %d:%d\n", dev, part); + return; + } + /* Loading ok, update default load address */ + load_addr = addr; + /* Check if we should attempt an auto-start */ + if (((ep = getenv("autostart")) != NULL) && (strcmp(ep,"yes") == 0)) { + char *local_args[2]; + extern void do_bootm (cmd_tbl_t *, bd_t *, int, int, char *[]); + local_args[0] = argv[0]; + local_args[1] = NULL; + printf ("Automatic boot of image at addr 0x%08lX ...\n", addr); + do_bootm (cmdtp, bd, 0, 1, local_args); + } +} + +/********************************************************************************* + * scsi command intepreter + */ +void do_scsi (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) +{ + switch (argc) { + case 0: + case 1: printf ("Usage:\n%s\n", cmdtp->usage); return; + case 2: + if (strncmp(argv[1],"res",3) == 0) { + printf("\nReset SCSI\n"); + scsi_bus_reset(); + scsi_scan(1); + return; + } + if (strncmp(argv[1],"inf",3) == 0) { + int i; + for (i=0; i= CFG_SCSI_MAX_DEVICE)) { + printf("\nno SCSI devices available\n"); + return; + } + printf ("\n Device %d: ", scsi_curr_dev); + dev_print(&scsi_dev_desc[scsi_curr_dev]); + return; + } + if (strncmp(argv[1],"scan",4) == 0) { + scsi_scan(1); + return; + } + if (strncmp(argv[1],"part",4) == 0) { + int dev, ok; + for (ok=0, dev=0; devusage); + return; + case 3: + if (strncmp(argv[1],"dev",3) == 0) { + int dev = (int)simple_strtoul(argv[2], NULL, 10); + printf ("\nSCSI device %d: ", dev); + if (dev >= CFG_SCSI_MAX_DEVICE) { + printf("unknown device\n"); + return; + } + printf ("\n Device %d: ", dev); + dev_print(&scsi_dev_desc[dev]); + if(scsi_dev_desc[dev].type == DEV_TYPE_UNKNOWN) { + return; + } + scsi_curr_dev = dev; + printf("... is now current device\n"); + return; + } + if (strncmp(argv[1],"part",4) == 0) { + int dev = (int)simple_strtoul(argv[2], NULL, 10); + if(scsi_dev_desc[dev].type != DEV_TYPE_UNKNOWN) { + print_part(&scsi_dev_desc[dev]); + } + else { + printf ("\nSCSI device %d not available\n", dev); + } + return; + } + printf ("Usage:\n%s\n", cmdtp->usage); + return; + default: + /* at least 4 args */ + if (strcmp(argv[1],"read") == 0) { + ulong addr = simple_strtoul(argv[2], NULL, 16); + ulong blk = simple_strtoul(argv[3], NULL, 16); + ulong cnt = simple_strtoul(argv[4], NULL, 16); + ulong n; + printf ("\nSCSI read: device %d block # %ld, count %ld ... ", + scsi_curr_dev, blk, cnt); + n = scsi_read(scsi_curr_dev, blk, cnt, (ulong *)addr); + printf ("%ld blocks read: %s\n",n,(n==cnt) ? "OK" : "ERROR"); + return; + } + } /* switch */ + printf ("Usage:\n%s\n", cmdtp->usage); +} + +/**************************************************************************************** + * scsi_read + */ + +#define SCSI_MAX_READ_BLK 0xFFFF /* almost the maximum amount of the scsi_ext command.. */ + +ulong scsi_read(int device, ulong blknr, ulong blkcnt, ulong *buffer) +{ + ulong start,blks, buf_addr; + unsigned short smallblks; + ccb* pccb=(ccb *)&tempccb; + device&=0xff; + /* Setup device + */ + pccb->target=scsi_dev_desc[device].target; + pccb->lun=scsi_dev_desc[device].lun; + buf_addr=(unsigned long)buffer; + start=blknr; + blks=blkcnt; + PRINTF("\nscsi_read: dev %d startblk %lx, blccnt %lx buffer %lx\n",device,start,blks,(unsigned long)buffer); + do { + pccb->pdata=(unsigned char *)buf_addr; + if(blks>SCSI_MAX_READ_BLK) { + pccb->datalen=scsi_dev_desc[device].blksz * SCSI_MAX_READ_BLK; + smallblks=SCSI_MAX_READ_BLK; + scsi_setup_read_ext(pccb,start,smallblks); + start+=SCSI_MAX_READ_BLK; + blks-=SCSI_MAX_READ_BLK; + } + else { + pccb->datalen=scsi_dev_desc[device].blksz * blks; + smallblks=(unsigned short) blks; + scsi_setup_read_ext(pccb,start,smallblks); + start+=blks; + blks=0; + } + PRINTF("scsi_read_ext: startblk %lx, blccnt %x buffer %lx\n",start,smallblks,buf_addr); + if(scsi_exec(pccb)!=TRUE) { + scsi_print_error(pccb); + blkcnt-=blks; + break; + } + buf_addr+=pccb->datalen; + } while(blks!=0); + PRINTF("scsi_read_ext: end startblk %lx, blccnt %x buffer %lx\n",start,smallblks,buf_addr); + return(blkcnt); +} + +/* copy src to dest, skipping leading and trailing blanks + * and null terminate the string + */ +void scsi_ident_cpy (unsigned char *dest, unsigned char *src, unsigned int len) +{ + int start,end; + + start=0; + while(startstart) { + if(src[end]!=' ') + break; + end--; + } + for( ; start<=end; start++) { + *dest++=src[start]; + } + *dest='\0'; +} + + + +/* Trim trailing blanks, and NUL-terminate string + */ +void scsi_trim_trail (unsigned char *str, unsigned int len) +{ + unsigned char *p = str + len - 1; + + while (len-- > 0) { + *p-- = '\0'; + if (*p != ' ') { + return; + } + } +} + + +/************************************************************************************ + * Some setup (fill-in) routines + */ +void scsi_setup_test_unit_ready(ccb * pccb) +{ + pccb->cmd[0]=SCSI_TST_U_RDY; + pccb->cmd[1]=pccb->lun<<5; + pccb->cmd[2]=0; + pccb->cmd[3]=0; + pccb->cmd[4]=0; + pccb->cmd[5]=0; + pccb->cmdlen=6; + pccb->msgout[0]=SCSI_IDENTIFY; /* NOT USED */ +} + +void scsi_setup_read_capacity(ccb * pccb) +{ + pccb->cmd[0]=SCSI_RD_CAPAC; + pccb->cmd[1]=pccb->lun<<5; + pccb->cmd[2]=0; + pccb->cmd[3]=0; + pccb->cmd[4]=0; + pccb->cmd[5]=0; + pccb->cmd[6]=0; + pccb->cmd[7]=0; + pccb->cmd[8]=0; + pccb->cmd[9]=0; + pccb->cmdlen=10; + pccb->msgout[0]=SCSI_IDENTIFY; /* NOT USED */ + +} + +void scsi_setup_read_ext(ccb * pccb, unsigned long start, unsigned short blocks) +{ + pccb->cmd[0]=SCSI_READ10; + pccb->cmd[1]=pccb->lun<<5; + pccb->cmd[2]=((unsigned char) (start>>24))&0xff; + pccb->cmd[3]=((unsigned char) (start>>16))&0xff; + pccb->cmd[4]=((unsigned char) (start>>8))&0xff; + pccb->cmd[5]=((unsigned char) (start))&0xff; + pccb->cmd[6]=0; + pccb->cmd[7]=((unsigned char) (blocks>>8))&0xff; + pccb->cmd[8]=(unsigned char) blocks & 0xff; + pccb->cmd[6]=0; + pccb->cmdlen=10; + pccb->msgout[0]=SCSI_IDENTIFY; /* NOT USED */ + PRINTF("scsi_setup_read_ext: cmd: %02X %02X startblk %02X%02X%02X%02X blccnt %02X%02X\n", + pccb->cmd[0],pccb->cmd[1], + pccb->cmd[2],pccb->cmd[3],pccb->cmd[4],pccb->cmd[5], + pccb->cmd[7],pccb->cmd[8]); +} + +void scsi_setup_read6(ccb * pccb, unsigned long start, unsigned short blocks) +{ + pccb->cmd[0]=SCSI_READ6; + pccb->cmd[1]=pccb->lun<<5 | (((unsigned char)(start>>16))&0x1f); + pccb->cmd[2]=((unsigned char) (start>>8))&0xff; + pccb->cmd[3]=((unsigned char) (start))&0xff; + pccb->cmd[4]=(unsigned char) blocks & 0xff; + pccb->cmd[5]=0; + pccb->cmdlen=6; + pccb->msgout[0]=SCSI_IDENTIFY; /* NOT USED */ + PRINTF("scsi_setup_read6: cmd: %02X %02X startblk %02X%02X blccnt %02X\n", + pccb->cmd[0],pccb->cmd[1], + pccb->cmd[2],pccb->cmd[3],pccb->cmd[4]); +} + + +void scsi_setup_inquiry(ccb * pccb) +{ + pccb->cmd[0]=SCSI_INQUIRY; + pccb->cmd[1]=pccb->lun<<5; + pccb->cmd[2]=0; + pccb->cmd[3]=0; + if(pccb->datalen>255) + pccb->cmd[4]=255; + else + pccb->cmd[4]=(unsigned char)pccb->datalen; + pccb->cmd[5]=0; + pccb->cmdlen=6; + pccb->msgout[0]=SCSI_IDENTIFY; /* NOT USED */ +} + +#endif /* #if (CONFIG_COMMANDS & CFG_CMD_SCSI) */ + + diff --git a/common/command.c b/common/command.c index 5447686..ec6c46f 100644 --- a/common/command.c +++ b/common/command.c @@ -48,11 +48,14 @@ #include #include /* board special functions */ +#include /* Floppy support */ +#include #ifdef CONFIG_HYMOD #include #endif + #include /* @@ -200,6 +203,8 @@ cmd_tbl_t cmd_tbl[] = { CMD_TBL_RARPB CMD_TBL_DHCP CMD_TBL_DISK + CMD_TBL_SCSIBOOT + CMD_TBL_FDC CMD_TBL_BOOTD CMD_TBL_LOADS CMD_TBL_LOADB @@ -225,6 +230,7 @@ cmd_tbl_t cmd_tbl[] = { CMD_TBL_IRQINFO CMD_TBL_CONINFO CMD_TBL_IDE + CMD_TBL_SCSI CMD_TBL_PINIT CMD_TBL_I2C CMD_TBL_EEPROM @@ -263,7 +269,6 @@ cmd_tbl_t cmd_tbl[] = { CMD_TBL_VERS CMD_TBL_HELP CMD_TBL_QUES - CMD_TBL_DIS CMD_TBL_ASM CMD_TBL_BREAK @@ -272,7 +277,6 @@ cmd_tbl_t cmd_tbl[] = { CMD_TBL_STEP CMD_TBL_NEXT CMD_TBL_RDUMP - /* the following entry terminates this table */ MK_CMD_TBL_ENTRY( NULL, 0, 0, 0, NULL, NULL, NULL ) }; diff --git a/common/console.c b/common/console.c index 748d33c..e416270 100644 --- a/common/console.c +++ b/common/console.c @@ -26,6 +26,23 @@ #include #include +#ifdef CFG_CONSOLE_IS_IN_ENV +/* + * if overwrite_console returns 1, the stdin, stderr and stdout + * are switched to the serial port, else the settings in the + * environment are used + */ +#ifdef CFG_CONSOLE_OVERWRITE_ROUTINE +extern int overwrite_console(void); +#else +int overwrite_console(void) +{ + return (0); +} +#endif + +#endif /* CFG_CONSOLE_IS_IN_ENV */ + static int console_setfile(int file, device_t *dev) { int error = 0; @@ -38,19 +55,19 @@ static int console_setfile(int file, device_t *dev) case stdin: case stdout: case stderr: - // Start new device + /* Start new device */ if (dev->start) { error = dev->start() ; - // If it's not started dont use it + /* If it's not started dont use it */ if (error < 0) break; } - // Assign the new device (leaving the existing one started) + /* Assign the new device (leaving the existing one started) */ stdio_devices[file] = dev ; - // Update monitor functions (to use the console stuff by other applications) + /* Update monitor functions (to use the console stuff by other applications) */ switch (file){ case stdin: bd_ptr->bi_mon_fnc->getc = dev->getc ; @@ -64,13 +81,13 @@ static int console_setfile(int file, device_t *dev) } break; - default: // Invalid file ID + default: /* Invalid file ID */ error = -1 ; } return error ; } -//** PPCBOOT INITIAL CONSOLE-NOT COMPATIBLE FUNCTIONS ************************* +/** PPCBOOT INITIAL CONSOLE-NOT COMPATIBLE FUNCTIONS *************************/ void serial_printf(const char *fmt, ...) { @@ -131,21 +148,21 @@ void fprintf(int file, const char *fmt, ...) i = vsprintf(printbuffer, fmt, args); va_end(args); - // Send to desired file + /* Send to desired file */ fputs(file, printbuffer); } -//** PPCBOOT INITIAL CONSOLE-COMPATIBLE FUNCTION ***************************** +/** PPCBOOT INITIAL CONSOLE-COMPATIBLE FUNCTION *****************************/ int getc(void) { init_data_t *idata = (init_data_t *)(CFG_INIT_RAM_ADDR + CFG_INIT_DATA_OFFSET); if (idata->relocated) - // Get from the standard input + /* Get from the standard input */ return fgetc (stdin); - // Send directly to the handler + /* Send directly to the handler */ return serial_getc(); } @@ -154,10 +171,10 @@ int tstc(void) init_data_t *idata = (init_data_t *)(CFG_INIT_RAM_ADDR + CFG_INIT_DATA_OFFSET); if (idata->relocated) - // Test the standard input + /* Test the standard input */ return ftstc (stdin); - // Send directly to the handler + /* Send directly to the handler */ return serial_tstc(); } @@ -166,10 +183,10 @@ void putc(const char c) init_data_t *idata = (init_data_t *)(CFG_INIT_RAM_ADDR + CFG_INIT_DATA_OFFSET); if (idata->relocated) - // Send to the standard output + /* Send to the standard output */ fputc (stdout, c); else - // Send directly to the handler + /* Send directly to the handler */ serial_putc(c); } @@ -178,10 +195,10 @@ void puts(const char *s) init_data_t *idata = (init_data_t *)(CFG_INIT_RAM_ADDR + CFG_INIT_DATA_OFFSET); if (idata->relocated) - // Send to the standard output + /* Send to the standard output */ fputs (stdout, s); else - // Send directly to the handler + /* Send directly to the handler */ serial_puts(s); } @@ -199,11 +216,11 @@ void printf(const char *fmt, ...) i = vsprintf(printbuffer, fmt, args); va_end(args); - // Print the string + /* Print the string */ puts (printbuffer); } -// test if ctrl-c was pressed. +/* test if ctrl-c was pressed */ static int ctrlc_disabled = 0; /* see disable_ctrl() */ static int ctrlc_was_pressed = 0; int @@ -248,13 +265,13 @@ clear_ctrlc(void) ctrlc_was_pressed = 0; } -//** PPCBOOT INIT FUNCTIONS ************************************************* +/** PPCBOOT INIT FUNCTIONS *************************************************/ int console_assign (int file, char *devname) { int flag , i; - // Check for valid file + /* Check for valid file */ switch(file){ case stdin: flag = DEV_FLAGS_INPUT ; @@ -267,7 +284,7 @@ int console_assign (int file, char *devname) return -1 ; } - // Check for valid device name + /* Check for valid device name */ for(i=1; i<=ListNumItems(devlist); i++) { @@ -285,12 +302,12 @@ int console_assign (int file, char *devname) return -1 ; } -// Called before relocation - use serial functions +/* Called before relocation - use serial functions */ void console_init_f (void) { init_data_t *idata = (init_data_t *)(CFG_INIT_RAM_ADDR + CFG_INIT_DATA_OFFSET); - idata->relocated = 0 ; // Use these pointers before relocation + idata->relocated = 0 ; /* Use these pointers before relocation */ idata->bi_mon_fnc.getc = serial_getc; idata->bi_mon_fnc.tstc = serial_tstc; idata->bi_mon_fnc.putc = serial_putc; @@ -298,17 +315,106 @@ void console_init_f (void) idata->bi_mon_fnc.printf = serial_printf; } -// Called after the relocation - use desierd console functions +#ifdef CFG_CONSOLE_IS_IN_ENV +/* search a device */ +device_t *search_device(int flags, char * name) +{ + int i,items; + device_t *dev = NULL; + items = ListNumItems(devlist); + if(name==NULL) + return dev; + for (i=1; i<=items; i++) { + dev = ListGetPtrToItem(devlist, i) ; + if ((dev->flags & flags) && (strcmp(name,dev->name)==0)) { + break; + } + } + return dev; +} +#endif /* CFG_CONSOLE_IS_IN_ENV */ + +#ifdef CFG_CONSOLE_IS_IN_ENV +/* Called after the relocation - use desierd console functions */ void console_init_r (ulong reloc_offset) { - init_data_t *idata = (init_data_t *)(CFG_INIT_RAM_ADDR + CFG_INIT_DATA_OFFSET); - device_t *inputdev = NULL, *outputdev = NULL ; - int i, items = ListNumItems(devlist) ; + init_data_t *idata = (init_data_t *)(CFG_INIT_RAM_ADDR + CFG_INIT_DATA_OFFSET); + device_t *inputdev = NULL, *outputdev = NULL, *errdev = NULL; + /* sdtin stdout and stderr are in environment */ + /* scan for it */ + char *stdinname = getenv("stdin"); + char *stdoutname = getenv("stdout"); + char *stderrname = getenv("stderr"); + + /* Global pointer to monitor structure (updated by the console stuff) */ + bd_ptr->bi_mon_fnc = &idata->bi_mon_fnc ; + + if(overwrite_console()==0) { /* if not overwritten by config switch */ + inputdev=search_device(DEV_FLAGS_INPUT,stdinname); + outputdev=search_device(DEV_FLAGS_OUTPUT,stdoutname); + errdev=search_device(DEV_FLAGS_OUTPUT,stderrname); + } + /* if the devices are overwritten or not found, use default device */ + if(inputdev==NULL) + inputdev=search_device(DEV_FLAGS_INPUT,"serial"); + if(outputdev==NULL) + outputdev=search_device(DEV_FLAGS_OUTPUT,"serial"); + if(errdev==NULL) + errdev=search_device(DEV_FLAGS_OUTPUT,"serial"); + /* Initializes output console first */ + if (outputdev != NULL) + console_setfile(stdout, outputdev); + if (errdev != NULL) + console_setfile(stderr, errdev); + if (inputdev != NULL) + console_setfile(stdin, inputdev); + + /* Print informations */ + printf(" In: "); + if (stdio_devices[stdin] == NULL) + printf("No input devices available!\n"); + else + printf("%s\n", stdio_devices[stdin]->name); + + printf(" Out: "); + if (stdio_devices[stdout] == NULL) + printf("No output devices available!\n"); + else + printf("%s\n", stdio_devices[stdout]->name); + + printf(" Err: "); + if (stdio_devices[stderr] == NULL) + printf("No error devices available!\n"); + else + printf("%s\n", stdio_devices[stderr]->name); + +#ifdef CFG_CONSOLE_ENV_OVERWRITE + /* set the environment variables (will overwrite previous env settings) */ + for (i=0; i<3; i++) + setenv(stdio_names[i], stdio_devices[i]->name); +#endif /* CFG_CONSOLE_ENV_OVERWRITE */ + /* If nothing usable installed, use only the initial console */ + if ((stdio_devices[stdin] == NULL) && (stdio_devices[stdout] == NULL)) + return ; + + /* Set the relocation flag */ + idata->relocated = reloc_offset; +} - // Global pointer to monitor structure (updated by the console stuff) - bd_ptr->bi_mon_fnc = &idata->bi_mon_fnc ; - // Scan devices looking for input and output devices +#else /* CFG_CONSOLE_IS_IN_ENV */ +/* Called after the relocation - use desierd console functions */ +void console_init_r (ulong reloc_offset) +{ + init_data_t *idata = (init_data_t *)(CFG_INIT_RAM_ADDR + CFG_INIT_DATA_OFFSET); + device_t *inputdev = NULL, *outputdev = NULL ; + int i, items = ListNumItems(devlist) ; + + /* Global pointer to monitor structure (updated by the console stuff) */ + bd_ptr->bi_mon_fnc = &idata->bi_mon_fnc ; + + + /* Scan devices looking for input and output devices */ for (i=1; (i<=items) && ((inputdev == NULL) || (outputdev == NULL)); i++) { device_t *dev = ListGetPtrToItem(devlist, i) ; @@ -320,18 +426,18 @@ void console_init_r (ulong reloc_offset) outputdev = dev ; } - // Initializes output console first + /* Initializes output console first */ if (outputdev != NULL) { console_setfile(stdout, outputdev); console_setfile(stderr, outputdev); } - // Initializes input console + /* Initializes input console */ if (inputdev != NULL) console_setfile(stdin, inputdev); - // Print informations + /* Print informations */ printf(" In: "); if (stdio_devices[stdin] == NULL) printf("No input devices available!\n"); @@ -350,14 +456,17 @@ void console_init_r (ulong reloc_offset) else printf("%s\n", stdio_devices[stderr]->name); - // Setting environment variables + /* Setting environment variables */ for (i=0; i<3; i++) setenv(stdio_names[i], stdio_devices[i]->name); - // If nothing usable installed, use only the initial console + /* If nothing usable installed, use only the initial console */ if ((stdio_devices[stdin] == NULL) && (stdio_devices[stdout] == NULL)) return ; - // Set the relocation flag + /* Set the relocation flag */ idata->relocated = reloc_offset; } + +#endif /* CFG_CONSOLE_IS_IN_ENV */ + diff --git a/common/devices.c b/common/devices.c index f782596..7f4a1ff 100644 --- a/common/devices.c +++ b/common/devices.c @@ -37,7 +37,9 @@ extern int drv_video_init(void); #ifdef CONFIG_WL_4PPM_KEYBOARD extern int drv_wlkbd_init(void); #endif - +#ifdef CONFIG_ISA_KEYBOARD +extern int drv_isa_kbd_init(void); +#endif // ************************************************************************** // * SYSTEM DRIVERS // ************************************************************************** @@ -71,6 +73,7 @@ int device_register (device_t *dev) return 0 ; } + int devices_init (ulong relocation_offset) { int i; @@ -95,6 +98,9 @@ int devices_init (ulong relocation_offset) #endif #ifdef CONFIG_WL_4PPM_KEYBOARD drv_wlkbd_init(); +#endif +#ifdef CONFIG_ISA_KEYBOARD + drv_isa_kbd_init(); #endif drv_system_init(); diff --git a/common/main.c b/common/main.c index fe33a8f..301b8b1 100644 --- a/common/main.c +++ b/common/main.c @@ -31,6 +31,7 @@ static int parse_line (char *, char *[]); #if (CONFIG_BOOTDELAY >= 0) static int abortboot(int); #endif +#undef DEBUG_PARSER char console_buffer[CFG_CBSIZE]; /* console I/O buffer */ @@ -178,7 +179,7 @@ static __inline__ int abortboot(int bootdelay) return abort; } # endif /* CONFIG_AUTOBOOT_KEYED */ -#endif /* CONFIG_BOOTDELAY >= 0 */ +#endif /* CONFIG_BOOTDELAY >= 0 */ /****************************************************************************/ @@ -191,7 +192,7 @@ void main_loop(bd_t *bd) #if (CONFIG_BOOTDELAY >= 0) char *s = getenv ("bootdelay"); - int bootdelay = s ? (int)simple_strtoul(s, NULL, 10) : 0; + int bootdelay = s ? (int)simple_strtol(s, NULL, 10) : 0; #if 0 printf ("### main_loop entered:\n\n"); diff --git a/cpu/mpc74xx/start.S b/cpu/mpc74xx/start.S index 224e2de..c267bff 100644 --- a/cpu/mpc74xx/start.S +++ b/cpu/mpc74xx/start.S @@ -42,6 +42,10 @@ #include #include +#ifndef CONFIG_IDENT_STRING +#define CONFIG_IDENT_STRING "" +#endif + /* We don't want the MMU yet. */ #undef MSR_KERNEL @@ -74,7 +78,9 @@ .long 0x27051956 /* PPCBOOT Magic Number */ .globl version_string version_string: - .ascii PPCBOOT_VERSION, " (", __DATE__, " - ", __TIME__, ")\0" + .ascii PPCBOOT_VERSION + .ascii " (", __DATE__, " - ", __TIME__, ")" + .ascii CONFIG_IDENT_STRING, "\0" #if 0 /* this is used in the led on/off routines */ diff --git a/cpu/mpc8240/start.S b/cpu/mpc8240/start.S index fca61d8..672659c 100644 --- a/cpu/mpc8240/start.S +++ b/cpu/mpc8240/start.S @@ -49,6 +49,10 @@ #include #include +#ifndef CONFIG_IDENT_STRING +#define CONFIG_IDENT_STRING "" +#endif + /* We don't want the MMU yet. */ #undef MSR_KERNEL @@ -83,7 +87,9 @@ .long 0x27051956 /* PPCBOOT Magic Number */ .globl version_string version_string: - .ascii PPCBOOT_VERSION, " (", __DATE__, " - ", __TIME__, ")\0" + .ascii PPCBOOT_VERSION + .ascii " (", __DATE__, " - ", __TIME__, ")" + .ascii CONFIG_IDENT_STRING, "\0" . = EXC_OFF_SYS_RESET .globl _start diff --git a/cpu/mpc8260/start.S b/cpu/mpc8260/start.S index 6189474..fcd0110 100644 --- a/cpu/mpc8260/start.S +++ b/cpu/mpc8260/start.S @@ -38,6 +38,10 @@ #include #include +#ifndef CONFIG_IDENT_STRING +#define CONFIG_IDENT_STRING "" +#endif + /* We don't want the MMU yet. */ #undef MSR_KERNEL @@ -79,7 +83,9 @@ .data .globl version_string version_string: - .ascii PPCBOOT_VERSION, " (", __DATE__, " - ", __TIME__, ")\0" + .ascii PPCBOOT_VERSION + .ascii " (", __DATE__, " - ", __TIME__, ")" + .ascii CONFIG_IDENT_STRING, "\0" /* * Hard Reset Configuration Word (HRCW) table diff --git a/cpu/mpc8xx/start.S b/cpu/mpc8xx/start.S index 5abd1b9..db470ed 100644 --- a/cpu/mpc8xx/start.S +++ b/cpu/mpc8xx/start.S @@ -50,6 +50,10 @@ #include #include +#ifndef CONFIG_IDENT_STRING +#define CONFIG_IDENT_STRING "" +#endif + /* We don't want the MMU yet. */ #undef MSR_KERNEL @@ -84,7 +88,9 @@ .long 0x27051956 /* PPCBOOT Magic Number */ .globl version_string version_string: - .ascii PPCBOOT_VERSION, " (", __DATE__, " - ", __TIME__, ")\0" + .ascii PPCBOOT_VERSION + .ascii " (", __DATE__, " - ", __TIME__, ")" + .ascii CONFIG_IDENT_STRING, "\0" . = EXC_OFF_SYS_RESET .globl _start diff --git a/cpu/ppc4xx/405gp_pci.c b/cpu/ppc4xx/405gp_pci.c index fbe4b58..cc2953d 100644 --- a/cpu/ppc4xx/405gp_pci.c +++ b/cpu/ppc4xx/405gp_pci.c @@ -57,6 +57,7 @@ #include <405gp_pci.h> #include +#ifndef CONFIG_PIP405 void pciinfo(int bus_no); @@ -903,3 +904,4 @@ pciBheaderPrint(PCI_HEADER_BRIDGE * pB) #endif /* CONFIG_PCI */ #endif /* CONFIG_PPC405GP */ +#endif /* CONFIG_PIP405 */ diff --git a/cpu/ppc4xx/i2c.c b/cpu/ppc4xx/i2c.c index 2f05cee..481a3bc 100644 --- a/cpu/ppc4xx/i2c.c +++ b/cpu/ppc4xx/i2c.c @@ -270,29 +270,91 @@ int i2c_send(unsigned char address, void i2c_read (uchar *addr, int alen, uchar *buffer, int len) { - if (alen != 2) { + + if ((alen != 2) && (alen != 3)) { printf ("I2C read: addr len %d not supported\n", alen); return; } - i2c_send (addr[0] << 1, 1, addr+1); + + i2c_send (addr[0] << 1, alen-1, addr+1); i2c_receive ((addr[0] << 1) | 0x01, len, buffer); } +#ifndef CFG_EEPROM_PAGE_WRITE_ENABLE + void i2c_write (uchar *addr, int alen, uchar *buffer, int len) { - uchar xbuf[2]; + uchar xbuf[3]; + unsigned short paddr; + + if (alen == 2) { + /* write with ack polling */ + while (len-- > 0) { + xbuf[0] = addr[1]++; /* increase write offset */ + xbuf[1] = *buffer++; + /* single write + ack polling */ + while (i2c_send (addr[0] << 1, 2, xbuf) != 0) { + udelay(100); + } + } + return; + } - if (alen != 2) { - printf ("I2C write: addr len %d not supported\n", alen); + paddr=(addr[1]<<8)+addr[2]; + + if (alen == 3) { + /* write with ack polling */ + while (len-- > 0) { + xbuf[0] = (uchar)(paddr>>8); /* High addr */ + xbuf[1] = (uchar)(paddr&0xff); /* Low addr */ + paddr++; + xbuf[2] = *buffer++; + /* single write + ack polling */ + while (i2c_send (addr[0] << 1, 3, xbuf) != 0) { + udelay(100); + } + } return; } - /* write with ack polling */ - /* XXX this should be improved to allow page write mode XXX - wd */ - while (len-- > 0) { - xbuf[0] = addr[1]++; /* increase write offset */ - xbuf[1] = *buffer++; - while (i2c_send (addr[0] << 1, 2, xbuf) != 0) /* single write + ack polling */ - udelay(100); + printf ("I2C write: addr len %d not supported\n", alen); +} + +#else /* CFG_EEPROM_PAGE_WRITE_ENABLE */ + +void i2c_write (uchar *addr, int alen, uchar *buffer, int len) +{ + /* buffer for one page + addresses */ + uchar wbuffer[(1< #include +#ifndef CONFIG_IDENT_STRING +#define CONFIG_IDENT_STRING "" +#endif + /* We don't want the MMU yet. */ #undef MSR_KERNEL @@ -105,7 +109,9 @@ .long 0x27051956 /* PPCBOOT Magic Number */ .globl version_string version_string: - .ascii PPCBOOT_VERSION, " (", __DATE__, " - ", __TIME__, ")\0" + .ascii PPCBOOT_VERSION + .ascii " (", __DATE__, " - ", __TIME__, ")" + .ascii CONFIG_IDENT_STRING, "\0" . = EXC_OFF_SYS_RESET .globl _start @@ -274,10 +280,10 @@ boot_warm: //----------------------------------------------------------------------- bl sdram_init - addis r1,r0,CFG_INIT_RAM_ADDR@h + addis r1,r0,CFG_INIT_RAM_ADDR@h ori r1,r1,CFG_INIT_SP_OFFSET /* set up the stack in SDRAM */ - GET_GOT /* initialize GOT access */ + GET_GOT /* initialize GOT access */ bl board_init_f /* run first part of init code (from Flash) */ diff --git a/disk/Makefile b/disk/Makefile index 449449e..7b80174 100644 --- a/disk/Makefile +++ b/disk/Makefile @@ -27,7 +27,7 @@ include $(TOPDIR)/config.mk LIB = libdisk.a -OBJS = part.o part_mac.o part_dos.o +OBJS = part.o part_mac.o part_dos.o part_iso.o all: $(LIB) diff --git a/disk/part.c b/disk/part.c index a0bbab3..e6d6e9a 100644 --- a/disk/part.c +++ b/disk/part.c @@ -26,42 +26,109 @@ #include #include -#if (CONFIG_COMMANDS & CFG_CMD_IDE) +#undef PART_DEBUG -#if defined(CONFIG_MAC_PARTITION) || defined(CONFIG_DOS_PARTITION) +#ifdef PART_DEBUG +#define PRINTF(fmt,args...) printf (fmt ,##args) +#else +#define PRINTF(fmt,args...) +#endif + +#if (CONFIG_COMMANDS & CFG_CMD_IDE) || (CONFIG_COMMANDS & CFG_CMD_SCSI) + +/* stdlib.h causes some compatibility problems; should fixe these! -- wd */ +#ifndef __ldiv_t_defined +typedef struct { + long int quot; /* Quotient */ + long int rem; /* Remainder */ +} ldiv_t; +extern ldiv_t ldiv (long int __numer, long int __denom); +# define __ldiv_t_defined 1 +#endif + + +/* ------------------------------------------------------------------------- */ +/* + * reports device info to the user + */ +void dev_print(block_dev_desc_t *dev_desc) +{ + ldiv_t mb, gb; + ulong lba512; /* number of blocks if 512bytes block size */ + if (dev_desc->type==DEV_TYPE_UNKNOWN) { + printf("not available\n"); + return; + } + if(dev_desc->if_type==IF_TYPE_SCSI) + printf ("(%d:%d) ", dev_desc->target,dev_desc->lun); + if(dev_desc->if_type==IF_TYPE_IDE) + printf ("Model: %s Firm: %s Ser#: %s\n", dev_desc->vendor,dev_desc->revision,dev_desc->product); + else + printf ("Vendor: %s Prod.: %s Rev: %s\n", dev_desc->vendor,dev_desc->product,dev_desc->revision); + printf(" Type: "); + if(dev_desc->removable) + printf ("Removable "); + switch(dev_desc->type & 0x1F) { + case DEV_TYPE_HARDDISK: printf("Hard Disk"); break; + case DEV_TYPE_CDROM: printf("CD ROM"); break; + case DEV_TYPE_OPDISK: printf("Optical Device"); break; + case DEV_TYPE_TAPE: printf("Tape"); break; + default: printf("# %02X #",dev_desc->type & 0x1F); break; + } + printf("\n"); + if((dev_desc->lba * dev_desc->blksz)>0L) { + lba512=(dev_desc->lba * (dev_desc->blksz/512)); + mb = ldiv(lba512, 2048); /* (1024 *1024 / 512 MB */ + /* round to 1 digit */ + mb.rem *= 10 * 512; + mb.rem += 512 * 1024; + mb.rem /= 1024 * 1024; + gb = ldiv(10 * mb.quot + mb.rem, 10240); + gb.rem += 512; + gb.rem /= 1024; + printf (" Capacity: %ld.%ld MB = %ld.%ld GB (%ld x %ld)\n",mb.quot, mb.rem, gb.quot, gb.rem,dev_desc->lba,dev_desc->blksz); + } + else { + printf (" Capacity: not available\n"); + } +} -#define PART_TYPE_UNKNOWN 0x00 -#define PART_TYPE_MAC 0x01 -#define PART_TYPE_DOS 0x02 -static char part_type [CFG_IDE_MAXDEVICE] = { PART_TYPE_UNKNOWN, }; -void init_part (int dev) +#if defined(CONFIG_MAC_PARTITION) || defined(CONFIG_DOS_PARTITION) || defined(CONFIG_ISO_PARTITION) + +void init_part (block_dev_desc_t * dev_desc) { +#ifdef CONFIG_ISO_PARTITION + if (test_part_iso(dev_desc) == 0) { + dev_desc->part_type = PART_TYPE_ISO; + return; + } +#endif + #ifdef CONFIG_MAC_PARTITION - if (test_part_mac(dev) == 0) { - part_type [dev] = PART_TYPE_MAC; + if (test_part_mac(dev_desc) == 0) { + dev_desc->part_type = PART_TYPE_MAC; return; } #endif #ifdef CONFIG_DOS_PARTITION - if (test_part_dos(dev) == 0) { - part_type [dev] = PART_TYPE_DOS; + if (test_part_dos(dev_desc) == 0) { + dev_desc->part_type = PART_TYPE_DOS; return; } #endif } -int get_partition_info (int dev, int part, disk_partition_t *info) + +int get_partition_info (block_dev_desc_t * dev_desc, int part, disk_partition_t *info) { - switch (part_type[dev]) { + switch(dev_desc->part_type) { #ifdef CONFIG_MAC_PARTITION case PART_TYPE_MAC: - if (get_partition_info_mac(dev,part,info) == 0) { -#ifdef DEBUG - printf ("## Valid MAC partition found ##\n"); -#endif + if (get_partition_info_mac(dev_desc,part,info) == 0) { + PRINTF ("## Valid MAC partition found ##\n"); return (0); } break; @@ -69,10 +136,17 @@ int get_partition_info (int dev, int part, disk_partition_t *info) #ifdef CONFIG_DOS_PARTITION case PART_TYPE_DOS: - if (get_partition_info_dos(dev,part,info) == 0) { -#ifdef DEBUG - printf ("## Valid DOS partition found ##\n"); + if (get_partition_info_dos(dev_desc,part,info) == 0) { + PRINTF ("## Valid DOS partition found ##\n"); + return (0); + } + break; #endif + +#ifdef CONFIG_ISO_PARTITION + case PART_TYPE_ISO: + if (get_partition_info_iso(dev_desc,part,info) == 0) { + PRINTF ("## Valid ISO boot partition found ##\n"); return (0); } break; @@ -83,39 +157,52 @@ int get_partition_info (int dev, int part, disk_partition_t *info) return (-1); } -static void print_part_header (const char *type, int dev) +static void print_part_header (const char *type, block_dev_desc_t * dev_desc) { - printf ("\nPartition Map for IDE device %d -- Partition Type: %s\n\n", - dev, type); + printf ("\nPartition Map for "); + switch(dev_desc->if_type) { + case IF_TYPE_IDE: printf("IDE"); break; + case IF_TYPE_SCSI: printf("SCSI"); break; + case IF_TYPE_ATAPI: printf("ATAPI"); break; + default: printf("UNKNOWN"); break; + } + printf(" device %d -- Partition Type: %s\n\n", + dev_desc->dev, type); } -void print_part (int dev) +void print_part (block_dev_desc_t * dev_desc) { - switch (part_type[dev]) { + + switch(dev_desc->part_type) { #ifdef CONFIG_MAC_PARTITION case PART_TYPE_MAC: -#ifdef DEBUG - printf ("## Testing for valid MAC partition ##\n"); -#endif - print_part_header ("MAC", dev); - print_part_mac (dev); + PRINTF ("## Testing for valid MAC partition ##\n"); + print_part_header ("MAC", dev_desc); + print_part_mac (dev_desc); return; #endif #ifdef CONFIG_DOS_PARTITION case PART_TYPE_DOS: -#ifdef DEBUG - printf ("## Testing for valid DOS partition ##\n"); + PRINTF ("## Testing for valid DOS partition ##\n"); + print_part_header ("DOS", dev_desc); + print_part_dos (dev_desc); + return; #endif - print_part_header ("DOS", dev); - print_part_dos (dev); + +#ifdef CONFIG_ISO_PARTITION + case PART_TYPE_ISO: + PRINTF ("## Testing for valid ISO Boot partition ##\n"); + print_part_header ("ISO", dev_desc); + print_part_iso (dev_desc); return; #endif } printf ("## Unknown partition table\n"); } -#else /* neither MAC nor DOS partition configured */ -# error neither CONFIG_MAC_PARTITION nor CONFIG_DOS_PARTITION configured! + +#else /* neither MAC nor DOS nor ISO partition configured */ +# error neither CONFIG_MAC_PARTITION nor CONFIG_DOS_PARTITION nor CONFIG_ISO_PARTITION configured! #endif -#endif /* (CONFIG_COMMANDS & CFG_CMD_IDE) */ +#endif /* (CONFIG_COMMANDS & CFG_CMD_IDE) || CONFIG_COMMANDS & CFG_CMD_SCSI) */ diff --git a/disk/part_dos.c b/disk/part_dos.c index 3949e6a..ff62614 100644 --- a/disk/part_dos.c +++ b/disk/part_dos.c @@ -36,7 +36,7 @@ #include #include "part_dos.h" -#if (CONFIG_COMMANDS & CFG_CMD_IDE) && defined(CONFIG_DOS_PARTITION) +#if ((CONFIG_COMMANDS & CFG_CMD_IDE) || (CONFIG_COMMANDS & CFG_CMD_SCSI)) && defined(CONFIG_DOS_PARTITION) /* Convert char[4] in little endian format to the host format integer */ @@ -66,11 +66,13 @@ static void print_one_part (dos_partition_t *p, int ext_part_sector, int part_nu (is_extended (p->sys_ind) ? " Extd" : "")); } -int test_part_dos (int dev) + + +int test_part_dos (block_dev_desc_t *dev_desc) { unsigned char buffer[DEFAULT_SECTOR_SIZE]; - if ((ide_read (dev, 0, 1, (ulong *) buffer) != 1) || + if ((dev_desc->block_read(dev_desc->dev, 0, 1, (ulong *) buffer) != 1) || (buffer[DOS_PART_MAGIC_OFFSET + 0] != 0x55) || (buffer[DOS_PART_MAGIC_OFFSET + 1] != 0xaa) ) { return (-1); @@ -78,19 +80,18 @@ int test_part_dos (int dev) return (0); } - /* Print a partition that is relative to its Extended partition table */ -static void print_partition_extended (int dev, int ext_part_sector, int relative, +static void print_partition_extended (block_dev_desc_t *dev_desc, int ext_part_sector, int relative, int part_num) { unsigned char buffer[DEFAULT_SECTOR_SIZE]; dos_partition_t *pt; int i; - if (ide_read (dev, ext_part_sector, 1, (ulong *) buffer) != 1) { + if (dev_desc->block_read(dev_desc->dev, ext_part_sector, 1, (ulong *) buffer) != 1) { printf ("** Can't read partition table on %d:%d **\n", - dev, ext_part_sector); + dev_desc->dev, ext_part_sector); return; } if (buffer[DOS_PART_MAGIC_OFFSET] != 0x55 || @@ -127,7 +128,7 @@ static void print_partition_extended (int dev, int ext_part_sector, int relative if (is_extended (pt->sys_ind)) { int lba_start = le32_to_int (pt->start4) + relative; - print_partition_extended (dev, lba_start, + print_partition_extended (dev_desc, lba_start, ext_part_sector == 0 ? lba_start : relative, part_num); @@ -140,7 +141,7 @@ static void print_partition_extended (int dev, int ext_part_sector, int relative /* Print a partition that is relative to its Extended partition table */ -static int get_partition_info_extended (int dev, int ext_part_sector, +static int get_partition_info_extended (block_dev_desc_t *dev_desc, int ext_part_sector, int relative, int part_num, int which_part, disk_partition_t *info) { @@ -148,9 +149,9 @@ static int get_partition_info_extended (int dev, int ext_part_sector, dos_partition_t *pt; int i; - if (ide_read (dev, ext_part_sector, 1, (ulong *) buffer) != 1) { + if (dev_desc->block_read (dev_desc->dev, ext_part_sector, 1, (ulong *) buffer) != 1) { printf ("** Can't read partition table on %d:%d **\n", - dev, ext_part_sector); + dev_desc->dev, ext_part_sector); return -1; } if (buffer[DOS_PART_MAGIC_OFFSET] != 0x55 || @@ -172,8 +173,18 @@ static int get_partition_info_extended (int dev, int ext_part_sector, info->blksz = 512; info->start = ext_part_sector + le32_to_int (pt->start4); info->size = le32_to_int (pt->size4); - sprintf (info->name, "hd%c%d\n", 'a' + dev, part_num); - // sprintf(info->type, "%d, pt->sys_ind); + switch(dev_desc->if_type) { + case IF_TYPE_IDE: + sprintf (info->name, "hd%c%d\n", 'a' + dev_desc->dev, part_num); + break; + case IF_TYPE_SCSI: + sprintf (info->name, "sd%c%d\n", 'a' + dev_desc->dev, part_num); + break; + default: + sprintf (info->name, "xx%c%d\n", 'a' + dev_desc->dev, part_num); + break; + } + /* sprintf(info->type, "%d, pt->sys_ind); */ sprintf (info->type, "PPCBoot"); return 0; } @@ -191,7 +202,7 @@ static int get_partition_info_extended (int dev, int ext_part_sector, if (is_extended (pt->sys_ind)) { int lba_start = le32_to_int (pt->start4) + relative; - return get_partition_info_extended (dev, lba_start, + return get_partition_info_extended (dev_desc, lba_start, ext_part_sector == 0 ? lba_start : relative, part_num, which_part, info); } @@ -199,15 +210,17 @@ static int get_partition_info_extended (int dev, int ext_part_sector, return -1; } -void print_part_dos (int dev) +void print_part_dos (block_dev_desc_t *dev_desc) { printf ("Partition Start Sector Num Sectors Type\n"); - print_partition_extended (dev, 0, 0, 1); + print_partition_extended (dev_desc, 0, 0, 1); } -int get_partition_info_dos (int dev, int part, disk_partition_t * info) +int get_partition_info_dos (block_dev_desc_t *dev_desc, int part, disk_partition_t * info) { - return get_partition_info_extended (dev, 0, 0, 1, part, info); + return get_partition_info_extended (dev_desc, 0, 0, 1, part, info); } + + #endif /* (CONFIG_COMMANDS & CFG_CMD_IDE) && CONFIG_DOS_PARTITION */ diff --git a/disk/part_iso.c b/disk/part_iso.c new file mode 100644 index 0000000..b1369a7 --- /dev/null +++ b/disk/part_iso.c @@ -0,0 +1,241 @@ +/* + * (C) Copyright 2001 + * Denis Peter, MPL AG Switzerland, d.peter@mpl.ch. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include +#include "part_iso.h" + +#if ((CONFIG_COMMANDS & CFG_CMD_IDE) || (CONFIG_COMMANDS & CFG_CMD_SCSI)) && defined(CONFIG_ISO_PARTITION) + +#undef ISO_PART_DEBUG + +#ifdef ISO_PART_DEBUG +#define PRINTF(fmt,args...) printf (fmt ,##args) +#else +#define PRINTF(fmt,args...) +#endif + +#define CD_SECTSIZE 2048 + +static unsigned char tmpbuf[CD_SECTSIZE]; + +/* Convert char[4] in little endian format to the host format integer + */ +static inline unsigned long le32_to_int(unsigned char *le32) +{ + return ((le32[3] << 24) + + (le32[2] << 16) + + (le32[1] << 8) + + le32[0] + ); +} + +/* only boot records will be listed as valid partitions */ +int get_partition_info_iso_verb(block_dev_desc_t * dev_desc, int part_num, disk_partition_t * info, int verb) +{ + int i,offset,entry_num; + unsigned short *chksumbuf; + unsigned short chksum; + unsigned long newblkaddr,blkaddr,lastsect,bootaddr; + iso_boot_rec_t *pbr = (iso_boot_rec_t *)tmpbuf; /* boot record */ + iso_pri_rec_t *ppr = (iso_pri_rec_t *)tmpbuf; /* primary desc */ + iso_val_entry_t *pve = (iso_val_entry_t *)tmpbuf; + iso_init_def_entry_t *pide; + iso_header_entry_t *phe; + + /* the first sector (sector 0x10) must be a primary volume desc */ + blkaddr=PVD_OFFSET; + if (dev_desc->block_read (dev_desc->dev, PVD_OFFSET, 1, (ulong *) tmpbuf) != 1) + return (-1); + if(ppr->desctype!=0x01) { + if(verb) + printf(" first descriptor is NOT a primary desc\n"); + return (-1); + } + if(strncmp(ppr->stand_ident,"CD001",5)!=0) { + if(verb) + printf("ISO Ident: %s wrong\n",ppr->stand_ident); + return (-1); + } + lastsect= ((ppr->firstsek_LEpathtab1_LE & 0xff)<<24) + + ((ppr->firstsek_LEpathtab1_LE & 0xff00)<<8) + + ((ppr->firstsek_LEpathtab1_LE & 0xff0000)>>8) + + ((ppr->firstsek_LEpathtab1_LE & 0xff000000)>>24); + info->blksz=ppr->secsize_BE; /* assuming same block size for all entries */ + PRINTF(" Lastsect:%08lx\n",lastsect); + for(i=blkaddr;iblock_read (dev_desc->dev, i, 1, (ulong *) tmpbuf) != 1) + return (-1); + if(ppr->desctype==0x00) + break; /* boot entry found */ + if(ppr->desctype==0xff) { + if(verb) + printf(" No valid boot catalog found\n"); + return (-1); + } + } + /* boot entry found */ + if(strncmp(pbr->ident_str,"EL TORITO SPECIFICATION",23)!=0) { + if(verb) + printf("Ident: %s wrong\n",pbr->ident_str); + return (-1); + } + bootaddr=le32_to_int(pbr->pointer); + PRINTF(" Boot Entry at: %08lX\n",bootaddr); + if (dev_desc->block_read (dev_desc->dev, bootaddr, 1, (ulong *) tmpbuf) != 1) + return (-1); + chksum=0; + chksumbuf = (unsigned short *)tmpbuf; + for(i=0;i<0x10;i++) + chksum+=((chksumbuf[i] &0xff)<<8)+((chksumbuf[i] &0xff00)>>8); + if(chksum!=0) { + if(verb) + printf(" checksum Error in booting catalog validation entry\n"); + return (-1); + } + if((pve->key[0]!=0x55)||(pve->key[1]!=0xAA)) { + if(verb) + printf(" key 0x55 0xAA error\n"); + return(-1); + } + /* the validation entry seems to be ok, now search the "partition" */ + entry_num=0; + offset=0x20; + if(part_num==0) { /* the default partition */ + #if 0 + if(pve->platform!=0x01) { + if(verb) + printf(" default entry is no PowerPC partition\n"); + return(-1); + } + #endif + sprintf(info->name,"%.32s",pve->manu_str); + sprintf (info->type, "PPCBoot"); + pide=(iso_init_def_entry_t *)&tmpbuf[offset]; + goto found; + } + /* partition is not the default partition */ + offset+=0x20; + while(1) { + phe=(iso_header_entry_t *)&tmpbuf[offset]; + if((phe->header_id & 0xfe)!=0x90) { /* no valid header ID */ + if(verb) + printf(" part %d not found\n",part_num); + return(-1); + } + if((entry_num+(phe->numentry[1]<<8)+phe->numentry[0])>=part_num) { /* partition lies in this header */ + #if 0 + if(phe->platform!=0x01) { + if(verb) + printf(" part %d is no PowerPC partition\n",part_num); + return(-1); + } + #endif + sprintf(info->type,"%.32s",phe->id_str); + entry_num++; + offset+=0x20; + while(entry_num!=part_num) { + offset+=0x20; + while(tmpbuf[offset]==0x44) + offset+=0x20; /* skip extension records */ + entry_num++; + } + /* part entry should be here */ + pide=(iso_init_def_entry_t *)&tmpbuf[offset]; + goto found; + } + else { /* search next header */ + if((phe->header_id)==0x91) { /* last header ID */ + if(verb) + printf(" part %d not found\n",part_num); + return(-1); + } + entry_num+=((phe->numentry[1]<<8)+phe->numentry[0]); /* count partitions */ + offset+=0x20; + while((tmpbuf[offset]=0x44) || /* skip extension records */ + (tmpbuf[offset]=0x88) || /* skip boot entries */ + (tmpbuf[offset]=0x00)) { /* skip no boot entries */ + offset+=0x20; + if(offset>=CD_SECTSIZE) { /* to prevent overflow */ + if(verb) + printf(" part %d not found\n",part_num); + return(-1); + } + } /* while skipping all unused records */ + } /* else */ + } /* while(TRUE) */ +found: + if(pide->boot_ind!=0x88) { + if(verb) + printf(" part %d is not bootable\n",part_num); + return (-1); + } + switch(pide->boot_media) { + case 0x00: info->size=2880>>2; break; /* dummy (No Emulation) */ + case 0x01: info->size=2400>>2; break; /* 1.2MByte Floppy */ + case 0x02: info->size=2880>>2; break; /* 1.44MByte Floppy */ + case 0x03: info->size=5760>>2; break; /* 2.88MByte Floppy */ + case 0x04: info->size=2880>>2; break; /* dummy (HD Emulation) */ + default: info->size=0; break; + } + newblkaddr=le32_to_int(pide->rel_block_addr); + info->start=newblkaddr; + if(verb) + printf(" part %d found @ %lx size %lx\n",part_num,newblkaddr,info->size); + return 0; +} + +int get_partition_info_iso(block_dev_desc_t * dev_desc, int part_num, disk_partition_t * info) +{ + return(get_partition_info_iso_verb(dev_desc, part_num, info, 0)); +} + + + +void print_part_iso(block_dev_desc_t * dev_desc) +{ + disk_partition_t info; + int i; + if(get_partition_info_iso_verb(dev_desc,0,&info,0)==-1) { + printf("** No boot partition found on device %d **\n",dev_desc->dev); + return; + } + printf("Part Start Sect x Size Type\n"); + i=0; + do { + printf(" %2d %8ld %8ld %6ld %.32s\n",i,info.start,info.size,info.blksz,info.type); + i++; + }while(get_partition_info_iso_verb(dev_desc,i,&info,0)!=-1); +} + +int test_part_iso (block_dev_desc_t *dev_desc) +{ + disk_partition_t info; + + return(get_partition_info_iso_verb(dev_desc,0,&info,0)); +} + +#endif /* ((CONFIG_COMMANDS & CFG_CMD_IDE) || (CONFIG_COMMANDS & CFG_CMD_SCSI)) && defined(CONFIG_ISO_PARTITION) */ + + diff --git a/disk/part_iso.h b/disk/part_iso.h new file mode 100644 index 0000000..2c733a3 --- /dev/null +++ b/disk/part_iso.h @@ -0,0 +1,171 @@ +/* + * (C) Copyright 2001 + * Denis Peter, MPL AG Switzerland, d.peter@mpl.ch. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#ifndef _PART_CD_H +#define _PART_CD_H + +#define BRVD 0x11 +#define PVD_OFFSET 0x10 + + +typedef struct iso_boot_rec { + unsigned char desctype; /* type of Volume descriptor: 0 = boot record, 1 = primary, 2 = Supplement, 3 = volume part 0xff trminator */ + unsigned char stand_ident[5]; /* "CD001" */ + unsigned char vers; /* Version */ + char ident_str[0x20]; /* Ident String "EL TORITO SPECIFICATION" */ + unsigned char unused[0x20]; /* unused */ + unsigned char pointer[4]; /* absolute pointer to Boot Catalog */ +} iso_boot_rec_t; + + +typedef struct iso_pri_rec { + unsigned char desctype; /* type of Volume descriptor: 0 = boot record, 1 = primary, 2 = Supplement, 3 = volume part 0xff trminator */ + unsigned char stand_ident[5]; /* "CD001" */ + unsigned char vers; /* Version */ + unsigned char unused; + char sysid[32]; /* system Identifier */ + char volid[32]; /* volume Identifier */ + unsigned char zeros1[8]; /* unused */ + unsigned long volsiz_LE; /* volume size Little Endian */ + unsigned long volsiz_BE; /* volume size Big Endian */ + unsigned char zeros2[32]; /* unused */ + unsigned short setsize_LE; /* volume set size LE */ + unsigned short setsize_BE; /* volume set size BE */ + unsigned short seqnum_LE; /* volume sequence number LE */ + unsigned short seqnum_BE; /* volume sequence number BE */ + unsigned short secsize_LE; /* sector size LE */ + unsigned short secsize_BE; /* sector size BE */ + unsigned long pathtablen_LE;/* Path Table size LE */ + unsigned long pathtablen_BE;/* Path Table size BE */ + unsigned long firstsek_LEpathtab1_LE; /* location of first occurrence of little endian type path table */ + unsigned long firstsek_LEpathtab2_LE; /* location of optional occurrence of little endian type path table */ + unsigned long firstsek_BEpathtab1_BE; /* location of first occurrence of big endian type path table */ + unsigned long firstsek_BEpathtab2_BE; /* location of optional occurrence of big endian type path table */ + unsigned char rootdir[34]; /* directory record for root dir */ + char volsetid[128];/* Volume set identifier */ + char pubid[128]; /* Publisher identifier */ + char dataprepid[128]; /* data preparer identifier */ + char appid[128]; /* application identifier */ + char copyr[37]; /* copyright string */ + char abstractfileid[37]; /* abstract file identifier */ + char bibliofileid[37]; /* bibliographic file identifier */ + unsigned char creationdate[17]; /* creation date */ + unsigned char modify[17]; /* modification date */ + unsigned char expire[17]; /* expiring date */ + unsigned char effective[17];/* effective date */ + unsigned char filestruc_ver; /* file structur version */ +} iso_pri_rec_t; + +typedef struct iso_sup_rec { + unsigned char desctype; /* type of Volume descriptor: 0 = boot record, 1 = primary, 2 = Supplement, 3 = volume part 0xff trminator */ + unsigned char stand_ident[5]; /* "CD001" */ + unsigned char vers; /* Version */ + unsigned char volumeflags; /* if bit 0 = 0 => all escape sequences are according ISO 2375 */ + char sysid[32]; /* system Identifier */ + char volid[32]; /* volume Identifier */ + unsigned char zeros1[8]; /* unused */ + unsigned long volsiz_LE; /* volume size Little Endian */ + unsigned long volsiz_BE; /* volume size Big Endian */ + unsigned char escapeseq[32];/* Escape sequences */ + unsigned short setsize_LE; /* volume set size LE */ + unsigned short setsize_BE; /* volume set size BE */ + unsigned short seqnum_LE; /* volume sequence number LE */ + unsigned short seqnum_BE; /* volume sequence number BE */ + unsigned short secsize_LE; /* sector size LE */ + unsigned short secsize_BE; /* sector size BE */ + unsigned long pathtablen_LE;/* Path Table size LE */ + unsigned long pathtablen_BE;/* Path Table size BE */ + unsigned long firstsek_LEpathtab1_LE; /* location of first occurrence of little endian type path table */ + unsigned long firstsek_LEpathtab2_LE; /* location of optional occurrence of little endian type path table */ + unsigned long firstsek_BEpathtab1_BE; /* location of first occurrence of big endian type path table */ + unsigned long firstsek_BEpathtab2_BE; /* location of optional occurrence of big endian type path table */ + unsigned char rootdir[34]; /* directory record for root dir */ + char volsetid[128];/* Volume set identifier */ + char pubid[128]; /* Publisher identifier */ + char dataprepid[128]; /* data preparer identifier */ + char appid[128]; /* application identifier */ + char copyr[37]; /* copyright string */ + char abstractfileid[37]; /* abstract file identifier */ + char bibliofileid[37]; /* bibliographic file identifier */ + unsigned char creationdate[17]; /* creation date */ + unsigned char modify[17]; /* modification date */ + unsigned char expire[17]; /* expiring date */ + unsigned char effective[17];/* effective date */ + unsigned char filestruc_ver; /* file structur version */ +}iso_sup_rec_t; + +typedef struct iso_part_rec { + unsigned char desctype; /* type of Volume descriptor: 0 = boot record, 1 = primary, 2 = Supplement, 3 = volume part 0xff trminator */ + unsigned char stand_ident[5]; /* "CD001" */ + unsigned char vers; /* Version */ + unsigned char unused; + char sysid[32]; /* system Identifier */ + char volid[32]; /* volume partition Identifier */ + unsigned long partloc_LE; /* volume partition location LE */ + unsigned long partloc_BE; /* volume partition location BE */ + unsigned long partsiz_LE; /* volume partition size LE */ + unsigned long partsiz_BE; /* volume partition size BE */ +}iso_part_rec_t; + + + + +typedef struct iso_val_entry { + unsigned char header_id; /* Header ID must be 0x01 */ + unsigned char platform; /* Platform: 0=x86, 1=PowerPC, 2=MAC */ + unsigned char res[2]; /* reserved */ + char manu_str[0x18]; /* Ident String of manufacturer/developer */ + unsigned char chk_sum[2]; /* Check sum (all words must be zero) */ + unsigned char key[2]; /* key[0]=55, key[1]=0xAA */ +} iso_val_entry_t; + +typedef struct iso_header_entry { + unsigned char header_id; /* Header ID must be 0x90 or 0x91 */ + unsigned char platform; /* Platform: 0=x86, 1=PowerPC, 2=MAC */ + unsigned char numentry[2]; /* number of entries */ + char id_str[0x1C]; /* Ident String of sectionr */ +} iso_header_entry_t; + + +typedef struct iso_init_def_entry { + unsigned char boot_ind; /* Boot indicator 0x88=bootable 0=not bootable */ + unsigned char boot_media; /* boot Media Type: 0=no Emulation, 1=1.2MB floppy, 2=1.44MB floppy, 3=2.88MB floppy 4=hd (0x80) */ + unsigned char ld_seg[2]; /* Load segment (flat model=addr/10) */ + unsigned char systype; /* System Type copy of byte5 of part table */ + unsigned char res; /* reserved */ + unsigned char sec_cnt[2]; /* sector count in VIRTUAL Blocks (0x200) */ + unsigned char rel_block_addr[4]; /* relative Block address */ +} iso_init_def_entry_t; + + +void print_partition_cd(int dev); + + + + + + + + +#endif /* _PART_CD_H */ + + diff --git a/disk/part_mac.c b/disk/part_mac.c index 3ecbb97..9783105 100644 --- a/disk/part_mac.c +++ b/disk/part_mac.c @@ -35,7 +35,7 @@ #include #include "part_mac.h" -#if (CONFIG_COMMANDS & CFG_CMD_IDE) && defined(CONFIG_MAC_PARTITION) +#if ((CONFIG_COMMANDS & CFG_CMD_IDE) || (CONFIG_COMMANDS & CFG_CMD_SCSI)) && defined(CONFIG_MAC_PARTITION) /* stdlib.h causes some compatibility problems; should fixe these! -- wd */ #ifndef __ldiv_t_defined @@ -48,26 +48,26 @@ extern ldiv_t ldiv (long int __numer, long int __denom); #endif -static int part_mac_read_ddb (int dev, mac_driver_desc_t *ddb_p); -static int part_mac_read_pdb (int dev, int part, mac_partition_t *pdb_p); +static int part_mac_read_ddb (block_dev_desc_t *dev_desc, mac_driver_desc_t *ddb_p); +static int part_mac_read_pdb (block_dev_desc_t *dev_desc, int part, mac_partition_t *pdb_p); /* * Test for a valid MAC partition */ -int test_part_mac (int dev) +int test_part_mac (block_dev_desc_t *dev_desc) { mac_driver_desc_t ddesc; mac_partition_t mpart; ulong i, n; - if (part_mac_read_ddb (dev, &ddesc)) { + if (part_mac_read_ddb (dev_desc, &ddesc)) { /* error reading Driver Desriptor Block, or no valid Signature */ return (-1); } n = 1; /* assuming at least one partition */ for (i=1; i<=n; ++i) { - if ((ide_read (dev, i, 1, (ulong *)&mpart) != 1) || + if ((dev_desc->block_read(dev_desc->dev, i, 1, (ulong *)&mpart) != 1) || (mpart.signature != MAC_PARTITION_MAGIC) ) { return (-1); } @@ -78,14 +78,14 @@ int test_part_mac (int dev) } -void print_part_mac (int dev) +void print_part_mac (block_dev_desc_t *dev_desc) { ulong i, n; mac_driver_desc_t ddesc; mac_partition_t mpart; ldiv_t mb, gb; - if (part_mac_read_ddb (dev, &ddesc)) { + if (part_mac_read_ddb (dev_desc, &ddesc)) { /* error reading Driver Desriptor Block, or no valid Signature */ return; } @@ -120,16 +120,16 @@ void print_part_mac (int dev) char c; printf ("%4ld: ", i); - if (ide_read (dev, i, 1, (ulong *)&mpart) != 1) { + if (dev_desc->block_read (dev_desc->dev, i, 1, (ulong *)&mpart) != 1) { printf ("** Can't read Partition Map on %d:%ld **\n", - dev, i); + dev_desc->dev, i); return; } if (mpart.signature != MAC_PARTITION_MAGIC) { printf ("** Bad Signature on %d:%ld - " "expected 0x%04x, got 0x%04x\n", - dev, i, MAC_PARTITION_MAGIC, mpart.signature); + dev_desc->dev, i, MAC_PARTITION_MAGIC, mpart.signature); return; } @@ -164,9 +164,9 @@ void print_part_mac (int dev) /* * Read Device Descriptor Block */ -static int part_mac_read_ddb (int dev, mac_driver_desc_t *ddb_p) +static int part_mac_read_ddb (block_dev_desc_t *dev_desc, mac_driver_desc_t *ddb_p) { - if (ide_read (dev, 0, 1, (ulong *)ddb_p) != 1) { + if (dev_desc->block_read(dev_desc->dev, 0, 1, (ulong *)ddb_p) != 1) { printf ("** Can't read Driver Desriptor Block **\n"); return (-1); } @@ -184,7 +184,7 @@ static int part_mac_read_ddb (int dev, mac_driver_desc_t *ddb_p) /* * Read Partition Descriptor Block */ -static int part_mac_read_pdb (int dev, int part, mac_partition_t *pdb_p) +static int part_mac_read_pdb (block_dev_desc_t *dev_desc, int part, mac_partition_t *pdb_p) { int n = 1; @@ -194,16 +194,16 @@ static int part_mac_read_pdb (int dev, int part, mac_partition_t *pdb_p) * partition 1 first since this is the only way to * know how many partitions we have. */ - if (ide_read (dev, n, 1, (ulong *)pdb_p) != 1) { + if (dev_desc->block_read (dev_desc->dev, n, 1, (ulong *)pdb_p) != 1) { printf ("** Can't read Partition Map on %d:%d **\n", - dev, n); + dev_desc->dev, n); return (-1); } if (pdb_p->signature != MAC_PARTITION_MAGIC) { printf ("** Bad Signature on %d:%d: " "expected 0x%04x, got 0x%04x\n", - dev, n, MAC_PARTITION_MAGIC, pdb_p->signature); + dev_desc->dev, n, MAC_PARTITION_MAGIC, pdb_p->signature); return (-1); } @@ -212,9 +212,9 @@ static int part_mac_read_pdb (int dev, int part, mac_partition_t *pdb_p) if ((part < 1) || (part > pdb_p->map_count)) { printf ("** Invalid partition %d:%d [%d:1...%d:%d only]\n", - dev, part, - dev, - dev, pdb_p->map_count); + dev_desc->dev, part, + dev_desc->dev, + dev_desc->dev, pdb_p->map_count); return (-1); } @@ -225,18 +225,18 @@ static int part_mac_read_pdb (int dev, int part, mac_partition_t *pdb_p) /* NOTREACHED */ } -int get_partition_info_mac (int dev, int part, disk_partition_t *info) +int get_partition_info_mac (block_dev_desc_t *dev_desc, int part, disk_partition_t *info) { mac_driver_desc_t ddesc; mac_partition_t mpart; - if (part_mac_read_ddb (dev, &ddesc)) { + if (part_mac_read_ddb (dev_desc, &ddesc)) { return (-1); } info->blksz = ddesc.blk_size; - if (part_mac_read_pdb (dev, part, &mpart)) { + if (part_mac_read_pdb (dev_desc, part, &mpart)) { return (-1); } diff --git a/doc/README.PIP405 b/doc/README.PIP405 new file mode 100644 index 0000000..1ffc056 --- /dev/null +++ b/doc/README.PIP405 @@ -0,0 +1,382 @@ +PPCBoot Changes due to PIP405 Port: +=================================== + +Changed files: +============== +- MAKEALL added PIP405 +- makefile added PIP405 +- common/Makefile added Floppy disk and SCSI support +- common/board.c added PIP405, SCSI support, get_PCI_freq() +- common/bootm.c added IH_OS_PPCBOOT, IH_TYPE_FIRMWARE +- common/cmd_i2c.c added "defined(CONFIG_PIP405)" +- common/cmd_ide.c changed div. functions to work with block device + description + added ATAPI support +- common/command.c added SCSI and Floppy support +- common/console.c replaced // with /* comments + added console settings from environment +- common/devices.c added ISA keyboard init +- common/main.c corrected the read of bootdelay +- cpu/ppc4xx/405gp_pci.c excluded file from PIP405 +- cpu/ppc4xx/i2c.c added 16bit read write I2C support + added page write +- cpu/ppc4xx/speed.c added get_PCI_freq +- cpu/ppc4xx/start.S added CONFIG_IDENT_STRING +- disk/Makefile added part_iso for CD support +- disk/part.c changed to work with block device description + added ISO CD support + added dev_print (was ide_print in cmd_ide.c) +- disk/part_dos.c changed to work with block device description +- disk/part_mac.c changed to work with block device description +- include/ata.h added ATAPI commands +- include/cmd_bsp.h added PIP405 commands definitions +- include/cmd_condefs.h added Floppy and SCSI support +- include/cmd_disk.h changed to work with block device description +- include/config_LANTEC.h excluded CFG_CMD_FDC and CFG_CMD_SCSI from + CONFIG_CMD_FULL +- include/config_hymod.h excluded CFG_CMD_FDC and CFG_CMD_SCSI from + CONFIG_CMD_FULL +- include/flash.h added INTEL_ID_28F320C3T 0x88C488C4 +- include/i2c.h added "defined(CONFIG_PIP405)" +- include/image.h added IH_OS_PPCBOOT, IH_TYPE_FIRMWARE +- include/ppcboot.h moved partitions functions definitions to part.h + added "defined(CONFIG_PIP405)" + added get_PCI_freq() definition +- rtc/Makefile added MC146818 RTC support +- tools/mkimage.c added IH_OS_PPCBOOT, IH_TYPE_FIRMWARE + +Added files: +============ +- board/pip405 directory for PIP405 +- board/pip405/cmd_pip405.c board specific commands +- board/pip405/config.mk config make +- board/pip405/flash.c flash support +- board/pip405/init.s start-up +- board/pip405/kbd.c keyboard support +- board/pip405/kbd.h keyboard support +- board/pip405/Makefile Makefile +- board/pip405/pci_piix4.h southbridge definitions +- board/pip405/pci_pip405.c PCI support for PIP405 +- board/pip405/pci_pip405.h PCI support for PIP405 +- board/pip405/pip405.c PIP405 board init +- board/pip405/pip405.h PIP405 board init +- board/pip405/pip405_isa.c ISA support +- board/pip405/pip405_isa.h ISA support +- board/pip405/ppcboot.lds Linker description +- board/pip405/ppcboot.lds.debugLinker description debug +- board/pip405/sym53c8xx.c SYM53C810A support +- board/pip405/sym53c8xx_defs.h SYM53C810A definitions +- board/pip405/vga_table.h definitions of tables for VGA +- board/pip405/video.c CT69000 support +- board/pip405/video.h CT69000 support +- common/cmd_fdc.c Floppy disk support +- common/cmd_scsi.c SCSI support +- disk/part_iso.c ISO CD ROM support +- disk/part_iso.h ISO CD ROM support +- include/cmd_fdc.h command forFloppy disk support +- include/cmd_scsi.h command for SCSI support +- include/part.h partitions functions definitions + (was part of ppcboot.h) +- include/scsi.h SCSI support +- rtc/mc146818.c MC146818 RTC support + + +New Config Switches: +==================== +For detailed description, refer to the corresponding paragraph in the +section "Changes". + +New Commands: +------------- +CFG_CMD_SCSI SCSI Support +CFG_CMF_FDC Floppy disk support + +IDE additions: +-------------- +CONFIG_IDE_RESET_ROUTINE defines that instead of a reset Pin, + the routine ide_set_reset(int idereset) is used. +ATAPI support (experimental) +---------------------------- +CONFIG_ATAPI enables ATAPI Support + +SCSI support (experimental) only SYM53C8xx supported +---------------------------------------------------- +CONFIG_SCSI_SYM53C8XX type of SCSI controller +CFG_SCSI_MAX_LUN 8 number of supported LUNs +CFG_SCSI_MAX_SCSI_ID 7 maximum SCSI ID (0..6) +CFG_SCSI_MAX_DEVICE CFG_SCSI_MAX_SCSI_ID * CFG_SCSI_MAX_LUN + maximum of Target devices (multiple LUN support + for boot) + +ISO (CD-Boot) partition support (Experimental) +---------------------------------------------- +CONFIG_ISO_PARTITION CD-boot support + +RTC +---- +CONFIG_RTC_MC146818 MC146818 RTC support + +Keyboard: +--------- +CONFIG_ISA_KEYBOARD Standard (PC-Style) Keyboard support + +Video: +------ +CONFIG_VIDEO_CT69000 Enable Chips & Technologies 69000 Video chip + CONFIG_VIDEO must be defined also + +External peripheral base address: +--------------------------------- +CFG_ISA_IO_BASE_ADDRESS address of all ISA-bus related parts + _must_ be defined for ISA-bus parts + +Identify: +--------- +CONFIG_IDENT_STRING added to the PPCBOOT_VERSION String + + +I2C stuff: +---------- +CFG_EEPROM_PAGE_WRITE_ENABLE enables page write of the I2C EEPROM + CFG_EEPROM_PAGE_WRITE_BITS _must_ be + defined. + + +Environment / Console: +---------------------- +CFG_CONSOLE_IS_IN_ENV if defined, stdin, stdout and stderr used from + the values stored in the evironment. +CFG_CONSOLE_OVERWRITE_ROUTINE if defined, console_overwrite() decides if the + values stored in the environment or the standard + serial in/out put should be assigned to the console. +CFG_CONSOLE_ENV_OVERWRITE if defined, the start-up console switching + are stored in the environment. + +PIP405 specific: +---------------- +CONFIG_PORT_ADDR address used to read boot configuration +MULTI_PURPOSE_SOCKET_ADDR address of the multi purpose socked +SDRAM_EEPROM_WRITE_ADDRESS addresses of the serial presence detect +SDRAM_EEPROM_READ_ADDRESS EEPROM on the SDRAM module. + + +Changes: +======== + +Added Devices: +============== + +Floppy support: +--------------- +Support of a standard floppy disk controller at address CFG_ISA_IO_BASE_ADDRESS ++ 0x3F0. Enabled with define CFG_CMD_FDC. Reads a unformated floppy disk with a +image header (see: mkimage). No interrupts and no DMA are used for this. +Added files: +- common/cmd_fdc.c +- include/cmd_fdc.h + +SCSI support: +------------- +Support for Symbios SYM53C810A chip. Implemented as follows: +- without disconnect +- only asynchrounous +- multiple LUN support (caution, needs a lot of RAM. define CFG_SCSI_MAX_LUN 1 to + save RAM) +- multiple SCSI ID support +- no write support +- analyses the MAC, DOS and ISO pratition similar to the IDE support +- allows booting from SCSI devices similar to the IDE support. +The device numbers are not assigned like they are within the IDE support. The first +device found will get the number 0, the next 1 etc. If all SCSI IDs (0..6) and all +LUNs (8) are enabled, 56 boot devices are possible. This uses a lot of RAM since the +device descriptors are not yet dynamically allocated. 56 boot devices are overkill +anyway. Please refer to the section "Todo" chapter "block device support enhancement". +The SYM53C810A uses 1 Interrupt and must be able of mastering the PCI bus. +Added files: +- common/cmd_scsi.c +- common/board.c +- include/cmd_scsi.h +- include/scsi.h +- board/pip405/sym53c8xx.c +- board/pip405/sym53c8xx_defs.h + +ATAPI support (IDE changes): +---------------------------- +Added ATAPI support (with CONFIG_ATAPI) in the file cmd_ide.c. +To support a hardreset, when the IDE reset pin is not connected to the +CFG_PC_IDE_RESET pin, the switch CONFIG_IDE_RESET_ROUTINE has been added. When +this switch is enabled the routine void ide_set_reset(int idereset) must be +within the board specific files. +Only read from ATAPI devices are supported. +Found out that the function trim_trail cuts off the last character if the whole +string is filled. Added function cpy_ident instead, which trims also leading +spaces and copies the string in the buffer. +Changed files: +- common/cmd_ide.c +- include/ata.h + +ISO partition support: +---------------------- +Added CD boot support for El-Torito bootable ISO CDs. The bootfile image must contain +the ppcboot image header. Since CDs do not have "partitions", the boot partition is 0. +The bootcatalog feature has not been tested so far. CD Boot is supported for ATAPI +("diskboot") and SCSI ("scsiboot") devices. +Added files: +- disk/iso_part.c +- disk/iso_part.h + +Block device changes: +--------------------- +To allow the use of dos_part.c, mac_part.c and iso_part.c, the parameter +block_dev_desc will be used when accessing the functions in these files. The block +device descriptor (block_dev_desc) contains a pointer to the read routine of the +device, which will be used to read blocks from the device. +Renamed function ide_print to dev_print and moved it to the file disk/part.c to use +it for IDE ATAPI and SCSI devices. +Please refer to the section "Todo" chapter "block device support enhancement". +Added files: +- include/part.h +changed files: +- disk/dos_part.c +- disk/dos_part.h +- disk/mac_part.c +- disk/mac_part.h +- disk/part.c +- common/cmd_ide.c +- include/ppcboot.h + + +MC146818 RTC support: +--------------------- +Added support for MC146818 RTC with defining CONFIG_RTC_MC146818. The ISA bus IO +base address must be defined with CFG_ISA_IO_BASE_ADDRESS. +Added files: +- rtc/mc146818.c + +Standard ISA bus Keyboard support: +---------------------------------- +Added support for the standard PC kyeboard controller. For the PIP405 the superIO +controller must be set up previously. The keyboard uses the standard ISA IRQ, so +the ISA PIC must also be set up. +Added files: +- board/pip405/kbd.c +- board/pip405/kbd.h +- board/pip405/pip405_isa.c +- board/pip405/pip405_isa.h + +Chips and Technologie 69000 VGA controller support: +--------------------------------------------------- +Added support for the CT69000 VGA controller. +Added files: +- board/pip405/video.c +- board/pip405/video.h +- board/pip405/vga_table.h + + +Changed Items: +============== + +Identify: +--------- +Added the config variable CONFIG_IDENT_STRING which will be added to the +"PPCBOOT_VERSION __TIME__ DATE___ " String, to allows to identify intermidiate +and custom versions. +Changed files: +- cpu/ppc4xx/start.s + +Firmware Image: +--------------- +Added IH_OS_PPCBOOT and IH_TYPE_FIRMWARE to the image definitions to allows the +PPCBoot update with prior CRC check. +Changed files: +- include/image.h +- tools/mkimage.c +- common/cmd_bootm.c + +Correct PCI Frequency for PPC405: +--------------------------------- +Added function (in cpu/ppc4xx/speed.c) to get the PCI frequency for PPC405 CPU. +The PCI Frequency will now be set correct in the board description in common/board.c. +(was set to the busfreq before). +Changed files: +- cpu/ppc4xx/speed.c +- common/board.c + +I2C Stuff: +---------- +Added defined(CONFIG_PIP405) at several points in common/cmd_i2c.c. +Added 16bit read/write support for I2C (PPC405), and page write to +I2C EEPROM if defined CFG_EEPROM_PAGE_WRITE_ENABLE. +Changed files: +- cpu/ppc4xx/i2c.c +- common/cmd_i2c.c + +Environment / Console: +---------------------- +Although in README.console described, the PPCBoot has not assinged the values +found in the environment to the console. Corrected this behavior, but only if +CFG_CONSOLE_IS_IN_ENV is defined. +If CFG_CONSOLE_OVERWRITE_ROUTINE is defined, console_overwrite() decides if the +values stored in the environment or the standard serial in/output should be +assigned to the console. This is useful if the environment values are not correct. +If CFG_CONSOLE_ENV_OVERWRITE is defined the devices assigned to the console at +start-up time will be written to the environment. This means that if the +environment values are overwritten by the overwrite_console() routine, they will be +stored in the environment. +Changed files: +- common/console.c + +Correct bootdelay intepretation: +-------------------------------- +Changed bootdelay read from the environment from simple_strtoul (unsigned) to +simple_strtol (signed), to be able to get a bootdelay of -1. +Changed files: +- common/main.c + +Todo: +===== + +Block device support enhancement: +--------------------------------- +Consider to unify the block device handling. Instead of using diskboot for IDE, +scsiboot for SCSI and fdcboot for floppy disks, it would make sense to use only +one command ("devboot" ???) with a parameter of the desired device ("hda1", "sda1", +"fd0" ???) to boot from. The other ide commands can be handled in the same way +("dev hda read.." instead of "ide read.." or "dev sda read.." instead of +"scsi read..."). Todo this, a common way of assign a block device to its name +(first found ide device = hda, second found hdb etc., or hda is device 0 on bus 0, +hdb is device 1 on bus 0 etc.) as well as the names (hdx for ide, sdx for scsi, fx for +floppy ???) must be defined. +Maybe there are better ideas to do this. + +Console assingment: +------------------- +Consider to initialize and assign the console stdin, stdout and stderr as soon as +possible to see the boot messages also on an other console than serial. + + +Todo for PIP405: +================ + +LCD support for VGA: +-------------------- +Add LCD support for the CT69000 + +Default environment: +-------------------- +Consider to write a default environment to the OTP part of the EEPROM and use it +if the normal environment is not valid. Useful for serial# and ethaddr values. + +Watchdog: +--------- +Implement Watchdog. + +Files clean-up: +--------------- +Following files needs to be cleaned up: +- cmd_pip405.c +- flash.c +- pci_pip405.c +- pip405.c +- pip405_isa.c +Consider to split up the files in their functions. diff --git a/include/ata.h b/include/ata.h index d6cded8..1c7c83b 100644 --- a/include/ata.h +++ b/include/ata.h @@ -100,6 +100,19 @@ #define ATA_CMD_IDENT 0xEC /* Identify Device */ #define ATA_CMD_SETF 0xEF /* Set Features */ +/* + * ATAPI Commands + */ +#define ATAPI_CMD_IDENT 0xA1 /* Identify AT Atachment Packed Interface Device */ +#define ATAPI_CMD_PACKET 0xA0 /* Packed Command */ + + +#define ATAPI_CMD_INQUIRY 0x12 +#define ATAPI_CMD_REQ_SENSE 0x03 +#define ATAPI_CMD_READ_CAP 0x25 +#define ATAPI_CMD_START_STOP 0x1B +#define ATAPI_CMD_READ_12 0xA8 + #define ATA_GET_ERR() inb(ATA_STATUS) #define ATA_GET_STAT() inb(ATA_STATUS) diff --git a/include/cmd_bsp.h b/include/cmd_bsp.h index 483a301..b9719a2 100644 --- a/include/cmd_bsp.h +++ b/include/cmd_bsp.h @@ -61,6 +61,24 @@ void do_puma (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]); #endif /* CONFIG_PCU_E */ /* ----------------------------------------------------------------------------*/ +/* ----- PIP405 ----------------------------------------------------------------- + */ +#if defined(CONFIG_PIP405) + +#define CMD_TBL_BSP MK_CMD_TBL_ENTRY( \ + "pip405", 4, 6, 1, do_pip405, \ + "pip405 - PIP405 specific Cmds\n", \ + "flash mem [SrcAddr] - updates PPCBOOT with image in memory\n" \ + "pip405 flash floppy [SrcAddr] - updates PPCBOOT with image from floppy\n" \ + "pip405 flash mps - updates PPCBOOT with image from MPS\n" \ +), + +void do_pip405 (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]); + +#endif /* CONFIG_PIP405 */ +/* ----------------------------------------------------------------------------*/ + + #else #define CMD_TBL_BSP diff --git a/include/cmd_confdefs.h b/include/cmd_confdefs.h index d5fd950..118b3ba 100644 --- a/include/cmd_confdefs.h +++ b/include/cmd_confdefs.h @@ -57,6 +57,8 @@ #define CFG_CMD_DATE 0x00800000 /* support for RTC, date/time...*/ #define CFG_CMD_DHCP 0x01000000 /* DHCP Support */ #define CFG_CMD_BEDBUG 0x02000000 /* Include BedBug Debugger */ +#define CFG_CMD_FDC 0x04000000 /* Floppy Disk Support */ +#define CFG_CMD_SCSI 0x08000000 /* SCSI Support */ #define CFG_CMD_BSP 0x80000000 /* Board SPecific functions */ #define CFG_CMD_ALL 0xFFFFFFFF /* ALL commands */ @@ -76,6 +78,8 @@ CFG_CMD_I2C | \ CFG_CMD_REGINFO | \ CFG_CMD_IMMAP | \ + CFG_CMD_FDC | \ + CFG_CMD_SCSI | \ CFG_CMD_DATE | \ CFG_CMD_BEDBUG | \ CFG_CMD_BSP ) diff --git a/include/cmd_disk.h b/include/cmd_disk.h index 5b9818f..93dc974 100644 --- a/include/cmd_disk.h +++ b/include/cmd_disk.h @@ -35,6 +35,8 @@ */ #define BOOT_PART_TYPE "PPCBoot" +#if 0 + typedef struct disk_partition { ulong start; /* # of first block in partition */ ulong size; /* number of blocks in partition */ @@ -43,12 +45,13 @@ typedef struct disk_partition { uchar type[32]; /* string type description */ } disk_partition_t; -int get_partition_info (int dev, int part, disk_partition_t *info); +int get_partition_info (block_dev_desc_t * dev_desc, int part, disk_partition_t *info); #ifdef CONFIG_MAC_PARTITION -int get_partition_info_mac (int dev, int part, disk_partition_t *info); +int get_partition_info_mac (block_dev_desc_t * dev_desc, int part, disk_partition_t *info); #endif #ifdef CONFIG_DOS_PARTITION -int get_partition_info_dos (int dev, int part, disk_partition_t *info); +int get_partition_info_dos (block_dev_desc_t * dev_desc, int part, disk_partition_t *info); #endif +#endif /* 0 */ #endif /* _CMD_DISK_H */ diff --git a/include/cmd_fdc.h b/include/cmd_fdc.h new file mode 100644 index 0000000..0c241c5 --- /dev/null +++ b/include/cmd_fdc.h @@ -0,0 +1,47 @@ +/* + * (C) Copyright 2001 + * Denis Peter, MPL AG, d.peter@mpl.ch + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* + * Floppy support + */ +#ifndef _CMD_FDC_H +#define _CMD_FDC_H + +#include +#include + + +#if (CONFIG_COMMANDS & CFG_CMD_FDC) + +#define CMD_TBL_FDC MK_CMD_TBL_ENTRY( \ + "fdcboot", 4, 3, 1, do_fdcboot, \ + "fdcboot - boot from floppy device\n", \ + "loadAddr drive\n" \ +), +void do_fdcboot (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]); + +#else +#define CMD_TBL_FDC +#endif + +#endif /* _CMD_FDC_H */ diff --git a/include/cmd_ide.h b/include/cmd_ide.h index eca0e35..fe20dca 100644 --- a/include/cmd_ide.h +++ b/include/cmd_ide.h @@ -47,7 +47,7 @@ #define CMD_TBL_DISK MK_CMD_TBL_ENTRY( \ "diskboot", 4, 3, 1, do_diskboot, \ - "diskboot- boot from IDE device", \ + "diskboot- boot from IDE device\n", \ "loadAddr dev:part\n" \ ), diff --git a/include/cmd_scsi.h b/include/cmd_scsi.h new file mode 100644 index 0000000..a73ca01 --- /dev/null +++ b/include/cmd_scsi.h @@ -0,0 +1,62 @@ +/* + * (C) Copyright 2001 + * Denis Peter, MPL AG Switzerland + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ +#ifndef _CMD_SCSI_H +#define _CMD_SCSI_H + +#include +#include + + +#if (CONFIG_COMMANDS & CFG_CMD_SCSI) + +#define CMD_TBL_SCSI MK_CMD_TBL_ENTRY( \ + "scsi", 4, 5, 1, do_scsi, \ + "scsi - SCSI sub-system\n", \ + "reset - reset SCSI controller\n" \ + "scsi info - show available SCSI devices\n" \ + "scsi scan - (re-)scan SCSI bus\n" \ + "scsi device [dev] - show or set current device\n" \ + "scsi part [dev] - print partition table of one or all SCSI devices\n" \ + "scsi read addr blk# cnt - read `cnt' blocks starting at block `blk#'\n" \ + " to memory address `addr'\n" \ +), + + +#define CMD_TBL_SCSIBOOT MK_CMD_TBL_ENTRY( \ + "scsiboot", 5, 3, 1, do_scsiboot, \ + "scsiboot- boot from SCSI device\n", \ + "loadAddr dev:part\n" \ +), + +void do_scsi (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]); +void do_scsiboot (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]); + + +#else +#define CMD_TBL_SCSI +#define CMD_TBL_SCSIBOOT +#endif + +#endif /* _CMD_SCSI_H */ + diff --git a/include/config_EVB64260.h b/include/config_EVB64260.h index 0922b36..16d4ce6 100644 --- a/include/config_EVB64260.h +++ b/include/config_EVB64260.h @@ -101,6 +101,7 @@ #if 1 #define CONFIG_COMMANDS (CFG_CMD_ALL & ~(CFG_CMD_KGDB | CFG_CMD_IDE \ | CFG_CMD_PCMCIA | CFG_CMD_PCI \ + | CFG_CMD_SCSI | CFG_CMD_FDC \ | CFG_CMD_EEPROM | CFG_CMD_DATE)) #else #define CONFIG_COMMANDS CONFIG_CMD_DFL diff --git a/include/config_LANTEC.h b/include/config_LANTEC.h index 90e5229..d1af627 100644 --- a/include/config_LANTEC.h +++ b/include/config_LANTEC.h @@ -87,6 +87,8 @@ & ~CFG_CMD_PCI \ & ~CFG_CMD_EEPROM \ & ~CFG_CMD_I2C \ + & ~CFG_CMD_FDC \ + & ~CFG_CMD_SCSI \ & ~CFG_CMD_IRQ \ & ~CFG_CMD_BEDBUG ) diff --git a/include/config_PIP405.h b/include/config_PIP405.h new file mode 100644 index 0000000..8311018 --- /dev/null +++ b/include/config_PIP405.h @@ -0,0 +1,308 @@ +/* + * (C) Copyright 2001 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* + * board/config.h - configuration options, board specific + */ + +#ifndef __CONFIG_H +#define __CONFIG_H + +/*********************************************************** + * High Level Configuration Options + * (easy to change) + ***********************************************************/ +#define CONFIG_PPC405GP 1 /* This is a PPC405 CPU */ +#define CONFIG_PPC405 1 /* ...member of PPC405 family */ +#define CONFIG_PIP405 1 /* ...on a PIP405 board */ +/*********************************************************** + * Clock + ***********************************************************/ +#define CONFIG_SYS_CLK_FREQ 33000000 /* external frequency to pll */ + +/*********************************************************** + * Command definitions + ***********************************************************/ +#define CONFIG_COMMANDS \ + (CONFIG_CMD_DFL | CFG_CMD_PCI | CFG_CMD_IRQ | \ + CFG_CMD_DATE | CFG_CMD_IDE | CFG_CMD_BSP | \ + CFG_CMD_FDC | CFG_CMD_SCSI ) + +/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */ +#include + + +/************************************************************** + * I2C Stuff: + * the PIP405 is equiped with an Atmel 24C128/256 EEPROM at address + * 0x53. + * Caution: on the same bus is the SPD (Serial Presens Detect + * EEPROM of the SDRAM + * The Atmel EEPROM uses 16Bit addressing. + ***************************************************************/ +#define CONFIG_I2C_X +#define CFG_I2C_EEPROM_ADDR 0x53 +#define CFG_ENV_IS_IN_EEPROM 1 /* use EEPROM for environment vars */ +#define CFG_ENV_OFFSET 0x000 /* environment starts at the beginning of the EEPROM */ +#define CFG_ENV_SIZE 0x200 /* 512 bytes may be used for env vars */ +/* The Atmel 24C128/256 has 64 byte page write mode using last 6 bits of the address */ +#define CFG_EEPROM_PAGE_WRITE_BITS 6 +#define CFG_EEPROM_PAGE_WRITE_ENABLE /* enable Page write */ +/*************************************************************** + * Definitions for Serial Presence Detect EEPROM address + * (to get SDRAM settings) + ***************************************************************/ +#define SDRAM_EEPROM_WRITE_ADDRESS 0xA0 +#define SDRAM_EEPROM_READ_ADDRESS 0xA1 + +/************************************************************** + * Environment definitions + **************************************************************/ +#define CONFIG_BAUDRATE 9600 /* STD Baudrate */ +#define CONFIG_BOOTDELAY -1 /* no autoboot */ + +#define CONFIG_BOOTCOMMAND "diskboot 200000 0:1; bootm" /* autoboot command */ +#define CONFIG_BOOTARGS "console=ttyS0,9600 root=/dev/hda5" /* boot arguments */ + +#define CONFIG_IPADDR 10.0.0.100 +#define CONFIG_SERVERIP 10.0.0.1 + +/*************************************************************** + * defines if the console is stored in the environment + ***************************************************************/ +#define CFG_CONSOLE_IS_IN_ENV /* stdin, stdout and stderr are in evironment */ +/*************************************************************** + * defines if an overwrite_console function exists + *************************************************************/ +#define CFG_CONSOLE_OVERWRITE_ROUTINE + +/*************************************************************** + * defines if the overwrite_console should be stored in the + * environment + **************************************************************/ +#undef CFG_CONSOLE_ENV_OVERWRITE + +/************************************************************** + * loads config + *************************************************************/ +#define CONFIG_LOADS_ECHO 1 /* echo on for serial download */ +#define CFG_LOADS_BAUD_CHANGE 1 /* allow baudrate change */ + + +/*********************************************************** + * Miscellaneous configurable options + **********************************************************/ +#define CFG_LONGHELP /* undef to save memory */ +#define CFG_PROMPT "=> " /* Monitor Command Prompt */ +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) +#define CFG_CBSIZE 1024 /* Console I/O Buffer Size */ +#else +#define CFG_CBSIZE 256 /* Console I/O Buffer Size */ +#endif +#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */ +#define CFG_MAXARGS 16 /* max number of command args */ +#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer Size */ + +#define CFG_MEMTEST_START 0x0400000 /* memtest works on */ +#define CFG_MEMTEST_END 0x0C00000 /* 4 ... 12 MB in DRAM */ + +#undef CFG_EXT_SERIAL_CLOCK /* no external serial clock used */ + +/* The following table includes the supported baudrates */ +#define CFG_BAUDRATE_TABLE \ + { 300, 600, 1200, 2400, 4800, 9600, 19200, 38400, \ + 57600, 115200, 230400, 460800, 921600 } + +#define CFG_CLKS_IN_HZ 1 /* everything, incl board info, in Hz */ + +#define CFG_LOAD_ADDR 0x200000 /* default load address */ +#define CFG_EXTBDINFO 1 /* To use extended board_into (bd_t) */ + +#define CFG_HZ 1000 /* decrementer freq: 1 ms ticks */ + +/*----------------------------------------------------------------------- + * PCI stuff + *----------------------------------------------------------------------- + */ +#define CONFIG_PCI /* include pci support */ +#define CONFIG_PCI_HOST /* configure as pci-host */ +#define CONFIG_PCI_PNP /* pci plug-and-play */ + /* resource configuration */ +#define CFG_PCI_SUBSYS_VENDORID 0x0000 /* PCI Vendor ID: to-do!!! */ +#define CFG_PCI_SUBSYS_DEVICEID 0x0000 /* PCI Device ID: to-do!!! */ +#define CFG_PCI_PTM1LA 0x00000000 /* point to sdram */ +#define CFG_PCI_PTM1MS 0x80000001 /* 2GB, enable hard-wired to 1 */ +#define CFG_PCI_PTM2LA 0x00000000 /* disabled */ +#define CFG_PCI_PTM2MS 0x00000000 /* disabled */ + +/*----------------------------------------------------------------------- + * Start addresses for the final memory configuration + * (Set up by the startup code) + * Please note that CFG_SDRAM_BASE _must_ start at 0 + */ +#define CFG_SDRAM_BASE 0x00000000 +#define CFG_FLASH_BASE 0xFFF80000 +#define CFG_MONITOR_BASE CFG_FLASH_BASE +#define CFG_MONITOR_LEN (512 * 1024) /* Reserve 512 kB for Monitor */ +#define CFG_MALLOC_LEN (128 * 1024) /* Reserve 128 kB for malloc() */ + +/* + * For booting Linux, the board info and command line data + * have to be in the first 8 MB of memory, since this is + * the maximum mapped by the Linux kernel during initialization. + */ +#define CFG_BOOTMAPSZ (8 << 20) /* Initial Memory map for Linux */ +/*----------------------------------------------------------------------- + * FLASH organization + */ +#define CFG_MAX_FLASH_BANKS 1 /* max number of memory banks */ +#define CFG_MAX_FLASH_SECT 256 /* max number of sectors on one chip */ + +#define CFG_FLASH_ERASE_TOUT 120000 /* Timeout for Flash Erase (in ms) */ +#define CFG_FLASH_WRITE_TOUT 500 /* Timeout for Flash Write (in ms) */ + +/*----------------------------------------------------------------------- + * Cache Configuration + */ +#define CFG_CACHELINE_SIZE 16 /* For all MPC8xx CPUs */ +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) +#define CFG_CACHELINE_SHIFT 4 /* log base 2 of the above value */ +#endif + +/* + * Init Memory Controller: + */ + +#define FLASH_BASE0_PRELIM 0xFFC00000 /* FLASH bank #0 */ +#define FLASH_BASE1_PRELIM 0 /* FLASH bank #1 */ + + +/* On Chip Memory location */ +#define OCM_DATA_ADDR 0xF0000000 + +/* Configuration Port location */ +#define CONFIG_PORT_ADDR 0xF4000000 +#define MULTI_PURPOSE_SOCKET_ADDR 0xF8000000 + + + +/*----------------------------------------------------------------------- + * Definitions for initial stack pointer and data area (in On Chip SRAM) + */ +#define CFG_INIT_RAM_ADDR OCM_DATA_ADDR /* inside of On Chip SRAM */ +#define CFG_INIT_RAM_END 0x1000 /* End of On Chip SRAM */ +#define CFG_INIT_DATA_SIZE 64 /* size in bytes reserved for initial data */ +#define CFG_INIT_DATA_OFFSET (CFG_INIT_RAM_END - CFG_INIT_DATA_SIZE) +#define CFG_INIT_SP_OFFSET CFG_INIT_DATA_OFFSET + +/* + * Internal Definitions + * + * Boot Flags + */ +#define BOOTFLAG_COLD 0x01 /* Normal Power-On: Boot from FLASH */ +#define BOOTFLAG_WARM 0x02 /* Software reboot */ + + +/*********************************************************************** + * External peripheral base address + ***********************************************************************/ +#define CFG_ISA_IO_BASE_ADDRESS 0xE8000000 + + +/************************************************************ + * Ethernet Stuff + ***********************************************************/ +#define CONFIG_PHY_ADDR 1 /* PHY address */ + +/************************************************************ + * RTC + ***********************************************************/ +#define CONFIG_RTC_MC146818 +#undef CONFIG_WATCHDOG /* watchdog disabled */ + +/************************************************************ + * IDE/ATA stuff + ************************************************************/ +#define CFG_IDE_MAXBUS 2 /* max. 2 IDE busses */ +#define CFG_IDE_MAXDEVICE (CFG_IDE_MAXBUS*2) /* max. 2 drives per IDE bus */ + +#define CFG_ATA_BASE_ADDR CFG_ISA_IO_BASE_ADDRESS /* base address */ +#define CFG_ATA_IDE0_OFFSET 0x01F0 /* ide0 offste */ +#define CFG_ATA_IDE1_OFFSET 0x0170 /* ide1 offset */ +#define CFG_ATA_DATA_OFFSET 0 /* data reg offset */ +#define CFG_ATA_REG_OFFSET 0 /* reg offset */ +#define CFG_ATA_ALT_OFFSET 0x200 /* alternate register offset */ + +#undef CONFIG_IDE_PCMCIA /* no pcmcia interface required */ +#undef CONFIG_IDE_LED /* no led for ide supported */ +#define CONFIG_IDE_RESET /* reset for ide supported... */ +#define CONFIG_IDE_RESET_ROUTINE /* with a special reset function */ + +/************************************************************ + * ATAPI support (experimental) + ************************************************************/ +#define CONFIG_ATAPI /* enable ATAPI Support */ + +/************************************************************ + * SCSI support (experimental) only SYM53C8xx supported + ************************************************************/ +#define CONFIG_SCSI_SYM53C8XX +#define CFG_SCSI_MAX_LUN 8 /* number of supported LUNs */ +#define CFG_SCSI_MAX_SCSI_ID 7 /* maximum SCSI ID (0..6) */ +#define CFG_SCSI_MAX_DEVICE CFG_SCSI_MAX_SCSI_ID * CFG_SCSI_MAX_LUN /* maximum Target devices */ + +/************************************************************ + * DISK Partition support + ************************************************************/ +#define CONFIG_DOS_PARTITION +#define CONFIG_MAC_PARTITION +#define CONFIG_ISO_PARTITION /* Experimental */ + +/************************************************************ + * Keyboard support + ************************************************************/ +#define CONFIG_ISA_KEYBOARD + +/************************************************************ + * Video support + ************************************************************/ +#define CONFIG_VIDEO /*To enable video controller support */ +#define CONFIG_VIDEO_CT69000 + +/************************************************************ + * Debug support + ************************************************************/ +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) +#define CONFIG_KGDB_BAUDRATE 230400 /* speed to run kgdb serial port */ +#define CONFIG_KGDB_SER_INDEX 2 /* which serial port to use */ +#endif + +/************************************************************ + * Ident + ************************************************************/ +#define VERSION_TAG "REL_1.0.0" +#define CONFIG_IDENT_STRING "\n(c) 2001 by MPL AG Switzerland, MEV-10066-001 " VERSION_TAG + + +#endif /* __CONFIG_H */ diff --git a/include/config_hymod.h b/include/config_hymod.h index 8b7cf7a..3ff9e2f 100644 --- a/include/config_hymod.h +++ b/include/config_hymod.h @@ -94,6 +94,8 @@ CFG_CMD_PCI | \ CFG_CMD_DATE | \ CFG_CMD_BEDBUG | \ + CFG_CMD_FDC | \ + CFG_CMD_SCSI | \ CFG_CMD_EEPROM ) ) /* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */ diff --git a/include/flash.h b/include/flash.h index 9510e4c..af7b7bd 100644 --- a/include/flash.h +++ b/include/flash.h @@ -127,6 +127,7 @@ int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt); #define INTEL_ID_28F160B3T 0x88908890 /* 16M = 1M x 16 top boot sector */ #define INTEL_ID_28F160B3B 0x88918891 /* 16M = 1M x 16 bottom boot sector */ #define INTEL_ID_28F320B3T 0x88968896 /* 32M = 2M x 16 top boot sector */ +#define INTEL_ID_28F320C3T 0x88C488C4 /* 32M = 2M x 16 top boot sector */ #define INTEL_ID_28F320B3B 0x88978897 /* 32M = 2M x 16 bottom boot sector */ #define INTEL_ID_28F640B3T 0x88988898 /* 64M = 4M x 16 top boot sector */ #define INTEL_ID_28F640B3B 0x88998899 /* 64M = 4M x 16 bottom boot sector */ diff --git a/include/i2c.h b/include/i2c.h index 953fc62..6f3d4be 100644 --- a/include/i2c.h +++ b/include/i2c.h @@ -22,7 +22,8 @@ void i2c_write (uchar *addr, int alen, uchar *buffer, int len); #if defined(CONFIG_CPCI405) || defined(CONFIG_AR405) || \ - defined (CONFIG_WALNUT405) || defined (CONFIG_ERIC) + defined (CONFIG_WALNUT405) || defined (CONFIG_ERIC) || \ + defined (CONFIG_PIP405) void i2c_init(void); int i2c_receive(unsigned char address, diff --git a/include/image.h b/include/image.h index 2c5c061..273d546 100644 --- a/include/image.h +++ b/include/image.h @@ -44,6 +44,7 @@ #define IH_OS_VXWORKS 14 /* VxWorks */ #define IH_OS_PSOS 15 /* pSOS */ #define IH_OS_QNX 16 /* QNX */ +#define IH_OS_PPCBOOT 17 /* Firmware */ /* * CPU Architecture Codes (supported by Linux) @@ -96,6 +97,7 @@ #define IH_TYPE_KERNEL 2 /* OS Kernel Image */ #define IH_TYPE_RAMDISK 3 /* RAMDisk Image */ #define IH_TYPE_MULTI 4 /* Multi-File Image */ +#define IH_TYPE_FIRMWARE 5 /* Binary Image to be programmed in the flash */ /* * Compression Types diff --git a/include/part.h b/include/part.h new file mode 100644 index 0000000..02fefff --- /dev/null +++ b/include/part.h @@ -0,0 +1,97 @@ +/* + * (C) Copyright 2000, 2001 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#ifndef _PART_H +#define _PART_H + + +typedef struct block_dev_desc { + int if_type; /* type of the interface */ + int dev; /* device number */ + unsigned char part_type; /* partition type */ + unsigned char target; /* target SCSI ID */ + unsigned char lun; /* target LUN */ + unsigned char type; /* device type */ + unsigned long lba; /* number of blocks */ + unsigned long blksz; /* block size */ + unsigned char vendor[40]; /* IDE model, SCSI Vendor */ + unsigned char product[20];/* IDE Serial no, SCSI product */ + unsigned char revision[8];/* firmware revision */ + unsigned char removable; /* removable device */ + unsigned long (*block_read)(int dev,unsigned long start,unsigned long blkcnt, unsigned long *buffer); +}block_dev_desc_t; +/* Interface types: */ +#define IF_TYPE_UNKNOWN 0 +#define IF_TYPE_IDE 1 +#define IF_TYPE_SCSI 2 +#define IF_TYPE_ATAPI 3 +/* Part types */ +#define PART_TYPE_UNKNOWN 0x00 +#define PART_TYPE_MAC 0x01 +#define PART_TYPE_DOS 0x02 +#define PART_TYPE_ISO 0x03 +/* device types */ +#define DEV_TYPE_UNKNOWN 0xff /* not connected */ +#define DEV_TYPE_HARDDISK 0x00 /* harddisk */ +#define DEV_TYPE_TAPE 0x01 /* Tape */ +#define DEV_TYPE_CDROM 0x05 /* CD-ROM */ +#define DEV_TYPE_OPDISK 0x07 /* optical disk */ + +typedef struct disk_partition { + ulong start; /* # of first block in partition */ + ulong size; /* number of blocks in partition */ + ulong blksz; /* block size in bytes */ + uchar name[32]; /* partition name */ + uchar type[32]; /* string type description */ +} disk_partition_t; + +/* disk/part.c */ +int get_partition_info (block_dev_desc_t * dev_desc, int part, disk_partition_t *info); +void print_part (block_dev_desc_t *dev_desc); +void init_part (block_dev_desc_t *dev_desc); +void dev_print(block_dev_desc_t *dev_desc); + + +#ifdef CONFIG_MAC_PARTITION +/* disk/part_mac.c */ +int get_partition_info_mac (block_dev_desc_t * dev_desc, int part, disk_partition_t *info); +void print_part_mac (block_dev_desc_t *dev_desc); +int test_part_mac (block_dev_desc_t *dev_desc); +#endif + +#ifdef CONFIG_DOS_PARTITION +/* disk/part_dos.c */ +int get_partition_info_dos (block_dev_desc_t * dev_desc, int part, disk_partition_t *info); +void print_part_dos (block_dev_desc_t *dev_desc); +int test_part_dos (block_dev_desc_t *dev_desc); +#endif + +#ifdef CONFIG_ISO_PARTITION +/* disk/part_iso.c */ +int get_partition_info_iso (block_dev_desc_t * dev_desc, int part, disk_partition_t *info); +void print_part_iso (block_dev_desc_t *dev_desc); +int test_part_iso (block_dev_desc_t *dev_desc); +#endif + +#endif /* _PART_H */ + + diff --git a/include/ppcboot.h b/include/ppcboot.h index 8927ad8..e95293f 100644 --- a/include/ppcboot.h +++ b/include/ppcboot.h @@ -49,6 +49,7 @@ typedef volatile unsigned short vu_short; #include #endif +#include #include #include @@ -188,6 +189,7 @@ void inline setenv (char *, char *); #if defined(CONFIG_CPCI405) || \ defined(CONFIG_AR405) || \ defined (CONFIG_WALNUT405) || \ + defined (CONFIG_PIP405) || \ defined (CONFIG_CPCIISER4) || \ defined (CONFIG_ERIC) /* $(CPU)/405gp_pci.c */ @@ -198,7 +200,7 @@ void pciinfo (int); #if defined(CONFIG_COGENT) || defined(CONFIG_SXNI855T) || \ defined(CONFIG_RSD_PROTO) || defined(CONFIG_HYMOD) || \ defined(CONFIG_CPCI405) || defined(CONFIG_PCU_E) || \ - defined(CONFIG_EVB64260) + defined(CONFIG_EVB64260) || defined(CONFIG_LWMON) /* cogent - $(BOARD)/mb.c */ /* SXNI855T and HYMOD - $(BOARD)/$(BOARD).c */ # ifndef CONFIG_PCU_E @@ -223,6 +225,7 @@ void reset_phy (void); defined(CONFIG_CPCI405) || \ defined(CONFIG_CANBT) || \ defined(CONFIG_WALNUT405) || \ + defined(CONFIG_PIP405) || \ defined(CONFIG_CPCIISER4) || \ defined(CONFIG_LWMON) || \ defined(CONFIG_TQM8260) || \ @@ -272,6 +275,7 @@ void perform_soft_reset(void); defined(CONFIG_AR405) || \ defined(CONFIG_CANBT) || \ defined(CONFIG_WALNUT405) || \ + defined(CONFIG_PIP405) || \ defined(CONFIG_CPCIISER4) || \ defined(CONFIG_ADCIOP) || \ defined(CONFIG_LWMON) || \ @@ -350,6 +354,9 @@ void prt_8260_clks (void); defined(CONFIG_CU824) ulong get_gclk_freq (void); ulong get_OPB_freq (void); +#ifdef CONFIG_PPC405 +ulong get_PCI_freq (void); +#endif #endif ulong get_bus_freq (ulong); @@ -404,20 +411,6 @@ int vsprintf(char *buf, const char *fmt, va_list args); /* ppc/crc32.c */ ulong crc32 (ulong, const unsigned char *, uint); -#ifdef CONFIG_MAC_PARTITION -/* disk/part_mac.c */ -void print_part_mac (int); -int test_part_mac (int); -#endif -#ifdef CONFIG_DOS_PARTITION -/* disk/part_dos.c */ -void print_part_dos (int); -int test_part_dos (int); -#endif -/* disk/part.c */ -void print_part (int); -void init_part (int); - /* common/console.c */ bd_t *bd_ptr ; diff --git a/include/scsi.h b/include/scsi.h new file mode 100644 index 0000000..27ed924 --- /dev/null +++ b/include/scsi.h @@ -0,0 +1,213 @@ +/* + * (C) Copyright 2001 + * Denis Peter, MPL AG Switzerland + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + #ifndef _SCSI_H + #define _SCSI_H + +typedef struct SCSI_cmd_block{ + unsigned char cmd[16]; /* command */ + unsigned char sense_buf[64]; /* for request sense */ + unsigned char status; /* SCSI Status */ + unsigned char target; /* Target ID */ + unsigned char lun; /* Target LUN */ + unsigned char cmdlen; /* command len */ + unsigned long datalen; /* Total data length */ + unsigned char * pdata; /* pointer to data */ + unsigned char msgout[12]; /* Messge out buffer (NOT USED) */ + unsigned char msgin[12]; /* Message in buffer */ + unsigned char sensecmdlen; /* Sense command len */ + unsigned long sensedatalen; /* Sense data len */ + unsigned char sensecmd[6]; /* Sense command */ + unsigned long contr_stat; /* Controller Status */ + unsigned long trans_bytes; /* tranfered bytes */ +}ccb; + +/*----------------------------------------------------------- +** +** SCSI constants. +** +**----------------------------------------------------------- +*/ + +/* +** Messages +*/ + +#define M_COMPLETE (0x00) +#define M_EXTENDED (0x01) +#define M_SAVE_DP (0x02) +#define M_RESTORE_DP (0x03) +#define M_DISCONNECT (0x04) +#define M_ID_ERROR (0x05) +#define M_ABORT (0x06) +#define M_REJECT (0x07) +#define M_NOOP (0x08) +#define M_PARITY (0x09) +#define M_LCOMPLETE (0x0a) +#define M_FCOMPLETE (0x0b) +#define M_RESET (0x0c) +#define M_ABORT_TAG (0x0d) +#define M_CLEAR_QUEUE (0x0e) +#define M_INIT_REC (0x0f) +#define M_REL_REC (0x10) +#define M_TERMINATE (0x11) +#define M_SIMPLE_TAG (0x20) +#define M_HEAD_TAG (0x21) +#define M_ORDERED_TAG (0x22) +#define M_IGN_RESIDUE (0x23) +#define M_IDENTIFY (0x80) + +#define M_X_MODIFY_DP (0x00) +#define M_X_SYNC_REQ (0x01) +#define M_X_WIDE_REQ (0x03) +#define M_X_PPR_REQ (0x04) + + +/* +** Status +*/ + +#define S_GOOD (0x00) +#define S_CHECK_COND (0x02) +#define S_COND_MET (0x04) +#define S_BUSY (0x08) +#define S_INT (0x10) +#define S_INT_COND_MET (0x14) +#define S_CONFLICT (0x18) +#define S_TERMINATED (0x20) +#define S_QUEUE_FULL (0x28) +#define S_ILLEGAL (0xff) +#define S_SENSE (0x80) + +/* + * Sense_keys + */ + +#define SENSE_NO_SENSE 0x0 +#define SENSE_RECOVERED_ERROR 0x1 +#define SENSE_NOT_READY 0x2 +#define SENSE_MEDIUM_ERROR 0x3 +#define SENSE_HARDWARE_ERROR 0x4 +#define SENSE_ILLEGAL_REQUEST 0x5 +#define SENSE_UNIT_ATTENTION 0x6 +#define SENSE_DATA_PROTECT 0x7 +#define SENSE_BLANK_CHECK 0x8 +#define SENSE_VENDOR_SPECIFIC 0x9 +#define SENSE_COPY_ABORTED 0xA +#define SENSE_ABORTED_COMMAND 0xB +#define SENSE_VOLUME_OVERFLOW 0xD +#define SENSE_MISCOMPARE 0xE + + +#define SCSI_CHANGE_DEF 0x40 /* Change Definition (Optional) */ +#define SCSI_COMPARE 0x39 /* Compare (O) */ +#define SCSI_COPY 0x18 /* Copy (O) */ +#define SCSI_COP_VERIFY 0x3A /* Copy and Verify (O) */ +#define SCSI_INQUIRY 0x12 /* Inquiry (MANDATORY) */ +#define SCSI_LOG_SELECT 0x4C /* Log Select (O) */ +#define SCSI_LOG_SENSE 0x4D /* Log Sense (O) */ +#define SCSI_MODE_SEL6 0x15 /* Mode Select 6-byte (Device Specific) */ +#define SCSI_MODE_SEL10 0x55 /* Mode Select 10-byte (Device Specific) */ +#define SCSI_MODE_SEN6 0x1A /* Mode Sense 6-byte (Device Specific) */ +#define SCSI_MODE_SEN10 0x5A /* Mode Sense 10-byte (Device Specific) */ +#define SCSI_READ_BUFF 0x3C /* Read Buffer (O) */ +#define SCSI_REQ_SENSE 0x03 /* Request Sense (MANDATORY) */ +#define SCSI_SEND_DIAG 0x1D /* Send Diagnostic (O) */ +#define SCSI_TST_U_RDY 0x00 /* Test Unit Ready (MANDATORY) */ +#define SCSI_WRITE_BUFF 0x3B /* Write Buffer (O) */ +/*************************************************************************** + * %%% Commands Unique to Direct Access Devices %%% + ***************************************************************************/ +#define SCSI_COMPARE 0x39 /* Compare (O) */ +#define SCSI_FORMAT 0x04 /* Format Unit (MANDATORY) */ +#define SCSI_LCK_UN_CAC 0x36 /* Lock Unlock Cache (O) */ +#define SCSI_PREFETCH 0x34 /* Prefetch (O) */ +#define SCSI_MED_REMOVL 0x1E /* Prevent/Allow medium Removal (O) */ +#define SCSI_READ6 0x08 /* Read 6-byte (MANDATORY) */ +#define SCSI_READ10 0x28 /* Read 10-byte (MANDATORY) */ +#define SCSI_RD_CAPAC 0x25 /* Read Capacity (MANDATORY) */ +#define SCSI_RD_DEFECT 0x37 /* Read Defect Data (O) */ +#define SCSI_READ_LONG 0x3E /* Read Long (O) */ +#define SCSI_REASS_BLK 0x07 /* Reassign Blocks (O) */ +#define SCSI_RCV_DIAG 0x1C /* Receive Diagnostic Results (O) */ +#define SCSI_RELEASE 0x17 /* Release Unit (MANDATORY) */ +#define SCSI_REZERO 0x01 /* Rezero Unit (O) */ +#define SCSI_SRCH_DAT_E 0x31 /* Search Data Equal (O) */ +#define SCSI_SRCH_DAT_H 0x30 /* Search Data High (O) */ +#define SCSI_SRCH_DAT_L 0x32 /* Search Data Low (O) */ +#define SCSI_SEEK6 0x0B /* Seek 6-Byte (O) */ +#define SCSI_SEEK10 0x2B /* Seek 10-Byte (O) */ +#define SCSI_SEND_DIAG 0x1D /* Send Diagnostics (MANDATORY) */ +#define SCSI_SET_LIMIT 0x33 /* Set Limits (O) */ +#define SCSI_START_STP 0x1B /* Start/Stop Unit (O) */ +#define SCSI_SYNC_CACHE 0x35 /* Synchronize Cache (O) */ +#define SCSI_VERIFY 0x2F /* Verify (O) */ +#define SCSI_WRITE6 0x0A /* Write 6-Byte (MANDATORY) */ +#define SCSI_WRITE10 0x2A /* Write 10-Byte (MANDATORY) */ +#define SCSI_WRT_VERIFY 0x2E /* Write and Verify (O) */ +#define SCSI_WRITE_LONG 0x3F /* Write Long (O) */ +#define SCSI_WRITE_SAME 0x41 /* Write Same (O) */ + + +/**************************************************************************** + * decleration of functions which have to reside in the LowLevel Part Driver + */ + +void scsi_print_error(ccb *pccb); +int scsi_exec(ccb *pccb); +void scsi_bus_reset(void); +void scsi_low_level_init(int busdevfunc); + + +/*************************************************************************** + * functions residing inside cmd_scsi.c + */ +void scsi_init(void); + + + +#define SCSI_IDENTIFY 0xC0 /* not used */ + +/* Hardware errors */ +#define SCSI_SEL_TIME_OUT 0x00000101 /* Selection time out */ +#define SCSI_HNS_TIME_OUT 0x00000102 /* Handshake */ +#define SCSI_MA_TIME_OUT 0x00000103 /* Phase error */ +#define SCSI_UNEXP_DIS 0x00000104 /* unexpected disconnect */ + +#define SCSI_INT_STATE 0x00010000 /* unknown Interrupt number is stored in 16 LSB */ + + + +#ifndef TRUE +#define TRUE 1 +#endif +#ifndef FALSE +#define FALSE 0 +#endif + + + + + +#endif /* _SCSI_H */ + diff --git a/include/version.h b/include/version.h index e3e4dce..e2d5df5 100644 --- a/include/version.h +++ b/include/version.h @@ -24,6 +24,6 @@ #ifndef __VERSION_H__ #define __VERSION_H__ -#define PPCBOOT_VERSION "PPCBoot 1.0.1" +#define PPCBOOT_VERSION "PPCBoot 1.0.2" #endif /* __VERSION_H__ */ diff --git a/rtc/Makefile b/rtc/Makefile index 7435d81..db29c61 100644 --- a/rtc/Makefile +++ b/rtc/Makefile @@ -27,7 +27,7 @@ include $(TOPDIR)/config.mk LIB = librtc.a -OBJS = date.o pcf8563.o mpc8xx.o +OBJS = date.o pcf8563.o mpc8xx.o mc146818.o all: $(LIB) diff --git a/rtc/mc146818.c b/rtc/mc146818.c new file mode 100644 index 0000000..6469391 --- /dev/null +++ b/rtc/mc146818.c @@ -0,0 +1,157 @@ +/* + * (C) Copyright 2001 + * Denis Peter MPL AG Switzerland. d.peter@mpl.ch + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* + * Date & Time support for the MC146818 (PIXX4) RTC + */ + +/*#define DEBUG*/ + +#include +#include +#include + +#if defined(CONFIG_RTC_MC146818) && (CONFIG_COMMANDS & CFG_CMD_DATE) + +static uchar rtc_read (uchar reg); +static void rtc_write (uchar reg, uchar val); +static uchar bin2bcd (unsigned int n); +static unsigned bcd2bin(uchar c); + +#define RTC_PORT_MC146818 CFG_ISA_IO_BASE_ADDRESS + 0x70 +#define RTC_SECONDS 0x00 +#define RTC_SECONDS_ALARM 0x01 +#define RTC_MINUTES 0x02 +#define RTC_MINUTES_ALARM 0x03 +#define RTC_HOURS 0x04 +#define RTC_HOURS_ALARM 0x05 +#define RTC_DAY_OF_WEEK 0x06 +#define RTC_DATE_OF_MONTH 0x07 +#define RTC_MONTH 0x08 +#define RTC_YEAR 0x09 +#define RTC_CONFIG_A 0x0A +#define RTC_CONFIG_B 0x0B +#define RTC_CONFIG_C 0x0C +#define RTC_CONFIG_D 0x0D + + +/* ------------------------------------------------------------------------- */ + +void rtc_get (struct rtc_time *tmp) +{ + uchar sec, min, hour, mday, wday, mon, year; + /* here check if rtc can be accessed */ + while((rtc_read(RTC_CONFIG_A)&0x80)==0x80); + sec = rtc_read (RTC_SECONDS); + min = rtc_read (RTC_MINUTES); + hour = rtc_read (RTC_HOURS); + mday = rtc_read (RTC_DATE_OF_MONTH); + wday = rtc_read (RTC_DAY_OF_WEEK); + mon = rtc_read (RTC_MONTH); + year = rtc_read (RTC_YEAR); +#ifdef RTC_DEBUG + printf ( "Get RTC year: %02x mon/cent: %02x mday: %02x wday: %02x " + "hr: %02x min: %02x sec: %02x\n", + year, mon_cent, mday, wday, + hour, min, sec ); + printf ( "Alarms: month: %02x hour: %02x min: %02x sec: %02x\n", + rtc_read (RTC_CONFIG_D) & 0x3F, + rtc_read (RTC_HOURS_ALARM), + rtc_read (RTC_MINUTES_ALARM), + rtc_read (RTC_SECONDS_ALARM) ); +#endif + tmp->tm_sec = bcd2bin (sec & 0x7F); + tmp->tm_min = bcd2bin (min & 0x7F); + tmp->tm_hour = bcd2bin (hour & 0x3F); + tmp->tm_mday = bcd2bin (mday & 0x3F); + tmp->tm_mon = bcd2bin (mon & 0x1F); + tmp->tm_year = bcd2bin (year); + tmp->tm_wday = bcd2bin (wday & 0x07); + if(tmp->tm_year<70) + tmp->tm_year+=2000; + else + tmp->tm_year+=1900; + tmp->tm_yday = 0; + tmp->tm_isdst= 0; +#ifdef RTC_DEBUG + printf ( "Get DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", + tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, + tmp->tm_hour, tmp->tm_min, tmp->tm_sec); +#endif +} + +void rtc_set (struct rtc_time *tmp) +{ +#ifdef RTC_DEBUG + printf ( "Set DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", + tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, + tmp->tm_hour, tmp->tm_min, tmp->tm_sec); +#endif + rtc_write(RTC_CONFIG_B,0x82); /* disables the RTC to update the regs */ + + rtc_write (RTC_YEAR, bin2bcd(tmp->tm_year % 100)); + rtc_write (RTC_MONTH, bin2bcd(tmp->tm_mon)); + + rtc_write (RTC_DAY_OF_WEEK, bin2bcd(tmp->tm_wday)); + rtc_write (RTC_DATE_OF_MONTH, bin2bcd(tmp->tm_mday)); + rtc_write (RTC_HOURS, bin2bcd(tmp->tm_hour)); + rtc_write (RTC_MINUTES, bin2bcd(tmp->tm_min )); + rtc_write (RTC_SECONDS, bin2bcd(tmp->tm_sec )); + rtc_write(RTC_CONFIG_B,0x02); /* enables the RTC to update the regs */ + +} + +void rtc_reset (void) +{ + rtc_write(RTC_CONFIG_B,0x82); /* disables the RTC to update the regs */ + rtc_write(RTC_CONFIG_A,0x20); /* Normal OP */ + rtc_write(RTC_CONFIG_B,0x00); + rtc_write(RTC_CONFIG_B,0x00); + rtc_write(RTC_CONFIG_B,0x02); /* enables the RTC to update the regs */ +} + +/* ------------------------------------------------------------------------- */ + +static uchar rtc_read (uchar reg) +{ + out8(RTC_PORT_MC146818,reg); + return(in8(RTC_PORT_MC146818+1)); +} + +static void rtc_write (uchar reg, uchar val) +{ + out8(RTC_PORT_MC146818,reg); + out8(RTC_PORT_MC146818+1,val); +} + +static unsigned bcd2bin (uchar n) +{ + return ((((n >> 4) & 0x0F) * 10) + (n & 0x0F)); +} + +static unsigned char bin2bcd (unsigned int n) +{ + return (((n / 10) << 4) | (n % 10)); +} + +#endif /* CONFIG_RTC_MC146818 && CFG_CMD_DATE */ diff --git a/tools/mkimage.c b/tools/mkimage.c index 7f2a67e..c4e9255 100644 --- a/tools/mkimage.c +++ b/tools/mkimage.c @@ -91,6 +91,7 @@ table_entry_t os_name[] = { { IH_OS_VXWORKS, "vxworks", "VxWorks", }, { IH_OS_PSOS, "psos", "pSOS", }, { IH_OS_QNX, "qnx", "QNX", }, + { IH_OS_PPCBOOT, "ppcboot", "PPCBoot", }, { -1, "", "", }, }; @@ -100,6 +101,7 @@ table_entry_t type_name[] = { { IH_TYPE_KERNEL, "kernel", "Kernel Image", }, { IH_TYPE_RAMDISK, "ramdisk", "RAMDisk Image", }, { IH_TYPE_MULTI, "multi", "Multi-File Image", }, + { IH_TYPE_FIRMWARE, "firmware", "Firmware", }, { -1, "", "", }, };